Multi-experiment design is useful when several experiments can be run in parallel. Instead of designing one experiment at a time, we optimize multiple experiments together so that they provide complementary information about the model parameters. In Pyomo.DoE, this is done by maximizing a scalar function of the sum of the Fisher information matrices from each experiment, together with any prior information.
Maximize a scalar-valued function of the sum of the Fisher information matrices :
Here, is the set of experiments in the experimental campaign.
For multi-experiment design, Pyomo.DoE automatically formulates, initializes, and solves this optimization problem for the following optimality criteria:
Maximizing , i.e., Pseudo A-optimality
Minimizing , i.e., A-optimality,
Maximizing , i.e., D-optimality.
Maximizing , i.e., E-optimality.
Minimizing , i.e., ME-optimality.
For documentation follow the Pyomo documentation page.
Import Necessary Functions for the Two-State TC Lab Model¶
import sys
# If running on Google Colab, install Pyomo and Ipopt via IDAES
on_colab = "google.colab" in sys.modules
if on_colab:
!wget "https://raw.githubusercontent.com/dowlinglab/pyomo-doe/main/notebooks/tclab_pyomo.py"
# import TCLab model, simulation, and data analysis functions
from tclab_pyomo import (
TC_Lab_data,
TC_Lab_experiment,
extract_plot_results,
results_summary,
)
# set default number of states in the TCLab model
number_tclab_states = 2--2026-05-24 18:25:54-- https://raw.githubusercontent.com/dowlinglab/pyomo-doe/main/notebooks/tclab_pyomo.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 46074 (45K) [text/plain]
Saving to: ‘tclab_pyomo.py.28’
tclab_pyomo.py.28 100%[===================>] 44.99K --.-KB/s in 0.01s
2026-05-24 18:25:54 (4.17 MB/s) - ‘tclab_pyomo.py.28’ saved [46074/46074]
Load Experimental Data (sine test)¶
We will load the sine test experimental data to serve as an initial point.
import pandas as pd
if on_colab:
file = "https://raw.githubusercontent.com/dowlinglab/pyomo-doe/main/data/tclab_sine_test_5min_period.csv"
else:
file = "../data/tclab_sine_test_5min_period.csv"
df = pd.read_csv(file)
df.head()Use Prior Parameter Information¶
We will use the parameter estimates and covariance matrix obtained in the previous notebook. Since the Fisher information matrix (FIM) is the inverse of the covariance matrix, we can use that result as prior information for the new design problem.
import numpy as np
# Load Pyomo.DoE class
from pyomo.contrib.doe import DesignOfExperiments
from pyomo.environ import SolverFactory
# Theta values estimated from the regularized regresssion in the previous notebook
# L2 regularization
theta_values = {
"Ua": 0.041705,
"Ub": 0.012009,
"inv_CpH": 0.167457,
"inv_CpS": 4.545432,
}
# Cov estimated from the regularized regression in the previous notebook
# L2 regularization
cov = np.array(
[
[1.857017e-10, -2.576198e-10, 1.402148e-09, -2.242347e-12],
[-2.576198e-10, 1.624383e-07, 9.109870e-08, -6.325555e-05],
[1.402148e-09, 9.109870e-08, 1.031454e-07, -3.890789e-05],
[-2.242347e-12, -6.325555e-05, -3.890789e-05, 2.499914e-02],
]
)
PRIOR_FIM = np.linalg.inv(cov)
results_summary(PRIOR_FIM)======Results Summary======
Five design criteria log10() value:
Pseudo A-optimality: 9.910298890895081
A-optimality: -1.6020703142934367
D-optimality: 27.781982236650116
E-optimality: 1.602071098791314
Modified E-optimality: 8.254407420205549
FIM:
[[ 7.17766325e+09 1.00811757e+08 -2.18902252e+08 -8.56071665e+04]
[ 1.00811757e+08 8.99331580e+08 1.51888631e+08 2.51198161e+06]
[-2.18902252e+08 1.51888631e+08 5.68992000e+07 4.72881315e+05]
[-8.56071665e+04 2.51198161e+06 4.72881315e+05 7.13206905e+03]]
eigenvalues:
[7.18585615e+09 9.25285788e+08 2.27591861e+07 4.00010230e+01]
Eigenvector matrix:
eigvec_1 eigvec_2 eigvec_3 eigvec_4
Ua 0.9994 0.0098 0.0326 -0.0000
Ub 0.0153 -0.9846 -0.1743 -0.0025
inv_CpH -0.0304 -0.1747 0.9842 -0.0016
inv_CpS -0.0000 -0.0028 0.0011 1.0000
from pyomo.contrib.doe.utils import rescale_FIM
theta_ref = np.array(
[
theta_values["Ua"],
theta_values["Ub"],
theta_values["inv_CpH"],
theta_values["inv_CpS"],
]
)
# Because the parameter values differ substantially in magnitude, we can use parameter
# scaling in DesignOfExperiments to improve numerical conditioning.
SCALE_BY_NOMINAL_PARAM = True
SCALE_CONSTANT_VALUE = 1e-2
if SCALE_BY_NOMINAL_PARAM:
PRIOR_FIM_SCALED = rescale_FIM(PRIOR_FIM, theta_ref) * SCALE_CONSTANT_VALUE**2
else:
PRIOR_FIM_SCALED = PRIOR_FIM * SCALE_CONSTANT_VALUE**2Initialize Two Experiments¶
We now create two experiment objects. The first uses the measured sine-test data, and the second uses a different initial input profile so that the optimizer can optimize both experiments simultaneously.
# Create the first experiment object
skip = 6
# Create the data object considering the new control points every 15 seconds
tc_data_1 = TC_Lab_data(
name="Sine Wave Test for Heater 1",
time=df["Time"].values[::skip],
T1=df["T1"].values[::skip],
u1=df["Q1"].values[::skip],
P1=200,
TS1_data=None,
T2=df["T2"].values[::skip],
u2=df["Q2"].values[::skip],
P2=200,
TS2_data=None,
Tamb=df["T1"].values[0],
)
# Create experiment object for design of experiments
doe_experiment_1 = TC_Lab_experiment(
data=tc_data_1,
theta_initial=theta_values,
number_of_states=number_tclab_states,
)# Create the second experiment object
from dataclasses import replace
# Set a random seed for reproducibility
SEED: int = 11 # Choose any integer seed you like
PDF = "uniform" # Choose between "normal" or "uniform" distribution for the new design of u1
def get_initial_u1_design(PDF="uniform", seed=11, sample_data=tc_data_1):
rng = np.random.default_rng(seed=seed)
if PDF == "normal":
u1_design = rng.normal(loc=50.0, scale=10.0, size=len(sample_data.time))
# Normal distribution is unbounded, so we need to clip the values to be within the
# bounds of the control input, which is [0, 100] in this case.
u1_design = np.clip(u1_design, 0.0, 100.0)
elif PDF == "uniform":
u1_design = rng.uniform(low=0.0, high=100.0, size=len(sample_data.time))
# To break permutation symmetry, we can enforce that the first value of u1_design
# is greater than the first value of the original u1 data.
if u1_design[0] <= sample_data.u1[0] and sample_data.u1[0] < 90.0:
u1_design[0] = sample_data.u1[0] + 10.0
else:
u1_design[0] = 100.0
# Create a new data object with only u1 replaced
tc_data_new = replace(sample_data, u1=u1_design)
return tc_data_new
tc_data_2 = get_initial_u1_design(PDF=PDF, seed=SEED, sample_data=tc_data_1)
# Build the experiment with the new design variable
doe_experiment_2 = TC_Lab_experiment(
data=tc_data_2,
theta_initial=theta_values,
number_of_states=number_tclab_states,
)Optimize Two Experiments (D-Optimality)¶
We now create a DesignOfExperiments object for the two experiments and choose a D-optimality objective. We also pass prior_FIM, which represents information already available from previous parameter estimation.
# Add a solver object to pass to DesignOfExperiments
solver = SolverFactory("ipopt")
solver.options["max_iter"] = 3000
solver.options["tol"] = 1e-5
solver.options["linear_solver"] = "ma57"
solver.options["nlp_scaling_method"] = "gradient-based"# Create the `design of experiments` object using our experiment instance from above
TC_Lab_DoE_D = DesignOfExperiments(
experiment=[doe_experiment_1, doe_experiment_2],
# We are optimizing two experiments simultaneously!
step=1e-2,
scale_constant_value=SCALE_CONSTANT_VALUE,
scale_nominal_param_value=SCALE_BY_NOMINAL_PARAM,
objective_option="determinant",
# Now we specify a type of objective, D-opt = "determinant"
prior_FIM=PRIOR_FIM_SCALED,
tee=True,
solver=solver,
)
# Optimize the experimental design
TC_Lab_DoE_D.optimize_experiments()WARNING:pyomo.contrib.doe.doe:No symmetry breaking variable specified. Automatically using the first experiment input 'U1[0.0]' for ordering constraints. To specify a different variable, add: m.sym_break_cons = pyo.Suffix(direction=pyo.Suffix.LOCAL); m.sym_break_cons[m.your_variable] = None
Ipopt 3.13.2: max_iter=3000
tol=1e-05
linear_solver=ma57
nlp_scaling_method=gradient-based
******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
Ipopt is released as open source code under the Eclipse Public License (EPL).
For more information visit http://projects.coin-or.org/Ipopt
This version of Ipopt was compiled from source code available at
https://github.com/IDAES/Ipopt as part of the Institute for the Design of
Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE
Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.
This version of Ipopt was compiled using HSL, a collection of Fortran codes
for large-scale scientific computation. All technical papers, sales and
publicity material resulting from use of the HSL codes within IPOPT must
contain the following acknowledgement:
HSL, a collection of Fortran codes for large-scale scientific
computation. See http://www.hsl.rl.ac.uk.
******************************************************************************
This is Ipopt version 3.13.2, running with linear solver ma57.
Number of nonzeros in equality constraint Jacobian...: 39418
Number of nonzeros in inequality constraint Jacobian.: 0
Number of nonzeros in Lagrangian Hessian.............: 3020
Total number of variables............................: 12984
variables with only lower bounds: 0
variables with lower and upper bounds: 6914
variables with only upper bounds: 0
Total number of equality constraints.................: 10884
Total number of inequality constraints...............: 1
inequality constraints with only lower bounds: 0
inequality constraints with lower and upper bounds: 0
inequality constraints with only upper bounds: 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
0 0.0000000e+00 6.24e+08 0.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 0.0000000e+00 2.13e+02 1.02e-02 -1.0 1.25e+09 - 9.90e-01 1.00e+00h 1
2 0.0000000e+00 2.24e+03 1.00e-06 -1.0 9.60e+02 - 1.00e+00 1.00e+00f 1
3 0.0000000e+00 5.88e+04 5.77e-04 -1.0 2.60e+04 - 1.00e+00 8.03e-01f 1
4 0.0000000e+00 8.00e+02 1.00e-06 -1.0 6.65e+04 - 1.00e+00 1.00e+00h 1
5 0.0000000e+00 4.81e+01 1.00e-06 -1.0 1.61e+03 - 1.00e+00 1.00e+00h 1
6 0.0000000e+00 6.39e-01 1.00e-06 -1.0 3.19e+02 - 1.00e+00 1.00e+00h 1
7 0.0000000e+00 3.62e-07 2.00e-07 -1.7 4.21e-01 - 1.00e+00 1.00e+00h 1
8 0.0000000e+00 5.96e-08 1.50e-09 -3.8 7.59e-03 - 1.00e+00 1.00e+00h 1
9 0.0000000e+00 8.15e-10 1.84e-11 -5.7 1.23e-02 - 1.00e+00 1.00e+00h 1
Number of Iterations....: 9
(scaled) (unscaled)
Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00
Dual infeasibility......: 1.8449144625272179e-11 1.8449144625272179e-11
Constraint violation....: 8.1490725278854370e-10 8.1490725278854370e-10
Complementarity.........: 1.8450305182103931e-06 1.8450305182103931e-06
Overall NLP error.......: 1.8450305182103931e-06 1.8450305182103931e-06
Number of objective function evaluations = 10
Number of objective gradient evaluations = 10
Number of equality constraint evaluations = 10
Number of inequality constraint evaluations = 10
Number of equality constraint Jacobian evaluations = 10
Number of inequality constraint Jacobian evaluations = 10
Number of Lagrangian Hessian evaluations = 9
Total CPU secs in IPOPT (w/o function evaluations) = 0.863
Total CPU secs in NLP function evaluations = 0.021
EXIT: Optimal Solution Found.
Ipopt 3.13.2: max_iter=3000
tol=1e-05
linear_solver=ma57
nlp_scaling_method=gradient-based
******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
Ipopt is released as open source code under the Eclipse Public License (EPL).
For more information visit http://projects.coin-or.org/Ipopt
This version of Ipopt was compiled from source code available at
https://github.com/IDAES/Ipopt as part of the Institute for the Design of
Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE
Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.
This version of Ipopt was compiled using HSL, a collection of Fortran codes
for large-scale scientific computation. All technical papers, sales and
publicity material resulting from use of the HSL codes within IPOPT must
contain the following acknowledgement:
HSL, a collection of Fortran codes for large-scale scientific
computation. See http://www.hsl.rl.ac.uk.
******************************************************************************
This is Ipopt version 3.13.2, running with linear solver ma57.
Number of nonzeros in equality constraint Jacobian...: 39774
Number of nonzeros in inequality constraint Jacobian.: 2
Number of nonzeros in Lagrangian Hessian.............: 3040
Total number of variables............................: 13296
variables with only lower bounds: 4
variables with lower and upper bounds: 7216
variables with only upper bounds: 0
Total number of equality constraints.................: 10894
Total number of inequality constraints...............: 1
inequality constraints with only lower bounds: 0
inequality constraints with lower and upper bounds: 0
inequality constraints with only upper bounds: 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
0 -2.2106523e+01 4.72e-03 6.67e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 -2.2107585e+01 1.12e-02 4.82e+00 -1.0 4.87e-02 2.0 9.90e-01 1.00e+00f 1
2 -2.2110773e+01 2.05e-04 5.10e-01 -1.0 1.40e-02 1.5 9.90e-01 1.00e+00f 1
3 -2.2120374e+01 4.72e-03 8.05e-01 -1.0 7.24e-02 1.0 1.00e+00 1.00e+00f 1
4 -2.2147363e+01 1.38e-03 1.44e-01 -1.7 3.88e-02 0.6 1.00e+00 1.00e+00f 1
5 -2.2235399e+01 2.87e-02 1.73e-01 -2.5 1.40e-01 0.1 1.00e+00 1.00e+00f 1
6 -2.2435675e+01 1.49e-01 2.55e-01 -2.5 4.22e-01 -0.4 1.00e+00 1.00e+00h 1
7 -2.2639739e+01 8.89e-02 1.18e-01 -2.5 7.25e-01 -0.9 1.00e+00 1.00e+00h 1
8 -2.2871315e+01 1.96e-01 1.37e-01 -2.5 1.33e+00 -1.3 1.00e+00 1.00e+00h 1
9 -2.3107216e+01 3.36e-01 8.15e-02 -2.5 2.35e+00 -1.8 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
10 -2.3157043e+01 2.07e-02 4.22e-02 -2.5 1.04e+00 -1.4 1.00e+00 1.00e+00h 1
11 -2.3283698e+01 1.64e-01 2.93e-02 -2.5 2.12e+00 -1.9 1.00e+00 1.00e+00h 1
12 -2.3456076e+01 5.62e-01 3.54e-02 -2.5 4.08e+00 -2.3 1.00e+00 1.00e+00h 1
13 -2.3657596e+01 2.69e+00 3.56e-02 -2.5 7.37e+00 -2.8 1.00e+00 1.00e+00h 1
14 -2.3876650e+01 1.19e+01 3.10e-02 -2.5 1.30e+01 -3.3 1.00e+00 1.00e+00h 1
15 -2.4105041e+01 4.83e+01 2.51e-02 -2.5 2.28e+01 -3.8 1.00e+00 1.00e+00h 1
16 -2.4338393e+01 1.78e+02 1.97e-02 -2.5 3.96e+01 -4.3 1.00e+00 1.00e+00h 1
17 -2.4574292e+01 5.75e+02 1.53e-02 -2.5 6.88e+01 -4.7 1.00e+00 1.00e+00h 1
18 -2.4811477e+01 1.54e+03 1.17e-02 -2.5 1.19e+02 -5.2 1.00e+00 1.00e+00h 1
19 -2.5049298e+01 2.85e+03 8.91e-03 -2.5 2.07e+02 -5.7 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
20 -2.5287400e+01 2.27e+03 6.78e-03 -2.5 3.58e+02 -6.2 1.00e+00 1.00e+00h 1
21 -2.5525585e+01 3.68e+02 5.15e-03 -2.5 6.20e+02 -6.6 1.00e+00 1.00e+00h 1
22 -2.5763762e+01 1.55e+02 3.91e-03 -2.5 1.07e+03 -7.1 1.00e+00 1.00e+00h 1
23 -2.6001976e+01 2.67e+02 2.97e-03 -2.5 1.85e+03 -7.6 1.00e+00 1.00e+00h 1
24 -2.6240626e+01 4.59e+02 2.24e-03 -2.5 3.19e+03 -8.1 1.00e+00 1.00e+00h 1
25 -2.6481255e+01 7.84e+02 1.69e-03 -2.5 5.48e+03 -8.5 1.00e+00 1.00e+00h 1
26 -2.6728504e+01 2.13e+03 1.27e-03 -2.5 9.36e+03 -9.0 1.00e+00 1.00e+00h 1
27 -2.6704984e+01 1.62e+03 4.46e-05 -2.5 7.58e+01 -6.8 1.00e+00 1.00e+00H 1
28 -2.6709570e+01 2.01e+02 1.22e-05 -2.5 2.27e+02 -7.3 1.00e+00 1.00e+00H 1
29 -2.6722767e+01 1.61e+03 1.18e-05 -2.5 6.60e+02 -7.7 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
30 -2.6757833e+01 3.06e+02 2.53e-05 -2.5 1.82e+03 -8.2 1.00e+00 1.00e+00h 1
31 -2.6836864e+01 5.68e+02 1.21e-04 -2.5 4.47e+03 -8.7 1.00e+00 1.00e+00h 1
32 -2.6976741e+01 6.99e+02 3.17e-04 -2.5 9.34e+03 -9.2 1.00e+00 1.00e+00h 1
33 -2.7180558e+01 1.71e+03 4.52e-04 -2.5 1.72e+04 -9.7 1.00e+00 1.00e+00h 1
34 -2.7180557e+01 1.71e+03 4.52e-04 -2.5 2.83e+03 -8.3 1.70e-01 3.48e-04h 10
35 -2.7166819e+01 3.83e+02 6.13e-06 -2.5 5.68e+00 -6.1 1.00e+00 1.00e+00h 1
36 -2.7166886e+01 1.70e+02 4.57e-06 -2.5 1.70e+01 -6.6 1.00e+00 1.00e+00h 1
37 -2.7167377e+01 2.71e+02 4.57e-06 -2.5 5.11e+01 -7.0 1.00e+00 1.00e+00h 1
38 -2.7168848e+01 7.31e+01 4.55e-06 -2.5 1.53e+02 -7.5 1.00e+00 1.00e+00h 1
39 -2.7173211e+01 1.27e+01 4.51e-06 -2.5 4.54e+02 -8.0 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
40 -2.7185880e+01 5.25e+01 4.39e-06 -2.5 1.33e+03 -8.5 1.00e+00 1.00e+00h 1
41 -2.7220586e+01 3.46e+02 1.07e-05 -2.5 3.70e+03 -9.0 1.00e+00 1.00e+00h 1
42 -2.7303631e+01 1.06e+03 5.54e-05 -2.5 9.24e+03 -9.4 1.00e+00 1.00e+00h 1
43 -2.7461529e+01 1.30e+03 1.59e-04 -2.5 1.95e+04 -9.9 1.00e+00 1.00e+00h 1
44 -2.7523300e+01 3.07e+03 1.34e-04 -2.5 3.49e+04 -10.4 1.00e+00 2.50e-01h 3
45 -2.7523423e+01 3.10e+03 1.33e-04 -2.5 2.58e+03 -9.1 7.59e-01 1.17e-02h 7
46 -2.7523354e+01 3.15e+03 1.32e-04 -2.5 1.20e+03 -7.7 5.60e-01 1.29e-02h 6
47 -2.7522599e+01 3.53e+03 1.15e-04 -2.5 2.22e+01 -5.5 1.00e+00 1.25e-01h 4
48 -2.7517307e+01 7.39e+03 1.11e-03 -2.5 1.24e+01 -6.0 1.00e+00 1.00e+00h 1
49 -2.7517339e+01 3.16e+03 1.14e-04 -2.5 2.42e+01 -6.5 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
50 -2.7517356e+01 2.97e+03 2.65e-04 -2.5 1.18e+03 -6.9 1.00e+00 1.25e-01h 4
51 -2.7517757e+01 5.47e+02 3.02e-03 -2.5 2.70e+03 -7.4 1.00e+00 1.00e+00h 1
52 -2.7518912e+01 5.60e+00 2.02e-04 -2.5 5.05e+02 -7.9 1.00e+00 1.00e+00h 1
53 -2.7522341e+01 1.42e+01 1.39e-05 -2.5 5.28e+02 -8.4 1.00e+00 1.00e+00h 1
54 -2.7532381e+01 7.22e+01 3.72e-06 -2.5 1.55e+03 -8.8 1.00e+00 1.00e+00h 1
55 -2.7560505e+01 3.87e+02 8.91e-06 -2.5 4.40e+03 -9.3 1.00e+00 1.00e+00h 1
56 -2.7630924e+01 3.04e+02 2.24e-05 -2.5 1.14e+04 -9.8 1.00e+00 1.00e+00h 1
57 -2.7772300e+01 1.29e+03 7.82e-05 -2.5 2.50e+04 -10.3 1.00e+00 1.00e+00h 1
58 -2.7772319e+01 1.25e+03 7.58e-05 -2.5 1.24e+03 -8.9 1.00e+00 3.12e-02h 6
59 -2.7766989e+01 2.59e+02 1.39e-05 -2.5 1.06e+01 -6.7 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
60 -2.7767089e+01 7.89e+01 4.58e-06 -2.5 2.19e+01 -7.2 1.00e+00 1.00e+00H 1
61 -2.7767131e+01 7.67e+00 1.43e-06 -2.5 8.24e+00 -6.8 1.00e+00 1.00e+00H 1
62 -2.7767146e+01 2.15e-01 1.44e-06 -2.5 3.09e+00 -6.3 1.00e+00 1.00e+00H 1
63 -2.7767193e+01 1.84e+02 1.85e-06 -2.5 9.33e+00 -6.8 1.00e+00 1.00e+00H 1
64 -2.7767210e+01 5.20e+00 1.45e-06 -2.5 3.52e+00 -6.4 1.00e+00 1.00e+00H 1
65 -2.7767211e+01 2.72e+01 5.16e-05 -2.5 2.22e+01 -6.9 1.00e+00 1.56e-02h 7
66 -2.7767231e+01 9.54e+01 2.58e-06 -2.5 3.99e+00 -6.4 1.00e+00 1.00e+00H 1
67 -2.7767291e+01 6.72e+02 2.26e-05 -2.5 1.24e+01 -6.9 1.00e+00 1.00e+00H 1
68 -2.7767472e+01 1.01e+03 2.84e-06 -2.5 3.69e+01 -7.4 1.00e+00 1.00e+00h 1
69 -2.7768014e+01 3.41e+01 1.50e-06 -2.5 1.10e+02 -7.9 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
70 -2.7769632e+01 3.17e-01 1.49e-06 -2.5 3.30e+02 -8.3 1.00e+00 1.00e+00h 1
71 -2.7774428e+01 1.68e+00 1.48e-06 -2.5 9.80e+02 -8.8 1.00e+00 1.00e+00h 1
72 -2.7788329e+01 1.42e+01 1.44e-06 -2.5 2.86e+03 -9.3 1.00e+00 1.00e+00h 1
73 -2.7826158e+01 1.07e+02 4.93e-06 -2.5 7.94e+03 -9.8 1.00e+00 1.00e+00h 1
74 -2.7914819e+01 1.16e+03 2.55e-05 -2.5 1.96e+04 -10.3 1.00e+00 1.00e+00h 1
75 -2.7942267e+01 3.60e+03 7.05e-06 -2.5 7.08e+03 -9.8 1.00e+00 1.00e+00h 1
76 -2.7946991e+01 4.45e+03 9.96e-05 -2.5 2.18e+04 -10.3 8.49e-01 5.48e-02h 5
77 -2.7946787e+01 2.48e+02 6.66e-06 -2.5 2.54e+00 -6.3 1.00e+00 1.00e+00h 1
78 -2.7946811e+01 2.49e+00 1.62e-06 -2.5 5.79e+00 -6.7 1.00e+00 1.00e+00h 1
79 -2.7946883e+01 6.71e-01 1.05e-06 -2.5 1.74e+01 -7.2 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
80 -2.7947098e+01 3.30e-01 1.05e-06 -2.5 5.21e+01 -7.7 1.00e+00 1.00e+00h 1
81 -2.7947743e+01 1.78e+00 1.05e-06 -2.5 1.56e+02 -8.2 1.00e+00 1.00e+00h 1
82 -2.7949671e+01 1.54e+01 1.04e-06 -2.5 4.66e+02 -8.7 1.00e+00 1.00e+00h 1
83 -2.7955392e+01 1.35e+02 1.03e-06 -2.5 1.38e+03 -9.1 1.00e+00 1.00e+00h 1
84 -2.7972002e+01 1.06e+03 2.61e-06 -2.5 4.01e+03 -9.6 1.00e+00 1.00e+00h 1
85 -2.8017020e+01 4.13e+03 1.07e-05 -2.5 1.09e+04 -10.1 1.00e+00 1.00e+00h 1
86 -2.8116699e+01 6.49e+03 2.33e-05 -2.5 2.60e+04 -10.6 1.00e+00 1.00e+00h 1
87 -2.8137923e+01 9.62e+03 8.88e-05 -2.5 6.94e+04 -11.0 1.00e+00 1.25e-01h 4
88 -2.8137900e+01 9.77e+03 1.89e-04 -2.5 5.51e+03 -8.8 1.00e+00 1.90e-02h 6
89 -2.8138223e+01 9.21e+03 6.52e-05 -2.5 5.30e+03 -9.3 1.00e+00 1.25e-01h 4
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
90 -2.8149857e+01 2.05e+04 2.62e-04 -2.5 3.91e+03 -9.8 1.00e+00 1.00e+00h 1
91 -2.8186023e+01 6.07e+03 7.74e-05 -2.5 1.07e+04 -10.2 1.00e+00 1.00e+00h 1
92 -2.8266784e+01 2.52e+03 1.39e-05 -2.5 2.58e+04 -10.7 1.00e+00 1.00e+00h 1
93 -2.8397601e+01 9.07e+02 3.23e-05 -2.5 4.85e+04 -11.2 1.00e+00 1.00e+00H 1
94 -2.8438411e+01 2.20e+02 2.28e-06 -2.5 1.67e+04 -10.8 1.00e+00 1.00e+00h 1
95 -2.8513416e+01 9.71e+02 1.00e-05 -2.5 3.37e+04 -11.2 1.00e+00 1.00e+00H 1
96 -2.8536878e+01 4.38e+02 8.38e-07 -2.5 1.12e+04 -10.8 1.00e+00 1.00e+00h 1
97 -2.8582235e+01 3.64e+03 4.31e-06 -2.5 3.95e+04 -11.3 1.00e+00 1.00e+00H 1
98 -2.8595309e+01 2.22e+03 7.12e-07 -2.5 1.62e+04 -10.9 1.00e+00 1.00e+00h 1
99 -2.8597827e+01 3.08e+03 4.34e-05 -2.5 8.30e+04 -11.3 1.00e+00 1.25e-01h 4
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
100 -2.8607984e+01 3.07e+02 3.43e-06 -2.5 2.40e+04 -10.9 1.00e+00 1.00e+00H 1
101 -2.8613043e+01 3.51e+03 3.31e-05 -2.5 9.03e+04 -11.4 1.00e+00 2.50e-01h 3
102 -2.8612820e+01 3.58e+03 1.45e-04 -2.5 1.00e+06 -11.9 1.75e-01 2.66e-03h 7
103 -2.8615847e+01 3.18e+03 2.77e-06 -2.5 1.08e+04 -10.5 1.00e+00 1.00e+00h 1
104 -2.8616186e+01 3.42e+03 6.43e-05 -2.5 4.61e+04 -11.0 1.00e+00 6.25e-02h 5
105 -2.8616682e+01 2.27e+03 1.46e-06 -2.5 1.53e+03 -9.7 1.00e+00 1.00e+00h 1
106 -2.8616726e+01 2.33e+03 4.17e-05 -2.5 6.37e+03 -10.2 1.00e+00 6.25e-02h 5
107 -2.8616726e+01 2.33e+03 1.46e-04 -2.5 1.47e+03 -7.9 7.61e-01 3.33e-03h 9
108 -2.8616726e+01 2.33e+03 5.73e-05 -2.5 6.52e+02 -7.5 6.05e-01 5.77e-03h 7
109 -2.8616727e+01 2.33e+03 1.32e-04 -2.5 6.62e+02 -7.1 1.00e+00 6.06e-03h 8
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
110 -2.8616729e+01 2.36e+03 7.26e-05 -2.5 5.74e+02 -7.6 7.61e-01 1.29e-02h 6
111 -2.8616751e+01 2.35e+03 4.85e-05 -2.5 1.24e+03 -8.0 1.00e+00 3.12e-02h 6
112 -2.8617373e+01 2.18e+03 1.21e-04 -2.5 2.06e+03 -8.5 1.00e+00 5.00e-01h 2
113 -2.8620123e+01 2.19e+03 1.20e-04 -2.5 9.88e+05 - 1.19e-01 6.28e-03h 5
114 -2.8621135e+01 1.76e+02 2.88e-05 -2.5 1.37e+03 -9.0 1.00e+00 1.00e+00h 1
115 -2.8623208e+01 1.13e+03 1.32e-04 -2.5 9.48e+05 - 1.02e-01 5.08e-03h 5
116 -2.8623728e+01 1.04e+03 5.78e-06 -2.5 7.33e+02 -9.5 1.00e+00 1.00e+00h 1
117 -2.8623729e+01 1.04e+03 4.87e-05 -2.5 3.47e+02 -7.2 1.00e+00 1.56e-02h 7
118 -2.8624488e+01 1.05e+03 9.55e-05 -2.5 1.34e+06 - 2.90e-01 2.82e-03h 7
119 -2.8624488e+01 1.05e+03 8.16e-05 -2.5 1.02e+03 -7.7 1.00e+00 3.03e-03h 9
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
120 -2.8624723e+01 7.67e+02 7.75e-05 -2.5 7.85e+02 -8.2 1.00e+00 5.00e-01h 2
121 -2.8786450e+01 4.57e+02 5.76e-05 -2.5 9.43e+04 - 1.00e+00 1.00e+00H 1
122 -2.8807639e+01 2.04e+01 6.07e-07 -2.5 1.38e+04 - 1.00e+00 1.00e+00H 1
123 -2.8807311e+01 2.39e+00 2.88e-08 -2.5 3.77e+02 - 1.00e+00 1.00e+00h 1
124 -2.8807310e+01 2.39e-05 2.83e-08 -2.5 3.66e-01 - 1.00e+00 1.00e+00h 1
125 -2.9414832e+01 1.99e+03 5.89e-04 -3.8 4.22e+05 - 7.32e-01 1.00e+00F 1
126 -2.9973868e+01 2.16e+03 3.49e-05 -3.8 7.60e+05 - 9.97e-01 1.00e+00H 1
127 -3.0001794e+01 2.56e+03 3.32e-05 -3.8 1.07e+06 - 1.00e+00 6.02e-02h 4
128 -3.0365243e+01 7.73e+02 8.84e-05 -3.8 9.41e+05 - 1.00e+00 1.00e+00H 1
129 -3.0373521e+01 1.18e+02 3.72e-06 -3.8 2.90e+04 - 1.00e+00 1.00e+00H 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
130 -3.0369609e+01 8.37e+01 1.49e-08 -3.8 1.90e+04 - 1.00e+00 1.00e+00h 1
131 -3.0369685e+01 3.45e-02 1.51e-09 -3.8 4.33e+02 - 1.00e+00 1.00e+00h 1
132 -3.0369685e+01 1.19e-07 1.50e-09 -3.8 3.21e-02 - 1.00e+00 1.00e+00h 1
133 -3.0581248e+01 3.30e+02 2.43e-05 -5.7 7.87e+05 - 8.33e-01 1.00e+00F 1
134 -3.0587018e+01 2.04e+03 1.97e-05 -5.7 6.68e+05 - 7.69e-01 1.87e-01h 3
Reallocating memory for MA57: lfact (412977)
135 -3.0587707e+01 2.27e+03 1.93e-05 -5.7 2.04e+06 - 7.90e-01 2.23e-02h 6
136 -3.0587913e+01 2.30e+03 2.28e-05 -5.7 3.15e+06 - 1.00e+00 5.76e-03h 8
137 -3.0588130e+01 2.32e+03 2.74e-05 -5.7 2.91e+06 - 1.00e+00 6.25e-03h 8
138 -3.0588364e+01 2.36e+03 2.73e-05 -5.7 2.94e+06 - 1.00e+00 6.79e-03h 8
139 -3.0588483e+01 2.37e+03 2.85e-05 -5.7 2.82e+06 - 1.00e+00 3.52e-03h 9
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
140 -3.0588604e+01 2.37e+03 2.86e-05 -5.7 2.85e+06 - 1.00e+00 3.56e-03h 9
141 -3.0588668e+01 2.37e+03 2.88e-05 -5.7 2.80e+06 - 1.00e+00 1.90e-03h 10
142 -3.0588732e+01 2.37e+03 2.97e-05 -5.7 2.82e+06 - 1.00e+00 1.92e-03h 10
143 -3.0588850e+01 2.37e+03 3.01e-05 -5.7 2.79e+06 - 1.00e+00 3.53e-03h 9
144 -3.0616219e+01 7.27e+05 5.27e-06 -5.7 2.79e+06 - 1.00e+00 8.26e-01w 1
145 -3.0621843e+01 1.23e+05 6.38e-08 -5.7 2.06e+06 - 1.00e+00 1.00e+00w 1
146 -3.0621756e+01 4.88e+03 3.01e-09 -5.7 1.34e+05 - 1.00e+00 1.00e+00h 1
147 -3.0621759e+01 2.76e+00 1.85e-11 -5.7 6.85e+03 - 1.00e+00 1.00e+00h 1
148 -3.0621759e+01 1.20e-06 1.84e-11 -5.7 1.73e+00 - 1.00e+00 1.00e+00h 1
Number of Iterations....: 148
(scaled) (unscaled)
Objective...............: -3.0621759113959421e+01 -3.0621759113959421e+01
Dual infeasibility......: 1.8449144690832783e-11 1.8449144690832783e-11
Constraint violation....: 3.7917877910781740e-07 1.2014061212539673e-06
Complementarity.........: 1.8449152194934589e-06 1.8449152194934589e-06
Overall NLP error.......: 1.8449152194934589e-06 1.8449152194934589e-06
Number of objective function evaluations = 207
Number of objective gradient evaluations = 149
Number of equality constraint evaluations = 452
Number of inequality constraint evaluations = 452
Number of equality constraint Jacobian evaluations = 149
Number of inequality constraint Jacobian evaluations = 149
Number of Lagrangian Hessian evaluations = 148
Total CPU secs in IPOPT (w/o function evaluations) = 23.932
Total CPU secs in NLP function evaluations = 0.516
EXIT: Optimal Solution Found.
multiexp_results = extract_plot_results(None, TC_Lab_DoE_D)
Interesting! The cold experiment (exp 1) operates near room temperature to isolate internal heat transfer () by eliminating ambient losses. It yields information along the coordinate axes of internal parameters (). The hot experiment (exp 2) drives steep thermal gradients to capture the exact behavior of ambient heat dissipation () and heat capacities.
FIM_D = np.asarray(TC_Lab_DoE_D.results["solution"]["param_scenarios"][0]["total_fim"])
if SCALE_BY_NOMINAL_PARAM:
D = np.diag(theta_ref)
FIM_unscaled_D = D @ FIM_D @ D / SCALE_CONSTANT_VALUE**2
else:
FIM_unscaled_D = FIM_D / SCALE_CONSTANT_VALUE**2
results_summary(np.asarray(FIM_unscaled_D))======Results Summary======
Five design criteria log10() value:
Pseudo A-optimality: 11.914399955393007
A-optimality: -8.672600624735777
D-optimality: 39.78410599788649
E-optimality: 8.942827955880793
Modified E-optimality: 2.9666353990745264
FIM:
[[ 7.21899524e+09 8.78022397e+07 -5.78467897e+06 -1.04510545e+07]
[ 8.78022397e+07 9.03427868e+08 8.47502225e+07 2.60112894e+06]
[-5.78467897e+06 8.47502225e+07 1.15821212e+09 2.54091911e+07]
[-1.04510545e+07 2.60112894e+06 2.54091911e+07 8.11826745e+11]]
eigenvalues:
[8.11826745e+11 7.22021904e+09 8.76653469e+08 1.18376178e+09]
Eigenvector matrix:
eigvec_1 eigvec_2 eigvec_3 eigvec_4
Ua 0.0 0.9999 0.0135 -0.0033
Ub -0.0 0.0139 -0.9574 0.2884
inv_CpH -0.0 -0.0008 0.2885 0.9575
inv_CpS -1.0 0.0000 -0.0000 -0.0000
Compare the Reduction in Predicted Uncertainty¶
# Helper function to print parameter values with their standard deviations
def param_std(
std: np.ndarray,
parameters: dict = theta_values,
):
for i, key in enumerate(parameters.keys()):
print(f"{key}: {parameters[key]:.3e} ± {std[i]:.3e}")# Now compare the uncertainty for the prior and the optimized design to see how much
# improvement we have achieved in terms of parameter uncertainty reduction.
cov_D = np.linalg.inv(FIM_unscaled_D)
std_D = np.sqrt(np.diag(cov_D))
std_prior = np.sqrt(np.diag(cov))
print("Parameter estimates with standard deviations for the prior:")
param_std(std_prior)
print(
"\nParameter estimates with predicted standard deviations for the optimized design:"
)
param_std(std_D)Parameter estimates with standard deviations for the prior:
Ua: 4.170e-02 ± 1.363e-05
Ub: 1.201e-02 ± 4.030e-04
inv_CpH: 1.675e-01 ± 3.212e-04
inv_CpS: 4.545e+00 ± 1.581e-01
Parameter estimates with predicted standard deviations for the optimized design:
Ua: 4.170e-02 ± 1.178e-05
Ub: 1.201e-02 ± 3.340e-05
inv_CpH: 1.675e-01 ± 2.949e-05
inv_CpS: 4.545e+00 ± 1.110e-06
Activity: Repeat the Design with A-Optimality¶
In this activity, we repeat the same workflow as above but change only the design objective. The repeated setup is shown again here so the section can be run independently.
# Create the design of experiments object using our experiment instance from above
TC_Lab_DoE_A = DesignOfExperiments(
experiment=[
doe_experiment_1,
doe_experiment_2,
], # We are optimizing two experiments simultaneously!
step=1e-2,
scale_constant_value=SCALE_CONSTANT_VALUE,
scale_nominal_param_value=SCALE_BY_NOMINAL_PARAM,
objective_option="trace", # Now we specify the A-optimality objective, A-opt = "trace"
prior_FIM=PRIOR_FIM_SCALED, # We use the prior information from the existing experiment!
tee=True,
solver=solver,
)
TC_Lab_DoE_A.optimize_experiments()WARNING:pyomo.contrib.doe.doe:No symmetry breaking variable specified. Automatically using the first experiment input 'U1[0.0]' for ordering constraints. To specify a different variable, add: m.sym_break_cons = pyo.Suffix(direction=pyo.Suffix.LOCAL); m.sym_break_cons[m.your_variable] = None
Ipopt 3.13.2: max_iter=3000
tol=1e-05
linear_solver=ma57
nlp_scaling_method=gradient-based
******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
Ipopt is released as open source code under the Eclipse Public License (EPL).
For more information visit http://projects.coin-or.org/Ipopt
This version of Ipopt was compiled from source code available at
https://github.com/IDAES/Ipopt as part of the Institute for the Design of
Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE
Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.
This version of Ipopt was compiled using HSL, a collection of Fortran codes
for large-scale scientific computation. All technical papers, sales and
publicity material resulting from use of the HSL codes within IPOPT must
contain the following acknowledgement:
HSL, a collection of Fortran codes for large-scale scientific
computation. See http://www.hsl.rl.ac.uk.
******************************************************************************
This is Ipopt version 3.13.2, running with linear solver ma57.
Number of nonzeros in equality constraint Jacobian...: 39418
Number of nonzeros in inequality constraint Jacobian.: 0
Number of nonzeros in Lagrangian Hessian.............: 3020
Total number of variables............................: 12984
variables with only lower bounds: 0
variables with lower and upper bounds: 6914
variables with only upper bounds: 0
Total number of equality constraints.................: 10884
Total number of inequality constraints...............: 1
inequality constraints with only lower bounds: 0
inequality constraints with lower and upper bounds: 0
inequality constraints with only upper bounds: 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
0 0.0000000e+00 6.24e+08 0.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 0.0000000e+00 2.13e+02 1.02e-02 -1.0 1.25e+09 - 9.90e-01 1.00e+00h 1
2 0.0000000e+00 2.24e+03 1.00e-06 -1.0 9.60e+02 - 1.00e+00 1.00e+00f 1
3 0.0000000e+00 5.88e+04 5.77e-04 -1.0 2.60e+04 - 1.00e+00 8.03e-01f 1
4 0.0000000e+00 8.00e+02 1.00e-06 -1.0 6.65e+04 - 1.00e+00 1.00e+00h 1
5 0.0000000e+00 4.81e+01 1.00e-06 -1.0 1.61e+03 - 1.00e+00 1.00e+00h 1
6 0.0000000e+00 6.39e-01 1.00e-06 -1.0 3.19e+02 - 1.00e+00 1.00e+00h 1
7 0.0000000e+00 3.62e-07 2.00e-07 -1.7 4.21e-01 - 1.00e+00 1.00e+00h 1
8 0.0000000e+00 5.96e-08 1.50e-09 -3.8 7.59e-03 - 1.00e+00 1.00e+00h 1
9 0.0000000e+00 8.15e-10 1.84e-11 -5.7 1.23e-02 - 1.00e+00 1.00e+00h 1
Number of Iterations....: 9
(scaled) (unscaled)
Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00
Dual infeasibility......: 1.8449144625272179e-11 1.8449144625272179e-11
Constraint violation....: 8.1490725278854370e-10 8.1490725278854370e-10
Complementarity.........: 1.8450305182103931e-06 1.8450305182103931e-06
Overall NLP error.......: 1.8450305182103931e-06 1.8450305182103931e-06
Number of objective function evaluations = 10
Number of objective gradient evaluations = 10
Number of equality constraint evaluations = 10
Number of inequality constraint evaluations = 10
Number of equality constraint Jacobian evaluations = 10
Number of inequality constraint Jacobian evaluations = 10
Number of Lagrangian Hessian evaluations = 9
Total CPU secs in IPOPT (w/o function evaluations) = 0.948
Total CPU secs in NLP function evaluations = 0.023
EXIT: Optimal Solution Found.
Ipopt 3.13.2: max_iter=3000
tol=1e-05
linear_solver=ma57
nlp_scaling_method=gradient-based
******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
Ipopt is released as open source code under the Eclipse Public License (EPL).
For more information visit http://projects.coin-or.org/Ipopt
This version of Ipopt was compiled from source code available at
https://github.com/IDAES/Ipopt as part of the Institute for the Design of
Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE
Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.
This version of Ipopt was compiled using HSL, a collection of Fortran codes
for large-scale scientific computation. All technical papers, sales and
publicity material resulting from use of the HSL codes within IPOPT must
contain the following acknowledgement:
HSL, a collection of Fortran codes for large-scale scientific
computation. See http://www.hsl.rl.ac.uk.
******************************************************************************
This is Ipopt version 3.13.2, running with linear solver ma57.
Number of nonzeros in equality constraint Jacobian...: 39859
Number of nonzeros in inequality constraint Jacobian.: 2
Number of nonzeros in Lagrangian Hessian.............: 3080
Total number of variables............................: 13317
variables with only lower bounds: 5
variables with lower and upper bounds: 7216
variables with only upper bounds: 0
Total number of equality constraints.................: 10915
Total number of inequality constraints...............: 1
inequality constraints with only lower bounds: 0
inequality constraints with lower and upper bounds: 0
inequality constraints with only upper bounds: 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
0 1.6841287e+00 4.72e-03 6.67e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 1.3939522e+00 2.31e-02 2.90e-01 -1.0 2.90e-01 0.0 9.90e-01 1.00e+00f 1
2 1.2894587e+00 5.28e-02 6.27e-01 -1.0 2.37e-01 0.4 9.90e-01 1.00e+00f 1
3 1.0062805e+00 3.21e-02 2.52e-01 -1.0 2.83e-01 -0.1 1.00e+00 1.00e+00f 1
4 5.2248787e-01 9.75e-02 1.48e-01 -1.7 5.00e-01 -0.5 9.39e-01 1.00e+00f 1
5 3.7208672e-01 9.22e-02 1.01e-01 -2.5 8.09e-01 -1.0 1.00e+00 1.00e+00h 1
6 2.7016726e-01 9.25e-02 8.59e-02 -2.5 1.02e+00 -1.5 1.00e+00 1.00e+00h 1
7 1.7878412e-01 1.49e-01 6.37e-02 -2.5 1.51e+00 -2.0 1.00e+00 1.00e+00h 1
8 1.2404472e-01 7.81e-01 5.25e-02 -2.5 2.20e+00 -2.4 1.00e+00 1.00e+00h 1
9 8.5578436e-02 3.60e+00 4.34e-02 -2.5 3.17e+00 -2.9 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
10 5.9194480e-02 1.57e+01 3.61e-02 -2.5 4.56e+00 -3.4 1.00e+00 1.00e+00h 1
11 4.1065400e-02 6.25e+01 3.01e-02 -2.5 6.54e+00 -3.9 1.00e+00 1.00e+00h 1
12 2.8565185e-02 2.25e+02 2.53e-02 -2.5 9.37e+00 -4.3 1.00e+00 1.00e+00h 1
13 1.9935228e-02 7.07e+02 2.14e-02 -2.5 1.34e+01 -4.8 1.00e+00 1.00e+00h 1
14 1.3974359e-02 1.80e+03 1.83e-02 -2.5 1.90e+01 -5.3 1.00e+00 1.00e+00h 1
15 9.8569496e-03 2.97e+03 1.57e-02 -2.5 2.67e+01 -5.8 1.00e+00 1.00e+00h 1
16 7.0145499e-03 1.86e+03 1.37e-02 -2.5 3.71e+01 -6.3 1.00e+00 1.00e+00h 1
17 5.0671402e-03 2.53e+02 1.17e-02 -2.5 5.04e+01 -6.7 1.00e+00 1.00e+00h 1
18 3.7469374e-03 1.37e+01 9.86e-03 -2.5 6.59e+01 -7.2 1.00e+00 1.00e+00h 1
19 2.8756900e-03 5.68e+00 7.70e-03 -2.5 8.04e+01 -7.7 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
20 2.3371575e-03 4.88e+00 5.02e-03 -2.5 8.58e+01 -8.2 1.00e+00 1.00e+00h 1
21 2.0521994e-03 2.61e+00 2.18e-03 -2.5 2.36e+02 -8.6 1.00e+00 1.00e+00h 1
22 1.9459476e-03 2.76e+00 4.05e-04 -2.5 7.07e+02 -9.1 1.00e+00 1.00e+00h 1
23 1.9257087e-03 2.59e+01 1.61e-05 -2.5 2.12e+03 -9.6 1.00e+00 1.00e+00h 1
24 1.9237218e-03 2.67e+02 5.42e-07 -2.5 6.37e+03 -10.1 1.00e+00 1.00e+00h 1
25 1.9228338e-03 8.51e+01 5.43e-07 -2.5 2.40e+03 -9.6 1.00e+00 1.00e+00h 1
26 1.9165214e-03 2.35e+03 6.44e-06 -2.5 7.35e+03 -10.1 1.00e+00 1.00e+00h 1
27 1.8979668e-03 3.25e+03 1.43e-02 -2.5 3.27e+03 -9.7 1.00e+00 5.00e-01h 2
28 1.9400989e-03 2.46e+03 1.00e-01 -2.5 1.19e+03 -9.3 1.00e+00 2.50e-01h 3
29 1.9499702e-03 2.36e+03 1.02e-01 -2.5 3.23e+02 -7.9 1.00e+00 6.25e-02h 5
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
30 1.9494784e-03 1.91e+03 1.47e-03 -2.5 1.08e+01 -5.7 1.00e+00 2.50e-01h 3
31 1.9448676e-03 1.94e+03 2.44e-02 -2.5 4.25e+01 -6.2 1.00e+00 1.25e-01h 4
32 1.9448863e-03 5.73e+03 2.03e-02 -2.5 2.48e+06 - 1.68e-01 1.53e-02h 5
33 1.9002482e-03 4.32e+03 1.02e-01 -2.5 9.66e+01 -6.7 1.00e+00 2.50e-01h 3
34 1.9005344e-03 9.26e+03 9.15e-02 -2.5 3.99e+06 - 7.49e-02 6.07e-03h 5
35 1.4094709e-03 5.15e+03 4.08e-01 -2.5 5.30e+02 -7.1 1.00e+00 5.00e-01h 2
36 1.0945097e-04 1.98e+03 1.24e-01 -2.5 1.41e+03 -7.6 1.00e+00 1.00e+00h 1
37 6.3160986e-04 1.57e+03 1.52e+00 -2.5 4.60e+02 -4.5 1.00e+00 1.00e+00h 1
38 6.0755954e-04 1.20e+03 1.16e+00 -2.5 5.34e+02 -5.0 1.00e+00 2.50e-01h 3
39 4.7760239e-04 1.34e+03 1.74e-01 -2.5 7.23e+02 -5.4 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
40 4.8061799e-04 1.34e+03 8.73e-02 -2.5 1.88e+02 -5.9 1.00e+00 5.00e-01h 2
41 4.8982926e-04 3.76e+02 2.97e-02 -2.5 5.38e+01 -4.6 1.00e+00 1.00e+00h 1
42 4.8857661e-04 3.74e+02 4.54e-02 -2.5 3.41e+01 -4.2 1.00e+00 2.50e-01h 3
43 1.7742819e-03 2.68e+03 9.58e+00 -2.5 6.27e+03 - 3.78e-01 1.00e+00H 1
44 8.8964522e-04 1.80e+03 7.96e+00 -2.5 1.95e+01 -4.6 1.00e+00 2.88e-01h 2
45 2.5064247e-06 2.02e+02 2.41e+00 -2.5 1.23e+01 -5.1 1.00e+00 7.92e-01h 1
46 2.2087717e-04 3.65e+01 9.65e-01 -2.5 8.48e+00 -5.6 1.00e+00 1.00e+00h 1
47 2.2138987e-04 2.95e+00 1.99e-02 -2.5 2.45e-01 -5.2 1.00e+00 1.00e+00h 1
48 2.2140819e-04 2.33e+01 2.96e-06 -2.5 4.22e-01 -5.6 1.00e+00 1.00e+00h 1
49 2.2141169e-04 2.66e+00 1.52e-06 -2.5 1.66e-01 -5.2 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
50 2.2142528e-04 2.23e+01 8.53e-07 -2.5 4.19e-01 -5.7 1.00e+00 1.00e+00h 1
51 2.2146707e-04 6.17e+01 2.82e-06 -2.5 1.16e+00 -6.2 1.00e+00 1.00e+00H 1
52 2.2159270e-04 2.96e+01 1.89e-06 -2.5 3.64e+00 -6.6 1.00e+00 1.00e+00H 1
53 2.2159758e-04 4.88e-01 6.91e-07 -2.5 1.43e-01 -5.3 1.00e+00 1.00e+00h 1
54 2.2161389e-04 1.10e+00 7.97e-07 -2.5 4.97e-01 -5.8 1.00e+00 1.00e+00h 1
55 2.2161694e-04 2.72e+00 2.63e-03 -2.5 2.01e+00 -6.3 1.00e+00 6.25e-02h 5
56 2.2163577e-04 6.37e+00 7.59e-03 -2.5 3.41e+00 -6.7 1.00e+00 1.25e-01h 4
57 2.2208118e-04 3.05e+00 8.08e-07 -2.5 1.04e+01 -7.2 1.00e+00 1.00e+00h 1
58 2.2343732e-04 1.32e+01 7.46e-06 -2.5 3.06e+01 -7.7 1.00e+00 1.00e+00h 1
59 2.2346446e-04 1.44e+01 3.91e-01 -2.5 7.86e+02 -8.2 1.00e+00 3.91e-03h 9
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
60 2.2366985e-04 1.57e+01 4.42e-06 -2.5 4.38e+00 -6.9 1.00e+00 1.00e+00h 1
61 2.2421594e-04 1.01e+01 1.65e-06 -2.5 1.21e+01 -7.3 1.00e+00 1.00e+00h 1
62 2.2588231e-04 7.06e+00 1.10e-05 -2.5 3.70e+01 -7.8 1.00e+00 1.00e+00h 1
63 2.3070847e-04 1.76e+01 9.05e-05 -2.5 1.05e+02 -8.3 1.00e+00 1.00e+00h 1
64 2.3413101e-04 7.88e+01 5.41e-01 -2.5 2.83e+02 -8.8 1.00e+00 2.50e-01h 3
65 2.4038125e-04 1.00e+02 2.15e+00 -2.5 1.01e+03 -9.2 1.00e+00 1.25e-01h 4
66 2.4299742e-04 1.12e+02 7.33e-01 -2.5 3.96e+02 -8.8 1.00e+00 1.25e-01h 4
67 2.4955244e-04 1.13e+02 2.08e+00 -2.5 9.75e+02 -9.3 1.00e+00 1.25e-01h 4
68 2.7591434e-04 1.03e+02 6.89e+00 -2.5 3.72e+03 -9.8 1.00e+00 1.25e-01h 4
69 3.6190160e-04 1.33e+02 2.46e-03 -2.5 1.17e+03 -9.3 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
70 9.2125363e-04 1.49e+03 6.37e+00 -2.5 3.95e+03 -9.8 5.89e-01 1.00e+00h 1
71 1.2022885e-03 5.57e+03 4.70e+00 -2.5 8.79e+03 - 1.00e+00 5.00e-01h 2
72 2.9755666e-03 3.76e+03 4.16e+00 -2.5 1.96e+01 -4.9 3.14e-01 5.00e-01h 2
73 4.2075541e-03 3.62e+03 4.69e+00 -2.5 1.03e+02 -5.4 1.00e+00 7.15e-02h 4
74 4.5831056e-03 3.64e+03 3.73e+00 -2.5 7.10e+02 -5.8 3.21e-01 3.12e-02h 6
75 4.9659478e-03 3.51e+03 4.07e+00 -2.5 1.26e+03 -6.3 1.00e+00 6.25e-02h 5
76 5.3527133e-03 3.10e+03 3.19e+00 -2.5 3.12e+03 -6.8 1.00e+00 1.25e-01h 4
77 5.3716332e-03 3.09e+03 3.33e+00 -2.5 3.05e+03 -6.4 9.51e-01 3.69e-03h 9
78 5.3807001e-03 3.09e+03 2.99e+00 -2.5 3.02e+03 -5.9 8.41e-01 9.77e-04h 11
79 5.3831460e-03 3.08e+03 3.51e+00 -2.5 3.04e+03 -6.4 1.00e+00 4.88e-04h 12
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
80 5.6956255e-03 2.70e+03 2.86e+00 -2.5 3.07e+03 -6.9 1.00e+00 1.25e-01h 4
81 1.8093001e-02 5.75e+05 4.33e-01 -2.5 2.68e+03 -5.6 6.00e-01 8.97e-01w 1
82 6.6500953e-02 1.52e+05 2.27e-01 -2.5 9.06e+01 -4.2 1.00e+00 1.00e+00w 1
83 4.1380180e-02 4.00e+04 2.76e-01 -2.5 2.04e+02 -4.7 9.60e-01 1.00e+00w 1
84 5.7440527e-03 2.69e+03 2.57e+00 -2.5 3.37e+02 -5.2 6.00e-01 3.51e-03h 8
85 5.7604907e-03 2.69e+03 2.87e+00 -2.5 2.67e+03 -5.7 6.18e-01 1.28e-03h 9
86 5.8199435e-03 2.68e+03 2.56e+00 -2.5 2.68e+03 -5.2 4.11e-01 3.39e-03h 9
87 5.9115681e-03 2.66e+03 3.02e+00 -2.5 2.67e+03 -5.7 1.00e+00 7.81e-03h 8
88 7.3051075e-03 1.99e+03 1.92e+00 -2.5 2.99e+03 -6.2 1.00e+00 2.50e-01h 3
89 7.3055113e-03 1.99e+03 1.95e+00 -2.5 4.11e+03 -6.7 9.49e-02 9.04e-05h 11
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
90 7.6304372e-03 1.74e+03 1.98e+00 -2.5 2.21e+03 -6.2 1.00e+00 1.25e-01h 4
91 7.7406764e-03 1.37e+03 9.86e-01 -2.5 1.98e+03 -6.7 1.00e+00 5.00e-01h 2
92 7.5477594e-03 1.42e+03 7.71e-01 -2.5 9.99e+02 -6.3 1.00e+00 2.50e-01h 3
93 8.0842601e-03 6.33e+02 1.27e-01 -2.5 7.50e+02 -5.0 1.00e+00 1.00e+00h 1
94 4.5180579e-03 1.56e+02 2.42e-02 -2.5 1.73e+02 - 1.00e+00 1.00e+00h 1
95 5.4731948e-03 3.00e+01 1.77e-05 -2.5 3.81e+00 -5.4 1.00e+00 1.00e+00h 1
96 5.4591696e-03 3.76e+01 1.67e-04 -2.5 2.15e+00 -5.0 1.00e+00 5.00e-01h 2
97 5.3325833e-03 2.85e+01 7.63e-05 -2.5 4.58e+00 -5.5 1.00e+00 1.00e+00h 1
98 5.2912221e-03 3.87e+01 2.90e-02 -2.5 1.20e+01 -6.0 1.00e+00 1.25e-01h 4
99 5.1485987e-03 7.56e+01 9.39e-05 -2.5 7.71e+00 -5.5 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
100 4.8221539e-03 2.66e+01 4.45e-04 -2.5 1.25e+01 -6.0 1.00e+00 1.00e+00h 1
101 4.8274747e-03 4.03e+00 1.41e-05 -2.5 6.19e-01 -4.7 1.00e+00 1.00e+00h 1
102 4.7924336e-03 2.08e+00 1.03e-05 -2.5 1.51e+00 -5.2 1.00e+00 1.00e+00h 1
103 4.6962875e-03 1.61e+00 4.45e-05 -2.5 4.22e+00 -5.6 1.00e+00 1.00e+00h 1
104 4.4561234e-03 7.88e+00 2.90e-04 -2.5 1.10e+01 -6.1 1.00e+00 1.00e+00h 1
105 3.9903659e-03 1.37e+01 1.22e-03 -2.5 2.41e+01 -6.6 1.00e+00 1.00e+00h 1
106 3.3642797e-03 4.84e+00 2.82e-03 -2.5 4.19e+01 -7.1 1.00e+00 1.00e+00h 1
107 2.7580323e-03 2.93e+00 3.91e-03 -2.5 6.02e+01 -7.6 1.00e+00 1.00e+00h 1
108 2.2939462e-03 9.39e+00 3.62e-03 -2.5 7.24e+01 -8.0 1.00e+00 1.00e+00h 1
109 2.0016315e-03 3.39e+01 2.18e-03 -2.5 7.75e+01 -8.5 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
110 1.8711176e-03 9.14e+00 6.06e-04 -2.5 4.26e+01 -9.0 1.00e+00 1.00e+00h 1
111 1.8314458e-03 1.42e+00 6.22e-05 -2.5 1.84e+01 - 1.00e+00 1.00e+00h 1
112 1.8309752e-03 3.20e-01 2.83e-08 -2.5 5.59e+01 - 1.00e+00 1.00e+00H 1
113 1.8309753e-03 9.61e-03 2.83e-08 -2.5 2.92e+00 - 1.00e+00 1.00e+00h 1
114 4.2381088e-04 8.22e+01 6.89e-02 -3.8 4.25e+02 - 7.50e-01 1.00e+00h 1
115 3.1180115e-04 2.21e+02 5.04e-03 -3.8 1.05e+03 - 1.00e+00 1.00e+00h 1
116 4.8712274e-04 5.42e+00 5.07e-03 -3.8 2.33e+00 -5.8 1.00e+00 1.00e+00h 1
117 3.3448460e-04 6.25e+01 5.19e-03 -3.8 7.17e+02 - 1.00e+00 1.00e+00h 1
118 3.7590403e-04 3.47e-01 6.91e-05 -3.8 5.89e-01 -6.3 1.00e+00 1.00e+00h 1
119 2.7609681e-04 5.23e+01 1.93e-03 -3.8 7.58e+02 - 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
120 2.5209517e-04 2.07e+01 3.60e-04 -3.8 5.95e+02 - 1.00e+00 1.00e+00h 1
121 2.5197789e-04 1.67e-01 4.59e-07 -3.8 7.31e+01 - 1.00e+00 1.00e+00h 1
122 2.5197919e-04 6.59e-07 1.50e-09 -3.8 2.71e-01 - 1.00e+00 1.00e+00h 1
123 1.1170942e-04 3.56e+02 5.63e-02 -5.7 2.43e+03 - 7.81e-01 1.00e+00h 1
124 7.1610780e-05 8.29e+02 1.79e-03 -5.7 5.16e+03 - 1.00e+00 1.00e+00h 1
125 9.5309511e-05 1.37e+01 2.67e-02 -5.7 3.70e+00 -6.8 8.56e-01 1.00e+00h 1
126 6.2410071e-05 4.92e+02 1.76e-03 -5.7 4.83e+03 - 1.00e+00 1.00e+00h 1
127 7.1952766e-05 3.54e+00 3.22e-05 -5.7 1.88e+00 -7.3 1.00e+00 1.00e+00h 1
128 4.7287696e-05 7.12e+02 1.34e-03 -5.7 6.88e+03 - 1.00e+00 1.00e+00h 1
Reallocating memory for MA57: lfact (410779)
129 5.4350435e-05 5.24e+00 3.32e-05 -5.7 2.29e+00 -7.8 1.00e+00 1.00e+00h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
130 4.2273183e-05 1.29e+02 8.62e-04 -5.7 8.21e+03 - 1.00e+00 1.00e+00H 1
131 4.2156018e-05 1.26e-01 1.65e-06 -5.7 3.54e-01 -8.2 1.00e+00 1.00e+00h 1
132 3.5659446e-05 3.83e+02 2.59e-04 -5.7 7.12e+03 - 1.00e+00 1.00e+00h 1
133 3.4720745e-05 6.01e+01 1.47e-05 -5.7 3.51e+03 - 1.00e+00 1.00e+00h 1
134 3.4731686e-05 5.86e-02 2.80e-09 -5.7 1.61e+02 - 1.00e+00 1.00e+00h 1
135 3.4731694e-05 2.38e-07 1.84e-11 -5.7 5.75e-02 - 1.00e+00 1.00e+00h 1
Number of Iterations....: 135
(scaled) (unscaled)
Objective...............: 3.4731694252493991e-05 3.4731694252493991e-05
Dual infeasibility......: 1.8449144625279314e-11 1.8449144625279314e-11
Constraint violation....: 2.3841857910156250e-07 2.3841857910156250e-07
Complementarity.........: 1.8449144625279519e-06 1.8449144625279519e-06
Overall NLP error.......: 1.8449144625279519e-06 1.8449144625279519e-06
Number of objective function evaluations = 242
Number of objective gradient evaluations = 136
Number of equality constraint evaluations = 348
Number of inequality constraint evaluations = 348
Number of equality constraint Jacobian evaluations = 136
Number of inequality constraint Jacobian evaluations = 136
Number of Lagrangian Hessian evaluations = 135
Total CPU secs in IPOPT (w/o function evaluations) = 21.977
Total CPU secs in NLP function evaluations = 0.407
EXIT: Optimal Solution Found.
Analyze the Results¶
multiexp_results = extract_plot_results(None, TC_Lab_DoE_A)
Depending on whether you used parameter scaling in the DesignOfExperiments
FIM_A = np.asarray(TC_Lab_DoE_A.results["solution"]["param_scenarios"][0]["total_fim"])
if SCALE_BY_NOMINAL_PARAM:
D = np.diag(theta_ref)
FIM_unscaled_A = D @ FIM_A @ D / SCALE_CONSTANT_VALUE**2
else:
FIM_unscaled_A = FIM_A / SCALE_CONSTANT_VALUE**2
results_summary(np.asarray(FIM_unscaled_A))======Results Summary======
Five design criteria log10() value:
Pseudo A-optimality: 10.23559046813628
A-optimality: -7.344252849475594
D-optimality: 36.137496106376815
E-optimality: 7.357207085369849
Modified E-optimality: 2.6003313400615897
FIM:
[[ 7.17766371e+09 1.00811755e+08 -2.18902125e+08 -1.78696757e+06]
[ 1.00811755e+08 8.99331580e+08 1.51888668e+08 2.53869117e+06]
[-2.18902125e+08 1.51888668e+08 5.69021857e+07 1.94676190e+06]
[-1.78696757e+06 2.53869117e+06 1.94676190e+06 9.06855902e+09]]
eigenvalues:
[7.18585487e+09 2.27618253e+07 9.25277825e+08 9.06856198e+09]
Eigenvector matrix:
eigvec_1 eigvec_2 eigvec_3 eigvec_4
Ua 0.9994 0.0326 0.0098 -0.0010
Ub 0.0153 -0.1743 -0.9846 0.0003
inv_CpH -0.0304 0.9842 -0.1747 0.0002
inv_CpS 0.0010 -0.0002 0.0004 1.0000
# Now compare the uncertainty for the prior and the optimized design to see how much
# improvement we have achieved in terms of parameter uncertainty reduction.
std_D = np.sqrt(np.diag(cov_D))
std_A = np.sqrt(np.diag(np.linalg.inv(FIM_unscaled_A)))
print("Parameter estimates with standard deviations for D-optimal design:")
param_std(std_D)
print("\nParameter estimates with standard deviations for A-optimal design:")
param_std(std_A)Parameter estimates with standard deviations for D-optimal design:
Ua: 4.170e-02 ± 1.363e-05
Ub: 1.201e-02 ± 4.928e-05
inv_CpH: 1.675e-01 ± 2.065e-04
inv_CpS: 4.545e+00 ± 2.855e-03
Parameter estimates with standard deviations for A-optimal design:
Ua: 4.170e-02 ± 1.363e-05
Ub: 1.201e-02 ± 4.881e-05
inv_CpH: 1.675e-01 ± 2.064e-04
inv_CpS: 4.545e+00 ± 1.050e-05
Discussion: How does changing the objective change the result? Which one is better for reducing the uncertainty in our experiments?