Skip to content

Commit b472357

Browse files
committed
Updated driver.rst file and minor string formats in parmest.py
1 parent 5e1d04a commit b472357

File tree

2 files changed

+39
-41
lines changed

2 files changed

+39
-41
lines changed

doc/OnlineDocs/explanation/analysis/parmest/driver.rst

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,21 @@ the model and the observations (typically defined as the sum of squared
1616
deviation between model values and observed values).
1717

1818
If the Pyomo model is not formatted as a two-stage stochastic
19-
programming problem in this format, the user can supply a custom
20-
function to use as the second stage cost and the Pyomo model will be
19+
programming problem in this format, the user can choose either the
20+
built-in "SSE" or "SSE_weighted" objective functions, or supply a custom
21+
objective function to use as the second stage cost. The Pyomo model will then be
2122
modified within parmest to match the required specifications.
22-
The stochastic programming callback function is also defined within parmest. The callback
23-
function returns a populated and initialized model for each scenario.
23+
The stochastic programming callback function is also defined within parmest.
24+
The callback function returns a populated and initialized model for each scenario.
2425

25-
To use parmest, the user creates a :class:`~pyomo.contrib.parmest.parmest.Estimator` object
26-
which includes the following methods:
26+
To use parmest, the user creates a :class:`~pyomo.contrib.parmest.parmest.Estimator`
27+
object which includes the following methods:
2728

2829
.. autosummary::
2930
:nosignatures:
3031

3132
~pyomo.contrib.parmest.parmest.Estimator.theta_est
33+
~pyomo.contrib.parmest.parmest.Estimator.cov_est
3234
~pyomo.contrib.parmest.parmest.Estimator.theta_est_bootstrap
3335
~pyomo.contrib.parmest.parmest.Estimator.theta_est_leaveNout
3436
~pyomo.contrib.parmest.parmest.Estimator.objective_at_theta
@@ -65,14 +67,6 @@ Section.
6567
columns=['hour', 'y'],
6668
)
6769

68-
# Sum of squared error function
69-
def SSE(model):
70-
expr = (
71-
model.experiment_outputs[model.y]
72-
- model.response_function[model.experiment_outputs[model.hour]]
73-
) ** 2
74-
return expr
75-
7670
# Create an experiment list
7771
from pyomo.contrib.parmest.examples.rooney_biegler.rooney_biegler import RooneyBieglerExperiment
7872
exp_list = []
@@ -83,22 +77,24 @@ Section.
8377
:skipif: not __import__('pyomo.contrib.parmest.parmest').contrib.parmest.parmest.parmest_available
8478

8579
>>> import pyomo.contrib.parmest.parmest as parmest
86-
>>> pest = parmest.Estimator(exp_list, obj_function=SSE)
80+
>>> pest = parmest.Estimator(exp_list, obj_function="SSE")
81+
>>> obj_val, theta_val = pest.theta_est()
8782

8883
Optionally, solver options can be supplied, e.g.,
8984

9085
.. doctest::
9186
:skipif: not __import__('pyomo.contrib.parmest.parmest').contrib.parmest.parmest.parmest_available
9287

9388
>>> solver_options = {"max_iter": 6000}
94-
>>> pest = parmest.Estimator(exp_list, obj_function=SSE, solver_options=solver_options)
89+
>>> pest = parmest.Estimator(exp_list, obj_function="SSE", solver_options=solver_options)
90+
>>> obj_val, theta_val = pest.theta_est()
9591

9692

9793
List of experiment objects
9894
--------------------------
9995

10096
The first argument is a list of experiment objects which is used to
101-
create one labeled model for each expeirment.
97+
create one labeled model for each experiment.
10298
The template :class:`~pyomo.contrib.parmest.experiment.Experiment`
10399
can be used to generate a list of experiment objects.
104100

@@ -137,17 +133,20 @@ expressions that are used to build an objective for the two-stage
137133
stochastic programming problem.
138134

