Skip to content
Open
Changes from 10 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
b3486ca
Add regularize term function, and modified SSE to add option
sscini Mar 20, 2025
76ffb22
Fixed term in function
sscini Mar 20, 2025
50d6417
Merge branch 'main' into parmest_obj_regularization
sscini Mar 26, 2025
055f14c
Update parmest.py
sscini Apr 2, 2025
626c1b9
Revert "Update parmest.py"
sscini Apr 2, 2025
e853cc2
Reapply "Update parmest.py"
sscini Apr 2, 2025
77c2832
Add theta_ref and prior_FIM to keyword args
sscini Apr 2, 2025
cfe6460
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Apr 2, 2025
7d0c956
Adjust naming convention to ensure consistency.
sscini Apr 2, 2025
fae8500
Update parmest.py, DoE meeting work
sscini Apr 2, 2025
7b16637
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Jun 23, 2025
22d9031
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Jul 1, 2025
61d72c7
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Jul 7, 2025
8f36179
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Jul 8, 2025
2d2ec2d
Updated for next round of review
sscini Jul 15, 2025
d1ab692
Added regularization weight to exp class initialize
sscini Jul 15, 2025
bd212f4
Still debugging, progress as of 7/15/2025
sscini Jul 15, 2025
31bdf53
Merge branch 'main' into parmest_obj_regularization
sscini Jan 30, 2026
ec14208
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Feb 5, 2026
a3b4b4c
Update parmest.py
sscini Feb 6, 2026
7a0f623
Fixed issues with merging changes
sscini Feb 15, 2026
31a61e9
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Feb 15, 2026
d44f13d
L2 regularization working
sscini Feb 17, 2026
906f280
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Feb 17, 2026
fec94fd
Made the theta_ref a series.
sscini Feb 17, 2026
6ecb2a3
Updated doc strings.
sscini Feb 17, 2026
865e51e
Update parmest.py
sscini Feb 17, 2026
5ffa566
added helper comments.
sscini Feb 17, 2026
53ca679
Updated implementation to add vectorized L2 calc, and reviewer questions
sscini Feb 19, 2026
ab583bb
Adjusted logging, ran black
sscini Feb 19, 2026
ac96277
Changed value to avoid zero for L2 term
sscini Feb 19, 2026
08bce8f
Commented out or removed print statements
sscini Feb 19, 2026
26bc6b6
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Feb 19, 2026
7aa3b17
Merge branch 'main' into parmest_obj_regularization
sscini Feb 23, 2026
ec60888
Chose to apply in compute_covariance
sscini Mar 2, 2026
9531d73
Update parmest.py
sscini Mar 2, 2026
bc79da5
Made weight default 1
sscini Mar 2, 2026
0456910
Ran black
sscini Mar 2, 2026
23eb2ea
Adjusted doc strings, ran black
sscini Mar 2, 2026
933da0f
Update regularization_example.py
sscini Mar 2, 2026
ec100ae
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Mar 6, 2026
e20e457
Added validation for prior_FIM and fixed inconsistencies
sscini Mar 6, 2026
850819c
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Mar 6, 2026
baadbf0
Added L1 reg support working prototype, black
sscini Mar 9, 2026
351920f
Fixed testing issue, and example issues
sscini Mar 9, 2026
a0decd0
Merge branch 'main' into parmest_obj_regularization
sscini Mar 17, 2026
a7d1fb8
Merge branch 'main' into parmest_obj_regularization
sscini Mar 24, 2026
9786fc5
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Mar 27, 2026
6d46119
Added tests to correct files, ran black.
sscini Mar 29, 2026
14bc329
Updated model structure, reordered, ran black
sscini Apr 2, 2026
f84786c
Merge branch 'Pyomo:main' into parmest_obj_regularization
sscini Apr 7, 2026
a123706
Merge branch 'main' into parmest_obj_regularization
sscini Apr 21, 2026
2bacc80
Archived L1 for now, removed from here, ran black
sscini May 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion pyomo/contrib/parmest/parmest.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,37 @@ def SSE(model):
expr = sum((y - y_hat) ** 2 for y, y_hat in model.experiment_outputs.items())
return expr

def regularize_term(model, prior_FIM, theta_ref):
"""
Regularization term for the objective function, which is used to penalize deviation from a
reference theta
(theta - theta_ref).transpose() * prior_FIM * (theta - theta_ref)

theta_ref: Reference parameter value, element of matrix
prior_FIM: Fisher Information Matrix from prior experimental design, matrix
theta: Parameter value, matrix

Added to SSE objective function
"""
# Check if prior_FIM is a square matrix
if prior_FIM.shape[0] != prior_FIM.shape[1]:
raise ValueError("prior_FIM must be a square matrix")
Comment thread
sscini marked this conversation as resolved.
Outdated

# Check if theta_ref is a vector of the same size as prior_FIM
if len(theta_ref) != prior_FIM.shape[0]:
Comment thread
sscini marked this conversation as resolved.
Outdated
raise ValueError("theta_ref must be a vector of the same size as prior_FIM")

# (theta - theta_ref).transpose() * prior_FIM * (theta - theta_ref)
expr = np.zeros(len(theta_ref))

for i in range(len(theta_ref)):
if theta_ref[i] is None:
Comment thread
sscini marked this conversation as resolved.
Outdated
raise ValueError("theta_ref must not contain None values")
expr[i] = (model.unknown_parameters[i] - theta_ref[i]).transpose() * prior_FIM[i] * (model.unknown_parameters[i] - theta_ref[i])
Comment thread
sscini marked this conversation as resolved.
Outdated
return sum(expr)**2

return expr


class Estimator(object):
"""
Expand Down Expand Up @@ -270,6 +301,8 @@ def __init__(
self,
experiment_list,
obj_function=None,
prior_FIM=None,
theta_ref=None,
tee=False,
diagnostic_mode=False,
solver_options=None,
Expand All @@ -296,6 +329,8 @@ def __init__(

# populate keyword argument options
self.obj_function = obj_function
self.prior_FIM = prior_FIM
self.theta_ref = theta_ref
self.tee = tee
self.diagnostic_mode = diagnostic_mode
self.solver_options = solver_options
Expand Down Expand Up @@ -427,7 +462,18 @@ def _create_parmest_model(self, experiment_number):
# TODO, this needs to be turned into an enum class of options that still support
# custom functions
if self.obj_function == 'SSE':
second_stage_rule = SSE

if self.prior_FIM and self.theta_ref is not None:
# Regularize the objective function
second_stage_rule = SSE + regularize_term(model = self.model_initialized, prior_FIM = self.prior_FIM, theta_ref = self.theta_ref)
Comment thread
sscini marked this conversation as resolved.
Outdated
elif self.prior_FIM:
theta_ref = model.unknown_parameters.values()
Comment thread
sscini marked this conversation as resolved.
Outdated
second_stage_rule = SSE + regularize_term(prior_FIM = self.prior_FIM, theta_ref = theta_ref)

else:
# Sum of squared errors
second_stage_rule = SSE

else:
# A custom function uses model.experiment_outputs as data
second_stage_rule = self.obj_function
Expand Down