Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
189 commits
Select commit Hold shift + click to select a range
cdd7d52
Work on multistart implement 4/23 morning
sscini Apr 23, 2025
eca0ba8
Finished first draft of pseudocode for multistart
sscini Apr 23, 2025
2160aec
Fixed logical errors in pseudocode
sscini Apr 23, 2025
266beea
Started implementing review comments 4/30
sscini Apr 30, 2025
b877ada
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Apr 30, 2025
9f1ffe5
Work on edits, 5/1/25
sscini May 1, 2025
43f1ab3
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini May 1, 2025
ea067c8
Made edits, still debugging
sscini May 2, 2025
3b839ef
Addressed some comments in code. Still working through example to debug
sscini May 14, 2025
3a7aa1d
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini May 14, 2025
c688f2d
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini May 21, 2025
50c36bc
Got dataframe formatted, still working on executing Q_opt
sscini May 21, 2025
8e5f078
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Jun 2, 2025
f4c7018
Working code, adding features 6/2/25
sscini Jun 2, 2025
4444e6d
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Jun 3, 2025
e788000
Added questions for next round of reviews
sscini Jun 3, 2025
4429caf
Merge branch 'multistart-in-parmest' of https://github.com/sscini/pyo…
sscini Jun 3, 2025
f071718
Removed diagnostic tables to simplify output
sscini Jun 3, 2025
9b1545d
Work from Wednesday of Sprint week
sscini Jun 4, 2025
80079cb
Create Simple_Multimodal_Multistart.ipynb
sscini Jun 4, 2025
1695519
New features Thursday morning
sscini Jun 5, 2025
0634014
First successful running multistart feature, before Alex recommended …
sscini Jun 5, 2025
a959346
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Jun 5, 2025
04a9096
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Jun 23, 2025
06e0a72
Ran black, removed temp example
sscini Jun 24, 2025
6b3ee40
Added utility to update model using suffix values
sscini Jun 27, 2025
5cadfac
Work on Friday 6/27 applying PR comments
sscini Jun 27, 2025
922fd57
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Jun 30, 2025
1be2d9e
Addressed some reviewer comments and ran black.
sscini Jun 30, 2025
56800f5
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Jul 1, 2025
05381c5
Updated argument for theta_est_multistart
sscini Jul 6, 2025
5b4f9c1
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Jul 7, 2025
07ae1e8
Addressed majority of review comments. State before 7/8 dev meeting
sscini Jul 8, 2025
33d838f
Fixing conflict
sscini Jul 8, 2025
65a9cff
Merge branch 'main' into multistart-in-parmest
sscini Jul 15, 2025
90093df
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Jul 17, 2025
e7b2df1
Added in TODO items based on Dan morning meeting
sscini Jul 17, 2025
10f6b37
First pass at code redesign, still need to figure out more
sscini Nov 18, 2025
b0b7e2c
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Nov 20, 2025
3e95e91
Added comments where I have question
sscini Nov 20, 2025
8d3a4d5
Merge branch 'Q_opt-redesign' of https://github.com/sscini/pyomo into…
sscini Nov 20, 2025
3982e1b
Got preliminary _Q_opt simple working with example!
sscini Nov 21, 2025
e829344
Ran black
sscini Nov 21, 2025
e464097
Changed name to _Q_opt_blocks
sscini Nov 21, 2025
dc5ee76
Update parmest.py
sscini Nov 21, 2025
6355818
Ran black
sscini Nov 21, 2025
099f541
Added in case for bootlist, works with example
sscini Nov 25, 2025
76ee05e
Ran black
sscini Nov 25, 2025
d91ce3f
Simplified structure, ran black
sscini Nov 29, 2025
1aea99f
Removed _Q_opt, and replicate functions, only using _Q_opt_blocks
sscini Dec 13, 2025
7d93cc0
Ran black on mac
sscini Dec 15, 2025
d7d2214
Revert "Removed _Q_opt, and replicate functions, only using _Q_opt_bl…
sscini Dec 15, 2025
7f21344
Added testing statement
sscini Dec 17, 2025
32d8d41
Ran black
sscini Dec 17, 2025
4e8c3ee
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Jan 6, 2026
1e802ba
Made small design changes, in progress, ran black.
sscini Jan 6, 2026
4b89bb3
Merge branch 'Q_opt-redesign' of https://github.com/sscini/pyomo into…
sscini Jan 6, 2026
4777253
Progress made on objective_at_theta_blocks, unfinished.
sscini Jan 8, 2026
c58d5f3
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Jan 11, 2026
ea734b7
Merge branch 'Q_opt-redesign' of https://github.com/sscini/pyomo into…
sscini Jan 11, 2026
490abea
Added notes for design meeting 01/12/26
sscini Jan 12, 2026
1074fb0
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Jan 14, 2026
9543456
Removed answered reviewer question, attempted adding covariance
sscini Jan 14, 2026
af4df1a
Added assertions for cov_n
sscini Jan 14, 2026
d4c4125
Finished implementing covariance
sscini Jan 14, 2026
9d396fa
Added functional return values argument
sscini Jan 14, 2026
a97b21e
Ran black
sscini Jan 14, 2026
0afb5ba
Corrected extraction for unknown parameters
sscini Jan 14, 2026
191b131
Initial attempt at objective_at_theta_blocks
sscini Jan 14, 2026
2c0760e
Working out bugs in _Q_at_theta implement. In progress.
sscini Jan 14, 2026
bbe994b
Corrected obj_at_theta_blocks
sscini Jan 15, 2026
2c2e024
Removed _Q_opt, commented out _Q_at_theta, ran black
sscini Jan 15, 2026
2333a4b
Fixed for loop issue
sscini Jan 15, 2026
b9af9f1
Removed fix_theta from create_parm_model
sscini Jan 15, 2026
6cd3b4b
Renamed objective_at_theta_blocks, ran black.
sscini Jan 15, 2026
b46e1a7
Removed mentions of _Q_opt_blocks
sscini Jan 15, 2026
3261798
Changed back to get_labeled_model in _cov_at_theta()
sscini Jan 15, 2026
fc478be
Added notes in unused files.
sscini Jan 15, 2026
acba985
Removed _Q_at_theta and objective_at_theta
sscini Jan 15, 2026
145c2d8
Added comments for reviewers, ran black.
sscini Jan 15, 2026
337095d
Corrected count_total_experiments to divide by # outputs.
sscini Jan 15, 2026
837192c
Ran black.
sscini Jan 15, 2026
4b46c30
Undo change to count_total_experiments.
sscini Jan 15, 2026
b9cf010
Update mpi_utils.py
sscini Jan 19, 2026
062a9ee
Switched unknown_params to Vars
sscini Jan 19, 2026
5baaa2f
Fixed number for cov_n, still need to adjust counting function
sscini Jan 19, 2026
c8194ac
Added question for reviewers
sscini Jan 19, 2026
26d70e3
Ran black
sscini Jan 19, 2026
4aa027d
Changed retrieval of variables for ind_red_hes.
sscini Jan 19, 2026
26ba2ea
Added note related to count_total_experiments, commented out assertion.
sscini Jan 19, 2026
dd926f8
Ran black
sscini Jan 19, 2026
7b70d1d
Removed dependence on cov_est for theta_est(), added bool for len(exp…
sscini Jan 19, 2026
43cbaa4
Merge branch 'main' into Q_opt-redesign
sscini Jan 19, 2026
07798c9
Ran black
sscini Jan 19, 2026
b325f0d
Attempted adding support for indexed vars
sscini Jan 19, 2026
8b47430
Ran black
sscini Jan 20, 2026
aac1476
Addressed some review comments.
sscini Jan 20, 2026
66a1396
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Jan 21, 2026
3957dc9
Added Shammah fix for exp count
sscini Jan 21, 2026
382ea20
Updates to address comments.
sscini Jan 21, 2026
0da606f
Addressed some comments, simplified scenarios
sscini Jan 22, 2026
935b700
Replaced getattr with suffix calls.
sscini Jan 22, 2026
1fc71ee
Updated, ran black.
sscini Jan 22, 2026
56ac15d
Noted failing tests, currently 15
sscini Jan 22, 2026
60dc796
Removed old comment during dev
sscini Jan 22, 2026
6bf439e
Fixed scenario count issue, ran black.
sscini Jan 22, 2026
a68906b
Added else statement in cov calc
sscini Jan 23, 2026
f31a35f
Update test_parmest.py
sscini Jan 23, 2026
b124def
Update parmest.py
sscini Jan 23, 2026
2908c78
Update simple_reaction_parmest_example.py
sscini Jan 23, 2026
58435d3
Added measurement error to reactor_design
sscini Jan 23, 2026
db646ba
Changed to built-in SSE
sscini Jan 23, 2026
d222c4f
Commented out model_initialized
sscini Jan 23, 2026
9d829c4
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Jan 23, 2026
7ffab76
Merge remote-tracking branch 'refs/remotes/origin/Q_opt-redesign' int…
sscini Jan 23, 2026
e267983
Remove solver import
sscini Jan 23, 2026
e3ae6e6
Ran black
sscini Jan 23, 2026
345c3f2
Update test_parmest.py
sscini Jan 23, 2026
6c3d5a0
Added back option, ran black
sscini Jan 23, 2026
49b787a
Rearranged _Q_opt for fix_theta
sscini Jan 23, 2026
8cf624e
Ran black
sscini Jan 26, 2026
c248c74
Adjusting parmest models, in progress
sscini Jan 27, 2026
b975089
Added more description, simplified comparison
sscini Jan 27, 2026
a63e4fc
Update parameter_estimation_example.py
sscini Jan 27, 2026
b92aa7d
Ran black
sscini Jan 27, 2026
471dbe7
Adjusted if statement
sscini Jan 27, 2026
98d91fc
Removed answered questions
sscini Jan 27, 2026
a6821ae
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Jan 27, 2026
f0ef6d6
Update parmest.py
sscini Feb 2, 2026
1f86b03
Fixed models in variants test
sscini Feb 5, 2026
72b4345
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Feb 5, 2026
c495e0f
Merge remote-tracking branch 'refs/remotes/origin/Q_opt-redesign' int…
sscini Feb 5, 2026
82ee4ce
Update test_parmest.py
sscini Feb 5, 2026
559a900
Update parmest.py
sscini Feb 5, 2026
65067d5
Update parmest.py
sscini Feb 5, 2026
db26533
Temporary remove failing test.
sscini Feb 5, 2026
c9b19d7
Fixed experiment counter
sscini Feb 5, 2026
7bba006
Modified testing
sscini Feb 5, 2026
2cd2614
Removed extra print statements
sscini Feb 5, 2026
5ba4fab
Updated error message.
sscini Feb 5, 2026
ee57ec9
Adjusted experimental counter
sscini Feb 5, 2026
7cffb34
Update test_examples.py
sscini Feb 6, 2026
ebbd279
Addressed comments
sscini Feb 6, 2026
0c1e605
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Feb 11, 2026
92a2dd6
Update simple_reaction_parmest_example.py
sscini Feb 15, 2026
854366b
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Feb 19, 2026
c55143d
Added in files from main now, removed example
sscini Feb 19, 2026
8f3a902
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Feb 19, 2026
3c87d7a
Added old files in temporarily for reference
sscini Feb 19, 2026
4e09d33
Ran black
sscini Feb 19, 2026
4f94329
Merge branch 'Q_opt-redesign' into multistart-in-parmest
sscini Feb 19, 2026
12d0af1
Made quick working example, and small modification for multistart
sscini Feb 19, 2026
72204d9
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Feb 23, 2026
0a1167d
Merge branch 'main' into multistart-in-parmest
sscini Feb 24, 2026
9ccfba4
Added theta generation and old multistart over
sscini Mar 3, 2026
78f65f3
Updated multistart example and code
sscini Mar 3, 2026
43a67ab
Added bounds to models, ran black
sscini Mar 3, 2026
ed2cf54
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Mar 6, 2026
2b41ba5
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Mar 6, 2026
cc0513a
Updated interface, added block scenario tests.
sscini Mar 6, 2026
2e5ac42
Merge branch 'Q_opt-redesign' into multistart-in-parmest
sscini Mar 6, 2026
813a981
Adjusted implementation, added new tests in separate file
sscini Mar 6, 2026
96a4792
Initial implementation
sscini Mar 6, 2026
44a0b83
Merge branch 'Pyomo:main' into multistart-in-parmest
sscini Mar 6, 2026
8b9db82
Merge branch 'Pyomo:main' into profile-likelihood
sscini Mar 6, 2026
9c0d0a3
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Mar 6, 2026
f9c8e3a
Fixed issue with repeat thetas, ran black
sscini Mar 9, 2026
d6cfe37
Merge branch 'multistart-in-parmest' into profile-likelihood
sscini Mar 9, 2026
a025512
Applied changes based on changes to multistart
sscini Mar 9, 2026
6444c54
Merge branch 'Pyomo:main' into profile-likelihood
sscini Mar 17, 2026
4df5b48
Merge branch 'main' into Q_opt-redesign
sscini Mar 17, 2026
12a3c1b
Merge branch 'main' into multistart-in-parmest
sscini Mar 24, 2026
07c42e7
Merge branch 'main' into profile-likelihood
sscini Mar 24, 2026
4fc0336
Merge branch 'main' into Q_opt-redesign
sscini Mar 24, 2026
b372edd
Moved new tests into the main parmest testing file.
sscini Mar 24, 2026
41e8e98
Ran black
sscini Mar 24, 2026
9fe600f
Update test_parmest.py
sscini Mar 25, 2026
48ba6a6
Merge branch 'main' into Q_opt-redesign
sscini Mar 25, 2026
ba4091c
Merge branch 'Pyomo:main' into Q_opt-redesign
sscini Mar 27, 2026
eba10b3
Removed covariance functionality from theta_est, in progress
sscini Mar 27, 2026
c997944
Update simple_reaction_parmest_example.py
sscini Mar 27, 2026
d2b5d74
Update simple_reaction_parmest_example.py
sscini Mar 27, 2026
ae9808f
Update parameter_estimation_example.py
sscini Mar 27, 2026
9fa6528
Adjusted tests, ran black
sscini Mar 27, 2026
cb1ecea
Update test_parmest.py
sscini Mar 27, 2026
261a78f
Delete scenarios.csv
sscini Mar 27, 2026
664d687
Merge branch 'Q_opt-redesign' into multistart-in-parmest
sscini Mar 27, 2026
ea876b1
Merge branch 'multistart-in-parmest' into profile-likelihood
sscini Mar 27, 2026
3f2a971
Merge branch 'Pyomo:main' into profile-likelihood
sscini Apr 7, 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
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,6 @@ def simple_reaction_model(data):
# fix all of the regressed parameters
model.k.fix()

# ===================================================================
# Stage-specific cost computations
def ComputeFirstStageCost_rule(model):
return 0

model.FirstStageCost = Expression(rule=ComputeFirstStageCost_rule)

def AllMeasurements(m):
return (float(data['y']) - m.y) ** 2

model.SecondStageCost = Expression(rule=AllMeasurements)

def total_cost_rule(m):
return m.FirstStageCost + m.SecondStageCost

model.Total_Cost_Objective = Objective(rule=total_cost_rule, sense=minimize)

return model


Expand All @@ -90,6 +73,8 @@ def label_model(self):
m.experiment_outputs.update(
[(m.x1, self.data['x1']), (m.x2, self.data['x2']), (m.y, self.data['y'])]
)
m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)
m.measurement_error.update([(m.y, None), (m.x1, None), (m.x2, None)])

