Skip to content

[Pyomo.DoE] Add simultaneous design of multiple experiments#3866

Open
smondal13 wants to merge 101 commits intoPyomo:mainfrom
smondal13:add-multiexperiment
Open

[Pyomo.DoE] Add simultaneous design of multiple experiments#3866
smondal13 wants to merge 101 commits intoPyomo:mainfrom
smondal13:add-multiexperiment

Conversation

@smondal13
Copy link
Contributor

Fixes # .

Summary/Motivation:

This PR adds a new DesignOfExperiments.optimize_experiments() API in pyomo/contrib/doe/doe.py to support simultaneous optimization of multiple experiments in one workflow. The motivation is to provide a first-class multi-experiment DoE interface with stronger initialization options, clearer mode handling (template vs. user-initialized experiments), and richer diagnostics/results than the existing single-experiment path.

Changes proposed in this PR:

  • Added public API optimize_experiments() for multi-experiment DoE optimization.
  • Implemented two operating modes:
    • Template mode: pass one experiment and set n_exp.
    • User-initialized mode: pass a list of experiments; n_exp is inferred/validated.
  • Added optional LHS-based initialization (initialization_method="lhs") with controls for:
    • sample count, seed, candidate evaluation parallelism, combination fim metric scoring parallelism,
    • worker count, chunk size, parallel threshold, and optional wall-clock budget.
  • Added symmetry-breaking constraints for multi-experiment solves:
    • supports user-specified variable through sym_break_cons suffix,
    • falls back to the first experiment input with a diagnostic warning when not provided.
  • Expanded output payload for this API:
    • per-scenario and per-experiment results (designs, outputs, measurement errors, FIM/sensitivities),
    • aggregated FIM metrics, timings, settings, names, diagnostics, and structured run_info.
  • Added JSON-safe serialization via _DoEResultsJSONEncoder for numpy/Pyomo-enum values when writing results_file.

Legal Acknowledgement

By contributing to this software project, I have read the contribution guide and agree to the following terms and conditions for my contribution:

  1. I agree my contributions are submitted under the BSD license.
  2. I represent I am authorized to make the contributions and grant the license. If my employer has rights to intellectual property that includes these contributions, I represent that I have received permission to make contributions and grant the required license on behalf of that employer.

…d replace `self.experiment` with `self.experiment_list[0]`. `doe/reactor_example.py` runs successfully.
…sing the `doe/reactor_multi_experiment.py`
…nt for `optimize_experiments()` and `compute_FIM()`
… both of sensitivity and optimize_experiments()
…A-opt gave different result for grid and optimization
smondal13 added 14 commits March 2, 2026 10:59
…hance error messaging in optimize_experiments tests
…ion and add multi-experiment example using Rooney-Biegler model
- Moved various tests related to error handling and warnings from test_doe_solve.py to test_doe_errors.py to align with classification rules.
- Updated test_doe_errors.py to include new tests for initialization method validation and LHS sample size checks.
- Consolidated solver configuration into a helper method for cleaner test setup.
- Removed deprecated tests and ensured that all tests are focused on their respective intents (numerical, error handling, and structure).
- Added documentation for test classification and design review to improve clarity and maintainability.
- Addressed issues with test coverage and robustness, including mocking solver calls for unit tests.
]
sigma_inv = [1 / v for k, v in model.scenario_blocks[0].measurement_error.items()]
sigma_inv = [
1 / v for k, v in model.fd_scenario_blocks[0].measurement_error.items()
Copy link
Contributor Author

@smondal13 smondal13 Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have renamed the block from scenario_blocks to fd_scenario_blocks to make it clearer and avoid ambiguity with param_scenario_blocks, which we will use in the near future.

…experiment optimization in ReactorExperiment.
- Updated the `get_standard_args` function to use `experiment_list` instead of `experiment`.
- Added new tests for handling exceptions and fallbacks in FIM computation.
- Enhanced tests for parallel execution and timeout handling in LHS sampling.
- Removed the `test_multi_exp.py` file as it is no longer needed.
def __init__(
self,
experiment=None,
experiment_list=None,
Copy link
Contributor Author

@smondal13 smondal13 Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adowling2 , @blnicho Should we keep both experiment and experiment_list? The user can pass the experiment_list argument if the user wants to pass the user-initialized experiment object. Another option is to keep the experiment argument and make it able to accept list objects as well, and maybe use a hint, e.g., experiment: list.

Currently, I have added a deprecation warning for the experiment argument.

"The 'experiment' parameter in DesignOfExperiments is deprecated and "
"will be removed in a future version. "
"Please use 'experiment_list' instead.",
DeprecationWarning,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@blnicho Is this DeprecationWarning acceptable, or is there a different approach Pyomo recommends?

"variable": None,
"source": None,
}
diagnostics_warnings = []
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to propagate the warning to the final result, which may help the user.

…ing and improve error handling; add utility methods for enum labels and input fixing.

Run black
@smondal13
Copy link
Contributor Author

@blnicho @adowling2 This PR is ready for an initial review. Please take a look when you have a moment.

@blnicho blnicho self-requested a review March 3, 2026 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready for design review

Development

Successfully merging this pull request may close these issues.

1 participant