@@ -1074,16 +1074,13 @@ def __init__(
10741074 assert isinstance (experiment_list , list )
10751075 self .exp_list = experiment_list
10761076
1077- # get the number of experiments
1078- self .number_exp = _count_total_experiments (self .exp_list )
1079-
10801077 # check if the experiment has a ``get_labeled_model`` function
10811078 model = _get_labeled_model (self .exp_list [0 ])
10821079
10831080 # check if the model has all the required suffixes
10841081 _check_model_labels (model )
10851082
1086- # populate keyword argument options
1083+ # check if the objective function is supplied correctly
10871084 if isinstance (obj_function , str ):
10881085 try :
10891086 self .obj_function = ObjectiveType (obj_function )
@@ -1113,6 +1110,18 @@ def __init__(
11131110 f"{ [e .value for e in RegularizationType ]} ."
11141111 )
11151112
1113+ # get the number of data points
1114+ # this is used to compute the covariance matrix for the case
1115+ # when the measurement errors are not supplied by the user
1116+ get_measurement_error = getattr (model , "measurement_error" , None )
1117+
1118+ all_unknown_errors = get_measurement_error is None or all (
1119+ model .measurement_error [y_hat ] is None for y_hat in model .experiment_outputs
1120+ )
1121+
1122+ if self .obj_function == ObjectiveType .SSE and all_unknown_errors :
1123+ self .number_exp = _count_total_experiments (self .exp_list )
1124+
11161125 self .tee = tee
11171126 self .diagnostic_mode = diagnostic_mode
11181127 self .solver_options = solver_options
@@ -1691,7 +1700,11 @@ def _cov_at_theta(self, method, solver, step):
16911700
16921701 # fix the value of the unknown parameters to the estimated values
16931702 for param in model .unknown_parameters :
1694- param .fix (self .estimated_theta [param .name ])
1703+ if param .is_indexed ():
1704+ for idx in param :
1705+ param [idx ].fix (self .estimated_theta [param [idx ].name ])
1706+ else :
1707+ param .fix (self .estimated_theta [param .name ])
16951708
16961709 # re-solve the model with the estimated parameters
16971710 results = pyo .SolverFactory (solver ).solve (model , tee = self .tee )
@@ -1720,12 +1733,6 @@ def _cov_at_theta(self, method, solver, step):
17201733 f"The sum of squared errors at the estimated parameter(s) is: { sse } "
17211734 )
17221735
1723- # Number of data points considered
1724- n = self .number_exp
1725-
1726- # Extract the number of fitted parameters
1727- l = len (self .estimated_theta )
1728-
17291736 """Calculate covariance assuming experimental observation errors are
17301737 independent and follow a Gaussian distribution with constant variance.
17311738
@@ -1763,6 +1770,17 @@ def _cov_at_theta(self, method, solver, step):
17631770
17641771 # check if the user supplied the values of the measurement errors
17651772 if all (item is None for item in meas_error ):
1773+ # Number of data points considered
1774+ n = self .number_exp
1775+
1776+ # Extract the number of fitted parameters
1777+ l = len (self .estimated_theta )
1778+
1779+ assert n > l , (
1780+ "The number of datapoints must be greater than the "
1781+ "number of parameters to estimate."
1782+ )
1783+
17661784 if cov_method == CovarianceMethod .reduced_hessian :
17671785 # in the "reduced_hessian" method, use the objective value
17681786 # to calculate the measurement error variance because this
@@ -2027,18 +2045,6 @@ def cov_est(self, method="finite_difference", solver="ipopt", step=1e-3):
20272045 if not isinstance (step , float ):
20282046 raise TypeError ("Expected a float for the step, e.g., 1e-2" )
20292047
2030- # number of unknown parameters
2031- num_unknowns = max (
2032- [
2033- len (_expanded_unknown_parameter_info (experiment .get_labeled_model ())[0 ])
2034- for experiment in self .exp_list
2035- ]
2036- )
2037- assert self .number_exp > num_unknowns , (
2038- "The number of datapoints must be greater than the "
2039- "number of parameters to estimate."
2040- )
2041-
20422048 return self ._cov_at_theta (method = method , solver = solver , step = step )
20432049
20442050 def theta_est_bootstrap (
0 commit comments