return m

Expand Down Expand Up @@ -161,7 +146,7 @@ def main():
# Only estimate the parameter k[1]. The parameter k[2] will remain fixed
# at its initial value

pest = parmest.Estimator(exp_list)
pest = parmest.Estimator(exp_list, obj_function="SSE")
obj, theta = pest.theta_est()
print(obj)
print(theta)
Expand All @@ -174,9 +159,11 @@ def main():

# =======================================================================
# Estimate both k1 and k2 and compute the covariance matrix
pest = parmest.Estimator(exp_list)
n = 15 # total number of data points used in the objective (y in 15 scenarios)
obj, theta, cov = pest.theta_est(calc_cov=True, cov_n=n)
pest = parmest.Estimator(exp_list, obj_function="SSE")
# Calculate the objective value and estimated parameters
obj, theta = pest.theta_est()
# Compute the covariance matrix using the reduced Hessian method
cov = pest.cov_est(method="reduced_hessian")
print(obj)
print(theta)
print(cov)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# ____________________________________________________________________________________
#
# Pyomo: Python Optimization Modeling Objects
# Copyright (c) 2008-2026 National Technology and Engineering Solutions of Sandia, LLC
# Under the terms of Contract DE-NA0003525 with National Technology and Engineering
# Solutions of Sandia, LLC, the U.S. Government retains certain rights in this
# software. This software is distributed under the 3-clause BSD License.
# ____________________________________________________________________________________