139135
If the Pyomo model is not written as a two-stage stochastic programming problem in
140-
this format, and/or if the user wants to use an objective that is
141-
different than the original model, a custom objective function can be
142-
defined for parameter estimation. The objective function has a single argument,
143-
which is the model from a single experiment.
136+
this format, the user can select the "SSE" or "SSE_weighted" built-in objective
137+
functions. If the user wants to use an objective that is different from the built-in
138+
options, a custom objective function can be defined for parameter estimation. However,
139+
covariance estimation will not support this custom objective function. The objective
140+
function (built-in or custom) has a single argument, which is the model from a single
141+
experiment.
144142
The objective function returns a Pyomo
145143
expression which is used to define "SecondStageCost". The objective
146144
function can be used to customize data points and weights that are used
147145
in parameter estimation.
148146

149-
Parmest includes one built in objective function to compute the sum of squared errors ("SSE") between the
150-
``m.experiment_outputs`` model values and data values.
147+
Parmest includes two built-in objective functions ("SSE" and "SSE_weighted") to compute
148+
the sum of squared errors between the ``m.experiment_outputs`` model values and
149+
data values.
151150

152151
Suggested initialization procedure for parameter estimation problems
153152
--------------------------------------------------------------------

pyomo/contrib/parmest/parmest.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -779,17 +779,20 @@ def __init__(
779779
except ValueError:
780780
raise ValueError(
781781
f"Invalid objective function: '{obj_function}'. "
782-
f"Choose from {[e.value for e in ObjectiveLib]}."
782+
f"Choose from: {[e.value for e in ObjectiveLib]}."
783783
)
784784
else:
785-
deprecation_warning(
786-
"You're using a deprecated input to the `obj_function` argument by "
787-
"passing a custom function. This usage will be removed in a "
788-
"future release. Please update to the new parmest interface using "
789-
"the built-in 'SSE' and 'SSE_weighted' objectives.",
790-
version="6.9.3.dev0",
791-
)
792-
self.obj_function = obj_function
785+
if obj_function is None:
786+
self.obj_function = obj_function
787+
else:
788+
deprecation_warning(
789+
"You're using a deprecated input to the `obj_function` argument by "
790+
"passing a custom function. This usage will be removed in a "
791+
"future release. Please update to the new parmest interface using "
792+
"the built-in 'SSE' and 'SSE_weighted' objectives.",
793+
version="6.9.3.dev0",
794+
)
795+
self.obj_function = obj_function
793796

794797
self.tee = tee
795798
self.diagnostic_mode = diagnostic_mode
@@ -923,13 +926,8 @@ def _create_parmest_model(self, experiment_number):
923926
if isinstance(self.obj_function, Enum):
924927
if self.obj_function == ObjectiveLib.SSE:
925928
second_stage_rule = SSE
926-
elif self.obj_function == ObjectiveLib.SSE_weighted:
927-
second_stage_rule = SSE_weighted
928929
else:
929-
raise ValueError(
930-
f"Invalid objective function: '{self.obj_function.value}'. "
931-
f"Choose from {[e.value for e in ObjectiveLib]}."
932-
)
930+
second_stage_rule = SSE_weighted
933931
else:
934932
# A custom function uses model.experiment_outputs as data
935933
second_stage_rule = self.obj_function
@@ -1246,8 +1244,9 @@ def _cov_at_theta(self, method, solver, cov_n, step):
12461244
sse_expr = SSE_weighted(model)
12471245
else:
12481246
raise ValueError(
1249-
f"Invalid objective function: '{self.obj_function.value}'. "
1250-
f"Choose from {[e.value for e in ObjectiveLib]}."
1247+
f"Invalid objective function for covariance calculation: "
1248+
f"{self.obj_function}. Choose from: "
1249+
f"{[e.value for e in ObjectiveLib]} in the Estimator object."
12511250
)
12521251

12531252
# evaluate the numerical SSE and store it
@@ -1272,7 +1271,7 @@ def _cov_at_theta(self, method, solver, cov_n, step):
12721271
except ValueError:
12731272
raise ValueError(
12741273
f"Invalid method: '{method}'. Choose "
1275-
f"from {[e.value for e in CovarianceMethodLib]}."
1274+
f"from: {[e.value for e in CovarianceMethodLib]}."
12761275
)
12771276

12781277
# check if the user specified 'SSE' or 'SSE_weighted' as the objective function

0 commit comments

Comments
 (0)