from pyomo.common.dependencies import numpy as np, pandas as pd
from itertools import product
from os.path import join, abspath, dirname
import pyomo.contrib.parmest.parmest as parmest
from pyomo.contrib.parmest.examples.reactor_design.reactor_design import (
ReactorDesignExperiment,
)


def main():

# Read in data
file_dirname = dirname(abspath(str(__file__)))
file_name = abspath(join(file_dirname, "reactor_data.csv"))
data = pd.read_csv(file_name)

# Create an experiment list
exp_list = [ReactorDesignExperiment(data, i) for i in range(data.shape[0])]

# Solver options belong here (Ipopt options shown as example)
solver_options = {"max_iter": 1000, "tol": 1e-6}

pest = parmest.Estimator(
exp_list, obj_function="SSE", solver_options=solver_options
)

# Single-start estimation
obj, theta = pest.theta_est()
print("Single-start objective:", obj)
print("Single-start theta:\n", theta)

# Multistart estimation
results_df, best_theta, best_obj = pest.theta_est_multistart(
n_restarts=10,
multistart_sampling_method="uniform_random",
seed=42,
save_results=False, # True if you want CSV via file_name=
)

print("\nMultistart best objective:", best_obj)
print("Multistart best theta:", best_theta)
print("\nAll multistart results:")
print(results_df)


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,17 @@ def main():

pest = parmest.Estimator(exp_list, obj_function='SSE')

# Parameter estimation with covariance
obj, theta, cov = pest.theta_est(calc_cov=True, cov_n=17)
print(obj)
# Parameter estimation
obj, theta = pest.theta_est()
print("Least squares objective value:", obj)
print("Estimated parameters (theta):\n")
print(theta)

# Compute the covariance matrix at the estimated parameter
cov = pest.cov_est()
print("Covariance matrix:\n")
print(cov)


if __name__ == "__main__":
main()
19 changes: 12 additions & 7 deletions pyomo/contrib/parmest/examples/reactor_design/reactor_design.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ def reactor_design_model():
# Create the concrete model
model = pyo.ConcreteModel()

# Rate constants
model.k1 = pyo.Param(
initialize=5.0 / 6.0, within=pyo.PositiveReals, mutable=True
# Rate constants, make unknown parameters variables
model.k1 = pyo.Var(
initialize=5.0 / 6.0, within=pyo.PositiveReals, bounds=(0.1, 10.0)
) # min^-1
model.k2 = pyo.Param(
initialize=5.0 / 3.0, within=pyo.PositiveReals, mutable=True
model.k2 = pyo.Var(
initialize=5.0 / 3.0, within=pyo.PositiveReals, bounds=(0.1, 10.0)
) # min^-1
model.k3 = pyo.Param(
initialize=1.0 / 6000.0, within=pyo.PositiveReals, mutable=True
model.k3 = pyo.Var(
initialize=1.0 / 6000.0, within=pyo.PositiveReals, bounds=(1e-5, 1e-3)
) # m^3/(gmol min)

# Inlet concentration of A, gmol/m^3
Expand Down Expand Up @@ -119,6 +119,11 @@ def label_model(self):
(k, pyo.ComponentUID(k)) for k in [m.k1, m.k2, m.k3]
)

m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL)
m.measurement_error.update(
[(m.ca, None), (m.cb, None), (m.cc, None), (m.cd, None)]
)

return m

def get_labeled_model(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# ____________________________________________________________________________________
#
# Pyomo: Python Optimization Modeling Objects
# Copyright (c) 2008-2026 National Technology and Engineering Solutions of Sandia, LLC
# Under the terms of Contract DE-NA0003525 with National Technology and Engineering
# Solutions of Sandia, LLC, the U.S. Government retains certain rights in this
# software. This software is distributed under the 3-clause BSD License.
# ____________________________________________________________________________________

from pyomo.common.dependencies import numpy as np, pandas as pd
from itertools import product
import pyomo.contrib.parmest.parmest as parmest
from pyomo.contrib.parmest.examples.rooney_biegler.rooney_biegler import (
RooneyBieglerExperiment,
)


def main():

# Data
data = pd.DataFrame(
data=[[1, 8.3], [2, 10.3], [3, 19.0], [4, 16.0], [5, 15.6], [7, 19.8]],
columns=['hour', 'y'],
)

# Create an experiment list
exp_list = []
for i in range(data.shape[0]):
exp_list.append(RooneyBieglerExperiment(data.loc[i, :]))

# View one model
# exp0_model = exp_list[0].get_labeled_model()
# exp0_model.pprint()

# Solver options belong here (Ipopt options shown as example)
solver_options = {"max_iter": 1000, "tol": 1e-6}

pest = parmest.Estimator(
exp_list, obj_function="SSE", solver_options=solver_options
)

# Single-start estimation
obj, theta = pest.theta_est()
print("Single-start objective:", obj)
print("Single-start theta:\n", theta)

# Multistart estimation
results_df, best_theta, best_obj = pest.theta_est_multistart(
n_restarts=10,
multistart_sampling_method="uniform_random",
seed=42,
save_results=False, # True if you want CSV via file_name=
)

print("\nMultistart best objective:", best_obj)
print("Multistart best theta:", best_theta)
print("\nAll multistart results:")
print(results_df)


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# ____________________________________________________________________________________
#
# Pyomo: Python Optimization Modeling Objects
# Copyright (c) 2008-2026 National Technology and Engineering Solutions of Sandia, LLC
# Under the terms of Contract DE-NA0003525 with National Technology and Engineering
# Solutions of Sandia, LLC, the U.S. Government retains certain rights in this
# software. This software is distributed under the 3-clause BSD License.
# ____________________________________________________________________________________

from pyomo.common.dependencies import pandas as pd
import pyomo.contrib.parmest.parmest as parmest
from pyomo.contrib.parmest.examples.rooney_biegler.rooney_biegler import (
RooneyBieglerExperiment,
)


def main():
# Data
data = pd.DataFrame(
data=[[1, 8.3], [2, 10.3], [3, 19.0], [4, 16.0], [5, 15.6], [7, 19.8]],
columns=["hour", "y"],
)

# Build experiment list
exp_list = [RooneyBieglerExperiment(data.loc[i, :]) for i in range(data.shape[0])]

# Create estimator
pest = parmest.Estimator(exp_list, obj_function="SSE")

# Compute profile likelihood for both unknown parameters.
# Use a small grid for quick terminal runs.
profile_results = pest.profile_likelihood(
profiled_theta=["asymptote", "rate_constant"],
n_grid=9,
solver="ef_ipopt",
warmstart="neighbor",
# Demonstrate baseline from multistart integration:
use_multistart_for_baseline=True,
baseline_multistart_kwargs={
"n_restarts": 5,
"multistart_sampling_method": "uniform_random",
"seed": 7,
},
)

# Display a compact summary table
profiles = profile_results["profiles"]
print("\nBaseline:")
print(profile_results["baseline"])
print("\nProfile results (first 12 rows):")
print(
profiles[
[
"profiled_theta",
"theta_value",
"obj",
"delta_obj",
"lr_stat",
"status",
"success",
]
].head(12)
)

# Plot profile curves to file for terminal/non-GUI usage
out_file = "rooney_biegler_profile_likelihood.png"
parmest.graphics.profile_likelihood_plot(
profile_results, alpha=0.95, filename=out_file
)
print(f"\nSaved plot to: {out_file}")


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ def rooney_biegler_model(data, theta=None):
if theta is None:
theta = {'asymptote': 15, 'rate_constant': 0.5}

model.asymptote = pyo.Var(initialize=theta['asymptote'])
model.rate_constant = pyo.Var(initialize=theta['rate_constant'])
model.asymptote = pyo.Var(initialize=theta['asymptote'], bounds=(0.1, 100))
model.rate_constant = pyo.Var(initialize=theta['rate_constant'], bounds=(0, 10))

# Fix the unknown parameters
model.asymptote.fix()
Expand Down
Loading