From cdd7d524d9da8645eff871ec980f8bbf5bcb7efa Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 23 Apr 2025 11:50:25 -0400 Subject: [PATCH 01/32] Work on multistart implement 4/23 morning --- pyomo/contrib/parmest/parmest.py | 103 +++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index ea9dfc00640..7c5cc618b83 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -235,6 +235,9 @@ def SSE(model): return expr +'''Adding pseudocode for draft implementation of the estimator class, +incorporating multistart. +''' class Estimator(object): """ Parameter estimation class @@ -273,8 +276,18 @@ def __init__( tee=False, diagnostic_mode=False, solver_options=None, + # Add the extra arguments needed for running the multistart implement + # _validate_multistart_args: + # if n_restarts > 1 and theta_samplig_method is not None: + # n_restarts=1, + # theta_sampling_method="random", ): + '''first theta would be provided by the user in the initialization of + the Estimator class through the unknown parameter variables. Additional + would need to be generated using the sampling method provided by the user. + ''' + # check that we have a (non-empty) list of experiments assert isinstance(experiment_list, list) self.exp_list = experiment_list @@ -447,6 +460,19 @@ def TotalCost_rule(model): parmest_model = utils.convert_params_to_vars(model, theta_names, fix_vars=False) return parmest_model + + # Make new private method, _generalize_initial_theta: + # This method will be used to generalize the initial theta values for multistart + # optimization. It will take the theta names and the initial theta values + # and return a dictionary of theta names and their corresponding values. + # def _generalize_initial_theta(self, theta_names, initial_theta): + # if self.method == "random": + # # Generate random theta values + # theta_vals = np.random.uniform(lower_bound, upper_bound, size=len(theta_names)) + + # elif self.method == "latin_hypercube": + # # Generate theta values using Latin hypercube sampling + # theta_vals = scipy.statsqmc.LatinHypercube(n=len(theta_names)).rvs(size=self.n_restarts) def _instance_creation_callback(self, experiment_number=None, cb_data=None): model = self._create_parmest_model(experiment_number) @@ -921,6 +947,83 @@ def theta_est( cov_n=cov_n, ) + ''' + def theta_est_multistart( + self, + n_restarts=1, + theta_sampling_method="random", + solver="ef_ipopt", + return_values=[], + calc_cov=False, + cov_n=None, + ): + """ + Parameter estimation using multistart optimization + + Parameters + ---------- + n_restarts: int, optional + Number of restarts for multistart. Default is 1. + theta_sampling_method: string, optional + Method used to sample theta values. Options are "random", "latin_hypercube", or "sobol". + Default is "random". + solver: string, optional + Currently only "ef_ipopt" is supported. Default is "ef_ipopt". + return_values: list, optional + List of Variable names, used to return values from the model for data reconciliation + calc_cov: boolean, optional + If True, calculate and return the covariance matrix (only for "ef_ipopt" solver). + Default is False. + cov_n: int, optional + If calc_cov=True, then the user needs to supply the number of datapoints + that are used in the objective function. + + Returns + ------- + objectiveval: float + The objective function value + thetavals: pd.Series + Estimated values for theta + variable values: pd.DataFrame + Variable values for each variable name in return_values (only for solver='ef_ipopt') + cov: pd.DataFrame + Covariance matrix of the fitted parameters (only for solver='ef_ipopt') + """ + + # check if we are using deprecated parmest + if self.pest_deprecated is not None: + return print( + "Multistart is not supported in the deprecated parmest interface") + ) + + assert isinstance(n_restarts, int) + assert isinstance(theta_sampling_method, str) + assert isinstance(solver, str) + assert isinstance(return_values, list) + assert isinstance(calc_cov, bool) + if calc_cov: + num_unknowns = max( + [ + len(experiment.get_labeled_model().unknown_parameters) + for experiment in self.exp_list + ] + ) + assert isinstance(cov_n, int), ( + "The number of datapoints that are used in the objective function is " + "required to calculate the covariance matrix" + ) + assert ( + cov_n > num_unknowns + ), "The number of datapoints must be greater than the number of parameters to estimate" + return_values = self._Q_opt( + solver=solver, + return_values=return_values, + bootlist=None, + calc_cov=calc_cov, + cov_n=cov_n, + ) + + ''' def theta_est_bootstrap( self, bootstrap_samples, From eca0ba802fe283ac18b451724c16cf9fe1bec927 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 23 Apr 2025 16:22:48 -0400 Subject: [PATCH 02/32] Finished first draft of pseudocode for multistart --- pyomo/contrib/parmest/parmest.py | 68 ++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 7c5cc618b83..88bc02c7c65 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -466,13 +466,30 @@ def TotalCost_rule(model): # optimization. It will take the theta names and the initial theta values # and return a dictionary of theta names and their corresponding values. # def _generalize_initial_theta(self, theta_names, initial_theta): + # if n_restarts == 1: + # # If only one restart, return an empty list + # return [] + + # return {theta_names[i]: initial_theta[i] for i in range(len(theta_names))} # if self.method == "random": # # Generate random theta values - # theta_vals = np.random.uniform(lower_bound, upper_bound, size=len(theta_names)) + # theta_vals = np.random.uniform(lower_bound, upper_bound, size=len(theta_names) + # else: + # # Generate theta values using Latin hypercube sampling or Sobol sampling + # samples # elif self.method == "latin_hypercube": # # Generate theta values using Latin hypercube sampling - # theta_vals = scipy.statsqmc.LatinHypercube(n=len(theta_names)).rvs(size=self.n_restarts) + # sampler = scipy.stats.qmc.LatinHypercube(d=len(theta_names)) + # samples = sampler.random(n=self.n_restarts) + # theta_vals = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) + + # elif self.method == "sobol": + # sampler = scipy.stats.qmc.Sobol(d=len(theta_names)) + # samples = sampler.random(n=self.n_restarts) + # theta_vals = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) + + # return theta_vals_multistart def _instance_creation_callback(self, experiment_number=None, cb_data=None): model = self._create_parmest_model(experiment_number) @@ -951,6 +968,7 @@ def theta_est( def theta_est_multistart( self, n_restarts=1, + theta_vals=None, theta_sampling_method="random", solver="ef_ipopt", return_values=[], @@ -1015,12 +1033,46 @@ def theta_est_multistart( assert ( cov_n > num_unknowns ), "The number of datapoints must be greater than the number of parameters to estimate" - return_values = self._Q_opt( - solver=solver, - return_values=return_values, - bootlist=None, - calc_cov=calc_cov, - cov_n=cov_n, + if n_restarts > 1 and theta_sampling_method is not None: + call self._generalize_initial_theta( + self.estimator_theta_names, self.initial_theta + ) + # make empty list to store results + + for i in range(n_restarts): + # for number of restarts, call the self._Q_opt method + # with the theta values generated using the _generalize_initial_theta method + + # Call the _Q_opt method with the generated theta values + objectiveval, thetavals, variable_values, cov = self._Q_opt( + ThetaVals=theta_vals, + solver=solver, + return_values=return_values, + calc_cov=calc_cov, + cov_n=cov_n, + ) + # Store the results in a list or DataFrame + # depending on the number of restarts + if n_restarts > 1 and cov is not None: + results.append( + { + "objectiveval": objectiveval, + "thetavals": thetavals, + "variable_values": variable_values, + "cov": cov, + } + elif n_restarts > 1 and cov is None: + results.append( + { objectiveval: objectiveval, + "thetavals": thetavals, + "variable_values": variable_values, + } + ) + return pd.DataFrame(results) + else: + return objectiveval, thetavals, variable_values, cov + + ) ''' From 2160aece3f9c91f87b5c2c321d32fd9e5eca1127 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 23 Apr 2025 16:38:59 -0400 Subject: [PATCH 03/32] Fixed logical errors in pseudocode --- pyomo/contrib/parmest/parmest.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 88bc02c7c65..8fc58831bbf 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -313,6 +313,10 @@ def __init__( self.diagnostic_mode = diagnostic_mode self.solver_options = solver_options + # add the extra multistart arguments to the Estimator class + # self.n_restarts = n_restarts + # self.theta_sampling_method = theta_sampling_method + # TODO: delete this when the deprecated interface is removed self.pest_deprecated = None @@ -1038,7 +1042,14 @@ def theta_est_multistart( self.estimator_theta_names, self.initial_theta ) # make empty list to store results + + + theta_vals = self._generalize_initial_theta( + self.estimator_theta_names, self.initial_theta, self.n_restarts, theta_sampling_method + ) + + results = [] for i in range(n_restarts): # for number of restarts, call the self._Q_opt method # with the theta values generated using the _generalize_initial_theta method From 266beea52a91488c29b8cd687a3b4c99209c73ca Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 30 Apr 2025 11:07:20 -0400 Subject: [PATCH 04/32] Started implementing review comments 4/30 --- pyomo/contrib/parmest/parmest.py | 163 +++++++++++++------------------ 1 file changed, 70 insertions(+), 93 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 8fc58831bbf..5428f49c00b 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -279,8 +279,8 @@ def __init__( # Add the extra arguments needed for running the multistart implement # _validate_multistart_args: # if n_restarts > 1 and theta_samplig_method is not None: - # n_restarts=1, - # theta_sampling_method="random", + n_restarts=20, + multistart_sampling_method="random", ): '''first theta would be provided by the user in the initialization of @@ -314,8 +314,8 @@ def __init__( self.solver_options = solver_options # add the extra multistart arguments to the Estimator class - # self.n_restarts = n_restarts - # self.theta_sampling_method = theta_sampling_method + self.n_restarts = n_restarts + self.multistart_sampling_method = multistart_sampling_method # TODO: delete this when the deprecated interface is removed self.pest_deprecated = None @@ -469,31 +469,51 @@ def TotalCost_rule(model): # This method will be used to generalize the initial theta values for multistart # optimization. It will take the theta names and the initial theta values # and return a dictionary of theta names and their corresponding values. - # def _generalize_initial_theta(self, theta_names, initial_theta): - # if n_restarts == 1: - # # If only one restart, return an empty list - # return [] - - # return {theta_names[i]: initial_theta[i] for i in range(len(theta_names))} - # if self.method == "random": - # # Generate random theta values - # theta_vals = np.random.uniform(lower_bound, upper_bound, size=len(theta_names) - # else: - # # Generate theta values using Latin hypercube sampling or Sobol sampling - # samples - - # elif self.method == "latin_hypercube": - # # Generate theta values using Latin hypercube sampling - # sampler = scipy.stats.qmc.LatinHypercube(d=len(theta_names)) - # samples = sampler.random(n=self.n_restarts) - # theta_vals = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) - - # elif self.method == "sobol": - # sampler = scipy.stats.qmc.Sobol(d=len(theta_names)) - # samples = sampler.random(n=self.n_restarts) - # theta_vals = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) - - # return theta_vals_multistart + def _generate_initial_theta(self, parmest_model, seed=None): + if self.n_restarts == 1: + # If only one restart, return an empty list + return print("No multistart optimization needed. Please use normal theta_est()") + + # Get the theta names and initial theta values + theta_names = self._return_theta_names() + initial_theta = [parmest_model.find_component(name)() for name in theta_names] + + # Get the lower and upper bounds for the theta values + lower_bound = np.array([parmest_model.find_component(name).lb for name in theta_names]) + upper_bound = np.array([parmest_model.find_component(name).ub for name in theta_names]) + # Check if the lower and upper bounds are defined + if np.any(np.isnan(lower_bound)) or np.any(np.isnan(upper_bound)): + raise ValueError( + "The lower and upper bounds for the theta values must be defined." + ) + + # Check the length of theta_names and initial_theta, and make sure bounds are defined + if len(theta_names) != len(initial_theta): + raise ValueError( + "The length of theta_names and initial_theta must be the same." + ) + + if self.method == "random": + np.random.seed(seed) + # Generate random theta values + theta_vals_multistart = np.random.uniform(lower_bound, upper_bound, size=len(theta_names)) + + # Generate theta values using Latin hypercube sampling or Sobol sampling + return theta_vals_multistart + + elif self.method == "latin_hypercube": + # Generate theta values using Latin hypercube sampling + sampler = scipy.stats.qmc.LatinHypercube(d=len(theta_names), seed=seed) + samples = sampler.random(n=self.n_restarts) + theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) + + + elif self.method == "sobol": + sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) + samples = sampler.random(n=self.n_restarts) + theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) + + return theta_vals_multistart def _instance_creation_callback(self, experiment_number=None, cb_data=None): model = self._create_parmest_model(experiment_number) @@ -968,16 +988,11 @@ def theta_est( cov_n=cov_n, ) - ''' def theta_est_multistart( self, - n_restarts=1, theta_vals=None, - theta_sampling_method="random", solver="ef_ipopt", return_values=[], - calc_cov=False, - cov_n=None, ): """ Parameter estimation using multistart optimization @@ -993,12 +1008,7 @@ def theta_est_multistart( Currently only "ef_ipopt" is supported. Default is "ef_ipopt". return_values: list, optional List of Variable names, used to return values from the model for data reconciliation - calc_cov: boolean, optional - If True, calculate and return the covariance matrix (only for "ef_ipopt" solver). - Default is False. - cov_n: int, optional - If calc_cov=True, then the user needs to supply the number of datapoints - that are used in the objective function. + Returns ------- @@ -1008,49 +1018,29 @@ def theta_est_multistart( Estimated values for theta variable values: pd.DataFrame Variable values for each variable name in return_values (only for solver='ef_ipopt') - cov: pd.DataFrame - Covariance matrix of the fitted parameters (only for solver='ef_ipopt') + """ # check if we are using deprecated parmest if self.pest_deprecated is not None: return print( - "Multistart is not supported in the deprecated parmest interface") + "Multistart is not supported in the deprecated parmest interface" ) - assert isinstance(n_restarts, int) - assert isinstance(theta_sampling_method, str) + assert isinstance(self.n_restarts, int) + assert isinstance(self.multistart_sampling_method, str) assert isinstance(solver, str) assert isinstance(return_values, list) - assert isinstance(calc_cov, bool) - if calc_cov: - num_unknowns = max( - [ - len(experiment.get_labeled_model().unknown_parameters) - for experiment in self.exp_list - ] - ) - assert isinstance(cov_n, int), ( - "The number of datapoints that are used in the objective function is " - "required to calculate the covariance matrix" - ) - assert ( - cov_n > num_unknowns - ), "The number of datapoints must be greater than the number of parameters to estimate" - if n_restarts > 1 and theta_sampling_method is not None: - call self._generalize_initial_theta( - self.estimator_theta_names, self.initial_theta - ) - # make empty list to store results - - + + if self.n_restarts > 1 and self.multistart_sampling_method is not None: + # Generate theta values using the sampling method theta_vals = self._generalize_initial_theta( - self.estimator_theta_names, self.initial_theta, self.n_restarts, theta_sampling_method + self.estimator_theta_names, self.initial_theta, self.n_restarts, self.multistart_sampling_method ) - + # make empty list to store results results = [] - for i in range(n_restarts): + for i in range(self.n_restarts): # for number of restarts, call the self._Q_opt method # with the theta values generated using the _generalize_initial_theta method @@ -1059,34 +1049,21 @@ def theta_est_multistart( ThetaVals=theta_vals, solver=solver, return_values=return_values, - calc_cov=calc_cov, - cov_n=cov_n, ) # Store the results in a list or DataFrame # depending on the number of restarts - if n_restarts > 1 and cov is not None: - results.append( - { - "objectiveval": objectiveval, - "thetavals": thetavals, - "variable_values": variable_values, - "cov": cov, - } - elif n_restarts > 1 and cov is None: - results.append( - { objectiveval: objectiveval, - "thetavals": thetavals, - "variable_values": variable_values, - } - ) + + if self.n_restarts > 1: + results.append( + { objectiveval: objectiveval, + "thetavals": thetavals, + "variable_values": variable_values, + } + ) return pd.DataFrame(results) - else: - return objectiveval, thetavals, variable_values, cov - - - ) - ''' + + def theta_est_bootstrap( self, bootstrap_samples, From 9f1ffe5ec226d177cc6125be8febe7775e405fe1 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 1 May 2025 15:51:16 -0400 Subject: [PATCH 05/32] Work on edits, 5/1/25 --- pyomo/contrib/parmest/parmest.py | 98 ++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 16 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 5428f49c00b..c5e418ac540 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -465,8 +465,8 @@ def TotalCost_rule(model): return parmest_model - # Make new private method, _generalize_initial_theta: - # This method will be used to generalize the initial theta values for multistart + # Make new private method, _generate_initial_theta: + # This method will be used to generate the initial theta values for multistart # optimization. It will take the theta names and the initial theta values # and return a dictionary of theta names and their corresponding values. def _generate_initial_theta(self, parmest_model, seed=None): @@ -504,16 +504,48 @@ def _generate_initial_theta(self, parmest_model, seed=None): elif self.method == "latin_hypercube": # Generate theta values using Latin hypercube sampling sampler = scipy.stats.qmc.LatinHypercube(d=len(theta_names), seed=seed) - samples = sampler.random(n=self.n_restarts) + samples = sampler.random(n=self.n_restarts+1)[1:] # Skip the first sample theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) elif self.method == "sobol": sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) - samples = sampler.random(n=self.n_restarts) + samples = sampler.random(n=self.n_restarts+1)[1:] theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) - return theta_vals_multistart + # elif self.method == "prior": + # # Still working on this + # theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in initial_theta]) + + else: + raise ValueError( + "Invalid sampling method. Choose 'random', 'latin_hypercube', 'sobol'." # or 'prior'." + ) + + # Make an output dataframe with the theta names and their corresponding values for each restart, + # and nan for the output info values + df_multistart = pd.DataFrame( + theta_vals_multistart, columns=theta_names + ) + df_multistart["initial objective"] = np.nan + df_multistart["final objective"] = np.nan + df_multistart["solver termination"] = np.nan + df_multistart["solve_time"] = np.nan + + # Add the initial theta values to the first row of the dataframe + for i in self.n_restarts: + df_multistart.iloc[i, :] = theta_vals_multistart[i, :] + df_multistart.iloc[0, :] = initial_theta + # # Add the initial objective value to the first row of the dataframe + # df_multistart.iloc[0, -1] = self._Q_at_theta(initial_theta, initialize_parmest_model=True)[0] + # # Add the final objective value to the first row of the dataframe + # df_multistart.iloc[0, -2] = self._Q_at_theta(initial_theta, initialize_parmest_model=True)[0] + # # Add the solver termination value to the first row of the dataframe + # df_multistart.iloc[0, -3] = self._Q_at_theta(initial_theta, initialize_parmest_model=True)[2] + # # Add the solve time to the first row of the dataframe + # df_multistart.iloc[0, -4] = self._Q_at_theta(initial_theta, initialize_parmest_model=True)[3] + + return theta_vals_multistart, df_multistart def _instance_creation_callback(self, experiment_number=None, cb_data=None): model = self._create_parmest_model(experiment_number) @@ -990,6 +1022,8 @@ def theta_est( def theta_est_multistart( self, + buffer=10, + save_results=False, theta_vals=None, solver="ef_ipopt", return_values=[], @@ -1034,33 +1068,65 @@ def theta_est_multistart( if self.n_restarts > 1 and self.multistart_sampling_method is not None: # Generate theta values using the sampling method - theta_vals = self._generalize_initial_theta( + theta_vals, results_df = self._generate_initial_theta( self.estimator_theta_names, self.initial_theta, self.n_restarts, self.multistart_sampling_method ) # make empty list to store results - results = [] for i in range(self.n_restarts): # for number of restarts, call the self._Q_opt method # with the theta values generated using the _generalize_initial_theta method # Call the _Q_opt method with the generated theta values - objectiveval, thetavals, variable_values, cov = self._Q_opt( + objectiveval, thetavals[i], variable_values = self._Q_opt( ThetaVals=theta_vals, solver=solver, return_values=return_values, ) + + # Check if the solver terminated successfully + if variable_values.solver.termination_condition != pyo.TerminationCondition.optimal: + # If not, set the objective value to NaN + solver_termination = variable_values.solver.termination_condition + solve_time = variable_values.solver.time + thetavals = np.nan + + else: + + # If the solver terminated successfully, set the objective value + init_objectiveval = objectiveval + final_objectiveval = variable_values.solver.objective() + solver_termination = variable_values.solver.termination_condition + solve_time = variable_values.solver.time + + # Check if the objective value is better than the best objective value + if final_objectiveval < best_objectiveval: + best_objectiveval = objectiveval + best_theta = thetavals + # Store the results in a list or DataFrame # depending on the number of restarts + results_df.iloc[i, :-4] = theta_vals + results_df.iloc[i, -4] = init_objectiveval + results_df.iloc[i, -3] = objectiveval + results_df.iloc[i, -2] = variable_values.solver.termination_condition + results_df.iloc[i, -1] = variable_values.solver.time + + # Add buffer to save the dataframe dynamically, if save_results is True + if save_results and (i + 1) % buffer == 0: + mode = 'w' if i + 1 == buffer else 'a' + header = i + 1 == buffer + results_df.to_csv( + f"multistart_results.csv", mode=mode, header=header, index=False + ) + print(f"Intermediate results saved after {i + 1} iterations.") - if self.n_restarts > 1: - results.append( - { objectiveval: objectiveval, - "thetavals": thetavals, - "variable_values": variable_values, - } - ) - return pd.DataFrame(results) + # Final save after all iterations + if save_results: + results_df.to_csv("multistart_results.csv", mode='a', header=False, index=False) + print("Final results saved.") + + return results_df, best_theta, best_objectiveval From ea067c80ebac177024f3007a5cb0a217e49d47ba Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Fri, 2 May 2025 06:50:36 -0400 Subject: [PATCH 06/32] Made edits, still debugging --- pyomo/contrib/parmest/parmest.py | 153 +++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 50 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index c5e418ac540..3352aa80fe2 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -276,11 +276,6 @@ def __init__( tee=False, diagnostic_mode=False, solver_options=None, - # Add the extra arguments needed for running the multistart implement - # _validate_multistart_args: - # if n_restarts > 1 and theta_samplig_method is not None: - n_restarts=20, - multistart_sampling_method="random", ): '''first theta would be provided by the user in the initialization of @@ -313,10 +308,6 @@ def __init__( self.diagnostic_mode = diagnostic_mode self.solver_options = solver_options - # add the extra multistart arguments to the Estimator class - self.n_restarts = n_restarts - self.multistart_sampling_method = multistart_sampling_method - # TODO: delete this when the deprecated interface is removed self.pest_deprecated = None @@ -469,8 +460,8 @@ def TotalCost_rule(model): # This method will be used to generate the initial theta values for multistart # optimization. It will take the theta names and the initial theta values # and return a dictionary of theta names and their corresponding values. - def _generate_initial_theta(self, parmest_model, seed=None): - if self.n_restarts == 1: + def _generate_initial_theta(self, parmest_model, seed=None, n_restarts=None, multistart_sampling_method=None, user_provided=None): + if n_restarts == 1: # If only one restart, return an empty list return print("No multistart optimization needed. Please use normal theta_est()") @@ -482,7 +473,7 @@ def _generate_initial_theta(self, parmest_model, seed=None): lower_bound = np.array([parmest_model.find_component(name).lb for name in theta_names]) upper_bound = np.array([parmest_model.find_component(name).ub for name in theta_names]) # Check if the lower and upper bounds are defined - if np.any(np.isnan(lower_bound)) or np.any(np.isnan(upper_bound)): + if any(bound is None for bound in lower_bound) and any(bound is None for bound in upper_bound): raise ValueError( "The lower and upper bounds for the theta values must be defined." ) @@ -493,33 +484,77 @@ def _generate_initial_theta(self, parmest_model, seed=None): "The length of theta_names and initial_theta must be the same." ) - if self.method == "random": + if multistart_sampling_method == "random": np.random.seed(seed) # Generate random theta values theta_vals_multistart = np.random.uniform(lower_bound, upper_bound, size=len(theta_names)) # Generate theta values using Latin hypercube sampling or Sobol sampling - return theta_vals_multistart - elif self.method == "latin_hypercube": + elif multistart_sampling_method == "latin_hypercube": # Generate theta values using Latin hypercube sampling sampler = scipy.stats.qmc.LatinHypercube(d=len(theta_names), seed=seed) - samples = sampler.random(n=self.n_restarts+1)[1:] # Skip the first sample + samples = sampler.random(n=n_restarts) theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) - elif self.method == "sobol": + elif multistart_sampling_method == "sobol": sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) - samples = sampler.random(n=self.n_restarts+1)[1:] + # Generate theta values using Sobol sampling + # The first value of the Sobol sequence is 0, so we skip it + samples = sampler.random(n=n_restarts+1)[1:] theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) - # elif self.method == "prior": - # # Still working on this - # theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in initial_theta]) + elif multistart_sampling_method == "user_provided": + # Add user provided dataframe option + if user_provided is not None: + + if isinstance(user_provided, np.ndarray): + # Check if the user provided numpy array has the same number of rows as the number of restarts + if user_provided.shape[0] != n_restarts: + raise ValueError( + "The user provided numpy array must have the same number of rows as the number of restarts." + ) + # Check if the user provided numpy array has the same number of columns as the number of theta names + if user_provided.shape[1] != len(theta_names): + raise ValueError( + "The user provided numpy array must have the same number of columns as the number of theta names." + ) + # Check if the user provided numpy array has the same theta names as the model + # if not, raise an error + # if not all(theta in theta_names for theta in user_provided.columns): + raise ValueError( + "The user provided numpy array must have the same theta names as the model." + ) + # If all checks pass, return the user provided numpy array + theta_vals_multistart = user_provided + elif isinstance(user_provided, pd.DataFrame): + # Check if the user provided dataframe has the same number of rows as the number of restarts + if user_provided.shape[0] != n_restarts: + raise ValueError( + "The user provided dataframe must have the same number of rows as the number of restarts." + ) + # Check if the user provided dataframe has the same number of columns as the number of theta names + if user_provided.shape[1] != len(theta_names): + raise ValueError( + "The user provided dataframe must have the same number of columns as the number of theta names." + ) + # Check if the user provided dataframe has the same theta names as the model + # if not, raise an error + # if not all(theta in theta_names for theta in user_provided.columns): + raise ValueError( + "The user provided dataframe must have the same theta names as the model." + ) + # If all checks pass, return the user provided dataframe + theta_vals_multistart = user_provided.iloc[0: len(initial_theta)].values + else: + raise ValueError( + "The user must provide a numpy array or pandas dataframe from a previous attempt to use the 'user_provided' method." + ) else: raise ValueError( - "Invalid sampling method. Choose 'random', 'latin_hypercube', 'sobol'." # or 'prior'." + "Invalid sampling method. Choose 'random', 'latin_hypercube', 'sobol' or 'user_provided'." ) # Make an output dataframe with the theta names and their corresponding values for each restart, @@ -527,25 +562,23 @@ def _generate_initial_theta(self, parmest_model, seed=None): df_multistart = pd.DataFrame( theta_vals_multistart, columns=theta_names ) - df_multistart["initial objective"] = np.nan - df_multistart["final objective"] = np.nan - df_multistart["solver termination"] = np.nan - df_multistart["solve_time"] = np.nan + # Add the initial theta values to the first row of the dataframe - for i in self.n_restarts: + for i in range(1, n_restarts): df_multistart.iloc[i, :] = theta_vals_multistart[i, :] df_multistart.iloc[0, :] = initial_theta - # # Add the initial objective value to the first row of the dataframe - # df_multistart.iloc[0, -1] = self._Q_at_theta(initial_theta, initialize_parmest_model=True)[0] - # # Add the final objective value to the first row of the dataframe - # df_multistart.iloc[0, -2] = self._Q_at_theta(initial_theta, initialize_parmest_model=True)[0] - # # Add the solver termination value to the first row of the dataframe - # df_multistart.iloc[0, -3] = self._Q_at_theta(initial_theta, initialize_parmest_model=True)[2] - # # Add the solve time to the first row of the dataframe - # df_multistart.iloc[0, -4] = self._Q_at_theta(initial_theta, initialize_parmest_model=True)[3] - return theta_vals_multistart, df_multistart + + # Add the output info values to the dataframe, starting values as nan + for i in range(len(theta_names)): + df_multistart[f'converged_{theta_names[i]}'] = np.nan + df_multistart["initial objective"] = np.nan + df_multistart["final objective"] = np.nan + df_multistart["solver termination"] = np.nan + df_multistart["solve_time"] = np.nan + + return df_multistart def _instance_creation_callback(self, experiment_number=None, cb_data=None): model = self._create_parmest_model(experiment_number) @@ -1022,10 +1055,15 @@ def theta_est( def theta_est_multistart( self, + n_restarts=20, buffer=10, + multistart_sampling_method="random", + user_provided=None, + seed=None, save_results=False, theta_vals=None, solver="ef_ipopt", + file_name = "multistart_results.csv", return_values=[], ): """ @@ -1061,25 +1099,39 @@ def theta_est_multistart( "Multistart is not supported in the deprecated parmest interface" ) - assert isinstance(self.n_restarts, int) - assert isinstance(self.multistart_sampling_method, str) + assert isinstance(n_restarts, int) + assert isinstance(multistart_sampling_method, str) assert isinstance(solver, str) assert isinstance(return_values, list) - if self.n_restarts > 1 and self.multistart_sampling_method is not None: + if n_restarts > 1 and multistart_sampling_method is not None: + + # Find the initialized values of theta from the labeled parmest model + # and the theta names from the estimator object + parmest_model = self._create_parmest_model(experiment_number=0) + theta_names = self._return_theta_names() + initial_theta = [parmest_model.find_component(name)() for name in theta_names] + # Generate theta values using the sampling method - theta_vals, results_df = self._generate_initial_theta( - self.estimator_theta_names, self.initial_theta, self.n_restarts, self.multistart_sampling_method - ) + results_df = self._generate_initial_theta(parmest_model, seed=seed, n_restarts=n_restarts, + multistart_sampling_method=multistart_sampling_method, user_provided=user_provided) + results_df = pd.DataFrame(results_df) + # Extract theta_vals from the dataframe + theta_vals = results_df.iloc[:, :len(theta_names)] + converged_theta_vals = np.zeros((n_restarts, len(theta_names))) # make empty list to store results - for i in range(self.n_restarts): - # for number of restarts, call the self._Q_opt method - # with the theta values generated using the _generalize_initial_theta method + for i in range(n_restarts): + # for number of restarts, call the self._Q_opt method + # with the theta values generated using the _generalize_initial_theta method + + # set the theta values in the model + theta_vals_current = theta_vals.iloc[i, :] + # Call the _Q_opt method with the generated theta values - objectiveval, thetavals[i], variable_values = self._Q_opt( - ThetaVals=theta_vals, + objectiveval, converged_theta, variable_values = self._Q_opt( + ThetaVals=theta_vals_current, solver=solver, return_values=return_values, ) @@ -1094,6 +1146,7 @@ def theta_est_multistart( else: # If the solver terminated successfully, set the objective value + converged_theta_vals[i, :] = converged_theta.values() init_objectiveval = objectiveval final_objectiveval = variable_values.solver.objective() solver_termination = variable_values.solver.termination_condition @@ -1106,7 +1159,7 @@ def theta_est_multistart( # Store the results in a list or DataFrame # depending on the number of restarts - results_df.iloc[i, :-4] = theta_vals + results_df.iloc[i, len(theta_names):len(theta_names) + len(theta_names)] = converged_theta_vals[i, :] results_df.iloc[i, -4] = init_objectiveval results_df.iloc[i, -3] = objectiveval results_df.iloc[i, -2] = variable_values.solver.termination_condition @@ -1117,13 +1170,13 @@ def theta_est_multistart( mode = 'w' if i + 1 == buffer else 'a' header = i + 1 == buffer results_df.to_csv( - f"multistart_results.csv", mode=mode, header=header, index=False + file_name, mode=mode, header=header, index=False ) print(f"Intermediate results saved after {i + 1} iterations.") # Final save after all iterations if save_results: - results_df.to_csv("multistart_results.csv", mode='a', header=False, index=False) + results_df.to_csv(file_name, mode='a', header=False, index=False) print("Final results saved.") return results_df, best_theta, best_objectiveval From 3b839ef8c204c33941969ee49fd54f6b107980a0 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 14 May 2025 08:18:00 -0600 Subject: [PATCH 07/32] Addressed some comments in code. Still working through example to debug --- pyomo/contrib/parmest/parmest.py | 38 +++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 3352aa80fe2..e122afb7560 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -460,7 +460,10 @@ def TotalCost_rule(model): # This method will be used to generate the initial theta values for multistart # optimization. It will take the theta names and the initial theta values # and return a dictionary of theta names and their corresponding values. - def _generate_initial_theta(self, parmest_model, seed=None, n_restarts=None, multistart_sampling_method=None, user_provided=None): + def _generate_initial_theta(self, parmest_model=None, seed=None, n_restarts=None, multistart_sampling_method=None, user_provided=None): + """ + Generate initial theta values for multistart optimization using selected sampling method. + """ if n_restarts == 1: # If only one restart, return an empty list return print("No multistart optimization needed. Please use normal theta_est()") @@ -484,25 +487,31 @@ def _generate_initial_theta(self, parmest_model, seed=None, n_restarts=None, mul "The length of theta_names and initial_theta must be the same." ) - if multistart_sampling_method == "random": + if multistart_sampling_method == "uniform": + # Generate random theta values using uniform distribution, with set seed for reproducibility np.random.seed(seed) # Generate random theta values theta_vals_multistart = np.random.uniform(lower_bound, upper_bound, size=len(theta_names)) - # Generate theta values using Latin hypercube sampling or Sobol sampling + elif multistart_sampling_method == "latin_hypercube": + # Generate theta values using Latin hypercube sampling or Sobol sampling # Generate theta values using Latin hypercube sampling + # Create a Latin Hypercube sampler that uses the dimensions of the theta names sampler = scipy.stats.qmc.LatinHypercube(d=len(theta_names), seed=seed) + # Generate random samples in the range of [0, 1] for number of restarts samples = sampler.random(n=n_restarts) - theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) - + # Resulting samples should be size (n_restarts, len(theta_names)) elif multistart_sampling_method == "sobol": sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) # Generate theta values using Sobol sampling # The first value of the Sobol sequence is 0, so we skip it samples = sampler.random(n=n_restarts+1)[1:] + + if multistart_sampling_method == "sobol" or multistart_sampling_method == "latin_hypercube": + # Scale the samples to the range of the lower and upper bounds for each theta in theta_names theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) elif multistart_sampling_method == "user_provided": @@ -1073,9 +1082,13 @@ def theta_est_multistart( ---------- n_restarts: int, optional Number of restarts for multistart. Default is 1. - theta_sampling_method: string, optional + th_sampling_method: string, optional Method used to sample theta values. Options are "random", "latin_hypercube", or "sobol". Default is "random". + buffer: int, optional + Number of iterations to save results dynamically. Default is 10. + user_provided: pd.DataFrame, optional + User provided dataframe of theta values for multistart optimization. solver: string, optional Currently only "ef_ipopt" is supported. Default is "ef_ipopt". return_values: list, optional @@ -1157,8 +1170,17 @@ def theta_est_multistart( best_objectiveval = objectiveval best_theta = thetavals - # Store the results in a list or DataFrame - # depending on the number of restarts + # Store the results in a list or DataFrame depending on the number of restarts + ''' General structure for dataframe: + theta_names = ['theta1', 'theta2', ...] + results_df = pd.DataFrame(columns=theta_names + ['converged_theta1', 'converged_theta2', ..., + 'initial objective', 'final objective', + 'solver termination', 'solve_time']) + Each row of the dataframe corresponds to a restart, and the columns + correspond to the theta names, the converged theta values, the initial and final objective values, + the solver termination condition, and the solve time. + ''' + results_df.iloc[i, len(theta_names):len(theta_names) + len(theta_names)] = converged_theta_vals[i, :] results_df.iloc[i, -4] = init_objectiveval results_df.iloc[i, -3] = objectiveval From 50c36bc7e9ba47f191231544633e037dd90d2ecf Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 21 May 2025 09:06:33 -0400 Subject: [PATCH 08/32] Got dataframe formatted, still working on executing Q_opt --- pyomo/contrib/parmest/parmest.py | 121 ++++++++++++++++--------------- 1 file changed, 63 insertions(+), 58 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index e122afb7560..9f647a5d02b 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -490,10 +490,10 @@ def _generate_initial_theta(self, parmest_model=None, seed=None, n_restarts=None if multistart_sampling_method == "uniform": # Generate random theta values using uniform distribution, with set seed for reproducibility np.random.seed(seed) - # Generate random theta values - theta_vals_multistart = np.random.uniform(lower_bound, upper_bound, size=len(theta_names)) - - + # Generate random theta values for each restart (n_restarts x len(theta_names)) + theta_vals_multistart = np.random.uniform( + low=lower_bound, high=upper_bound, size=(n_restarts, len(theta_names)) + ) elif multistart_sampling_method == "latin_hypercube": # Generate theta values using Latin hypercube sampling or Sobol sampling @@ -510,10 +510,6 @@ def _generate_initial_theta(self, parmest_model=None, seed=None, n_restarts=None # The first value of the Sobol sequence is 0, so we skip it samples = sampler.random(n=n_restarts+1)[1:] - if multistart_sampling_method == "sobol" or multistart_sampling_method == "latin_hypercube": - # Scale the samples to the range of the lower and upper bounds for each theta in theta_names - theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) - elif multistart_sampling_method == "user_provided": # Add user provided dataframe option if user_provided is not None: @@ -563,30 +559,39 @@ def _generate_initial_theta(self, parmest_model=None, seed=None, n_restarts=None else: raise ValueError( - "Invalid sampling method. Choose 'random', 'latin_hypercube', 'sobol' or 'user_provided'." + "Invalid sampling method. Choose 'uniform', 'latin_hypercube', 'sobol' or 'user_provided'." ) - # Make an output dataframe with the theta names and their corresponding values for each restart, - # and nan for the output info values - df_multistart = pd.DataFrame( - theta_vals_multistart, columns=theta_names - ) - - - # Add the initial theta values to the first row of the dataframe - for i in range(1, n_restarts): - df_multistart.iloc[i, :] = theta_vals_multistart[i, :] - df_multistart.iloc[0, :] = initial_theta - - - # Add the output info values to the dataframe, starting values as nan - for i in range(len(theta_names)): - df_multistart[f'converged_{theta_names[i]}'] = np.nan + if multistart_sampling_method == "sobol" or multistart_sampling_method == "latin_hypercube": + # Scale the samples to the range of the lower and upper bounds for each theta in theta_names + theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) + + # Create a DataFrame where each row is an initial theta vector for a restart, + # columns are theta_names, and values are the initial theta values for each restart + if multistart_sampling_method == "user_provided": + # If user_provided is a DataFrame, use its columns and values directly + if isinstance(user_provided, pd.DataFrame): + df_multistart = user_provided.copy() + df_multistart.columns = theta_names + else: + df_multistart = pd.DataFrame(theta_vals_multistart, columns=theta_names) + else: + # Ensure theta_vals_multistart is 2D (n_restarts, len(theta_names)) + arr = np.atleast_2d(theta_vals_multistart) + if arr.shape[0] == 1 and n_restarts > 1: + arr = np.tile(arr, (n_restarts, 1)) + df_multistart = pd.DataFrame(arr, columns=theta_names) + + # Add columns for output info, initialized as nan + for name in theta_names: + df_multistart[f'converged_{name}'] = np.nan df_multistart["initial objective"] = np.nan df_multistart["final objective"] = np.nan df_multistart["solver termination"] = np.nan df_multistart["solve_time"] = np.nan + print(df_multistart) + return df_multistart def _instance_creation_callback(self, experiment_number=None, cb_data=None): @@ -1066,7 +1071,7 @@ def theta_est_multistart( self, n_restarts=20, buffer=10, - multistart_sampling_method="random", + multistart_sampling_method="uniform", user_provided=None, seed=None, save_results=False, @@ -1083,8 +1088,8 @@ def theta_est_multistart( n_restarts: int, optional Number of restarts for multistart. Default is 1. th_sampling_method: string, optional - Method used to sample theta values. Options are "random", "latin_hypercube", or "sobol". - Default is "random". + Method used to sample theta values. Options are "uniform", "latin_hypercube", or "sobol". + Default is "uniform". buffer: int, optional Number of iterations to save results dynamically. Default is 10. user_provided: pd.DataFrame, optional @@ -1139,53 +1144,53 @@ def theta_est_multistart( # with the theta values generated using the _generalize_initial_theta method # set the theta values in the model - theta_vals_current = theta_vals.iloc[i, :] + theta_vals_current = theta_vals.iloc[i, :].to_dict() # Call the _Q_opt method with the generated theta values - objectiveval, converged_theta, variable_values = self._Q_opt( + qopt_result = self._Q_opt( ThetaVals=theta_vals_current, solver=solver, return_values=return_values, ) - # Check if the solver terminated successfully - if variable_values.solver.termination_condition != pyo.TerminationCondition.optimal: - # If not, set the objective value to NaN - solver_termination = variable_values.solver.termination_condition - solve_time = variable_values.solver.time + # Unpack results depending on return_values + if len(return_values) > 0: + objectiveval, converged_theta, variable_values = qopt_result + else: + objectiveval, converged_theta = qopt_result + variable_values = None + + # Since _Q_opt does not return the solver result object, we cannot check + # solver termination condition directly here. Instead, we can assume + # that if converged_theta contains NaN, the solve failed. + if converged_theta.isnull().any(): + solver_termination = "not optimal" + solve_time = np.nan thetavals = np.nan - + final_objectiveval = np.nan + init_objectiveval = np.nan else: - - # If the solver terminated successfully, set the objective value - converged_theta_vals[i, :] = converged_theta.values() + converged_theta_vals[i, :] = converged_theta.values init_objectiveval = objectiveval - final_objectiveval = variable_values.solver.objective() - solver_termination = variable_values.solver.termination_condition - solve_time = variable_values.solver.time + final_objectiveval = objectiveval + solver_termination = "optimal" + solve_time = np.nan # Check if the objective value is better than the best objective value if final_objectiveval < best_objectiveval: best_objectiveval = objectiveval best_theta = thetavals - # Store the results in a list or DataFrame depending on the number of restarts - ''' General structure for dataframe: - theta_names = ['theta1', 'theta2', ...] - results_df = pd.DataFrame(columns=theta_names + ['converged_theta1', 'converged_theta2', ..., - 'initial objective', 'final objective', - 'solver termination', 'solve_time']) - Each row of the dataframe corresponds to a restart, and the columns - correspond to the theta names, the converged theta values, the initial and final objective values, - the solver termination condition, and the solve time. - ''' - - results_df.iloc[i, len(theta_names):len(theta_names) + len(theta_names)] = converged_theta_vals[i, :] - results_df.iloc[i, -4] = init_objectiveval - results_df.iloc[i, -3] = objectiveval - results_df.iloc[i, -2] = variable_values.solver.termination_condition - results_df.iloc[i, -1] = variable_values.solver.time + # Store the results in the DataFrame for this restart + # Fill converged theta values + for j, name in enumerate(theta_names): + results_df.at[i, f'converged_{name}'] = converged_theta[j] if not np.isnan(converged_theta_vals[i, j]) else np.nan + # Fill initial and final objective values, solver termination, and solve time + results_df.at[i, "initial objective"] = init_objectiveval if 'init_objectiveval' in locals() else np.nan + results_df.at[i, "final objective"] = objectiveval if 'objectiveval' in locals() else np.nan + results_df.at[i, "solver termination"] = solver_termination if 'solver_termination' in locals() else np.nan + results_df.at[i, "solve_time"] = solve_time if 'solve_time' in locals() else np.nan # Add buffer to save the dataframe dynamically, if save_results is True if save_results and (i + 1) % buffer == 0: From f4c7018736e437eb03cf37e2300f6742e56f31ff Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Mon, 2 Jun 2025 14:15:04 -0400 Subject: [PATCH 09/32] Working code, adding features 6/2/25 --- .../reactor_design/multistart_example.py | 53 +++++++++++++++++++ pyomo/contrib/parmest/parmest.py | 42 +++++++++------ 2 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 pyomo/contrib/parmest/examples/reactor_design/multistart_example.py diff --git a/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py new file mode 100644 index 00000000000..90c6791c188 --- /dev/null +++ b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py @@ -0,0 +1,53 @@ +# ___________________________________________________________________________ +# +# Pyomo: Python Optimization Modeling Objects +# Copyright (c) 2008-2025 +# 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 +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 = [] + for i in range(data.shape[0]): + exp_list.append(ReactorDesignExperiment(data, i)) + + # View one model + # exp0_model = exp_list[0].get_labeled_model() + # exp0_model.pprint() + + pest = parmest.Estimator(exp_list, obj_function='SSE') + + # Parameter estimation + obj, theta = pest.theta_est() + + # Parameter estimation with multistart to avoid local minima + obj, theta = pest.theta_est_multistart( + num_starts=10, + start_method='random', + random_seed=42, + max_iter=1000, + tol=1e-6, + ) + + + +if __name__ == "__main__": + main() diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 9f647a5d02b..b02803608b9 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -1128,7 +1128,7 @@ def theta_est_multistart( # and the theta names from the estimator object parmest_model = self._create_parmest_model(experiment_number=0) theta_names = self._return_theta_names() - initial_theta = [parmest_model.find_component(name)() for name in theta_names] + # initial_theta = [parmest_model.find_component(name)() for name in theta_names] # Generate theta values using the sampling method results_df = self._generate_initial_theta(parmest_model, seed=seed, n_restarts=n_restarts, @@ -1146,20 +1146,24 @@ def theta_est_multistart( # set the theta values in the model theta_vals_current = theta_vals.iloc[i, :].to_dict() + # Set current theta values in the model + for name, value in theta_vals_current.items(): + parmest_model.find_component(name).set_value(value) + + # Print the current theta values being set + print(f"Setting {name} to {value}") + # Call the _Q_opt method with the generated theta values qopt_result = self._Q_opt( - ThetaVals=theta_vals_current, + bootlist=None, solver=solver, return_values=return_values, ) - # Unpack results depending on return_values - if len(return_values) > 0: - objectiveval, converged_theta, variable_values = qopt_result - else: - objectiveval, converged_theta = qopt_result - variable_values = None + # Unpack results + objectiveval, converged_theta = qopt_result + # Since _Q_opt does not return the solver result object, we cannot check # solver termination condition directly here. Instead, we can assume @@ -1175,13 +1179,18 @@ def theta_est_multistart( init_objectiveval = objectiveval final_objectiveval = objectiveval solver_termination = "optimal" - solve_time = np.nan - - # Check if the objective value is better than the best objective value - if final_objectiveval < best_objectiveval: - best_objectiveval = objectiveval - best_theta = thetavals + solve_time = converged_theta.get('solve_time', np.nan) + + # # Check if the objective value is better than the best objective value + # # Set a very high initial best objective value + # best_objectiveval = np.inf + # best_theta = np.inf + # if final_objectiveval < best_objectiveval: + # best_objectiveval = objectiveval + # best_theta = thetavals + print(f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}") + # Store the results in the DataFrame for this restart # Fill converged theta values for j, name in enumerate(theta_names): @@ -1192,6 +1201,9 @@ def theta_est_multistart( results_df.at[i, "solver termination"] = solver_termination if 'solver_termination' in locals() else np.nan results_df.at[i, "solve_time"] = solve_time if 'solve_time' in locals() else np.nan + # Diagnostic: print the table after each restart + print(results_df) + # Add buffer to save the dataframe dynamically, if save_results is True if save_results and (i + 1) % buffer == 0: mode = 'w' if i + 1 == buffer else 'a' @@ -1206,7 +1218,7 @@ def theta_est_multistart( results_df.to_csv(file_name, mode='a', header=False, index=False) print("Final results saved.") - return results_df, best_theta, best_objectiveval + return results_df # just this for now, then best_theta, best_objectiveval From e7880005b003ca37570444e772939abaee6d652a Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Tue, 3 Jun 2025 11:21:40 -0400 Subject: [PATCH 10/32] Added questions for next round of reviews --- pyomo/contrib/parmest/parmest.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index b02803608b9..b6f37571503 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -1126,6 +1126,8 @@ def theta_est_multistart( # Find the initialized values of theta from the labeled parmest model # and the theta names from the estimator object + + # @Reviewers, pyomo team: Use this or use instance creation callback? parmest_model = self._create_parmest_model(experiment_number=0) theta_names = self._return_theta_names() # initial_theta = [parmest_model.find_component(name)() for name in theta_names] @@ -1139,6 +1141,8 @@ def theta_est_multistart( converged_theta_vals = np.zeros((n_restarts, len(theta_names))) # make empty list to store results + # @ Pyomo team, each of these instances are independent and thus embarassingly parallelizable, + # Do you have recommendations on how to parallelize this for loop on a multicore machine for i in range(n_restarts): # for number of restarts, call the self._Q_opt method # with the theta values generated using the _generalize_initial_theta method @@ -1179,7 +1183,10 @@ def theta_est_multistart( init_objectiveval = objectiveval final_objectiveval = objectiveval solver_termination = "optimal" - solve_time = converged_theta.get('solve_time', np.nan) + + # plan to add solve time if available, @Reviewers, recommendations on how from current pyomo examples would + # be appreciated + solve_time = converged_theta.solve_time if hasattr(converged_theta, 'solve_time') else np.nan # # Check if the objective value is better than the best objective value # # Set a very high initial best objective value From f071718bc76063f86be016f63b163709aef0c23a Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Tue, 3 Jun 2025 11:37:11 -0400 Subject: [PATCH 11/32] Removed diagnostic tables to simplify output --- pyomo/contrib/parmest/parmest.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index b6f37571503..9ff6ab8a135 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -590,7 +590,8 @@ def _generate_initial_theta(self, parmest_model=None, seed=None, n_restarts=None df_multistart["solver termination"] = np.nan df_multistart["solve_time"] = np.nan - print(df_multistart) + # Debugging output + # print(df_multistart) return df_multistart @@ -1209,7 +1210,7 @@ def theta_est_multistart( results_df.at[i, "solve_time"] = solve_time if 'solve_time' in locals() else np.nan # Diagnostic: print the table after each restart - print(results_df) + # print(results_df) # Add buffer to save the dataframe dynamically, if save_results is True if save_results and (i + 1) % buffer == 0: From 9b1545da4940542aeac0e8d7a977ce2acce5968b Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 4 Jun 2025 15:57:10 -0400 Subject: [PATCH 12/32] Work from Wednesday of Sprint week --- pyomo/contrib/parmest/parmest.py | 41 +++++++++++++++++--------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 9ff6ab8a135..4aa5eb81016 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -1128,37 +1128,38 @@ def theta_est_multistart( # Find the initialized values of theta from the labeled parmest model # and the theta names from the estimator object + # print statement to indicate multistart optimization is starting + print(f"Starting multistart optimization with {n_restarts} restarts using {multistart_sampling_method} sampling method.") + # @Reviewers, pyomo team: Use this or use instance creation callback? - parmest_model = self._create_parmest_model(experiment_number=0) theta_names = self._return_theta_names() - # initial_theta = [parmest_model.find_component(name)() for name in theta_names] - # Generate theta values using the sampling method - results_df = self._generate_initial_theta(parmest_model, seed=seed, n_restarts=n_restarts, - multistart_sampling_method=multistart_sampling_method, user_provided=user_provided) + parmest_model_for_bounds = self._create_parmest_model(experiment_number=0) + results_df = self._generate_initial_theta( + parmest_model_for_bounds, seed=seed, n_restarts=n_restarts, + multistart_sampling_method=multistart_sampling_method, user_provided=user_provided + ) results_df = pd.DataFrame(results_df) # Extract theta_vals from the dataframe theta_vals = results_df.iloc[:, :len(theta_names)] converged_theta_vals = np.zeros((n_restarts, len(theta_names))) - # make empty list to store results - # @ Pyomo team, each of these instances are independent and thus embarassingly parallelizable, - # Do you have recommendations on how to parallelize this for loop on a multicore machine + # Each restart uses a fresh model instance for i in range(n_restarts): - # for number of restarts, call the self._Q_opt method - # with the theta values generated using the _generalize_initial_theta method - - # set the theta values in the model + # Create a fresh model for each restart + parmest_model = self._create_parmest_model(experiment_number=0) theta_vals_current = theta_vals.iloc[i, :].to_dict() # Set current theta values in the model for name, value in theta_vals_current.items(): parmest_model.find_component(name).set_value(value) - # Print the current theta values being set - print(f"Setting {name} to {value}") - - + # Optional: Print the current theta values being set + print(f"Setting {name} to {value}") + for name in theta_names: + current_value = parmest_model.find_component(name)() + print(f"Current value of {name} is {current_value}") + # Call the _Q_opt method with the generated theta values qopt_result = self._Q_opt( bootlist=None, @@ -1174,16 +1175,18 @@ def theta_est_multistart( # solver termination condition directly here. Instead, we can assume # that if converged_theta contains NaN, the solve failed. if converged_theta.isnull().any(): - solver_termination = "not optimal" + solver_termination = "not successful" solve_time = np.nan thetavals = np.nan final_objectiveval = np.nan init_objectiveval = np.nan else: converged_theta_vals[i, :] = converged_theta.values - init_objectiveval = objectiveval + # Calculate the initial objective value using the current theta values + # Use the _Q_at_theta method to evaluate the objective at these theta values + init_objectiveval, _, _ = self._Q_at_theta(theta_vals_current) final_objectiveval = objectiveval - solver_termination = "optimal" + solver_termination = "successful" # plan to add solve time if available, @Reviewers, recommendations on how from current pyomo examples would # be appreciated From 80079cb90a0cedf15eb286de04d3f2e48a8ac503 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Wed, 4 Jun 2025 16:01:40 -0400 Subject: [PATCH 13/32] Create Simple_Multimodal_Multistart.ipynb --- .../Simple_Multimodal_Multistart.ipynb | 8231 +++++++++++++++++ 1 file changed, 8231 insertions(+) create mode 100644 pyomo/contrib/parmest/examples/Simple_Multimodal_Multistart.ipynb diff --git a/pyomo/contrib/parmest/examples/Simple_Multimodal_Multistart.ipynb b/pyomo/contrib/parmest/examples/Simple_Multimodal_Multistart.ipynb new file mode 100644 index 00000000000..0c2a2eb2062 --- /dev/null +++ b/pyomo/contrib/parmest/examples/Simple_Multimodal_Multistart.ipynb @@ -0,0 +1,8231 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d3d4744d-5ea5-45d6-8e8b-aefc5d8b8118", + "metadata": {}, + "source": [ + "This example is created by Stephen Cini, inspired by example in Montana's manuscript and advice from Dr. Alex Dowling. Purpose is to test multistart function's ability to find local minima.\n", + "\n", + "**Equation:** \n", + " $$f(x, \\theta) = (\\theta_1 x^3 - \\theta_2 x^2 + 2x - 1)^2 + (\\theta_1 - \\theta_2)^2 + (x^2 - 1)^2$$ \n", + "$\\qquad f(x, \\theta)\\rightarrow$ (response / output variable) \n", + "$\\qquad \\theta_1, \\theta_2 \\rightarrow$ parameters \n", + "$\\qquad x\\rightarrow$ (control / decision variable) \n", + "\n", + "**Data:** \n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
SubstrateVelocity
Concentration(counts/min2)
(ppm)(a) Treated(b) Untreated
0.0276
47
67
51
0.0697
107
84
86
0.11123
139
98
115
0.22159
152
131
124
0.56191
201
144
158
1.10207
200
160
\n", + "\n", + "[Find data or remove table]" + ] + }, + { + "cell_type": "markdown", + "id": "7f241a55-464a-41f6-9bc2-28f7467c2234", + "metadata": {}, + "source": [ + "# Importing packages" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "2a458e95", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Pyomo version after reload:\n", + "6.9.3.dev0\n", + "pyomo.__file__: /Users/scini/Documents/GitHub/pyomo/pyomo/__init__.py\n" + ] + } + ], + "source": [ + "# Get version of pyomo\n", + "\n", + "# Force reload of pyomo module to ensure we get the latest version\n", + "import importlib\n", + "import pyomo # your .py file without the .py extension\n", + "importlib.reload(pyomo)\n", + "print(\"Pyomo version after reload:\")\n", + "print(pyomo.__version__)\n", + "print(\"pyomo.__file__:\", pyomo.__file__)\n", + "\n", + "import pyomo.environ as pyo\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "f6c3dd5b-0200-4262-9315-de03690bec0b", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import scipy\n", + "import seaborn as sns # This package is only needed for pairplot\n", + "import matplotlib.pyplot as plt\n", + "import pyomo.environ as pyo\n", + "import pyomo.contrib.parmest.parmest as parmest # import parmest\n", + "import pyomo.contrib.parmest.experiment as experiment\n", + "import pyomo.contrib.doe as doe\n", + "import pandas as pd\n", + "from itertools import product\n", + "import idaes" + ] + }, + { + "cell_type": "markdown", + "id": "5915d030-b939-4162-a85c-9f90c28a17c9", + "metadata": {}, + "source": [ + "# Data\n", + "Data for this model in Montana's manuscript was generated by simulating the model with true parameter values and adding 1% Gaussian error. So this is replicated here." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "231649a2-75e9-43af-938f-00b71ff136e8", + "metadata": {}, + "outputs": [], + "source": [ + "# True param values\n", + "true_params = {\n", + " 'theta1': -1.5,\n", + " 'theta2': 0.5,\n", + "}\n", + "\n", + "# $$f(x, \\theta) = (\\theta_1 x^3 - \\theta_2 x^2 + 2x - 1)^2 + (\\theta_1 - \\theta_2)^2 + (x^2 - 1)^2$$ \n", + "\n", + "def model(x, theta1, theta2):\n", + " return ((theta1 * x**3 - theta2 * x**2 + 2 * x - 1)**2 +\n", + " (theta1 - theta2)**2 +\n", + " (x**2 - 1)**2)\n", + "\n", + "def generate_data(num_samples=1000):\n", + " x_values = np.linspace(-4, 4, num_samples)\n", + " y_values = np.array([model(x, true_params['theta1'], true_params['theta2']) for x in x_values])\n", + "\n", + " # Add 1% Gaussian noise to the y values\n", + " noise = np.random.normal(0, 0.01 * np.abs(y_values), size=y_values.shape)\n", + " y_values += noise\n", + " # Create a DataFrame with the x and y values\n", + " # and return it\n", + " return pd.DataFrame({'x': x_values, 'y': y_values})\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "ae697125", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Data generated with 1000 samples.\n", + " x y\n", + "0 -4.000000 6515.412188\n", + "1 -3.991992 6367.720590\n", + "2 -3.983984 6257.737250\n", + "3 -3.975976 6182.891231\n", + "4 -3.967968 6013.270490\n" + ] + }, + { + "data": { + "image/png": "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aOHzODIyUpJUXFzs85w9e/as9vkaNfK9FxkTE6NmzZr5HDtx4oQcDof27NmjP/7xj+rWrZtiY2N14sQJpaWleb/XydQ2jv3790uSkpKSqrRJSkrStm3bTvm9TsXzf+JZu7djxw5ddtll6ty5s55++mm1bdtWUVFRWrduncaNG1ern2/dunVyOBzq16+fXnzxRbVq1UpNmjTRO++8o0cffbRWzwEAICEDANSR8PBwDRgwQFlZWcrNzfVZR3bBBRdIUpXkomXLlpKkadOm6frrr6/2eTt37nxacXie8x//+Id3ROtkKo5KeXz33Xf65ptvtHDhQt16663e45s3b67zODwJZl5eXpVz1R07E0uXLlVYWJguv/xySdI777yjoqIi/fOf//SJLScnp9bPuWTJEkVEROj9999XVFSU9/g777xTJzEDQENBQgYAqDPTpk3Thx9+qLvuukv/+Mc/FBERcdL2nTt3VqdOnfTNN99o5syZdRLD4MGD1bhxY/3000/VTkWsDU+S5hl985g/f36VtpVH6E43js6dOys5OVmLFy/WpEmTvN97+/btWr16dZWKlKfr5Zdf1ocffqiRI0eqdevWkqr/+dxut1588cVqf77qRrvCwsLUuHFjhYeHe48VFxfr1VdfPat4AaChISEDANSZvn376tlnn9X48eN1ySWX6M4779SFF16oRo0aKTc3V2+99ZYk+UwRnD9/vq666ioNHjxYt912m84991wdOHBAGzdu1L///W+9+eabpxVD27Zt9dBDD2n69OnasmWLrrzyStntduXn52vdunWKjY31VlKsyfnnn68OHTrovvvuk9vtVnx8vN577z0tX768Sttu3bpJkp5++mndeuutioiIUOfOnWsdR6NGjfTwww9r9OjR+uUvf6k77rhDBw8e1IwZM6qdxliT4uJiZWdne/+9ZcsWvfPOO3r//fd1xRVX6Pnnn/e2HTRokJo0aaIRI0Zo6tSpOnr0qObNmyen01ntz/fPf/5T8+bNU48ePdSoUSNdeumluuaaa/Tkk09q5MiRuvPOO7V//3498cQTVZJYAMApWFxUBAAQgnJycty/+c1v3O3atXNHRka6o6Ki3B07dnTfcsst7pUrV1Zp/80337hvvPFGd0JCgjsiIsKdlJTkHjBggPv555/3tvFUWVy/fr3P165atcotyb1q1Sqf4++88467f//+7mbNmrkjIyPdbdq0cd9www3uFStWeNvceuut7tjY2Gp/hu+//949aNAgd1xcnNtut7uHDx/u3rFjh1uS+4EHHvBpO23aNHdKSoq7UaNGVWKpTRxut9u9YMECd6dOndxNmjRxn3feee6//vWv7ltvvbXWVRYleT9iY2Pd7du3d99www3uN99801upsqL33nvPffHFF7ujoqLc5557rvt3v/udtxpjxfgPHDjgvuGGG9zNmzd3h4WFuSteOvz1r391d+7c2R0ZGelu3769e9asWe6XXnqp2qqTAIDqhbnd7N4IAAAAAFag7D0AAAAAWISEDAAAAAAsQkIGAAAAABYhIQMAAAAAi5CQAQAAAIBFSMgAAAAAwCJsDF2HTpw4oT179iguLk5hYWFWhwMAAADAIm63W4cOHVJKSooaNap5HIyErA7t2bNHqampVocBAAAAIEjs3LlTrVq1qvE8CVkdiouLk2Q6vVmzZpbGUlpaqqysLDkcDkVERFgaSyiif/2L/vUv+te/6F//on/9i/71L/rXv4KtfwsLC5WamurNEWpCQlaHPNMUmzVrFhQJWUxMjJo1axYUv5Chhv71L/rXv+hf/6J//Yv+9S/617/oX/8K1v491VImS4t6fPrppxo6dKhSUlIUFhamd955x+e82+3WjBkzlJKSoujoaPXr108bNmzwaVNSUqLx48erZcuWio2N1bBhw7Rr1y6fNk6nU6NGjZLNZpPNZtOoUaN08OBBnzY7duzQ0KFDFRsbq5YtW2rChAk6duyYP35sAAAAAJBkcUJWVFSkiy++WHPnzq32/OzZs/Xkk09q7ty5Wr9+vZKSkjRo0CAdOnTI2yYjI0Nvv/22lixZos8//1yHDx/WkCFDVFZW5m0zcuRI5eTkaNmyZVq2bJlycnI0atQo7/mysjJdc801Kioq0ueff64lS5borbfe0uTJk/33wwMAAABo8CydsnjVVVfpqquuqvac2+1WZmampk+fruuvv16S9MorrygxMVGvvfaaxowZI5fLpZdeekmvvvqqBg4cKElatGiRUlNTtWLFCg0ePFgbN27UsmXLlJ2drV69ekmSXnzxRfXu3VubNm1S586dlZWVpe+//147d+5USkqKJOkvf/mLbrvtNj366KM1Tj8sKSlRSUmJ93FhYaEkM1xaWlpaN510hjzf3+o4QhX9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8INOnDih+fPna8OGDXrqqaf0/PPP6w9/+IPVoYWMY8eOafjw4br77rutDiUkvP7668rIyND06dP19ddf67LLLtNVV12lHTt2WB1avVdUVKSLL75Yc+fOtTqUkPTJJ59o3Lhxys7O1vLly3X8+HE5HA4VFRVZHVpIaNWqlR577DF9+eWX+vLLLzVgwABde+212rBhg9WhhZz169frhRde0EUXXWR1KLVG2fsG4sMPP9SkSZP01ltv6cILL9TXX3+t7t27Wx1WSFq6dKmuu+46lZSUKCIiwupwQs7jjz+uefPmacuWLVaHElIWLlyojIwMHTx40OpQ6rVevXrpkksu0bx587zHunTpouuuu06zZs2yMLLQEhYWprffflvXXXed1aGErL179yohIUGffPKJLr/8cqvDCUnx8fF6/PHHdfvtt1sdSsg4fPiwLrnkEj333HN65JFH1L17d2VmZlod1ikxQtYA5Ofn64477tCrr76qmJgYq8MJaQcOHNDf//539enTh2TMT1wul+Lj460OA6ji2LFj+uqrr+RwOHyOOxwOrV692qKogDPjcrkkiddbPygrK9OSJUtUVFSk3r17Wx1OSBk3bpyuueYaDRw40OpQTgsJWYhzu9267bbbdNddd+nSSy+1OpyQ9fvf/16xsbFq0aKFduzYoXfffdfqkELSTz/9pDlz5uiuu+6yOhSgin379qmsrEyJiYk+xxMTE5WXl2dRVMDpc7vdmjRpkn7xi1+oa9euVocTMr799ls1bdpUkZGRuuuuu/T222/rggsusDqskLFkyRL9+9//rpezEUjI6qkZM2YoLCzspB9ffvml5syZo8LCQk2bNs3qkOuV2vavx+9+9zt9/fXXysrKUnh4uG655RYxG7hmp9u/krRnzx5deeWVGj58uEaPHm1R5PXDmfQv6k5YWJjPY7fbXeUYEMzuuece/ec//9HixYutDiWkdO7cWTk5OcrOztbdd9+tW2+9Vd9//73VYYWEnTt3auLEiVq0aJGioqKsDue0sYasntq3b5/27dt30jZt27bVzTffrPfee8/nYqCsrEzh4eH61a9+pVdeecXfodZLte3f6v7od+3apdTUVK1evZqpCDU43f7ds2eP+vfvr169emnhwoVq1Ih7SSdzJr+/rCE7e8eOHVNMTIzefPNN/fKXv/QenzhxonJycvTJJ59YGF1oYQ2Z/4wfP17vvPOOPv30U7Vr187qcELawIED1aFDB82fP9/qUOq9d955R7/85S8VHh7uPVZWVqawsDA1atRIJSUlPueCTWOrA8CZadmypVq2bHnKds8884weeeQR7+M9e/Zo8ODBev3119WrVy9/hliv1bZ/q+O5x1FSUlKXIYWU0+nf3bt3q3///urRo4defvllkrFaOJvfX5y5Jk2aqEePHlq+fLlPQrZ8+XJde+21FkYGnJrb7db48eP19ttv6+OPPyYZCwC32821Qh1JT0/Xt99+63PsN7/5jc4//3z9/ve/D+pkTCIhC3mtW7f2edy0aVNJUocOHdSqVSsrQgop69at07p16/SLX/xCdrtdW7Zs0Z/+9Cd16NCB0bE6sGfPHvXr10+tW7fWE088ob1793rPJSUlWRhZ6NixY4cOHDigHTt2qKyszLtHYceOHb2vF6i9SZMmadSoUbr00kvVu3dvvfDCC9qxYwfrHuvA4cOHtXnzZu/jrVu3KicnR/Hx8VXe63D6xo0bp9dee03vvvuu4uLivOsebTaboqOjLY6u/vvDH/6gq666SqmpqTp06JCWLFmijz/+WMuWLbM6tJAQFxdXZb2jZ21/fVgHSUIGnIXo6Gj985//1AMPPKCioiIlJyfryiuv1JIlSxQZGWl1ePVeVlaWNm/erM2bN1e5gcBs67rxpz/9yWfq8s9+9jNJ0qpVq9SvXz+Loqq/brrpJu3fv18PPfSQcnNz1bVrV/3rX/9SmzZtrA6t3vvyyy/Vv39/7+NJkyZJkm699VYtXLjQoqhCh2erhsp/9y+//LJuu+22wAcUYvLz8zVq1Cjl5ubKZrPpoosu0rJlyzRo0CCrQ0MQYA0ZAAAAAFiExRgAAAAAYBESMgAAAACwCAkZAAAAAFiEhAwAAAAALEJCBgAAAAAWISEDAAAAAIuQkAEAAACARUjIAAAAAMAiJGQAAAAAYBESMgAAAACwCAkZAAAAAFiEhAwAgLO0d+9eJSUlaebMmd5ja9euVZMmTZSVlWVhZACAYBfmdrvdVgcBAEB9969//UvXXXedVq9erfPPP18/+9nPdM011ygzM9Pq0AAAQYyEDACAOjJu3DitWLFCPXv21DfffKP169crKirK6rAAAEGMhAwAgDpSXFysrl27aufOnfryyy910UUXWR0SACDIsYYMAIA6smXLFu3Zs0cnTpzQ9u3brQ4HAFAPMEIGAEAdOHbsmH7+85+re/fuOv/88/Xkk0/q22+/VWJiotWhAQCCGAkZAAB14He/+53+8Y9/6JtvvlHTpk3Vv39/xcXF6f3337c6NABAEGPKIgAAZ+njjz9WZmamXn31VTVr1kyNGjXSq6++qs8//1zz5s2zOjwAQBBjhAwAAAAALMIIGQAAAABYhIQMAAAAACxCQgYAAAAAFiEhAwAAAACLkJABAAAAgEVIyAAAAADAIiRkAAAAAGAREjIAAAAAsAgJGQAAAABYhIQMAAAAACxCQgYAAAAAFvn/Jx8hh9P2+OwAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Make some data\n", + "data_df = generate_data()\n", + "print(\"Data generated with {} samples.\".format(len(data_df)))\n", + "\n", + "print(data_df.head())\n", + "\n", + "# Plot the data\n", + "plt.figure(figsize=(10, 6))\n", + "sns.scatterplot(data=data_df, x='x', y='y', color='blue', label='Data')\n", + "plt.title('Generated Data')\n", + "plt.xlabel('x')\n", + "plt.ylabel('y')\n", + "plt.legend()\n", + "plt.grid()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "580a2f7a", + "metadata": {}, + "outputs": [], + "source": [ + "conc = data_df['x'].values\n", + "vel = data_df['y'].values" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7172aa46", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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TRs0btwYQFm+p8FgwIcffogPP/zQaRudERERgcGDB2Pw4MEAgLNnz6Jz585444038Oyzz6JixYps2fKvo3mb+XU0mUzo2rUr/vnnH0ydOhVNmzZFhQoVYDKZkJycjKKiIgBlImY0Gl2+Zv/++y927NhhN5+O6/U5Ijo6GiNGjGD/SDhw4AB69OiB8ePHs6+FmVatWqFVq1YAgNLSUrz66qv44IMP8N5771l1GAsKCmLLucP169cRExNj88dYVFQUtFqt1X06cuRIbNq0CZmZmejWrRv7x45ZgAHu964ZR/nFfKhcubLVunnkB/N7/++//wIApkyZgilTpnBqX3m43mfeYPPmzRg4cCAef/xxvPzyy4iJiYFWq8WyZcvs9sov//oAZa+R5WfDZDI5/KwJgZzfo1OnTqFLly6oV68edu7cqaiRRcTmzp07aN68OUaMGIH+/fu7fbzRaERwcDDGjRuHTZs22S1z8eJF9OzZE88++yzWrl2LH3/8ES+++CKqVq3K65z+Akmtn6HRaNCxY0d89913+Pvvv+3K0N9//40TJ06gR48eVlEIoKyzUfXq1dl1g8GA69ev2/2CMVOlShVUrlwZ3333nd395miLOdL4999/C9oDd8SIEdi4cSMyMzMRFxeHY8eOYdmyZez+SpUqQaPRYMiQIQ6jxAkJCW6ft3HjxnjiiSewcOFC/PHHH2xnDKDsdSxPXl4e6tatCwD49ddfcfr0aWRkZGDYsGFsmT///NPqmMjISGg0GpcdPKpUqYJmzZph1qxZdvdXq1aN83W54qGHHkLXrl2xdetWXL16FVFRUXbLBQQEYNq0afjggw8E6yVfuXJl/PTTT2AYxkpsr169CoPBgCpVqrDbunXrhmrVqmHVqlXo1q0bVq1ahbZt21qN3sH13jXDZexToTBfS3p6ulXHNkvq16/vtA6u95k3WLt2LRISErBhwwar19Gyg587VKpUCSqVyuFnzRtI9T06deoUOnfujPj4eOzevRsRERG86/JHevTowf7KZQ+9Xo8333wTX3zxBW7duoUmTZpg7ty5bAfqChUqsN9BP/74I27dumVTx/LlyxEXF8eOk9ywYUMcP34c8+bNI6l1AkmtH5Keno5vv/0WL774IrZs2WIlrkajES+88AIYhkF6errNsV988QWSkpLY9a+++goGg8HpZAuPPPIIvvzy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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Analyze the objective space by evaluating the sum of squared errors (SSE)\n", + "# over a grid of theta_1 and theta_2 values\n", + "theta1_range = np.linspace(-2, 2, 200)\n", + "theta2_range = np.linspace(-2, 2, 200)\n", + "sse_grid = np.zeros((len(theta1_range), len(theta2_range)))\n", + "\n", + "# Use the model function from cell 5\n", + "for i, t1 in enumerate(theta1_range):\n", + " for j, t2 in enumerate(theta2_range):\n", + " y_sim = np.array([model(x, t1, t2) for x in conc])\n", + " sse = np.sum((vel - y_sim) ** 2)\n", + " sse_grid[i, j] = sse\n", + "\n", + "# Plot the objective space\n", + "plt.figure(figsize=(8, 6))\n", + "X, Y = np.meshgrid(theta2_range, theta1_range)\n", + "cp = plt.contourf(X, Y, sse_grid, levels=50, cmap='viridis')\n", + "plt.colorbar(cp, label='Sum of Squared Errors (SSE)')\n", + "plt.xlabel('theta_2')\n", + "plt.ylabel('theta_1')\n", + "plt.title('Objective Space: SSE over theta_1 and theta_2')\n", + "# Optionally, mark the minimum SSE location on the grid\n", + "min_idx = np.unravel_index(np.argmin(sse_grid), sse_grid.shape)\n", + "plt.scatter([theta2_range[min_idx[1]]], [theta1_range[min_idx[0]]], color='red', label='Grid Minimum')\n", + "plt.scatter([true_params['theta2']], [true_params['theta1']], color='white', marker='*', s=100, label='True Params')\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "5eb58543", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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RkhIiEPfEwAANwLjzpyKwrjTMAxj27ZthpeXl9GzZ8+rnlucx53OFG2zMe4Eipdi3R7hzz//VLdu3RQWFiaLxaLFixc79fzU1FQNGDBAderUkdVq1Z133nnJ81auXKlGjRrJ09NTlSpV0vvvv3/94YF8UqpUKa1atUobNmzQG2+8oR49emjv3r0aPXq06tSpk+NjQF26dFF0dLQWLVqkUaNGqVatWlq8eLG6d+9+yZ1vn3jiCW3YsOGiW/369a+YadCgQUpJScmxIcWsWbPk4eGhvn37SpJKliypypUra9KkSZoyZYq2bNlyyf5m16JNmzby8/Oz3w8JCVFwcLD942Opqan67bff1LNnT3l7eyszM9N+69Kli1JTUy/5Ua3cEhMT9eyzz6pKlSqyWq2yWq3y9fVVUlKSdu/enSffiyOOHz8uSQoODnb6uV27dpWrq6v9ft26dSXJ/l7t379f//zzj+6//35Juui9iomJ0Z49e676OnFxcRo6dKjCw8NltVrl5uamiIgISbqu92rz5s3q3bu3mjZtqgkTJlzzdS7n6aefVteuXdWnTx999tlnevfdd1WnTh374z/++KNq166t+vXr53hvOnbsmONjb3/88Yck2d/HbNl/Hy4lODhYcXFxyszMzPPvCwCAa8G482KFfdx56NAh3XHHHQoPD9fHH3981fOL87gzvzHuBAq/Yl20TUpKUr169fTee+9d0/OzsrLk5eWl4cOHq127dpc8JyoqSl26dFHLli21ZcsWPf/88xo+fLi+/fbb64kO5LvGjRvr2Wef1YIFC3T8+HE9+eSTOnTo0EU7gXp5eenOO+/UpEmTtHLlSu3fv181a9bU9OnTFRkZmePccuXKqXHjxhfdfH19r5ilVq1aatKkiWbNmiXpwt+9L774Qj169FDJkiUlyd5/rGPHjpo4caIaNmyooKAgDR8+XOfPn7+u96JUqVIXHfPw8FBKSoqkC33WMjMz9e6778rNzS3HrUuXLpLkUM+rvn376r333tOQIUO0dOlSrV+/Xhs2bFBQUJD9tW6E7Nfy9PR0+rm53ysPD48c1zxx4oSkCzsE536vhg0bJunq75XNZlOHDh20cOFCPfPMM/rtt9+0fv16+wTlWt+rLVu2qH379qpataqWLFliz56XLBaLBgwYoNTUVIWGhuboKSZdeH+2b99+0Xvj5+cnwzDs783p06dltVover9DQ0Mv+9qenp4yDEOpqal5/n0BAHA9GHf+v8I87jx8+LDatGkjq9Wq3377zf5+XUlxHXfeCIw7gcLv4o7vxUjnzp0v2nXxv9LT0/Xiiy/qyy+/1Llz51S7dm29+eabat26taQLTddnzpwpSfrrr7907ty5i67x/vvvq3z58po6daokqUaNGtq4caPeeust3X333Xn9LQH5ws3NTWPGjNHbb7991R1Oy5cvr4cfflgjRoxQZGSkatWqlScZBg4cqGHDhmn37t06ePCgYmJiNHDgwBznRERE6JNPPpEk7d27V/Pnz9fYsWOVnp6eryvcS5QoIVdXVz344IN67LHHLnlOxYoVr3iN+Ph4/fjjjxozZoyee+45+/G0tDSdOXMmT/NeTenSpSUpX143+9qjR4/WXXfddclzqlWrdsVr7Ny5U9u2bdPs2bPVv39/+/H9+/dfc64tW7aoXbt2ioiI0LJlyxQQEHDN17qSmJgYPfbYY6pfv74iIyM1atQovfPOO/bHS5cuLS8vL3366aeXfH72+1eqVCllZmbq9OnTOQbQsbGxl33tM2fOyMPD46qTVQAAzMS488oK6rjz8OHDat26tQzD0IoVK1SuXDmHnlccx503CuNOoPAr1kXbqxk4cKAOHTqkr7/+WmFhYVq0aJE6deqkHTt2qGrVqg5dY+3aterQoUOOYx07dtQnn3yijIyMS+5aDpgpJibmkjvzZn/0JywsTJJ0/vx5WSyWS/5DnPvcvNCnTx+NHDlSs2fP1sGDB1W2bNmL/m7910033aQXX3xR3377rTZv3nzFa//3t/JeXl5OZ/P29labNm20ZcsW1a1bV+7u7g691n9ZLBYZhnHR6s6PP/5YWVlZTme6HhEREfLy8tKBAwcueuy/Kz2uRbVq1VS1alVt27ZN48ePv+K5V3qv/vt4tg8++OCaMm3dulXt2rVTuXLltHz5cpUoUeKarnM1WVlZ6tOnjywWi37++Wd9+eWXGjVqlFq3bm2fSNxxxx0aP368SpUqdcUJV5s2bTRx4kR9+eWXGj58uP34V199ddnnHDx4UDVr1sy7bwgAgOvEuLNojDujo6PVunVrZWVlacWKFfbWAY4obuPOG4VxJ1A0ULS9jAMHDmju3Lk6evSofQAwatQo/fLLL5o1a9ZVf+hni42NVUhISI5jISEhyszM1KlTpy45SAHM1LFjR5UrV07dunVT9erVZbPZtHXrVk2ePFm+vr564oknJEl79uxRx44ddd9996lVq1YqU6aMzp49q59++kkffvihWrdurebNm+e4dnR09CV7bAUFBaly5cpXzBUYGKiePXtq9uzZOnfunEaNGiUXl//v8LJ9+3Y9/vjjuueee1S1alW5u7vr999/1/bt23OsILiU7N5Ob775pjp37ixXV9erDoJzmzZtmm699Va1bNlSjz76qCpUqKDz589r//79+uGHH/T7779LkipXriwvLy99+eWXqlGjhnx9fRUWFqawsDDddtttmjRpkkqXLq0KFSpo5cqV+uSTTxQYGOhwjmyHDx/Whg0bJMk+CP7mm28kSRUqVFDjxo0v+1x3d3c1a9bskv+v6tSpo4ULF2rmzJlq1KiRXFxcrnitS/nggw/UuXNndezYUQMGDFDZsmV15swZ7d69W5s3b9aCBQskSbVr15Ykffjhh/Lz85Onp6cqVqyo6tWrq3LlynruuedkGIZKliypH374QcuXL3cqh3Thz3F2e5vXX39d+/bt0759++yPV65cWUFBQU5f91LGjBmjVatWadmyZQoNDdVTTz2llStXavDgwWrQoIEqVqyoESNG6Ntvv9Vtt92mJ598UnXr1pXNZlN0dLSWLVump556Srfccos6dOig2267Tc8884ySkpLUuHFj/fXXX/r8888v+do2m03r16/X4MGD8+R7AQAgLzDuLPzjzri4OLVp00YxMTH65JNPFBcXp7i4OPvj5cqVu+Kq2+I07pSkXbt2adeuXZIu1AqSk5PtY/SaNWvmWaGTcSdQRJi2BVoBo393Vcw2f/58Q5Lh4+OT42a1Wo3evXtf9Pz+/fsbPXr0uOh41apVjfHjx+c4tnr1akOSERMTk9ffBnDd5s2bZ/Tt29eoWrWq4evra7i5uRnly5c3HnzwQWPXrl32886ePWu89tprxu23326ULVvWcHd3N3x8fIz69esbr732mpGcnGw/92q7+N5///0OZVu2bJn9OXv37s3x2IkTJ4wBAwYY1atXN3x8fAxfX1+jbt26xttvv51jV9lLSUtLM4YMGWIEBQUZFovFkGRERUUZhnHpHVoNwzAiIiKM/v375zgWFRVlDBo0yChbtqzh5uZmBAUFGc2bNzdee+21HOfNnTvXqF69uuHm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THsEPz8/+fn55enrZzMMQ1u3blWdOnUkyd7yYvny5erZs6f9vOXLl6tHjx6SLrSLCA0N1fLly9WgQQNJF3rhrly5Um+++Wa+5JQo2gIAAKAAifq3aFux9PV/DA8AAOB6DR06VOHh4XrxxReVnp6uhg0batSoUZo+fbratWunZs2a6c4779Sbb76patWq6fjx41qyZInuvPNONW7cWE888YT69++vxo0b69Zbb9WXX36pyMhIVapU6bKvGRERIYvFoh9//FFdunSRl5dXjv67l+NIngoVKigqKkpbt25VuXLl5Ofnp8qVKyszM1PvvvuuunXrpr/++kvvv/++U+/Trl27lJ6erjNnzuj8+fP2Am39+vUlOdce4XLOnDmj6OhoHT9+XNKFjdqkCyths1fD9uvXT2XLltWECRMkSePGjVPTpk1VtWpVJSQk6J133tHWrVs1ffp0+3VHjhypBx98UI0bN1azZs304YcfKjo62t7WwmKxaMSIERo/fryqVq2qqlWravz48fL29lbfvn2v63u6Eoq2KDBshk3R8dGSpPIB5eVicTE5EQAAuNEOnszuZ0vRFgBQfDAfLpjmzJmjJUuWaMuWLbJarbJarfryyy/VvHlzde3aVV26dNGSJUv0wgsvaNCgQTp58qRCQ0N122232T82f++99+rAgQN69tlnlZqaqrvvvluPPvqoli69/IZtZcuW1bhx4/Tcc89p4MCB6tevn2bPnn3VvBaL5ap57r77bi1cuFBt2rTRuXPnNGvWLA0YMEBTpkzRm2++qdGjR+u2227ThAkTcqwOvpouXbrk2JQre0WqYRgOX+Nqvv/+ew0cONB+/7777pMkjRkzRmPHjpUkRUdH21cLS9K5c+f08MMPKzY2VgEBAWrQoIH+/PNP3XzzzfZz7r33Xp0+fVqvvPKKYmJiVLt2bS1ZskQRERH2c5555hmlpKRo2LBhOnv2rG655RYtW7Ys31YES5LFyMt3rxBISEhQQECA4uPj5e/vb3Yc/EdSepJ8J1z4zVHi6ET5uDNZAwCguBk+d4u+33ZcoztX1yOtKt/Q187rcSLjTgCAowrjfDg1NVVRUVGqWLGiPD09zY4DFChX+vvh6BiRX90AAACgwKA9AgAAAEDRFgAAAAWEYRj2om2lIIq2AAAABUHnzp3l6+t7ydv48ePNjldk0dMWAAAABcLJxDQlpmXKxSKFl/Q2Ow4AAAAkffzxx0pJSbnkYyVLlrzBaYoPirYAAAAoEKL+3YSsXAlveVhdTU4DAAAA6cLGaLjxaI8AAACAAoF+tgAAAMAFFG0BAABQIFC0BQAAAC6gPQIKDKuLVcMaD7N/DQAAipeDbEIGACimmA8DyI2fBCgwPKwemt51utkxAACASVhpCwAorpgPA8iN9ggAAAAwXZbN0OHTFG0BAAAAiaItChDDMHQy6aROJp2UYRhmxwEAADfQsbMpysgy5G51UViAl9lxAAC4oZgPI9uKFStksVh07tw5s6PAZBRtUWAkZyQr+K1gBb8VrOSMZLPjAACAG+jgqURJUsVSPnJxsZicBgCAG4v58I1jsViueBswYMANy9K6dWuNGDEiX65tsVi0ePHiPLteRkaGnn32WdWpU0c+Pj4KCwtTv379dPz48Tx7DeRET1sAAACYjn62AADgRoiJibF/PW/ePL388svas2eP/ZiXV85P/GRkZMjNze2G5SuokpOTtXnzZr300kuqV6+ezp49qxEjRqh79+7auHGj2fGKJFbaAgAAwHTZRdtKQRRtAQBA/gkNDbXfAgICZLFY7PdTU1MVGBio+fPnq3Xr1vL09NQXX3yhsWPHqn79+jmuM3XqVFWoUCHHsVmzZqlGjRry9PRU9erVNWPGjMvmGDBggFauXKlp06bZV/keOnTI/vimTZvUuHFjeXt7q3nz5jkKy5L0ww8/qFGjRvL09FSlSpU0btw4ZWZmSpI9V8+ePWWxWOz3Dxw4oB49eigkJES+vr5q0qSJfv31V4fet4CAAC1fvly9e/dWtWrV1LRpU7377rvatGmToqOjHboGnEPRFgAAAKY7ePJC0bYCK20BACj0ktKTLntLzUx1+NyUjBSHzs1rzz77rIYPH67du3erY8eODj3no48+0gsvvKDXX39du3fv1vjx4/XSSy/ps88+u+T506ZNU7NmzfTQQw8pJiZGMTExCg8Ptz/+wgsvaPLkydq4caOsVqsGDRpkf2zp0qV64IEHNHz4cO3atUsffPCBZs+erddff12StGHDBkkXisgxMTH2+4mJierSpYt+/fVXbdmyRR07dlS3bt2uuegaHx8vi8WiwMDAa3o+roz2CAAAADDdwZMXetpWZqUtAACFnu8E38s+1qVqF/3U9yf7/Sv18W0V0UorBqyw368wrYJOJZ+66DxjTN5u3jZixAjdddddTj3n1Vdf1eTJk+3Pq1ixor2g2r9//4vODwgIkLu7u7y9vRUaGnrR46+//rpatWolSXruuefUtWtXpaamytPTU6+//rqee+45+3UrVaqkV199Vc8884zGjBmjoKAgSVJgYGCOa9erV0/16tWz33/ttde0aNEiff/993r88ced+n5TU1P13HPPqW/fvvL393fquXAMRVsAAACYKjk9U8fjL6y6qVT68pM8AACAG6Fx48ZOnX/y5EkdOXJEgwcP1kMPPWQ/npmZqYCAgGvKULduXfvXZcqUkSTFxcWpfPny2rRpkzZs2GBfWStJWVlZSk1NVXJysry9vS95zaSkJI0bN04//vijjh8/rszMTKWkpDi90jYjI0P33XefbDbbFVtA4PpQtAUAAICpslsjlPRxVwkfd5PTAACA65U4OvGyj7m6uOa4Hzcq7rLnulhydvU89MSh68rlKB+fnJ/8cXFxkWHkXM2bkZFh/9pms0m60CLhlltuyXGeq2vO79dR/938zGKx5Hgdm82mcePGXXI1sKen52Wv+fTTT2vp0qV66623VKVKFXl5ealXr15KT093OFdGRoZ69+6tqKgo/f7776yyzUcUbVFgWF2s6l+vv/1rAABQPBygNQIAoJgravNhH3fH/03Pr3PzUlBQkGJjY2UYhr2AunXrVvvjISEhKlu2rA4ePKj777/f4eu6u7srKyvL6TwNGzbUnj17VKVKlcue4+bmdtG1V61apQEDBqhnz56SLvS4/e/mZ1eTXbDdt2+f/vjjD5UqVcrp7HBc4f9JgCLDw+qh2XfONjsGAAC4wQ78u9K2chCtEQAAxRPz4YKtdevWOnnypCZOnKhevXrpl19+0c8//5xjlenYsWM1fPhw+fv7q3PnzkpLS9PGjRt19uxZjRw58pLXrVChgv7++28dOnRIvr6+KlmypEN5Xn75Zd1xxx0KDw/XPffcIxcXF23fvl07duzQa6+9Zr/2b7/9phYtWsjDw0MlSpRQlSpVtHDhQnXr1k0Wi0UvvfSSffXu1WRmZqpXr17avHmzfvzxR2VlZSk2NlaSVLJkSbm782mpvOZy9VMAAACA/JO9CVklVtoCAIACqEaNGpoxY4amT5+uevXqaf369Ro1alSOc4YMGaKPP/5Ys2fPVp06ddSqVSvNnj1b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uB4OF22ffvpppaena9q0aZKk9PR0NWvWTJGRkfL29tYzzzyj5cuXq1mzZvkWFkWft5u32REAAMA1yG6NUK6ElwK83UxOAwBA4cN8GMB/Obyt788//6y2bdva73/55Zc6fPiw9u3bp7Nnz+qee+7Ra6+95nSAGTNmqGLFivL09FSjRo20atWqK57/5Zdfql69evL29laZMmU0cOBAnT592unXRcHj4+6jpOeTlPR8knzcfcyOAwAAnJDdGqEWrREAAHAa82EAuTlctI2OjlbNmjXt95ctW6ZevXopIiJCFotFTzzxhLZs2eLUi8+bN08jRozQCy+8oC1btqhly5bq3LmzoqOjL3n+6tWr1a9fPw0ePFiRkZFasGCBNmzYoCFDhjj1ugAAAMhbkcfjJUm1wmiNAAAAAFwvh4u2Li4uMgzDfn/dunVq2rSp/X5gYKDOnj3r1ItPmTJFgwcP1pAhQ1SjRg1NnTpV4eHhmjlz5iXPX7dunSpUqKDhw4erYsWKuvXWW/XII49o48aNTr0uAAAA8hYrbQEAAIC843DRtnr16vrhhx8kSZGRkYqOjlabNm3sjx8+fFghISEOv3B6ero2bdqkDh065DjeoUMHrVmz5pLPad68uY4ePaolS5bIMAydOHFC33zzjbp27erw66LgSs1MVdevuqrrV12VmplqdhwAAOCglPQsHTiZKImVtgAAXAvmwwByc2ojsj59+uinn35SZGSkunTpoooVK9ofX7JkiW6++WaHX/jUqVPKysq6qNAbEhKi2NjYSz6nefPm+vLLL3XvvfcqNTVVmZmZ6t69u959993Lvk5aWprS0tLs9xMSEhzOiBsry5alJfuW2L8GAACFwz+xCbIZUikfd4X4e5gdxzSMOwEA14r5MIDcHF5pe/fdd2vJkiWqW7eunnzySc2bNy/H497e3ho2bJjTASwWS477hmFcdCzbrl27NHz4cL388svatGmTfvnlF0VFRWno0KGXvf6ECRMUEBBgv4WHhzudEQAAAJeX3RqhZpj/ZcdxxQHjTgAAAOQVh1faSlK7du3Url27Sz42ZswYp164dOnScnV1vWhVbVxc3GXbLEyYMEEtWrTQ008/LUmqW7eufHx81LJlS7322msqU6bMRc8ZPXq0Ro4cab+fkJDAABoAACAP/X8/2+LdGoFxJwAAAPKKQytto6Ojnbro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59O3334ryOVy4bPPPhOSkpKEOXPmCC4uLkJqaqogCIIwf/58YfLkyeb1k5OTBWdnZ+GZZ54RkpKShM8++0yQy+XCDz/8INZHaBL1bad3331X2LJli3DhwgXh9OnTwvz58wUAwqZNm8T6CI2utLTU/LsHgLB8+XIhMTFRSEtLEwSB59J19W0nezyXZs2aJahUKiEuLq5aflReXm5eh+eT5ZhzWo55Z92Yc1qGOefNmHNahjln3ZhzWoY5Z92aQ87Jom0jWbt2rQCgxseNAAhr1641vzaZTMLChQuFgIAAwdHRURgwYIBw6tSpJo6+6UydOrXGNtqzZ495nRvbqLy8XBg2bJjg6+sryOVyISQkRJg6daqQnp4uzgdoIvVtJ0Gwv3NJEAShsLBQmDRpkuDm5ia4ubkJkyZNEoqKiqqtY4/n00cffSSEhoYKCoVC6N69u7B3717ze1OnThUGDhxYbf24uDghKipKUCgUQlhYmPDxxx83ccTiqE87vf3220JERISgVCoFT09P4Y477hB+/vlnEaJuOnv27Knx99DUqVMFQeC5dF1928kez6Xa8qMb/4bxfLIcc07LMe+sG3NOyzDnrBlzTssw57w15pyWYc5Zt+aQc0oE4dqIukREREREREREREQkulsPeEVERERERERERERETYpFWyIiIiIiIiIiIiIrwqItERERERERERERkRVh0ZaIiIiIiIiIiIjIirBoS0RERERERERERGRFWLQlIiIiIiIiIiIisiIs2hIRERERERERERFZERZtiYiIiIiIiIiIiKwIi7ZERDYkLi4OEokExcXFYodCRERERM0Uc04iIvGxaEtEZMUGDRqEOXPmNPh+JRIJfvzxxwbd5+bNmzF8+HD4+PhAIpHg+PHjDbp/IiIiImoctpJz6vV6zJs3D507d4aLiwuCgoIwZcoUZGdnN9gxiIisBYu2RETUIDQaDfr164e33npL7FCIiIiIqBkqLy/HsWPH8Morr+DYsWPYvHkzLly4gHvuuUfs0IiIGhyLtkREVio2NhZ79+7Fe++9B4lEAolEgtTUVABAQkICevToAWdnZ/Tt2xfnz5+vtu22bdsQHR0NpVKJVq1aYfHixTAYDACAsLAwAMC4ceMgkUjMry9fvoyxY8fC398frq6u6NmzJ3bv3m1xvJMnT8arr76KoUOH/uvPTkRERERNw5ZyTpVKhV27duGBBx5Au3bt0KdPH3zwwQdISEhAenp6g7QHEZG1YNGWiMhKvffee4iJicGMGTOQk5ODnJwcBAcHAwBeeuklLFu2DEePHoWDgwMee+wx83Y7d+7EI488gqeeegpJSUlYvXo11q1bhzfffBMAcOTIEQDA2rVrkZOTY35dVlaGUaNGYffu3UhMTMTw4cMxZswYJsBEREREzZit55xqtRoSiQQeHh7/ohWIiKyPRBAEQewgiIioZoMGDUK3bt2wYsUKAFWTQgwePBi7d+/GkCFDAAA7duzA6NGjUVFRAaVSiQEDBmDkyJF48cUXzftZv349XnjhBfN4XxKJBFu2bMG99957y+N37NgRs2bNwhNPPGFxzKmpqQgPD0diYiK6detWr89LRERERE3PFnNOANBqtbjjjjvQvn17rF+/vl7bEhFZOwexAyAiovrr0qWL+XlgYCAAIC8vDyEhIUhISMCRI0fMvRwAwGg0QqvVory8HM7OzjXuU6PRYPHixdi+fTuys7NhMBhQUVHBnrZEREREdsqac069Xo8HH3wQJpMJK1euvI1PR0Rk3Vi0JSKyQXK53PxcIpEAAEwmk/nn4sWLcd999920nVKprHWfzz//PHbu3ImlS5eidevWcHJywv333w+dTtfA0RMRERGRLbDWnFOv1+OBBx5ASkoK/vjjD7i7u1u8LRGRrWDRlojIiikUChiNxnpt0717d5w/fx6tW7eudR25XH7Tfvfv34/Y2FiMGzcOQNV4Y9cnoSAiIiKi5suWcs7rBduLFy9iz5498Pb2rlfcRES2gkVbIiIrFhYWhkOHDiE1NRWurq7mng238uqrr+Luu+9GcHAwJkyYAKlUipMnT+LUqVN44403zPv9/fff0a9fPzg6OsLT0xOtW7fG5s2bMWbMGEgkErzyyisWHe+6q1evIj093TyG2fXZhQMCAhAQEHAbn56IiIiImoKt5JwGgwH3338/jh07hu3bt8NoNCI3NxcA4OXlBYVCcfuNQERkZaRiB0BERLV77rnnIJPJEBkZCV9fX4vG+ho+fDi2b9+OXbt2oWfPnujTpw+WL1+O0NBQ8zrLli3Drl27EBwcjKioKADAu+++C09PT/Tt2xdjxozB8OHD0b17d4tj3bp1K6KiojB69GgAwIMPPoioqCisWrWqnp+aiIiIiJqSreScmZmZ2Lp1KzIzM9GtWzcEBgaaHwcOHLi9D09EZKUkgiAIYgdBRERERERERERERFXY05aIiIiIiIiIiIjIirBoS0REddq/fz9cXV1rfRARERER/VvMOYmI/sbhEYiIqE4VFRXIysqq9f1bzRpMRERERGQJ5pxERH9j0ZaIiIiIiIiIiIjIinB4BCIiIiIiIiIiIiIrwqItERERERERERERkRVh0ZaIiIiIiIiIiIjIirBoS0RERERERERERGRFWLQlIiIiIiIiIiIisiIs2hIRERERERERERFZERZtiYiIiIiIiIiIiKwIi7ZEREREREREREREVuT/AbV6d16DARXiAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Plot the effect of varying each parameter (theta_1 and theta_2) one at a time\n", + "\n", + "fig, axes = plt.subplots(1, 2, figsize=(14, 5), sharey=True)\n", + "\n", + "# Vary theta_1, fix theta_2 at true value\n", + "theta1_vals = theta1_range\n", + "theta2_fixed = true_params[\"theta2\"]\n", + "sse_theta1 = []\n", + "for t1 in theta1_vals:\n", + " y_sim = np.array([model(x, t1, theta2_fixed) for x in conc])\n", + " sse = np.sum((vel - y_sim) ** 2)\n", + " sse_theta1.append(sse)\n", + "axes[0].plot(theta1_vals, sse_theta1, label=f'Fixed theta_2={theta2_fixed:.3f}')\n", + "axes[0].axvline(true_params['theta1'], color='green', linestyle='--', label='True theta_1')\n", + "axes[0].set_xlabel('theta_1')\n", + "axes[0].set_ylabel('Sum of Squared Errors (SSE)')\n", + "axes[0].set_title('SSE vs theta_1 (theta_2 fixed)')\n", + "axes[0].legend()\n", + "\n", + "# Vary theta_2, fix theta_1 at true value\n", + "theta2_vals = theta2_range\n", + "theta1_fixed = true_params[\"theta1\"]\n", + "sse_theta2 = []\n", + "for t2 in theta2_vals:\n", + " y_sim = np.array([model(x, theta1_fixed, t2) for x in conc])\n", + " sse = np.sum((vel - y_sim) ** 2)\n", + " sse_theta2.append(sse)\n", + "axes[1].plot(theta2_vals, sse_theta2, label=f'Fixed theta_1={theta1_fixed:.3f}')\n", + "axes[1].axvline(true_params['theta2'], color='green', linestyle='--', label='True theta_2')\n", + "axes[1].set_xlabel('theta_2')\n", + "axes[1].set_title('SSE vs theta_2 (theta_1 fixed)')\n", + "axes[1].legend()\n", + "\n", + "plt.tight_layout()\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "id": "be805271-1f41-4066-ad50-f912ba61fa53", + "metadata": {}, + "source": [ + "# PARMEST" + ] + }, + { + "cell_type": "markdown", + "id": "2b95ecb7-a1c7-4b09-b32e-dafe3fca3944", + "metadata": {}, + "source": [ + "## Creating an experiment class for both DOE and ParmEst\n", + "We will use this class for both parmest (to estimate the parameters) and DOE (To calculate the FIM and factorial design)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "a5e84eb1-94a6-40ec-a940-2306778a4f71", + "metadata": {}, + "outputs": [], + "source": [ + "class Simple_Multimodal(experiment.Experiment):\n", + "\n", + " # Defining the constructor for our model\n", + " def __init__(self, data, theta_initial=None):\n", + " \"\"\"\n", + " Arguments:\n", + " data: data from our experiment. type: 'dict'\n", + " theta_initial: initial guess of the parameter values, dtype: dict. pass the values as theta_initial = {1 : , 2 : }\n", + " default: {1: 100, 2: 0.05}\n", + " \n", + " \"\"\"\n", + " self.conc = data[\"x\"]\n", + " self.vel = data[\"y\"]\n", + " self.model = None \n", + " self.theta_initial = theta_initial\n", + " if self.theta_initial is None:\n", + " self.theta_initial = {1: -1.5, 2: 0.5} # default initial guess of theta[1] & theta[2]\n", + " else:\n", + " self.theta_initial = theta_initial\n", + "\n", + " # Creating the get_labeled_model which is a must for ``DOE`` and ``ParmEst``\n", + " def get_labeled_model(self):\n", + " if self.model is None:\n", + " self.create_model()\n", + " self.label_model()\n", + " self.finalize_model()\n", + " return self.model\n", + "\n", + " \n", + " def create_model(self):\n", + " \"\"\"\n", + " Here, we will create different variables, parameters, and constraints.\n", + " The index set for data points will be the actual substrate concentrations (x values).\n", + " \"\"\"\n", + " m = self.model = pyo.ConcreteModel()\n", + "\n", + " # theta_1 and theta_2 as parameters to be estimated\n", + " m.theta_1 = pyo.Var(initialize=self.theta_initial[1], bounds=(-2, 2))\n", + " m.theta_2 = pyo.Var(initialize=self.theta_initial[2], bounds=(-2, 2))\n", + "\n", + " # Use the actual conc values as the index set\n", + " m.x_set = pyo.Set(initialize=[float(val) for val in self.conc], ordered=True)\n", + "\n", + " # Substrate concentration (x) as a parameter, indexed by x_set\n", + " m.x = pyo.Param(m.x_set, initialize={float(val): float(val) for val in self.conc}, mutable=False)\n", + "\n", + " # Measured variable for each data point (indexed by x_set)\n", + " m.measured_var = pyo.Var(m.x_set)\n", + "\n", + " # Constraint for each data point\n", + " def meas_con(m, xval):\n", + " return m.measured_var[xval] == (m.theta_1 * m.x[xval]**3 - m.theta_2 * m.x[xval]**2 + 2 * m.x[xval] - 1)**2 + (m.theta_1 - m.theta_2)**2 + (m.x[xval]**2 - 1)**2\n", + " m.meas_con = pyo.Constraint(m.x_set, rule=meas_con)\n", + "\n", + " # Objective function: sum of squared errors over all data points\n", + " m.FirstStageCost = pyo.Expression(initialize=0)\n", + " m.SecondStageCost = pyo.Expression(expr=sum((self.vel[i] - m.measured_var[float(self.conc[i])]) ** 2 for i in range(len(self.conc))))\n", + " m.Total_Cost_Obj = pyo.Objective(expr=(m.FirstStageCost + m.SecondStageCost), sense=pyo.minimize)\n", + "\n", + " return m\n", + "\n", + " \n", + " def finalize_model(self):\n", + " \"\"\"\n", + " Finalizing the model. Here, we will set the experimental conditions (e.g, initial conditions),\n", + " fixing the parameter values (if needed), update `t` values, and discretize the model (if model is dynamic). \n", + " It makes a solvable model.\n", + " \"\"\" \n", + " m=self.model\n", + "\n", + " # fixing the parameters\n", + " m.theta_1.fix(self.theta_initial[1]) \n", + " m.theta_2.fix(self.theta_initial[2]) \n", + "\n", + "\n", + " return m\n", + "\n", + " \n", + " def label_model(self):\n", + " \"\"\"\n", + " The model is updated with outputs, and unknown parameters. This makes the model labeled with full experiment.\n", + " In `ParmEst` output (given data) is the most important. For `DOE` input is most important.\n", + " \"\"\"\n", + " m = self.model\n", + "\n", + " m.experiment_outputs = pyo.Suffix(direction = pyo.Suffix.LOCAL) \n", + " m.experiment_outputs.update([(m.measured_var, self.vel)]) # Pass the data as a list of `tuple`\n", + " # If we only use ``DOE``, we could use ``m.experiment_ouputs.update([(m.x, None)])``.\n", + " # Output is not important for ``DOE``\n", + "\n", + " # m.experiment_inputs = pyo.Suffix(direction = pyo.Suffix.LOCAL) \n", + " # # m.experiment_inputs[m.x] = self.conc\n", + " # m.experiment_inputs.update([(m.x, self.conc)])\n", + " # # If we only use ``DOE``, we could use ``m.experiment_inputs.update([(m.x, None)])``\n", + "\n", + " m.unknown_parameters = pyo.Suffix(direction = pyo.Suffix.LOCAL)\n", + " m.unknown_parameters.update((p, pyo.value(p)) for p in [m.theta_1, m.theta_2])\n", + " # m.unknown_parameters[m.theta_1]= self.theta_initial[1]\n", + " # m.unknown_parameters[m.theta_2]= self.theta_initial[2]\n", + "\n", + " m.measurement_error = pyo.Suffix(direction = pyo.Suffix.LOCAL)\n", + " # m.measurement_error[m.measured_var] = 0.03\n", + " m.measurement_error.update([(m.measured_var, 0.03**2)]) # variance of the measurement error, b/c in doe, the measurement error is passed as variance, not std\n", + " # this will be fixed in later update \n", + "\n", + " return m" + ] + }, + { + "cell_type": "markdown", + "id": "c303c406-ac5a-4ff6-9535-48967393acc4", + "metadata": {}, + "source": [ + "## Parmest Example\n", + "We will evaluate diffent parameters, visualize pairwise plots and show bootstrap table" + ] + }, + { + "cell_type": "markdown", + "id": "32d11b62-0040-4a65-b4f7-035730272094", + "metadata": {}, + "source": [ + "### Treated velocity\n", + "Here, we will calculate objective value at optimum parameter value, paramater values, $\\theta$, and covariance matrix for treated velocity." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "09b0eae6-e1d1-404c-be2a-98a1a8e776bf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.10e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.51e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 2.77e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 1.50e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 1.4985094187954244e-12 2.8984606156203206e-10\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "\n", + "theta values:\n", + "theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "\n", + "SSE value: 428163.2965187811\n", + "\n", + "Covariance matrix:\n", + " theta_1 theta_2\n", + "theta_1 4.667923e-08 3.978519e-08\n", + "theta_2 3.978519e-08 6.376757e-07\n" + ] + } + ], + "source": [ + "exp_list = [] \n", + "conc = data_df[\"x\"].values # substrate concentration (control variable)\n", + "vel = data_df[\"y\"].values # reaction velocity (output variable)\n", + "n_exp = 1\n", + "\n", + "# exp_list to separate each experiment\n", + "# for i in range(n_exp):\n", + "exp_list.append(Simple_Multimodal(data_df))\n", + "\n", + "# Creating an Estimator object\n", + "pest = parmest.Estimator(exp_list, tee = True) \n", + "\n", + "# Estimating d\n", + "obj, theta, cov = pest.theta_est(calc_cov=True, cov_n=len(conc),)\n", + "\n", + "# ``parmest`` can mess up the order of the theta estimates and also the covariance. So we need to fix the order so that we can manipulate it properly.\n", + "t_order = [\"theta_1\", \"theta_2\"]\n", + "theta_perm = theta.loc[t_order] # ``theta`` in the order we want\n", + "cov_perm = cov.loc[t_order, t_order] # ``covariance`` matrix in the order we want\n", + "\n", + "print(\"\\ntheta values:\")\n", + "print(theta_perm)\n", + "\n", + "print(\"\\nSSE value: \", obj)\n", + "\n", + "print(\"\\nCovariance matrix:\")\n", + "print(cov_perm)" + ] + }, + { + "cell_type": "markdown", + "id": "fe378b08", + "metadata": {}, + "source": [ + "### Manual multistart test\n", + "\n", + "Made a for loop version of multistart, to see expected results from solver being accessed each time. Sobol sampling, n = 50, seed = 12345" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "5a2cc375", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 8.33e+03 9.73e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.9834030e+07 2.32e+03 1.15e+05 -1.0 9.25e+03 - 2.54e-01 1.00e+00f 1\n", + " 2 2.6443991e+07 1.71e+02 1.35e+04 -1.0 9.35e+01 - 8.83e-01 1.00e+00h 1\n", + " 3 2.7180925e+07 1.23e+00 3.23e+02 -1.0 1.06e+01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186293e+07 5.91e-05 4.09e-02 -1.0 7.54e-02 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 3.89e-12 1.48e-10 -2.5 1.72e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 5.57e-12 6.31e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 1.10e-09 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 7.61e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027403e+05 2.7186293738994990e+07\n", + "Dual infeasibility......: 7.6089379903002177e-10 1.4717429743825483e-07\n", + "Constraint violation....: 7.7375360819269268e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Applications/anaconda3/envs/parmest-dev-mac2/lib/python3.13/site-packages/scipy/stats/_qmc.py:993: UserWarning: The balance properties of Sobol' points require n to be a power of 2.\n", + " sample = self._random(n, workers=workers)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 2.15e+04 9.85e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 9.7588988e+06 2.78e+03 5.57e+04 -1.0 9.41e+03 - 1.46e-02 1.00e+00f 1\n", + " 2 2.6386162e+07 2.49e+02 1.19e+04 -1.0 2.49e+02 - 9.29e-01 1.00e+00h 1\n", + " 3 2.7175624e+07 2.55e+00 5.81e+02 -1.0 1.51e+01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186293e+07 2.61e-04 1.56e-01 -1.0 1.51e-01 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 5.40e-12 3.64e-09 -2.5 3.02e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.41e-12 1.03e-09 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 1.23e-09 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 5.64e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 5.6444294344696339e-10 1.0917620008427717e-07\n", + "Constraint violation....: 6.8047436072523522e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.10e+03 1.06e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.2271200e+09 1.06e+04 5.22e+06 -1.0 1.41e+04 - 1.55e-01 2.75e-01f 1\n", + " 2 4.9620454e+06 1.15e+03 1.42e+06 -1.0 6.05e+03 - 1.49e-02 1.00e+00f 1\n", + " 3 4.3909756e+05 6.85e+01 8.18e+04 -1.0 3.03e+02 - 9.74e-01 1.00e+00f 1\n", + " 4 4.2816904e+05 2.93e-01 4.24e+02 -1.0 1.76e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 4.2816330e+05 6.80e-06 1.39e-02 -1.0 1.19e-01 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 5.03e-12 1.55e-10 -2.5 2.53e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 4.18e-12 4.43e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 8 4.2816330e+05 5.09e-12 2.61e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 4.2816330e+05 3.50e-12 6.22e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", + "Dual infeasibility......: 6.2153811273360234e-12 1.2021971422198111e-09\n", + "Constraint violation....: 3.4631683699249438e-13 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.07e+03 8.68e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.4414889e+09 1.02e+03 2.34e+05 -1.0 1.25e+04 - 2.26e-01 5.25e-02f 1\n", + " 2 4.4306624e+09 1.02e+03 2.34e+05 -1.0 7.54e+03 - 9.36e-01 1.31e-03f 1\n", + " 3 4.4294973e+09 1.02e+03 6.00e+06 -1.0 3.07e+03 - 1.00e+00 6.02e-04f 1\n", + " 4 3.0552690e+09 9.12e+02 1.82e+07 -1.0 2.98e+03 - 1.00e+00 9.96e-01f 1\n", + " 5 1.5613347e+09 1.89e+03 3.20e+07 -1.0 6.63e+03 -2.0 4.47e-01 1.00e+00f 1\n", + " 6 1.0074442e+09 2.86e+01 4.84e+06 -1.0 1.43e+03 - 1.37e-02 1.00e+00f 1\n", + " 7 9.7365090e+08 1.54e+00 4.43e+06 -1.0 2.29e+02 - 1.36e-04 1.00e+00f 1\n", + " 8 1.4779113e+08 2.15e+03 2.83e+07 -1.0 3.47e+03 -1.6 1.90e-02 1.00e+00f 1\n", + " 9 2.9134338e+06 2.92e+01 1.03e+06 -1.0 1.61e+03 - 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 4.2930909e+05 2.52e+00 2.09e+04 -1.0 2.46e+02 - 1.00e+00 1.00e+00f 1\n", + " 11 4.2816335e+05 2.53e-03 1.42e+01 -1.0 5.43e+00 - 1.00e+00 1.00e+00f 1\n", + " 12 4.2816330e+05 1.59e-09 7.66e-06 -1.0 3.76e-03 - 1.00e+00 1.00e+00h 1\n", + " 13 4.2816330e+05 3.21e-12 2.17e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 14 4.2816330e+05 4.18e-12 2.30e-03 -3.8 7.13e-07 - 1.00e+00 5.00e-01h 2\n", + " 15 4.2816330e+05 4.01e-12 1.68e-11 -3.8 3.56e-07 - 1.00e+00 1.00e+00h 1\n", + " 16 4.2816330e+05 5.09e-12 2.77e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00h 1\n", + " 17 4.2816330e+05 3.50e-12 9.85e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 17\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 9.8533599348512529e-12 1.9058656118194543e-09\n", + "Constraint violation....: 2.9162136132700857e-13 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597866419e-09 4.8469917395800629e-07\n", + "Overall NLP error.......: 2.5059035597866419e-09 4.8469917395800629e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 20\n", + "Number of objective gradient evaluations = 18\n", + "Number of equality constraint evaluations = 20\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 18\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 17\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.010\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.72e+03 9.63e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.6711997e+07 4.94e+01 4.67e+03 -1.0 9.15e+03 - 8.25e-01 1.00e+00f 1\n", + " 2 2.7185876e+07 1.30e-01 3.12e+01 -1.0 5.38e+00 - 1.00e+00 1.00e+00h 1\n", + " 3 2.7186294e+07 8.26e-07 2.97e-04 -1.0 7.99e-03 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186294e+07 3.41e-12 2.29e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 4.41e-12 4.78e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 3.67e-12 9.05e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.12e-12 2.65e-10 -8.6 3.89e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 7\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027403e+05 2.7186293738994990e+07\n", + "Dual infeasibility......: 2.6501622456984170e-10 5.1260210965743845e-08\n", + "Constraint violation....: 4.6417226757976225e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597868338e-09 4.8469917395804345e-07\n", + "Overall NLP error.......: 2.5059035597868338e-09 4.8469917395804345e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 8\n", + "Number of objective gradient evaluations = 8\n", + "Number of equality constraint evaluations = 8\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 8\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 7\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 2.37e+03 9.51e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 5.2544727e+08 1.26e+04 4.35e+05 -1.0 9.02e+03 - 2.75e-01 6.86e-01f 1\n", + " 2 2.2794582e+07 1.25e+03 9.75e+04 -1.0 2.97e+03 - 2.39e-02 1.00e+00f 1\n", + " 3 2.7074814e+07 3.89e+01 6.86e+03 -1.0 5.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186179e+07 4.02e-02 1.85e+01 -1.0 1.74e+00 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 3.87e-08 4.24e-05 -1.0 3.08e-03 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.58e-12 3.65e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.41e-12 3.77e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.21e-12 9.78e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 2.7186294e+07 4.12e-12 7.89e-10 -8.6 3.89e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 7.8853941762349164e-10 1.5252159360353654e-07\n", + "Constraint violation....: 1.8412683274148882e-13 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597868338e-09 4.8469917395804345e-07\n", + "Overall NLP error.......: 2.5059035597868338e-09 4.8469917395804345e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 8.36e+03 1.01e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 3.6567139e+06 2.70e+03 6.69e+04 -1.0 9.84e+03 - 3.42e-01 1.00e+00f 1\n", + " 2 4.3352737e+05 1.69e+02 6.65e+03 -1.0 1.86e+02 - 8.09e-01 1.00e+00f 1\n", + " 3 4.2816873e+05 8.05e-01 4.30e+01 -1.0 7.01e+00 - 1.00e+00 1.00e+00f 1\n", + " 4 4.2816330e+05 1.82e-05 3.52e-03 -1.0 3.07e-02 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 3.69e-12 7.46e-11 -2.5 2.58e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 4.18e-12 7.82e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 5.09e-12 1.10e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 4.2816330e+05 3.50e-12 2.88e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", + "Dual infeasibility......: 2.8795658903932589e-12 5.5697403157450258e-10\n", + "Constraint violation....: 9.8520816457861569e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 8.43e+03 1.01e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.1035343e+07 5.64e+03 1.01e+06 -1.0 9.86e+03 - 1.52e-01 1.00e+00f 1\n", + " 2 7.7062599e+05 7.40e+02 1.98e+05 -1.0 4.05e+02 - 6.58e-01 1.00e+00f 1\n", + " 3 4.2910167e+05 2.42e+01 8.77e+03 -1.0 8.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 4.2816393e+05 3.08e-02 1.65e+01 -1.0 3.60e+00 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.42e-08 4.48e-05 -1.0 5.94e-03 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.89e-12 2.24e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 5.31e-12 1.87e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", + " 8 4.2816330e+05 3.04e-12 1.45e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 4.2816330e+05 3.50e-12 2.62e-11 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 2.6224264566340445e-11 5.0723737245673013e-09\n", + "Constraint violation....: 1.6351447811689176e-13 3.4958702599396925e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 11\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 11\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 8.08e+02 9.23e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 3.5436370e+08 1.58e+04 3.23e+06 -1.0 9.13e+03 - 4.82e-01 7.24e-01f 1\n", + " 2 3.0476400e+07 1.98e+03 6.74e+05 -1.0 2.56e+03 - 3.12e-02 1.00e+00f 1\n", + " 3 2.7331790e+07 9.12e+01 5.74e+04 -1.0 5.85e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 2.7186712e+07 2.48e-01 3.36e+02 -1.0 7.25e+00 - 1.00e+00 1.00e+00f 1\n", + " 5 2.7186294e+07 3.56e-06 7.20e-03 -1.0 4.95e-02 - 1.00e+00 1.00e+00f 1\n", + " 6 2.7186294e+07 3.58e-12 1.45e-10 -2.5 2.01e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.41e-12 2.03e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.69e-12 2.62e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 2.7186294e+07 4.12e-12 7.32e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 7.3178996857371158e-10 1.4154494968219492e-07\n", + "Constraint violation....: 1.6008713042790100e-13 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.21e+04 9.67e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.3904826e+07 7.92e+02 1.65e+04 -1.0 9.20e+03 - 6.85e-01 1.00e+00f 1\n", + " 2 2.7078421e+07 2.47e+01 2.40e+03 -1.0 4.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 3 2.7186180e+07 2.61e-02 8.33e+00 -1.0 1.57e+00 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186294e+07 2.61e-08 2.15e-05 -1.0 1.65e-03 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 3.58e-12 2.84e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.41e-12 8.12e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 1.17e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 6.44e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 6.4447847720351047e-10 1.2465690641376951e-07\n", + "Constraint violation....: 5.4622972811557702e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 2.11e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.8316028e+09 2.06e+03 8.87e+03 -1.0 6.09e+03 - 3.06e-01 2.48e-02f 1\n", + " 2 4.8286802e+09 2.06e+03 2.41e+04 -1.0 6.72e+03 - 6.43e-01 3.26e-04f 1\n", + " 3 4.8221153e+09 2.05e+03 5.20e+06 -1.0 1.77e+03 - 1.00e+00 4.84e-03f 1\n", + " 4 3.6291264e+09 1.18e+01 2.25e+06 -1.0 1.75e+03 - 1.00e+00 1.00e+00f 1\n", + " 5 3.6164199e+09 1.93e-02 1.33e+04 -1.0 1.77e+01 0.0 1.00e+00 1.00e+00f 1\n", + " 6 3.6142797e+09 9.44e-02 3.42e+04 -1.0 2.49e+01 -0.5 1.00e+00 1.00e+00f 1\n", + " 7 3.6063319e+09 1.26e+00 6.91e+03 -1.0 9.04e+01 -1.0 1.00e+00 1.00e+00f 1\n", + " 8 3.5609956e+09 4.91e+01 2.62e+05 -1.0 5.47e+02 -1.4 1.00e+00 1.00e+00f 1\n", + " 9 3.4536087e+09 1.18e+01 3.09e+05 -1.0 2.54e+02 -1.0 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 3.1279033e+09 4.24e+02 2.06e+06 -1.0 1.38e+03 -1.5 1.00e+00 1.00e+00f 1\n", + " 11 3.4934385e+09 1.21e+02 2.69e+07 -1.0 1.18e+04 -2.0 3.42e-01 5.36e-02H 1\n", + " 12 2.9025111e+09 9.96e+02 5.96e+06 -1.0 2.40e+03 -1.5 1.00e+00 1.00e+00f 1\n", + " 13 3.0988933e+09 8.23e+02 3.70e+07 -1.0 3.37e+04 - 3.57e-01 1.95e-02H 1\n", + " 14 1.4289790e+09 1.38e+03 1.82e+07 -1.0 5.41e+03 -2.0 7.49e-01 1.00e+00f 1\n", + " 15 9.1847716e+08 2.03e+00 4.74e+06 -1.0 1.66e+03 - 6.80e-02 1.00e+00f 1\n", + " 16 9.1753645e+08 3.84e-02 4.80e+06 -1.0 3.84e+01 - 7.33e-04 1.00e+00f 1\n", + " 17 2.6734760e+08 8.34e+02 1.25e+07 -1.0 2.22e+03 -1.6 4.98e-04 1.00e+00f 1\n", + " 18 3.1392273e+07 4.23e+01 1.36e+06 -1.0 1.71e+03 - 9.07e-01 1.00e+00f 1\n", + " 19 2.7168841e+07 4.01e+00 3.90e+04 -1.0 3.38e+02 - 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 2.7186259e+07 7.87e-03 4.66e+01 -1.0 9.43e+00 - 1.00e+00 1.00e+00h 1\n", + " 21 2.7186294e+07 1.60e-08 7.92e-05 -1.0 1.13e-02 - 1.00e+00 1.00e+00h 1\n", + " 22 2.7186294e+07 4.09e-12 4.46e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 23 2.7186294e+07 4.41e-12 1.77e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 24 2.7186294e+07 4.69e-12 4.44e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 25 2.7186294e+07 4.12e-12 9.32e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 25\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027403e+05 2.7186293738994990e+07\n", + "Dual infeasibility......: 9.3170592537955412e-10 1.8021327701920809e-07\n", + "Constraint violation....: 2.8906604310374570e-13 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 28\n", + "Number of objective gradient evaluations = 26\n", + "Number of equality constraint evaluations = 28\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 26\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 25\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.018\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 3.71e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 3.6253900e+06 7.03e+03 4.94e+05 -1.0 9.73e+03 - 5.66e-01 1.00e+00f 1\n", + " 2 6.3155920e+05 9.68e+02 1.03e+05 -1.0 2.11e+02 - 3.06e-01 1.00e+00f 1\n", + " 3 4.2943835e+05 3.66e+01 6.18e+03 -1.0 6.27e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 4.2816462e+05 6.43e-02 1.50e+01 -1.0 3.60e+00 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 2.08e-07 6.53e-05 -1.0 7.59e-03 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.92e-12 2.10e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 4.18e-12 3.09e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 8 4.2816330e+05 5.09e-12 6.41e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 4.2816330e+05 3.50e-12 4.40e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 4.3995938736571737e-12 8.5098227662596132e-10\n", + "Constraint violation....: 1.2311475077887451e-13 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 2.36e+04 9.68e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.9411233e+07 2.24e+03 2.14e+04 -1.0 9.12e+03 - 9.31e-02 1.00e+00f 1\n", + " 2 2.7249209e+07 1.10e+02 1.53e+03 -1.0 2.59e+01 - 9.65e-01 1.00e+00f 1\n", + " 3 2.7186190e+07 3.26e-01 3.14e+00 -1.0 1.24e+00 - 1.00e+00 1.00e+00f 1\n", + " 4 2.7186294e+07 2.93e-06 8.94e-05 -1.0 5.33e-03 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 4.32e-12 6.52e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.41e-12 6.15e-11 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 2.62e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 1.03e-09 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027398e+05 2.7186293738994978e+07\n", + "Dual infeasibility......: 1.0262933743643622e-09 1.9850865722675085e-07\n", + "Constraint violation....: 4.3964831775156199e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 5.50e+03 9.77e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.5759216e+08 1.17e+04 2.18e+05 -1.0 9.43e+03 - 1.70e-01 8.24e-01f 1\n", + " 2 2.3277921e+07 1.37e+03 9.11e+04 -1.0 1.41e+03 - 3.04e-02 1.00e+00f 1\n", + " 3 2.7051971e+07 4.76e+01 1.10e+03 -1.0 6.63e+01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186107e+07 6.48e-02 2.18e+00 -1.0 2.12e+00 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 1.19e-07 1.67e-05 -1.0 2.83e-03 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.69e-12 1.19e-09 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.41e-12 3.60e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.69e-12 2.91e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 2.7186294e+07 4.12e-12 5.86e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 5.8627081629004306e-10 1.1339821090148592e-07\n", + "Constraint violation....: 1.7015480447604767e-13 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.08e+04 9.98e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 9.8648968e+05 4.31e+02 1.25e+04 -1.0 9.71e+03 - 5.64e-01 1.00e+00f 1\n", + " 2 4.2829757e+05 9.37e+00 2.57e+02 -1.0 7.16e+01 - 1.00e+00 1.00e+00f 1\n", + " 3 4.2816336e+05 3.72e-03 4.88e-01 -1.0 2.97e-01 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 5.74e-10 2.35e-07 -1.7 1.82e-04 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.51e-12 6.63e-12 -3.8 5.28e-06 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 1.88e-12 2.17e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00H 1\n", + " 7 4.2816330e+05 3.50e-12 3.72e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 7\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 3.7174728473274775e-12 7.1904443859138779e-10\n", + "Constraint violation....: 6.7272184213622484e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597866419e-09 4.8469917395800629e-07\n", + "Overall NLP error.......: 2.5059035597866419e-09 4.8469917395800629e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 8\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 8\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 7\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.51e+04 9.87e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.4591296e+05 4.94e+02 3.70e+03 -1.0 9.66e+03 - 6.72e-01 1.00e+00f 1\n", + " 2 4.2820756e+05 6.55e+00 1.50e+02 -1.0 1.56e+01 - 1.00e+00 1.00e+00f 1\n", + " 3 4.2816331e+05 1.24e-03 2.54e-02 -1.0 2.82e-01 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.29e-11 1.22e-08 -2.5 4.22e-05 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 4.49e-12 2.73e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 5.09e-12 1.09e-11 -5.7 3.95e-08 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 3.50e-12 1.67e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 7\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", + "Dual infeasibility......: 1.6711097683383890e-12 3.2323092448766719e-10\n", + "Constraint violation....: 4.4162799930954544e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597866419e-09 4.8469917395800629e-07\n", + "Overall NLP error.......: 2.5059035597866419e-09 4.8469917395800629e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 8\n", + "Number of objective gradient evaluations = 8\n", + "Number of equality constraint evaluations = 8\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 8\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 7\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 3.14e+03 9.52e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 3.2143856e+07 3.08e+03 8.73e+04 -1.0 9.13e+03 - 7.71e-01 1.00e+00f 1\n", + " 2 2.7516639e+07 2.13e+02 1.12e+04 -1.0 4.02e+01 - 8.52e-01 1.00e+00f 1\n", + " 3 2.7187562e+07 1.86e+00 1.48e+02 -1.0 3.04e+00 - 1.00e+00 1.00e+00f 1\n", + " 4 2.7186294e+07 1.48e-04 1.42e-02 -1.0 2.39e-02 - 1.00e+00 1.00e+00f 1\n", + " 5 2.7186294e+07 5.83e-12 4.05e-10 -2.5 1.58e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.60e-12 7.46e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 1.22e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 6.01e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 6.0082273151840992e-10 1.1621288477955682e-07\n", + "Constraint violation....: 7.9483276450609387e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 2.03e+04 9.73e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.2603904e+07 2.57e+03 2.37e+04 -1.0 9.24e+03 - 2.68e-01 1.00e+00f 1\n", + " 2 2.6435802e+07 1.99e+02 7.37e+03 -1.0 8.27e+01 - 9.14e-01 1.00e+00h 1\n", + " 3 2.7178955e+07 1.68e+00 2.58e+02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186293e+07 1.18e-04 5.10e-02 -1.0 1.04e-01 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 4.18e-12 4.94e-10 -2.5 1.35e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 5.57e-12 3.19e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 3.46e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 7.83e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 7.8272167187299556e-10 1.5139630825544308e-07\n", + "Constraint violation....: 5.4622972811557702e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 6.27e+03 1.05e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.8071968e+08 1.32e+04 5.04e+06 -1.0 1.14e+04 - 1.01e-01 7.28e-01f 1\n", + " 2 2.1061322e+06 1.58e+03 1.08e+06 -1.0 1.60e+03 - 3.02e-02 1.00e+00f 1\n", + " 3 4.3722926e+05 7.27e+01 7.33e+04 -1.0 2.26e+02 - 1.00e+00 1.00e+00f 1\n", + " 4 4.2816494e+05 2.11e-01 3.44e+02 -1.0 1.68e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 4.2816330e+05 2.17e-06 5.34e-03 -1.0 7.53e-02 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.81e-12 1.86e-10 -2.5 2.47e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 5.31e-12 3.37e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", + " 8 4.2816330e+05 3.04e-12 7.53e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 4.2816330e+05 3.50e-12 5.59e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 5.5912355767736014e-12 1.0814730897694733e-09\n", + "Constraint violation....: 2.6290081223123707e-13 3.4958702599396925e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 11\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 11\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.08e+03 1.04e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.9442460e+09 2.90e+02 1.62e+06 -1.0 8.40e+01 0.0 9.06e-01 1.00e+00f 1\n", + " 2 3.8682267e+09 4.36e+03 3.75e+06 -1.0 7.36e+03 - 2.57e-01 2.22e-01f 1\n", + " 3 1.0445680e+09 2.36e+03 1.30e+07 -1.0 8.06e+03 - 5.91e-02 1.00e+00f 1\n", + " 4 1.8847235e+09 1.86e+03 8.68e+06 -1.0 1.76e+04 - 1.00e+00 1.41e-01H 1\n", + " 5 1.8845015e+09 1.84e+03 8.61e+06 -1.0 2.22e+02 -0.5 1.00e+00 8.89e-03f 1\n", + " 6 1.8845004e+09 1.84e+03 8.61e+06 -1.0 2.48e+02 -1.0 1.00e+00 8.80e-05f 1\n", + " 7 1.0031971e+09 1.86e+01 4.64e+06 -1.0 2.13e+03 - 6.41e-02 1.00e+00f 1\n", + " 8 9.8333743e+08 5.43e-01 4.40e+06 -1.0 1.34e+02 - 7.30e-04 1.00e+00f 1\n", + " 9 3.6753899e+08 8.32e+02 1.39e+07 -1.0 2.13e+03 -1.4 1.80e-02 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 1.6993277e+07 9.18e+01 2.49e+06 -1.0 2.09e+03 - 8.49e-01 1.00e+00f 1\n", + " 11 4.7911844e+05 1.48e+01 1.42e+05 -1.0 6.73e+02 - 1.00e+00 1.00e+00f 1\n", + " 12 4.2816647e+05 1.06e-01 6.23e+02 -1.0 3.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 13 4.2816330e+05 2.92e-06 1.44e-02 -1.0 1.64e-01 - 1.00e+00 1.00e+00h 1\n", + " 14 4.2816330e+05 3.58e-12 1.88e-10 -2.5 2.55e-05 - 1.00e+00 1.00e+00h 1\n", + " 15 4.2816330e+05 4.18e-12 6.06e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 16 4.2816330e+05 5.09e-12 3.46e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00h 1\n", + " 17 4.2816330e+05 3.50e-12 5.36e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 17\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 5.3638619013303694e-12 1.0374938104246155e-09\n", + "Constraint violation....: 4.9127553950366949e-13 3.4958702599396933e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 19\n", + "Number of objective gradient evaluations = 18\n", + "Number of equality constraint evaluations = 19\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 18\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 17\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.011\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.50e+04 9.72e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.1140621e+07 5.69e+02 1.74e+04 -1.0 9.20e+03 - 9.48e-02 1.00e+00f 1\n", + " 2 2.7192445e+07 1.01e+01 6.77e+02 -1.0 6.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 3 2.7186294e+07 2.68e-03 2.93e-01 -1.0 3.18e-01 - 1.00e+00 1.00e+00f 1\n", + " 4 2.7186294e+07 1.79e-10 9.00e-08 -1.7 1.58e-04 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 5.57e-12 6.03e-10 -3.8 4.19e-06 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.69e-12 1.24e-09 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.12e-12 7.28e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 7\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 7.2797911218231232e-10 1.4080784272619497e-07\n", + "Constraint violation....: 5.4978276510060899e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 8\n", + "Number of objective gradient evaluations = 8\n", + "Number of equality constraint evaluations = 8\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 8\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 7\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.70e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.6387946e+09 1.63e+03 2.20e+04 -1.0 7.94e+03 - 2.58e-01 4.56e-02f 1\n", + " 2 4.6312518e+09 1.62e+03 2.19e+04 -1.0 8.01e+03 - 7.47e-01 8.57e-04f 1\n", + " 3 4.6299809e+09 1.62e+03 6.03e+06 -1.0 1.30e+03 - 1.00e+00 9.08e-04f 1\n", + " 4 3.4045767e+09 1.71e+02 8.63e+06 -1.0 1.24e+03 - 1.00e+00 1.00e+00f 1\n", + " 5 3.2357580e+09 1.04e-06 1.04e+07 -1.0 1.71e+02 0.0 3.67e-01 1.00e+00f 1\n", + " 6 3.2335364e+09 7.43e-03 1.67e+07 -1.0 5.07e+02 - 1.00e+00 1.34e-02f 1\n", + " 7 3.0814424e+09 4.30e+01 1.10e+07 -1.0 5.19e+02 - 1.00e+00 1.00e+00f 1\n", + " 8 3.0074467e+09 1.00e+00 2.28e+05 -1.0 1.35e+02 -0.5 1.00e+00 1.00e+00f 1\n", + " 9 2.8905662e+09 1.28e+01 3.92e+05 -1.0 3.38e+02 -1.0 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 2.4797474e+09 1.64e+02 1.29e+06 -1.0 1.31e+03 -1.4 1.00e+00 1.00e+00f 1\n", + " 11 2.7418252e+09 5.14e+01 1.73e+07 -1.0 8.37e+04 - 2.44e-01 2.23e-02H 1\n", + " 12 1.9145132e+09 1.64e+03 9.70e+06 -1.0 4.53e+03 -1.9 7.97e-01 1.00e+00f 1\n", + " 13 1.0117309e+09 5.41e+01 4.54e+06 -1.0 3.05e+03 - 3.70e-02 1.00e+00f 1\n", + " 14 9.9642132e+08 4.47e-01 4.35e+06 -1.0 8.39e+01 - 4.55e-04 1.00e+00f 1\n", + " 15 2.6824003e+08 1.38e+03 2.06e+07 -1.0 2.71e+03 -1.5 1.25e-03 1.00e+00f 1\n", + " 16 3.7706102e+06 2.82e+01 1.15e+06 -1.0 1.91e+03 - 1.00e+00 1.00e+00f 1\n", + " 17 4.3043555e+05 3.35e+00 2.95e+04 -1.0 2.95e+02 - 1.00e+00 1.00e+00f 1\n", + " 18 4.2816340e+05 4.89e-03 2.80e+01 -1.0 7.70e+00 - 1.00e+00 1.00e+00f 1\n", + " 19 4.2816330e+05 6.04e-09 2.94e-05 -1.0 7.38e-03 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 4.2816330e+05 3.69e-12 1.91e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 21 4.2816330e+05 4.18e-12 4.47e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 22 4.2816330e+05 1.88e-12 2.88e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00H 1\n", + " 23 4.2816330e+05 3.50e-12 6.44e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 23\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", + "Dual infeasibility......: 6.4351411026732109e-12 1.2447037574879725e-09\n", + "Constraint violation....: 3.8099280283971188e-13 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 26\n", + "Number of objective gradient evaluations = 24\n", + "Number of equality constraint evaluations = 26\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 24\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 23\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.015\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 5.14e+03 9.96e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 5.1361724e+05 1.16e+03 5.52e+03 -1.0 9.68e+03 - 7.33e-01 1.00e+00f 1\n", + " 2 4.2850802e+05 3.35e+01 5.98e+02 -1.0 3.02e+01 - 1.00e+00 1.00e+00f 1\n", + " 3 4.2816351e+05 3.18e-02 2.65e+00 -1.0 1.13e+00 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 2.81e-08 6.99e-06 -1.0 1.21e-03 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 3.47e-12 2.02e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 5.31e-12 1.01e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", + " 7 4.2816330e+05 3.04e-12 1.11e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 4.2816330e+05 3.50e-12 7.58e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.5828253298624225e-12 1.4666921874539710e-09\n", + "Constraint violation....: 8.0852985719428312e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 8.79e+03 9.90e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.3423860e+05 1.42e+02 3.82e+03 -1.0 9.65e+03 - 9.02e-01 1.00e+00f 1\n", + " 2 4.2817922e+05 8.43e-01 1.02e+02 -1.0 4.91e+00 - 1.00e+00 1.00e+00f 1\n", + " 3 4.2816330e+05 2.99e-05 1.09e-02 -1.0 4.22e-02 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 3.18e-12 1.14e-10 -2.5 2.42e-05 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 2.76e-12 2.30e-03 -3.8 7.13e-07 - 1.00e+00 5.00e-01h 2\n", + " 6 4.2816330e+05 3.69e-12 1.15e-03 -3.8 3.56e-07 - 1.00e+00 5.00e-01h 2\n", + " 7 4.2816330e+05 4.18e-12 2.30e-11 -5.7 2.18e-07 - 1.00e+00 1.00e+00H 1\n", + " 8 4.2816330e+05 3.50e-12 1.89e-11 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", + "Dual infeasibility......: 1.8948306952157019e-11 3.6650367855318503e-09\n", + "Constraint violation....: 5.8616380029777494e-14 3.4958702599396925e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 14\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 14\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 2.01e+03 1.03e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 3.1611112e+09 1.31e+04 1.30e+07 -1.0 5.97e+03 -2.0 8.06e-02 3.16e-01f 1\n", + " 2 1.7336542e+07 2.79e+03 2.12e+06 -1.0 7.56e+03 - 1.17e-02 1.00e+00f 1\n", + " 3 2.7661414e+07 1.95e+02 2.35e+05 -1.0 7.82e+02 - 8.45e-01 1.00e+00h 1\n", + " 4 2.7187779e+07 1.42e+00 3.85e+03 -1.0 6.38e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 2.7186293e+07 2.57e-04 9.05e-01 -1.0 1.01e+00 - 1.00e+00 1.00e+00f 1\n", + " 6 2.7186294e+07 1.00e-11 4.03e-08 -1.7 2.25e-04 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 3.52e-12 6.33e-10 -3.8 4.19e-06 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.69e-12 1.07e-09 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 2.7186294e+07 4.12e-12 7.17e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 7.1723805334492121e-10 1.3873027580404212e-07\n", + "Constraint violation....: 3.9907987116676576e-13 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.28e+03 9.77e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 8.7268227e+06 3.80e+03 3.76e+04 -1.0 9.35e+03 - 2.32e-01 1.00e+00f 1\n", + " 2 2.6617881e+07 3.09e+02 1.04e+04 -1.0 2.12e+02 - 7.03e-01 1.00e+00h 1\n", + " 3 2.7179492e+07 2.60e+00 1.35e+02 -1.0 1.25e+01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186293e+07 1.89e-04 3.26e-02 -1.0 1.05e-01 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 4.97e-12 8.21e-10 -2.5 2.46e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 3.75e-12 3.04e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 6.58e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 9.83e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027403e+05 2.7186293738994990e+07\n", + "Dual infeasibility......: 9.8263762867883811e-10 1.9006463559245624e-07\n", + "Constraint violation....: 1.0134854702842251e-13 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 4.05e+02 7.12e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2427232e+09 1.39e+03 1.78e+06 -1.0 6.75e+03 -2.0 2.33e-01 1.21e-01f 1\n", + " 2 4.2335006e+09 1.39e+03 1.77e+06 -1.0 1.56e+04 - 3.72e-01 7.80e-04f 1\n", + " 3 4.2319049e+09 1.39e+03 2.67e+06 -1.0 5.42e+03 - 7.99e-01 4.52e-04f 1\n", + " 4 2.4661840e+09 1.62e+03 1.40e+07 -1.0 5.45e+03 - 1.00e+00 8.02e-01f 1\n", + " 5 1.4734739e+09 1.44e+03 1.59e+07 -1.0 7.78e+03 - 2.47e-01 1.00e+00f 1\n", + " 6 9.7692393e+08 2.37e+02 5.76e+06 -1.0 2.22e+03 - 5.27e-03 1.00e+00f 1\n", + " 7 6.1520348e+08 7.93e+01 5.07e+06 -1.0 9.78e+02 - 5.43e-05 1.00e+00f 1\n", + " 8 1.7354679e+08 2.47e+03 1.42e+07 -1.0 1.01e+04 - 9.76e-02 5.00e-01f 2\n", + " 9 3.1087330e+07 3.84e+02 1.69e+06 -1.0 1.44e+03 - 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 2.7129946e+07 1.89e+01 7.70e+04 -1.0 3.15e+02 - 1.00e+00 1.00e+00f 1\n", + " 11 2.7186030e+07 6.02e-02 2.49e+02 -1.0 1.83e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 2.7186294e+07 6.36e-07 2.66e-03 -1.0 6.05e-02 - 1.00e+00 1.00e+00h 1\n", + " 13 2.7186294e+07 3.58e-12 1.12e-09 -2.5 2.04e-05 - 1.00e+00 1.00e+00h 1\n", + " 14 2.7186294e+07 4.41e-12 4.03e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 15 2.7186294e+07 4.69e-12 8.72e-11 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 16 2.7186294e+07 4.12e-12 5.21e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 16\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 5.2078719776239223e-10 1.0073217845016686e-07\n", + "Constraint violation....: 3.0797477427240214e-13 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 20\n", + "Number of objective gradient evaluations = 17\n", + "Number of equality constraint evaluations = 20\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 17\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 16\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.010\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 4.47e+03 9.77e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.8483214e+09 1.07e+03 1.08e+07 -1.0 3.06e+02 0.0 1.33e-01 1.00e+00f 1\n", + " 2 2.7753495e+09 2.82e+03 8.80e+06 -1.0 1.07e+04 - 3.66e-01 3.05e-01f 1\n", + " 3 2.6846467e+09 2.73e+03 8.51e+06 -1.0 5.59e+03 - 1.00e+00 3.18e-02f 1\n", + " 4 2.6837149e+09 2.72e+03 8.51e+06 -1.0 5.41e+03 - 1.00e+00 3.43e-04f 1\n", + " 5 2.6591967e+09 2.70e+03 8.42e+06 -1.0 4.45e+03 - 1.00e+00 1.08e-02f 1\n", + " 6 1.2784608e+09 1.22e+02 1.09e+07 -1.0 4.43e+03 - 1.00e+00 1.00e+00f 1\n", + " 7 1.1089604e+09 3.44e+02 6.21e+06 -1.0 3.45e+03 - 2.95e-01 1.00e+00f 1\n", + " 8 1.0049821e+09 2.85e+01 4.47e+06 -1.0 8.11e+02 - 5.20e-03 1.00e+00f 1\n", + " 9 3.7408506e+08 2.96e+03 1.10e+07 -1.0 4.03e+03 - 2.70e-05 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.0448479e+06 1.49e+02 9.10e+05 -1.0 2.54e+03 - 1.00e+00 1.00e+00f 1\n", + " 11 4.2998863e+05 4.45e+00 3.44e+04 -1.0 2.81e+02 - 1.00e+00 1.00e+00f 1\n", + " 12 4.2816332e+05 3.34e-03 2.10e+01 -1.0 6.77e+00 - 1.00e+00 1.00e+00f 1\n", + " 13 4.2816330e+05 1.51e-09 8.78e-06 -1.0 4.22e-03 - 1.00e+00 1.00e+00h 1\n", + " 14 4.2816330e+05 3.69e-12 2.07e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 15 4.2816330e+05 5.31e-12 2.82e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", + " 16 4.2816330e+05 3.04e-12 2.81e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 17 4.2816330e+05 3.50e-12 5.99e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 17\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 5.9912096017597981e-12 1.1588372320399661e-09\n", + "Constraint violation....: 1.1815048168495169e-12 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 19\n", + "Number of objective gradient evaluations = 18\n", + "Number of equality constraint evaluations = 19\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 18\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 17\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.010\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.25e+04 9.65e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.7174519e+07 6.12e+02 8.07e+03 -1.0 9.16e+03 - 6.72e-01 1.00e+00f 1\n", + " 2 2.7157675e+07 1.43e+01 5.15e+02 -1.0 1.08e+01 - 1.00e+00 1.00e+00f 1\n", + " 3 2.7186261e+07 8.71e-03 1.33e+00 -1.0 5.48e-01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186294e+07 3.15e-09 1.28e-06 -1.0 4.74e-04 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 3.52e-12 3.69e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.41e-12 8.31e-11 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 3.86e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 7.90e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 7.8999762948675547e-10 1.5280364519439663e-07\n", + "Constraint violation....: 4.7101559432420681e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 4.14e+03 9.57e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.4927485e+07 2.77e+03 5.05e+04 -1.0 9.14e+03 - 6.25e-01 1.00e+00f 1\n", + " 2 2.6826558e+07 1.63e+02 5.13e+03 -1.0 3.63e+01 - 8.14e-01 1.00e+00h 1\n", + " 3 2.7184194e+07 7.34e-01 6.95e+01 -1.0 5.26e+00 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186294e+07 1.49e-05 3.78e-03 -1.0 3.04e-02 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 2.47e-12 8.83e-10 -2.5 2.11e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.41e-12 6.32e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 2.33e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 8.30e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 8.2984251878098616e-10 1.6051055987271177e-07\n", + "Constraint violation....: 8.3214129700933826e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 2.01e+04 1.01e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 5.1232904e+06 2.26e+03 2.68e+04 -1.0 9.80e+03 - 1.37e-01 1.00e+00f 1\n", + " 2 4.4576929e+05 1.76e+02 6.61e+03 -1.0 2.13e+02 - 1.00e+00 1.00e+00f 1\n", + " 3 4.2819162e+05 1.33e+00 2.00e+02 -1.0 1.07e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 4.2816330e+05 7.39e-05 3.52e-02 -1.0 7.94e-02 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 3.84e-12 2.26e-10 -2.5 2.16e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 4.18e-12 1.33e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 1.88e-12 1.97e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00H 1\n", + " 8 4.2816330e+05 3.50e-12 8.34e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", + "Dual infeasibility......: 8.3365341010308284e-12 1.6124767358510909e-09\n", + "Constraint violation....: 6.5831840901751260e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 2.29e+04 9.88e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 7.8310154e+05 1.91e+03 9.41e+03 -1.0 9.72e+03 - 6.19e-02 1.00e+00f 1\n", + " 2 4.3005112e+05 8.54e+01 1.56e+03 -1.0 6.58e+01 - 1.00e+00 1.00e+00f 1\n", + " 3 4.2816476e+05 2.09e-01 6.47e+00 -1.0 3.77e+00 - 1.00e+00 1.00e+00f 1\n", + " 4 4.2816330e+05 1.24e-06 1.73e-04 -1.0 8.41e-03 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 3.92e-12 2.06e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 4.18e-12 2.30e-03 -3.8 7.13e-07 - 1.00e+00 5.00e-01h 2\n", + " 7 4.2816330e+05 3.69e-12 1.15e-03 -3.8 3.56e-07 - 1.00e+00 5.00e-01h 2\n", + " 8 4.2816330e+05 4.18e-12 2.66e-11 -5.7 2.18e-07 - 1.00e+00 1.00e+00H 1\n", + " 9 4.2816330e+05 3.50e-12 4.40e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", + "Dual infeasibility......: 4.3963917237901670e-12 8.5036290746094841e-10\n", + "Constraint violation....: 3.5289081297329319e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 15\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 15\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 4.99e+03 9.57e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.8459805e+07 9.05e+02 3.08e+03 -1.0 9.14e+03 - 8.90e-01 1.00e+00f 1\n", + " 2 2.7214552e+07 2.03e+01 2.33e+02 -1.0 1.11e+01 - 1.00e+00 1.00e+00f 1\n", + " 3 2.7186309e+07 1.13e-02 3.06e-01 -1.0 2.51e-01 - 1.00e+00 1.00e+00f 1\n", + " 4 2.7186294e+07 3.47e-09 1.40e-07 -1.7 1.44e-04 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 4.43e-12 5.75e-10 -3.8 4.19e-06 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.69e-12 6.00e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.12e-12 7.10e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 7\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 7.0996209573073779e-10 1.3732293886500667e-07\n", + "Constraint violation....: 6.4371955330339621e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 8\n", + "Number of objective gradient evaluations = 8\n", + "Number of equality constraint evaluations = 8\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 8\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 7\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.30e+04 9.67e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.6124087e+07 9.63e+02 1.22e+04 -1.0 9.18e+03 - 6.10e-01 1.00e+00f 1\n", + " 2 2.7077188e+07 3.41e+01 1.82e+03 -1.0 2.77e+01 - 1.00e+00 1.00e+00h 1\n", + " 3 2.7186081e+07 5.00e-02 9.45e+00 -1.0 1.70e+00 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186294e+07 1.02e-07 5.14e-05 -1.0 2.98e-03 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 2.67e-12 4.46e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.41e-12 3.04e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 5.16e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 5.64e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 5.6444294344749279e-10 1.0917620008437956e-07\n", + "Constraint violation....: 5.0470631526657618e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 4.15e+03 1.10e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.9476936e+09 1.04e+03 3.45e+05 -1.0 1.14e+02 0.0 5.04e-01 1.00e+00f 1\n", + " 2 3.7919093e+09 2.35e+03 8.76e+05 -1.0 6.79e+03 - 5.62e-01 4.46e-01f 1\n", + " 3 3.4291421e+09 5.47e+02 1.25e+07 -1.0 6.72e+02 -0.5 1.00e+00 1.00e+00f 1\n", + " 4 1.4862561e+09 1.08e+03 2.19e+07 -1.0 2.79e+03 - 7.85e-01 1.00e+00f 1\n", + " 5 1.0803970e+09 6.74e+03 3.96e+07 -1.0 1.93e+04 - 1.00e+00 5.85e-01f 1\n", + " 6 7.1117865e+07 1.32e+03 7.64e+06 -1.0 3.91e+03 - 1.70e-01 1.00e+00f 1\n", + " 7 1.2641918e+06 1.32e+02 7.40e+05 -1.0 1.21e+03 - 1.00e+00 1.00e+00f 1\n", + " 8 4.2836369e+05 1.99e+00 1.09e+04 -1.0 1.45e+02 - 1.00e+00 1.00e+00f 1\n", + " 9 4.2816330e+05 4.66e-04 2.53e+00 -1.0 2.20e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 4.2816330e+05 2.83e-11 1.37e-07 -1.0 5.11e-04 - 1.00e+00 1.00e+00h 1\n", + " 11 4.2816330e+05 4.92e-12 2.04e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 12 4.2816330e+05 5.31e-12 1.30e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", + " 13 4.2816330e+05 3.04e-12 1.29e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 14 4.2816330e+05 3.50e-12 1.17e-11 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 14\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 1.1672349337973593e-11 2.2576998464963993e-09\n", + "Constraint violation....: 7.6028072726330720e-13 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 16\n", + "Number of objective gradient evaluations = 15\n", + "Number of equality constraint evaluations = 16\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 15\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 14\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.009\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 4.57e+02 9.29e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.9537123e+09 3.20e+02 4.79e+05 -1.0 1.07e+02 0.0 6.34e-01 1.00e+00f 1\n", + " 2 4.7229788e+09 2.17e+02 2.38e+06 -1.0 2.42e+02 -0.5 7.40e-01 1.00e+00f 1\n", + " 3 4.6081291e+09 1.51e+01 1.98e+05 -1.0 8.20e+01 -0.1 1.00e+00 1.00e+00f 1\n", + " 4 3.3364039e+09 4.66e+03 3.38e+06 -1.0 1.97e+04 - 1.21e-01 1.01e-01f 1\n", + " 5 8.5294751e+08 1.47e+03 1.28e+07 -1.0 6.99e+03 - 1.00e+00 1.00e+00f 1\n", + " 6 1.7203645e+09 1.37e+03 8.91e+06 -1.0 2.40e+04 - 3.10e-01 9.05e-02H 1\n", + " 7 1.7200201e+09 1.35e+03 8.82e+06 -1.0 1.79e+02 -0.5 1.00e+00 1.03e-02f 1\n", + " 8 1.7199986e+09 1.35e+03 8.82e+06 -1.0 2.26e+02 -1.0 1.00e+00 1.29e-04f 1\n", + " 9 1.0216189e+09 7.78e+01 5.04e+06 -1.0 1.88e+03 - 1.92e-01 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.9725562e+08 3.93e+00 4.37e+06 -1.0 3.37e+02 - 2.74e-03 1.00e+00f 1\n", + " 11 2.7996079e+08 1.31e+03 1.96e+07 -1.0 2.64e+03 -1.5 1.29e-03 1.00e+00f 1\n", + " 12 4.8482859e+06 2.85e+01 1.31e+06 -1.0 1.93e+03 - 8.31e-01 1.00e+00f 1\n", + " 13 4.3209489e+05 4.39e+00 3.90e+04 -1.0 3.41e+02 - 1.00e+00 1.00e+00f 1\n", + " 14 4.2816348e+05 8.48e-03 4.87e+01 -1.0 1.02e+01 - 1.00e+00 1.00e+00f 1\n", + " 15 4.2816330e+05 1.82e-08 8.87e-05 -1.0 1.28e-02 - 1.00e+00 1.00e+00h 1\n", + " 16 4.2816330e+05 4.18e-12 2.22e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 17 4.2816330e+05 5.31e-12 1.01e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", + " 18 4.2816330e+05 3.04e-12 1.54e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 19 4.2816330e+05 3.50e-12 4.40e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 19\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 4.3995938736571737e-12 8.5098227662596132e-10\n", + "Constraint violation....: 4.6942418461511737e-13 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 22\n", + "Number of objective gradient evaluations = 20\n", + "Number of equality constraint evaluations = 22\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 20\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 19\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.013\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 8.99e+03 9.64e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.5839765e+07 3.16e+02 8.96e+03 -1.0 9.16e+03 - 6.70e-01 1.00e+00f 1\n", + " 2 2.7166753e+07 4.34e+00 8.37e+01 -1.0 1.51e+01 - 1.00e+00 1.00e+00h 1\n", + " 3 2.7186290e+07 8.47e-04 9.25e-02 -1.0 2.86e-01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186294e+07 3.28e-11 9.72e-09 -2.5 3.34e-05 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 5.43e-12 1.38e-09 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.69e-12 1.41e-09 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.12e-12 8.95e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 7\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 8.9532613730863700e-10 1.7317659232403083e-07\n", + "Constraint violation....: 5.0554756559712512e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 8\n", + "Number of objective gradient evaluations = 8\n", + "Number of equality constraint evaluations = 8\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 8\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 7\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 2.98e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.0130337e+09 1.42e+04 3.05e+06 -1.0 9.58e+03 - 2.26e-02 1.43e-01f 1\n", + " 2 2.0683948e+07 6.26e+02 4.78e+05 -1.0 8.07e+03 - 2.73e-02 1.00e+00f 1\n", + " 3 2.7200387e+07 8.95e+00 1.34e+04 -1.0 1.07e+02 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186293e+07 2.26e-03 2.41e+00 -1.0 3.61e+00 - 1.00e+00 1.00e+00f 1\n", + " 5 2.7186294e+07 4.02e-10 1.02e-06 -1.0 9.28e-04 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 3.18e-12 1.31e-09 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.41e-12 7.76e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.69e-12 3.74e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 2.7186294e+07 4.12e-12 8.08e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 8.0801464593843588e-10 1.5628854905560542e-07\n", + "Constraint violation....: 1.3908096331519524e-12 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.84e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.7575504e+06 9.13e+02 1.38e+04 -1.0 9.75e+03 - 4.47e-01 1.00e+00f 1\n", + " 2 4.2824668e+05 2.49e+01 1.18e+03 -1.0 1.05e+02 - 1.00e+00 1.00e+00f 1\n", + " 3 4.2816335e+05 1.64e-02 2.86e+00 -1.0 6.45e-01 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 6.88e-09 3.30e-06 -1.0 4.97e-04 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 3.58e-12 2.27e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 4.18e-12 1.86e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 1.88e-12 6.52e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00H 1\n", + " 8 4.2816330e+05 3.50e-12 8.34e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", + "Dual infeasibility......: 8.3365341010308284e-12 1.6124767358510909e-09\n", + "Constraint violation....: 7.9278799075454343e-14 3.4958702599396933e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 5.18e+03 9.94e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.4742544e+05 1.01e+03 5.01e+03 -1.0 9.66e+03 - 8.96e-01 1.00e+00f 1\n", + " 2 4.2822932e+05 2.50e+01 3.20e+02 -1.0 1.24e+01 - 1.00e+00 1.00e+00f 1\n", + " 3 4.2816333e+05 1.69e-02 4.70e-01 -1.0 3.08e-01 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 7.77e-09 5.77e-07 -1.7 1.95e-04 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.83e-12 6.32e-12 -3.8 5.28e-06 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 5.09e-12 5.58e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 3.50e-12 2.86e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 7\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 2.8627514714548167e-12 5.5372173763117912e-10\n", + "Constraint violation....: 7.8113496119784019e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 8\n", + "Number of objective gradient evaluations = 8\n", + "Number of equality constraint evaluations = 8\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 8\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 7\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.70e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.8345448e+09 1.66e+03 6.22e+02 -1.0 7.58e+03 - 3.85e-01 2.30e-02f 1\n", + " 2 4.8321364e+09 1.66e+03 6.32e+04 -1.0 7.40e+03 - 9.64e-01 2.63e-04f 1\n", + " 3 4.7840829e+09 1.64e+03 4.48e+06 -1.0 4.93e+03 - 1.00e+00 1.38e-02f 1\n", + " 4 2.5854958e+09 1.81e+03 2.34e+07 -1.0 5.10e+03 - 1.00e+00 1.00e+00f 1\n", + " 5 2.4006679e+09 2.48e+03 3.67e+07 -1.0 1.01e+04 - 2.59e-01 1.00e+00f 1\n", + " 6 1.0935406e+09 5.82e+02 7.41e+06 -1.0 3.94e+03 - 6.77e-03 1.00e+00f 1\n", + " 7 6.7957486e+08 5.18e+01 5.05e+06 -1.0 9.85e+02 - 8.72e-05 1.00e+00f 1\n", + " 8 2.6794664e+08 3.62e+03 1.93e+07 -1.0 2.03e+04 - 3.53e-02 2.81e-01f 2\n", + " 9 3.6194377e+07 6.17e+02 2.61e+06 -1.0 1.73e+03 - 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 2.7100647e+07 4.15e+01 1.63e+05 -1.0 4.49e+02 - 1.00e+00 1.00e+00f 1\n", + " 11 2.7185103e+07 2.75e-01 1.11e+03 -1.0 3.84e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 2.7186294e+07 1.30e-05 5.36e-02 -1.0 2.71e-01 - 1.00e+00 1.00e+00h 1\n", + " 13 2.7186294e+07 3.52e-12 3.60e-10 -2.5 1.90e-05 - 1.00e+00 1.00e+00h 1\n", + " 14 2.7186294e+07 4.41e-12 1.67e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 15 2.7186294e+07 4.69e-12 1.53e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 16 2.7186294e+07 4.12e-12 6.92e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 16\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 6.9159932411192459e-10 1.3377115803112010e-07\n", + "Constraint violation....: 1.6697754290362354e-13 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 20\n", + "Number of objective gradient evaluations = 17\n", + "Number of equality constraint evaluations = 20\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 17\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 16\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.009\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.40e+04 9.84e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 6.7882418e+06 2.02e+03 4.86e+04 -1.0 9.42e+03 - 1.15e-01 1.00e+00f 1\n", + " 2 2.7335745e+07 1.17e+02 1.07e+04 -1.0 2.72e+02 - 9.36e-01 1.00e+00h 1\n", + " 3 2.7186688e+07 3.81e-01 7.08e+01 -1.0 1.50e+00 - 1.00e+00 1.00e+00f 1\n", + " 4 2.7186294e+07 4.25e-06 1.56e-03 -1.0 8.68e-03 - 1.00e+00 1.00e+00f 1\n", + " 5 2.7186294e+07 4.12e-12 8.98e-10 -2.5 2.03e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.41e-12 1.60e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 8.78e-11 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 5.06e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 5.0623528253402496e-10 9.7917504572095877e-08\n", + "Constraint violation....: 8.9958290210069930e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 5.24e+02 1.06e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.8138975e+09 9.77e+03 5.01e+06 -1.0 1.59e+04 - 1.46e-01 1.92e-01f 1\n", + " 2 1.2458106e+07 2.49e+03 2.37e+06 -1.0 6.91e+03 - 1.10e-02 1.00e+00f 1\n", + " 3 5.9638509e+05 2.45e+02 2.68e+05 -1.0 5.41e+02 - 8.34e-01 1.00e+00f 1\n", + " 4 4.2833613e+05 3.87e+00 6.05e+03 -1.0 7.33e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 4.2816332e+05 1.27e-03 2.81e+00 -1.0 1.76e+00 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 1.69e-10 4.83e-07 -1.0 7.86e-04 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 3.38e-12 1.99e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 8 4.2816330e+05 4.18e-12 2.79e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 9 4.2816330e+05 5.09e-12 4.90e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 4.2816330e+05 3.50e-12 6.96e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 10\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 6.9554776294329938e-12 1.3453487658386204e-09\n", + "Constraint violation....: 4.1257311072239357e-13 3.4958702599396933e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 11\n", + "Number of objective gradient evaluations = 11\n", + "Number of equality constraint evaluations = 11\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 11\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 10\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 5.14e+03 1.01e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.2558366e+07 9.25e+03 1.72e+06 -1.0 9.81e+03 - 3.06e-01 1.00e+00f 1\n", + " 2 1.4246827e+06 1.46e+03 3.89e+05 -1.0 4.34e+02 - 2.34e-01 1.00e+00f 1\n", + " 3 4.3546419e+05 8.26e+01 3.35e+04 -1.0 1.54e+02 - 9.56e-01 1.00e+00f 1\n", + " 4 4.2817095e+05 3.63e-01 2.26e+02 -1.0 1.32e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 4.2816330e+05 7.79e-06 7.54e-03 -1.0 7.81e-02 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.69e-12 1.66e-10 -2.5 2.53e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 4.18e-12 4.88e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 8 4.2816330e+05 5.09e-12 4.37e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 4.2816330e+05 3.50e-12 1.42e-11 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 1.4181073467955190e-11 2.7429445833665322e-09\n", + "Constraint violation....: 1.7763568394002505e-13 3.4958702599396925e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.81e+04 9.66e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.9003335e+07 1.13e+03 1.55e+04 -1.0 9.14e+03 - 3.32e-01 1.00e+00f 1\n", + " 2 2.7238948e+07 3.20e+01 1.01e+03 -1.0 1.69e+01 - 1.00e+00 1.00e+00f 1\n", + " 3 2.7186331e+07 4.27e-02 2.05e+00 -1.0 5.65e-01 - 1.00e+00 1.00e+00f 1\n", + " 4 2.7186294e+07 7.75e-08 3.69e-06 -1.0 5.69e-04 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 3.21e-12 5.51e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.41e-12 1.76e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 2.40e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 8.01e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 8.0073868832425246e-10 1.5488121211656997e-07\n", + "Constraint violation....: 3.7925743719988039e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 3.55e+03 9.62e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.5339484e+08 1.19e+04 3.21e+05 -1.0 9.18e+03 - 2.52e-01 7.84e-01f 1\n", + " 2 2.2997591e+07 1.30e+03 4.50e+04 -1.0 1.97e+03 - 2.63e-02 1.00e+00f 1\n", + " 3 2.7064893e+07 4.24e+01 5.28e+03 -1.0 6.00e+01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186154e+07 4.87e-02 1.67e+01 -1.0 1.89e+00 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 5.94e-08 4.87e-05 -1.0 2.66e-03 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 2.79e-12 3.95e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.41e-12 1.99e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.69e-12 3.32e-11 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 2.7186294e+07 4.12e-12 5.94e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 5.9354677390422649e-10 1.1480554784052137e-07\n", + "Constraint violation....: 1.6765154534897615e-13 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.41e+04 1.01e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.9401960e+06 1.02e+03 1.97e+04 -1.0 9.77e+03 - 3.26e-01 1.00e+00f 1\n", + " 2 4.2927250e+05 4.60e+01 1.72e+03 -1.0 1.52e+02 - 1.00e+00 1.00e+00f 1\n", + " 3 4.2816494e+05 8.94e-02 1.45e+01 -1.0 1.80e+00 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 3.28e-07 1.56e-04 -1.0 4.73e-03 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 3.58e-12 2.16e-10 -2.5 2.58e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 5.31e-12 6.42e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", + " 7 4.2816330e+05 3.04e-12 1.36e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 4.2816330e+05 3.50e-12 6.22e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 6.2153811273360234e-12 1.2021971422198111e-09\n", + "Constraint violation....: 7.1908036628402804e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 1.12e+04 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.4982169e+05 6.60e+01 4.87e+03 -1.0 9.66e+03 - 7.20e-01 1.00e+00f 1\n", + " 2 4.2816538e+05 2.24e-01 6.53e+01 -1.0 1.30e+01 - 1.00e+00 1.00e+00f 1\n", + " 3 4.2816330e+05 1.71e-06 1.54e-03 -1.0 1.79e-02 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 3.64e-12 1.98e-10 -2.5 2.58e-05 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 4.18e-12 7.60e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 5.09e-12 3.60e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 7 4.2816330e+05 3.50e-12 3.49e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 7\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 3.4900991718842455e-12 6.7506515924652994e-10\n", + "Constraint violation....: 5.1473574040930074e-14 3.4958702599396925e-12\n", + "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 8\n", + "Number of objective gradient evaluations = 8\n", + "Number of equality constraint evaluations = 8\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 8\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 7\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 5.28e+03 9.78e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 1.9323923e+07 7.90e+03 4.80e+05 -1.0 9.33e+03 - 2.42e-01 1.00e+00f 1\n", + " 2 2.3574045e+07 1.13e+03 1.06e+05 -1.0 1.29e+02 - 6.53e-01 1.00e+00h 1\n", + " 3 2.6987010e+07 4.63e+01 1.05e+04 -1.0 5.24e+01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7185919e+07 8.56e-02 5.03e+01 -1.0 2.77e+00 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 2.43e-07 3.68e-04 -1.0 1.09e-02 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 3.52e-12 9.77e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.41e-12 3.25e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.69e-12 4.15e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 9 2.7186294e+07 4.12e-12 7.50e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 9\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", + "Dual infeasibility......: 7.4980698502496848e-10 1.4502985354332181e-07\n", + "Constraint violation....: 1.1133569257438686e-13 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 10\n", + "Number of objective gradient evaluations = 10\n", + "Number of equality constraint evaluations = 10\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 10\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 9\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + "Ipopt 3.13.2: bound_relax_factor=0\n", + "honor_original_bounds=no\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 2.18e+04 9.74e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 2.2432629e+07 2.91e+03 2.66e+04 -1.0 9.25e+03 - 1.74e-01 1.00e+00f 1\n", + " 2 2.6283816e+07 2.45e+02 8.03e+03 -1.0 8.73e+01 - 8.79e-01 1.00e+00h 1\n", + " 3 2.7175244e+07 2.54e+00 3.60e+02 -1.0 1.33e+01 - 1.00e+00 1.00e+00h 1\n", + " 4 2.7186293e+07 2.70e-04 1.09e-01 -1.0 1.57e-01 - 1.00e+00 1.00e+00h 1\n", + " 5 2.7186294e+07 5.40e-12 1.77e-09 -2.5 1.89e-05 - 1.00e+00 1.00e+00h 1\n", + " 6 2.7186294e+07 4.41e-12 1.55e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", + " 7 2.7186294e+07 4.69e-12 6.07e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", + " 8 2.7186294e+07 4.12e-12 9.83e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 8\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.4055363392027403e+05 2.7186293738994990e+07\n", + "Dual infeasibility......: 9.8263762867873223e-10 1.9006463559243576e-07\n", + "Constraint violation....: 5.4622972811557702e-14 4.1211478674085811e-12\n", + "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 9\n", + "Number of objective gradient evaluations = 9\n", + "Number of equality constraint evaluations = 9\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 9\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 8\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", + " run theta1_init theta2_init theta1_est theta2_est objective\n", + "0 0 0.904117 -1.570500 1.204754 -0.646637 2.718629e+07\n", + "1 1 1.646200 1.969240 1.204754 -0.646637 2.718629e+07\n", + "2 2 -0.500088 -0.410770 -1.500300 0.501315 4.281633e+05\n", + "3 3 -0.032914 1.388731 -1.500300 0.501315 4.281633e+05\n", + "4 4 1.175866 -0.947448 1.204754 -0.646637 2.718629e+07\n", + "5 5 0.434035 0.596308 1.204754 -0.646637 2.718629e+07\n", + "6 6 -1.290840 -1.037834 -1.500300 0.501315 4.281633e+05\n", + "7 7 -1.114986 1.637305 -1.500300 0.501315 4.281633e+05\n", + "8 8 0.218859 -0.196021 1.204754 -0.646637 2.718629e+07\n", + "9 9 1.477024 0.343782 1.204754 -0.646637 2.718629e+07\n", + "10 10 -0.372907 -1.785309 1.204754 -0.646637 2.718629e+07\n", + "11 11 -0.840302 0.764188 -1.500300 0.501315 4.281633e+05\n", + "12 12 1.947122 -1.322903 1.204754 -0.646637 2.718629e+07\n", + "13 13 0.689208 1.220790 1.204754 -0.646637 2.718629e+07\n", + "14 14 -1.582145 -0.662319 -1.500300 0.501315 4.281633e+05\n", + "15 15 -1.744031 1.077411 -1.500300 0.501315 4.281633e+05\n", + "16 16 0.605718 -0.511126 1.204754 -0.646637 2.718629e+07\n", + "17 17 1.847797 0.909993 1.204754 -0.646637 2.718629e+07\n", + "18 18 -0.985865 -1.476522 -1.500300 0.501315 4.281633e+05\n", + "19 19 -0.453270 0.450540 -1.500300 0.501315 4.281633e+05\n", + "20 20 1.317900 -1.884256 1.204754 -0.646637 2.718629e+07\n", + "21 21 0.076058 1.533004 -1.500300 0.501315 4.281633e+05\n", + "22 22 -1.211183 -0.099532 -1.500300 0.501315 4.281633e+05\n", + "23 23 -1.379087 0.702927 -1.500300 0.501315 4.281633e+05\n", + "24 24 0.267140 -1.136644 1.204754 -0.646637 2.718629e+07\n", + "25 25 1.025302 1.284538 1.204754 -0.646637 2.718629e+07\n", + "26 26 -0.137004 -0.851065 1.204754 -0.646637 2.718629e+07\n", + "27 27 -0.669836 1.826000 -1.500300 0.501315 4.281633e+05\n", + "28 28 1.554977 -0.259714 1.204754 -0.646637 2.718629e+07\n", + "29 29 0.797052 0.157482 1.204754 -0.646637 2.718629e+07\n", + "30 30 -1.911667 -1.724012 -1.500300 0.501315 4.281633e+05\n", + "31 31 -1.986316 1.915811 -1.500300 0.501315 4.281633e+05\n", + "32 32 0.848017 -0.482338 1.204754 -0.646637 2.718629e+07\n", + "33 33 1.605694 0.067732 1.204754 -0.646637 2.718629e+07\n", + "34 34 -0.743749 -1.501449 -1.500300 0.501315 4.281633e+05\n", + "35 35 -0.211159 0.542803 -1.500300 0.501315 4.281633e+05\n", + "36 36 1.075776 -1.109333 1.204754 -0.646637 2.718629e+07\n", + "37 37 0.318351 1.444601 1.204754 -0.646637 2.718629e+07\n", + "38 38 -1.453490 -0.878315 -1.500300 0.501315 4.281633e+05\n", + "39 39 -1.136904 0.290293 -1.500300 0.501315 4.281633e+05\n", + "40 40 0.024975 -1.856822 1.204754 -0.646637 2.718629e+07\n", + "41 41 1.267545 1.693189 1.204754 -0.646637 2.718629e+07\n", + "42 42 -0.379231 -0.126904 -1.500300 0.501315 4.281633e+05\n", + "43 43 -0.912072 1.167345 -1.500300 0.501315 4.281633e+05\n", + "44 44 1.797196 -0.733872 1.204754 -0.646637 2.718629e+07\n", + "45 45 0.554877 0.820121 1.204754 -0.646637 2.718629e+07\n", + "46 46 -1.669509 -1.253837 -1.500300 0.501315 4.281633e+05\n", + "47 47 -1.500417 0.979125 -1.500300 0.501315 4.281633e+05\n", + "48 48 0.646298 -1.420653 1.204754 -0.646637 2.718629e+07\n", + "49 49 1.903972 1.005914 1.204754 -0.646637 2.718629e+07\n", + "\n", + "Unique estimated theta_1 values:\n", + "[ 1.20475361 -1.50030035]\n", + "\n", + "Unique estimated theta_2 values:\n", + "[-0.64663711 0.5013147 -0.64663711]\n" + ] + } + ], + "source": [ + "\n", + "# Run parmest estimation for multiple random initial guesses of theta within bounds\n", + "\n", + "num_runs = 50 # Number of random initializations\n", + "theta_names = ['theta_1', 'theta_2']\n", + "theta1_bounds = (-2, 2)\n", + "theta2_bounds = (-2, 2)\n", + "\n", + "results = []\n", + "\n", + "for run in range(num_runs):\n", + " # Sobol sampling for initial values\n", + " if run == 0:\n", + " sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed = 12345)\n", + " sobol_samples = sampler.random(num_runs + 1)[1:]\n", + " sobol_theta1 = theta1_bounds[0] + (theta1_bounds[1] - theta1_bounds[0]) * sobol_samples[:, 0]\n", + " sobol_theta2 = theta2_bounds[0] + (theta2_bounds[1] - theta2_bounds[0]) * sobol_samples[:, 1]\n", + " theta1_init = sobol_theta1[run]\n", + " theta2_init = sobol_theta2[run]\n", + " theta_initial = {1: theta1_init, 2: theta2_init}\n", + " # Create experiment and estimator\n", + " exp = Simple_Multimodal(data_df, theta_initial=theta_initial)\n", + " pest = parmest.Estimator([exp], tee=True)\n", + " \n", + " # Estimate parameters\n", + " obj, theta, cov = pest.theta_est(calc_cov=True, cov_n=len(conc))\n", + " results.append({\n", + " 'run': run,\n", + " 'theta1_init': theta1_init,\n", + " 'theta2_init': theta2_init,\n", + " 'theta1_est': theta['theta_1'],\n", + " 'theta2_est': theta['theta_2'],\n", + " 'objective': obj\n", + " })\n", + "\n", + "# Convert results to DataFrame for inspection\n", + "random_init_results_df = pd.DataFrame(results)\n", + "print(random_init_results_df)\n", + "\n", + "# Print unique values of estimated parameters\n", + "print(\"\\nUnique estimated theta_1 values:\")\n", + "print(random_init_results_df['theta1_est'].unique())\n", + "print(\"\\nUnique estimated theta_2 values:\")\n", + "print(random_init_results_df['theta2_est'].unique())\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "44c57a03", + "metadata": {}, + "outputs": [], + "source": [ + "# # Print the model ef_instance from the Estimator\n", + "# ef_instance = pest.ef_instance\n", + "\n", + "# ef_instance.pprint()" + ] + }, + { + "cell_type": "markdown", + "id": "7301ae3c", + "metadata": {}, + "source": [ + "### Integrated Multistart test\n", + "\n", + "Now checking results against embedded feature version of multistart. Same settings" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "e6841131", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Starting multistart optimization with 50 restarts using sobol sampling method.\n", + "Setting theta_2 to -1.570499699562788\n", + "Current value of theta_1 is 0.9041174054145813\n", + "Current value of theta_2 is -1.570499699562788\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 1/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Applications/anaconda3/envs/parmest-dev-mac2/lib/python3.13/site-packages/scipy/stats/_qmc.py:993: UserWarning: The balance properties of Sobol' points require n to be a power of 2.\n", + " sample = self._random(n, workers=workers)\n", + "/Users/scini/Documents/GitHub/pyomo/pyomo/contrib/parmest/parmest.py:1208: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`\n", + " results_df.at[i, f'converged_{name}'] = converged_theta[j] if not np.isnan(converged_theta_vals[i, j]) else np.nan\n", + "/Users/scini/Documents/GitHub/pyomo/pyomo/contrib/parmest/parmest.py:1212: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value 'successful' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n", + " results_df.at[i, \"solver termination\"] = solver_termination if 'solver_termination' in locals() else np.nan\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Setting theta_2 to 1.9692404232919216\n", + "Current value of theta_1 is 1.6461998745799065\n", + "Current value of theta_2 is 1.9692404232919216\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 2/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.4107704162597656\n", + "Current value of theta_1 is -0.5000881142914295\n", + "Current value of theta_2 is -0.4107704162597656\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 3/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/scini/Documents/GitHub/pyomo/pyomo/contrib/parmest/parmest.py:1208: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`\n", + " results_df.at[i, f'converged_{name}'] = converged_theta[j] if not np.isnan(converged_theta_vals[i, j]) else np.nan\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Setting theta_2 to 1.3887314423918724\n", + "Current value of theta_1 is -0.03291422128677368\n", + "Current value of theta_2 is 1.3887314423918724\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 4/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.9474484585225582\n", + "Current value of theta_1 is 1.1758659072220325\n", + "Current value of theta_2 is -0.9474484585225582\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 5/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.5963075272738934\n", + "Current value of theta_1 is 0.4340350441634655\n", + "Current value of theta_2 is 0.5963075272738934\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 6/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.03783418238163\n", + "Current value of theta_1 is -1.2908396199345589\n", + "Current value of theta_2 is -1.03783418238163\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 7/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.637305174022913\n", + "Current value of theta_1 is -1.114986129105091\n", + "Current value of theta_2 is 1.637305174022913\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 8/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.19602123647928238\n", + "Current value of theta_1 is 0.21885917708277702\n", + "Current value of theta_2 is -0.19602123647928238\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 9/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.34378181397914886\n", + "Current value of theta_1 is 1.4770240969955921\n", + "Current value of theta_2 is 0.34378181397914886\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 10/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.7853094227612019\n", + "Current value of theta_1 is -0.37290745973587036\n", + "Current value of theta_2 is -1.7853094227612019\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 11/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.764187891036272\n", + "Current value of theta_1 is -0.8403021283447742\n", + "Current value of theta_2 is 0.764187891036272\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 12/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.3229034766554832\n", + "Current value of theta_1 is 1.9471220299601555\n", + "Current value of theta_2 is -1.3229034766554832\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 13/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.2207895517349243\n", + "Current value of theta_1 is 0.6892080903053284\n", + "Current value of theta_2 is 1.2207895517349243\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 14/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.6623185910284519\n", + "Current value of theta_1 is -1.5821445994079113\n", + "Current value of theta_2 is -0.6623185910284519\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 15/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.077410764992237\n", + "Current value of theta_1 is -1.7440308779478073\n", + "Current value of theta_2 is 1.077410764992237\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 16/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.5111263506114483\n", + "Current value of theta_1 is 0.6057177819311619\n", + "Current value of theta_2 is -0.5111263506114483\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 17/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.909992840141058\n", + "Current value of theta_1 is 1.84779679402709\n", + "Current value of theta_2 is 0.909992840141058\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 18/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.4765218794345856\n", + "Current value of theta_1 is -0.9858651980757713\n", + "Current value of theta_2 is -1.4765218794345856\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 19/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.4505395218729973\n", + "Current value of theta_1 is -0.45326995477080345\n", + "Current value of theta_2 is 0.4505395218729973\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 20/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.8842555843293667\n", + "Current value of theta_1 is 1.3178998976945877\n", + "Current value of theta_2 is -1.8842555843293667\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 21/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.5330041460692883\n", + "Current value of theta_1 is 0.07605770975351334\n", + "Current value of theta_2 is 1.5330041460692883\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 22/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.09953175485134125\n", + "Current value of theta_1 is -1.211183074861765\n", + "Current value of theta_2 is -0.09953175485134125\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 23/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.7029270566999912\n", + "Current value of theta_1 is -1.3790867365896702\n", + "Current value of theta_2 is 0.7029270566999912\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 24/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.136644072830677\n", + "Current value of theta_1 is 0.2671399489045143\n", + "Current value of theta_2 is -1.136644072830677\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 25/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.2845380455255508\n", + "Current value of theta_1 is 1.0253018885850906\n", + "Current value of theta_2 is 1.2845380455255508\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 26/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.8510647006332874\n", + "Current value of theta_1 is -0.13700413331389427\n", + "Current value of theta_2 is -0.8510647006332874\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 27/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.8259997852146626\n", + "Current value of theta_1 is -0.6698363646864891\n", + "Current value of theta_2 is 1.8259997852146626\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 28/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.25971441715955734\n", + "Current value of theta_1 is 1.5549770556390285\n", + "Current value of theta_2 is -0.25971441715955734\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 29/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.1574823558330536\n", + "Current value of theta_1 is 0.7970522679388523\n", + "Current value of theta_2 is 0.1574823558330536\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 30/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.7240123488008976\n", + "Current value of theta_1 is -1.9116670340299606\n", + "Current value of theta_2 is -1.7240123488008976\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 31/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.9158114604651928\n", + "Current value of theta_1 is -1.9863164275884628\n", + "Current value of theta_2 is 1.9158114604651928\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 32/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.4823381155729294\n", + "Current value of theta_1 is 0.8480171598494053\n", + "Current value of theta_2 is -0.4823381155729294\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 33/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.06773220747709274\n", + "Current value of theta_1 is 1.6056938730180264\n", + "Current value of theta_2 is 0.06773220747709274\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 34/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.5014492236077785\n", + "Current value of theta_1 is -0.7437494024634361\n", + "Current value of theta_2 is -1.5014492236077785\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 35/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.5428028963506222\n", + "Current value of theta_1 is -0.21115940436720848\n", + "Current value of theta_2 is 0.5428028963506222\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 36/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.1093328893184662\n", + "Current value of theta_1 is 1.0757764726877213\n", + "Current value of theta_2 is -1.1093328893184662\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 37/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.4446007087826729\n", + "Current value of theta_1 is 0.3183508887887001\n", + "Current value of theta_2 is 1.4446007087826729\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 38/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.8783153407275677\n", + "Current value of theta_1 is -1.4534900821745396\n", + "Current value of theta_2 is -0.8783153407275677\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 39/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.29029324650764465\n", + "Current value of theta_1 is -1.1369038261473179\n", + "Current value of theta_2 is 0.29029324650764465\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 40/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.8568222858011723\n", + "Current value of theta_1 is 0.024974681437015533\n", + "Current value of theta_2 is -1.8568222858011723\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 41/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.6931888945400715\n", + "Current value of theta_1 is 1.2675453573465347\n", + "Current value of theta_2 is 1.6931888945400715\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 42/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.12690448015928268\n", + "Current value of theta_1 is -0.37923091277480125\n", + "Current value of theta_2 is -0.12690448015928268\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 43/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.1673445254564285\n", + "Current value of theta_1 is -0.912072204053402\n", + "Current value of theta_2 is 1.1673445254564285\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 44/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -0.7338721342384815\n", + "Current value of theta_1 is 1.7971962057054043\n", + "Current value of theta_2 is -0.7338721342384815\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 45/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.8201205767691135\n", + "Current value of theta_1 is 0.5548769868910313\n", + "Current value of theta_2 is 0.8201205767691135\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 46/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.253836639225483\n", + "Current value of theta_1 is -1.669509395956993\n", + "Current value of theta_2 is -1.253836639225483\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 47/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 0.9791254512965679\n", + "Current value of theta_1 is -1.500417035073042\n", + "Current value of theta_2 is 0.9791254512965679\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 48/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to -1.420653060078621\n", + "Current value of theta_1 is 0.6462979316711426\n", + "Current value of theta_2 is -1.420653060078621\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 49/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "Setting theta_2 to 1.0059135183691978\n", + "Current value of theta_1 is 1.9039716646075249\n", + "Current value of theta_2 is 1.0059135183691978\n", + "Ipopt 3.13.2: \n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma27.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 3000\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 1003\n", + "\n", + "Total number of variables............................: 1002\n", + " variables with only lower bounds: 0\n", + " variables with lower and upper bounds: 2\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 1000\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", + " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", + " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", + " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", + " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", + "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", + "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", + "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Restart 50/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", + "theta_2 0.501315\n", + "dtype: float64\n", + "\n", + "\n", + "Results DataFrame:\n", + " theta_1 theta_2 converged_theta_1 converged_theta_2 \\\n", + "0 0.904117 -1.570500 -1.5003 0.501315 \n", + "1 1.646200 1.969240 -1.5003 0.501315 \n", + "2 -0.500088 -0.410770 -1.5003 0.501315 \n", + "3 -0.032914 1.388731 -1.5003 0.501315 \n", + "4 1.175866 -0.947448 -1.5003 0.501315 \n", + "5 0.434035 0.596308 -1.5003 0.501315 \n", + "6 -1.290840 -1.037834 -1.5003 0.501315 \n", + "7 -1.114986 1.637305 -1.5003 0.501315 \n", + "8 0.218859 -0.196021 -1.5003 0.501315 \n", + "9 1.477024 0.343782 -1.5003 0.501315 \n", + "10 -0.372907 -1.785309 -1.5003 0.501315 \n", + "11 -0.840302 0.764188 -1.5003 0.501315 \n", + "12 1.947122 -1.322903 -1.5003 0.501315 \n", + "13 0.689208 1.220790 -1.5003 0.501315 \n", + "14 -1.582145 -0.662319 -1.5003 0.501315 \n", + "15 -1.744031 1.077411 -1.5003 0.501315 \n", + "16 0.605718 -0.511126 -1.5003 0.501315 \n", + "17 1.847797 0.909993 -1.5003 0.501315 \n", + "18 -0.985865 -1.476522 -1.5003 0.501315 \n", + "19 -0.453270 0.450540 -1.5003 0.501315 \n", + "20 1.317900 -1.884256 -1.5003 0.501315 \n", + "21 0.076058 1.533004 -1.5003 0.501315 \n", + "22 -1.211183 -0.099532 -1.5003 0.501315 \n", + "23 -1.379087 0.702927 -1.5003 0.501315 \n", + "24 0.267140 -1.136644 -1.5003 0.501315 \n", + "25 1.025302 1.284538 -1.5003 0.501315 \n", + "26 -0.137004 -0.851065 -1.5003 0.501315 \n", + "27 -0.669836 1.826000 -1.5003 0.501315 \n", + "28 1.554977 -0.259714 -1.5003 0.501315 \n", + "29 0.797052 0.157482 -1.5003 0.501315 \n", + "30 -1.911667 -1.724012 -1.5003 0.501315 \n", + "31 -1.986316 1.915811 -1.5003 0.501315 \n", + "32 0.848017 -0.482338 -1.5003 0.501315 \n", + "33 1.605694 0.067732 -1.5003 0.501315 \n", + "34 -0.743749 -1.501449 -1.5003 0.501315 \n", + "35 -0.211159 0.542803 -1.5003 0.501315 \n", + "36 1.075776 -1.109333 -1.5003 0.501315 \n", + "37 0.318351 1.444601 -1.5003 0.501315 \n", + "38 -1.453490 -0.878315 -1.5003 0.501315 \n", + "39 -1.136904 0.290293 -1.5003 0.501315 \n", + "40 0.024975 -1.856822 -1.5003 0.501315 \n", + "41 1.267545 1.693189 -1.5003 0.501315 \n", + "42 -0.379231 -0.126904 -1.5003 0.501315 \n", + "43 -0.912072 1.167345 -1.5003 0.501315 \n", + "44 1.797196 -0.733872 -1.5003 0.501315 \n", + "45 0.554877 0.820121 -1.5003 0.501315 \n", + "46 -1.669509 -1.253837 -1.5003 0.501315 \n", + "47 -1.500417 0.979125 -1.5003 0.501315 \n", + "48 0.646298 -1.420653 -1.5003 0.501315 \n", + "49 1.903972 1.005914 -1.5003 0.501315 \n", + "\n", + " initial objective final objective solver termination solve_time \n", + "0 7.220190e+08 428163.296519 successful NaN \n", + "1 1.136218e+10 428163.296519 successful NaN \n", + "2 4.193775e+09 428163.296519 successful NaN \n", + "3 4.072387e+09 428163.296519 successful NaN \n", + "4 8.684940e+07 428163.296519 successful NaN \n", + "5 3.426209e+09 428163.296519 successful NaN \n", + "6 1.655079e+09 428163.296519 successful NaN \n", + "7 9.394389e+08 428163.296519 successful NaN \n", + "8 4.087402e+09 428163.296519 successful NaN \n", + "9 1.685132e+09 428163.296519 successful NaN \n", + "10 3.826184e+09 428163.296519 successful NaN \n", + "11 2.305593e+09 428163.296519 successful NaN \n", + "12 1.052740e+10 428163.296519 successful NaN \n", + "13 2.766225e+09 428163.296519 successful NaN \n", + "14 1.074960e+09 428163.296519 successful NaN \n", + "15 1.255159e+09 428163.296519 successful NaN \n", + "16 2.216156e+09 428163.296519 successful NaN \n", + "17 9.265699e+09 428163.296519 successful NaN \n", + "18 2.791493e+09 428163.296519 successful NaN \n", + "19 4.117223e+09 428163.296519 successful NaN \n", + "20 1.783957e+09 428163.296519 successful NaN \n", + "21 3.932326e+09 428163.296519 successful NaN \n", + "22 9.345576e+08 428163.296519 successful NaN \n", + "23 1.248299e+08 428163.296519 successful NaN \n", + "24 3.404587e+09 428163.296519 successful NaN \n", + "25 2.374101e+09 428163.296519 successful NaN \n", + "26 4.522286e+09 428163.296519 successful NaN \n", + "27 2.285725e+09 428163.296519 successful NaN \n", + "28 1.544874e+09 428163.296519 successful NaN \n", + "29 1.609095e+09 428163.296519 successful NaN \n", + "30 7.979763e+09 428163.296519 successful NaN \n", + "31 7.531637e+09 428163.296519 successful NaN \n", + "32 1.022801e+09 428163.296519 successful NaN \n", + "33 2.387392e+09 428163.296519 successful NaN \n", + "34 3.402058e+09 428163.296519 successful NaN \n", + "35 4.564792e+09 428163.296519 successful NaN \n", + "36 2.227816e+08 428163.296519 successful NaN \n", + "37 3.700507e+09 428163.296519 successful NaN \n", + "38 1.293657e+09 428163.296519 successful NaN \n", + "39 1.049181e+09 428163.296519 successful NaN \n", + "40 3.409571e+09 428163.296519 successful NaN \n", + "41 4.407327e+09 428163.296519 successful NaN \n", + "42 4.488860e+09 428163.296519 successful NaN \n", + "43 1.760318e+09 428163.296519 successful NaN \n", + "44 5.155549e+09 428163.296519 successful NaN \n", + "45 3.009035e+09 428163.296519 successful NaN \n", + "46 2.948710e+09 428163.296519 successful NaN \n", + "47 1.650676e+08 428163.296519 successful NaN \n", + "48 1.612714e+09 428163.296519 successful NaN \n", + "49 1.129338e+10 428163.296519 successful NaN \n", + "\n", + "Unique converged_theta_1 values: [-1.50030035]\n", + "Unique converged_theta_2 values: [0.5013147]\n" + ] + } + ], + "source": [ + "exp_list = [] \n", + "conc = data_df[\"x\"].values # substrate concentration (control variable)\n", + "vel = data_df[\"y\"].values # reaction velocity (output variable)\n", + "n_exp = 1\n", + "\n", + "# exp_list to separate each experiment\n", + "# for i in range(n_exp):\n", + "exp_list.append(Simple_Multimodal(data_df))\n", + "\n", + "# Creating an Estimator object\n", + "pest = parmest.Estimator(exp_list, tee = True) \n", + "\n", + "# obj, theta = pest.theta_est()\n", + "results_df = pest.theta_est_multistart(multistart_sampling_method=\"sobol\", n_restarts=50, seed = 12345)\n", + "\n", + "print(\"\\n\\nResults DataFrame:\")\n", + "print(results_df)\n", + "\n", + "# # Print unique parameter values\n", + "print(\"\\nUnique converged_theta_1 values:\", results_df['converged_theta_1'].unique())\n", + "print(\"Unique converged_theta_2 values:\", results_df['converged_theta_2'].unique())" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "parmest-dev-mac2", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 1695519b623cbf5bf6d1860be89362401e017012 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 5 Jun 2025 08:18:16 -0400 Subject: [PATCH 14/32] New features Thursday morning --- pyomo/contrib/parmest/parmest.py | 85 ++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 4aa5eb81016..b6f371a9b70 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -65,6 +65,10 @@ import pyomo.contrib.parmest.graphics as graphics from pyomo.dae import ContinuousSet +# Add imports for HierchicalTimer +import time +from pyomo.common.timing import TicTocTimer + from pyomo.common.deprecation import deprecated from pyomo.common.deprecation import deprecation_warning @@ -209,7 +213,10 @@ def _experiment_instance_creation_callback( scen_model=instance, ) ] - + # @Reviewers, here is where the parmest model is made for each run + # This is the only way I see to pass the theta values to the model + # Can we add an optional argument to fix them or not? + # Curently, thetavals provided are fixed if not None if "ThetaVals" in outer_cb_data: thetavals = outer_cb_data["ThetaVals"] @@ -1088,28 +1095,34 @@ def theta_est_multistart( ---------- n_restarts: int, optional Number of restarts for multistart. Default is 1. - th_sampling_method: string, optional - Method used to sample theta values. Options are "uniform", "latin_hypercube", or "sobol". + multistart_sampling_method: string, optional + Method used to sample theta values. Options are "uniform", "latin_hypercube", "sobol", or "user_provided". Default is "uniform". buffer: int, optional Number of iterations to save results dynamically. Default is 10. - user_provided: pd.DataFrame, optional - User provided dataframe of theta values for multistart optimization. + user_provided: pd.DataFrame or np.ndarray, optional + User provided array or dataframe of theta values for multistart optimization. + seed: int, optional + Random seed for reproducibility. + save_results: bool, optional + If True, intermediate and final results are saved to file_name. + theta_vals: pd.DataFrame, optional + Initial theta values for restarts (overrides sampling). solver: string, optional Currently only "ef_ipopt" is supported. Default is "ef_ipopt". + file_name: str, optional + File name for saving results if save_results is True. return_values: list, optional - List of Variable names, used to return values from the model for data reconciliation - + List of Variable names, used to return values from the model for data reconciliation. Returns ------- - objectiveval: float - The objective function value - thetavals: pd.Series - Estimated values for theta - variable values: pd.DataFrame - Variable values for each variable name in return_values (only for solver='ef_ipopt') - + results_df: pd.DataFrame + DataFrame containing initial and converged theta values, objectives, and solver info for each restart. + best_theta: dict + Dictionary of theta values corresponding to the best (lowest) objective value found. + best_objectiveval: float + The best (lowest) objective function value found across all restarts. """ # check if we are using deprecated parmest @@ -1144,24 +1157,32 @@ def theta_est_multistart( theta_vals = results_df.iloc[:, :len(theta_names)] converged_theta_vals = np.zeros((n_restarts, len(theta_names))) + timer = TicTocTimer() + # Each restart uses a fresh model instance for i in range(n_restarts): - # Create a fresh model for each restart - parmest_model = self._create_parmest_model(experiment_number=0) + + # Add a timer for each restart + timer.tic(f"Restart {i+1}/{n_restarts}") + + # No longer needed, keeping until confirming update works as expected + # # Create a fresh model for each restart + # parmest_model = self._create_parmest_model(experiment_number=0) theta_vals_current = theta_vals.iloc[i, :].to_dict() - # Set current theta values in the model - for name, value in theta_vals_current.items(): - parmest_model.find_component(name).set_value(value) + # # Set current theta values in the model + # for name, value in theta_vals_current.items(): + # parmest_model.find_component(name).set_value(value) - # Optional: Print the current theta values being set - print(f"Setting {name} to {value}") - for name in theta_names: - current_value = parmest_model.find_component(name)() - print(f"Current value of {name} is {current_value}") + # # Optional: Print the current theta values being set + # print(f"Setting {name} to {value}") + # for name in theta_names: + # current_value = parmest_model.find_component(name)() + # print(f"Current value of {name} is {current_value}") # Call the _Q_opt method with the generated theta values qopt_result = self._Q_opt( + ThetaVals=theta_vals_current, bootlist=None, solver=solver, return_values=return_values, @@ -1177,7 +1198,6 @@ def theta_est_multistart( if converged_theta.isnull().any(): solver_termination = "not successful" solve_time = np.nan - thetavals = np.nan final_objectiveval = np.nan init_objectiveval = np.nan else: @@ -1194,14 +1214,17 @@ def theta_est_multistart( # # Check if the objective value is better than the best objective value # # Set a very high initial best objective value - # best_objectiveval = np.inf - # best_theta = np.inf - # if final_objectiveval < best_objectiveval: - # best_objectiveval = objectiveval - # best_theta = thetavals + best_objectiveval = np.inf + best_theta = np.inf + if final_objectiveval < best_objectiveval: + best_objectiveval = objectiveval + best_theta = theta_vals_current print(f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}") + # Stop the timer for this restart + solve_time = timer.toc(f"Restart {i+1}/{n_restarts}") + # Store the results in the DataFrame for this restart # Fill converged theta values for j, name in enumerate(theta_names): @@ -1229,7 +1252,7 @@ def theta_est_multistart( results_df.to_csv(file_name, mode='a', header=False, index=False) print("Final results saved.") - return results_df # just this for now, then best_theta, best_objectiveval + return results_df, best_theta, best_objectiveval From 063401472127293441e7169d72aecb5049bfcb61 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 5 Jun 2025 10:41:11 -0400 Subject: [PATCH 15/32] First successful running multistart feature, before Alex recommended changes --- pyomo/contrib/parmest/experiment.py | 8 ++++++++ pyomo/contrib/parmest/parmest.py | 25 ++++++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/pyomo/contrib/parmest/experiment.py b/pyomo/contrib/parmest/experiment.py index 67a8be71f66..16411858095 100644 --- a/pyomo/contrib/parmest/experiment.py +++ b/pyomo/contrib/parmest/experiment.py @@ -29,3 +29,11 @@ def __init__(self, model=None): def get_labeled_model(self): return self.model + + def reinitialize_unknown_parameters(self): + raise NotImplementedError( + "The reinitialize_unknown_parameters method should implemented in the subclass." \ + "Thi method will take new values for the unknown parameters from the Suffix " + "and allow users to reinitialize the model." + ) + diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index b6f371a9b70..2764983942a 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -91,7 +91,7 @@ def ef_nonants(ef): def _experiment_instance_creation_callback( - scenario_name, node_names=None, cb_data=None + scenario_name, node_names=None, cb_data=None, fix_vars=False, ): """ This is going to be called by mpi-sppy or the local EF and it will call into @@ -107,6 +107,8 @@ def _experiment_instance_creation_callback( that is the "callback" value. "BootList" is None or bootstrap experiment number list. (called cb_data by mpisppy) + fix_vars: `bool` If True, the theta variables are fixed to the values + provided in the cb_data["ThetaVals"] dictionary. Returns: @@ -217,6 +219,7 @@ def _experiment_instance_creation_callback( # This is the only way I see to pass the theta values to the model # Can we add an optional argument to fix them or not? # Curently, thetavals provided are fixed if not None + # Suggested fix in this function and _Q_at_theta if "ThetaVals" in outer_cb_data: thetavals = outer_cb_data["ThetaVals"] @@ -224,9 +227,14 @@ def _experiment_instance_creation_callback( for name, val in thetavals.items(): theta_cuid = ComponentUID(name) theta_object = theta_cuid.find_component_on(instance) - if val is not None: + if val is not None and fix_vars is True: # print("Fixing",vstr,"at",str(thetavals[vstr])) theta_object.fix(val) + # ADDED OPTION: Set initial value, but do not fix + elif val is not None and fix_vars is False: + # print("Setting",vstr,"to",str(thetavals[vstr])) + theta_object.set_value(val) + theta_object.unfix() else: # print("Freeing",vstr) theta_object.unfix() @@ -829,7 +837,7 @@ def _Q_at_theta(self, thetavals, initialize_parmest_model=False): # start block of code to deal with models with no constraints # (ipopt will crash or complain on such problems without special care) - instance = _experiment_instance_creation_callback("FOO0", None, dummy_cb) + instance = _experiment_instance_creation_callback("FOO0", None, dummy_cb,) try: # deal with special problems so Ipopt will not crash first = next(instance.component_objects(pyo.Constraint, active=True)) active_constraints = True @@ -846,7 +854,7 @@ def _Q_at_theta(self, thetavals, initialize_parmest_model=False): for snum in scenario_numbers: sname = "scenario_NODE" + str(snum) - instance = _experiment_instance_creation_callback(sname, None, dummy_cb) + instance = _experiment_instance_creation_callback(sname, None, dummy_cb, fix_vars=True) model_theta_names = self._expand_indexed_unknowns(instance) if initialize_parmest_model: @@ -1214,11 +1222,14 @@ def theta_est_multistart( # # Check if the objective value is better than the best objective value # # Set a very high initial best objective value - best_objectiveval = np.inf - best_theta = np.inf + if i == 0: + # Initialize best objective value and theta + best_objectiveval = np.inf + best_theta = np.inf + # Check if the final objective value is better than the best found so far if final_objectiveval < best_objectiveval: best_objectiveval = objectiveval - best_theta = theta_vals_current + best_theta = converged_theta.values print(f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}") From 06e0a7289a12b601e2bad95f7eaba7ee9810f07c Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Tue, 24 Jun 2025 09:33:44 -0400 Subject: [PATCH 16/32] Ran black, removed temp example --- .../Simple_Multimodal_Multistart.ipynb | 8231 ----------------- .../reactor_design/multistart_example.py | 7 +- pyomo/contrib/parmest/experiment.py | 3 +- pyomo/contrib/parmest/parmest.py | 149 +- 4 files changed, 98 insertions(+), 8292 deletions(-) delete mode 100644 pyomo/contrib/parmest/examples/Simple_Multimodal_Multistart.ipynb diff --git a/pyomo/contrib/parmest/examples/Simple_Multimodal_Multistart.ipynb b/pyomo/contrib/parmest/examples/Simple_Multimodal_Multistart.ipynb deleted file mode 100644 index 0c2a2eb2062..00000000000 --- a/pyomo/contrib/parmest/examples/Simple_Multimodal_Multistart.ipynb +++ /dev/null @@ -1,8231 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "d3d4744d-5ea5-45d6-8e8b-aefc5d8b8118", - "metadata": {}, - "source": [ - "This example is created by Stephen Cini, inspired by example in Montana's manuscript and advice from Dr. Alex Dowling. Purpose is to test multistart function's ability to find local minima.\n", - "\n", - "**Equation:** \n", - " $$f(x, \\theta) = (\\theta_1 x^3 - \\theta_2 x^2 + 2x - 1)^2 + (\\theta_1 - \\theta_2)^2 + (x^2 - 1)^2$$ \n", - "$\\qquad f(x, \\theta)\\rightarrow$ (response / output variable) \n", - "$\\qquad \\theta_1, \\theta_2 \\rightarrow$ parameters \n", - "$\\qquad x\\rightarrow$ (control / decision variable) \n", - "\n", - "**Data:** \n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
SubstrateVelocity
Concentration(counts/min2)
(ppm)(a) Treated(b) Untreated
0.0276
47
67
51
0.0697
107
84
86
0.11123
139
98
115
0.22159
152
131
124
0.56191
201
144
158
1.10207
200
160
\n", - "\n", - "[Find data or remove table]" - ] - }, - { - "cell_type": "markdown", - "id": "7f241a55-464a-41f6-9bc2-28f7467c2234", - "metadata": {}, - "source": [ - "# Importing packages" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "2a458e95", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Pyomo version after reload:\n", - "6.9.3.dev0\n", - "pyomo.__file__: /Users/scini/Documents/GitHub/pyomo/pyomo/__init__.py\n" - ] - } - ], - "source": [ - "# Get version of pyomo\n", - "\n", - "# Force reload of pyomo module to ensure we get the latest version\n", - "import importlib\n", - "import pyomo # your .py file without the .py extension\n", - "importlib.reload(pyomo)\n", - "print(\"Pyomo version after reload:\")\n", - "print(pyomo.__version__)\n", - "print(\"pyomo.__file__:\", pyomo.__file__)\n", - "\n", - "import pyomo.environ as pyo\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f6c3dd5b-0200-4262-9315-de03690bec0b", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import scipy\n", - "import seaborn as sns # This package is only needed for pairplot\n", - "import matplotlib.pyplot as plt\n", - "import pyomo.environ as pyo\n", - "import pyomo.contrib.parmest.parmest as parmest # import parmest\n", - "import pyomo.contrib.parmest.experiment as experiment\n", - "import pyomo.contrib.doe as doe\n", - "import pandas as pd\n", - "from itertools import product\n", - "import idaes" - ] - }, - { - "cell_type": "markdown", - "id": "5915d030-b939-4162-a85c-9f90c28a17c9", - "metadata": {}, - "source": [ - "# Data\n", - "Data for this model in Montana's manuscript was generated by simulating the model with true parameter values and adding 1% Gaussian error. So this is replicated here." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "231649a2-75e9-43af-938f-00b71ff136e8", - "metadata": {}, - "outputs": [], - "source": [ - "# True param values\n", - "true_params = {\n", - " 'theta1': -1.5,\n", - " 'theta2': 0.5,\n", - "}\n", - "\n", - "# $$f(x, \\theta) = (\\theta_1 x^3 - \\theta_2 x^2 + 2x - 1)^2 + (\\theta_1 - \\theta_2)^2 + (x^2 - 1)^2$$ \n", - "\n", - "def model(x, theta1, theta2):\n", - " return ((theta1 * x**3 - theta2 * x**2 + 2 * x - 1)**2 +\n", - " (theta1 - theta2)**2 +\n", - " (x**2 - 1)**2)\n", - "\n", - "def generate_data(num_samples=1000):\n", - " x_values = np.linspace(-4, 4, num_samples)\n", - " y_values = np.array([model(x, true_params['theta1'], true_params['theta2']) for x in x_values])\n", - "\n", - " # Add 1% Gaussian noise to the y values\n", - " noise = np.random.normal(0, 0.01 * np.abs(y_values), size=y_values.shape)\n", - " y_values += noise\n", - " # Create a DataFrame with the x and y values\n", - " # and return it\n", - " return pd.DataFrame({'x': x_values, 'y': y_values})\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "ae697125", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Data generated with 1000 samples.\n", - " x y\n", - "0 -4.000000 6515.412188\n", - "1 -3.991992 6367.720590\n", - "2 -3.983984 6257.737250\n", - "3 -3.975976 6182.891231\n", - "4 -3.967968 6013.270490\n" - ] - }, - { - "data": { - "image/png": "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aOHzODIyUpJUXFzs85w9e/as9vkaNfK9FxkTE6NmzZr5HDtx4oQcDof27NmjP/7xj+rWrZtiY2N14sQJpaWleb/XydQ2jv3790uSkpKSqrRJSkrStm3bTvm9TsXzf+JZu7djxw5ddtll6ty5s55++mm1bdtWUVFRWrduncaNG1ern2/dunVyOBzq16+fXnzxRbVq1UpNmjTRO++8o0cffbRWzwEAICEDANSR8PBwDRgwQFlZWcrNzfVZR3bBBRdIUpXkomXLlpKkadOm6frrr6/2eTt37nxacXie8x//+Id3ROtkKo5KeXz33Xf65ptvtHDhQt16663e45s3b67zODwJZl5eXpVz1R07E0uXLlVYWJguv/xySdI777yjoqIi/fOf//SJLScnp9bPuWTJEkVEROj9999XVFSU9/g777xTJzEDQENBQgYAqDPTpk3Thx9+qLvuukv/+Mc/FBERcdL2nTt3VqdOnfTNN99o5syZdRLD4MGD1bhxY/3000/VTkWsDU+S5hl985g/f36VtpVH6E43js6dOys5OVmLFy/WpEmTvN97+/btWr16dZWKlKfr5Zdf1ocffqiRI0eqdevWkqr/+dxut1588cVqf77qRrvCwsLUuHFjhYeHe48VFxfr1VdfPat4AaChISEDANSZvn376tlnn9X48eN1ySWX6M4779SFF16oRo0aKTc3V2+99ZYk+UwRnD9/vq666ioNHjxYt912m84991wdOHBAGzdu1L///W+9+eabpxVD27Zt9dBDD2n69OnasmWLrrzyStntduXn52vdunWKjY31VlKsyfnnn68OHTrovvvuk9vtVnx8vN577z0tX768Sttu3bpJkp5++mndeuutioiIUOfOnWsdR6NGjfTwww9r9OjR+uUvf6k77rhDBw8e1IwZM6qdxliT4uJiZWdne/+9ZcsWvfPOO3r//fd1xRVX6Pnnn/e2HTRokJo0aaIRI0Zo6tSpOnr0qObNmyen01ntz/fPf/5T8+bNU48ePdSoUSNdeumluuaaa/Tkk09q5MiRuvPOO7V//3498cQTVZJYAMApWFxUBAAQgnJycty/+c1v3O3atXNHRka6o6Ki3B07dnTfcsst7pUrV1Zp/80337hvvPFGd0JCgjsiIsKdlJTkHjBggPv555/3tvFUWVy/fr3P165atcotyb1q1Sqf4++88467f//+7mbNmrkjIyPdbdq0cd9www3uFStWeNvceuut7tjY2Gp/hu+//949aNAgd1xcnNtut7uHDx/u3rFjh1uS+4EHHvBpO23aNHdKSoq7UaNGVWKpTRxut9u9YMECd6dOndxNmjRxn3feee6//vWv7ltvvbXWVRYleT9iY2Pd7du3d99www3uN99801upsqL33nvPffHFF7ujoqLc5557rvt3v/udtxpjxfgPHDjgvuGGG9zNmzd3h4WFuSteOvz1r391d+7c2R0ZGelu3769e9asWe6XXnqp2qqTAIDqhbnd7N4IAAAAAFag7D0AAAAAWISEDAAAAAAsQkIGAAAAABYhIQMAAAAAi5CQAQAAAIBFSMgAAAAAwCJsDF2HTpw4oT179iguLk5hYWFWhwMAAADAIm63W4cOHVJKSooaNap5HIyErA7t2bNHqampVocBAAAAIEjs3LlTrVq1qvE8CVkdiouLk2Q6vVmzZpbGUlpaqqysLDkcDkVERFgaSyiif/2L/vUv+te/6F//on/9i/71L/rXv4KtfwsLC5WamurNEWpCQlaHPNMUmzVrFhQJWUxMjJo1axYUv5Chhv71L/rXv+hf/6J//Yv+9S/617/oX/8K1v491VImS4t6fPrppxo6dKhSUlIUFhamd955x+e82+3WjBkzlJKSoujoaPXr108bNmzwaVNSUqLx48erZcuWio2N1bBhw7Rr1y6fNk6nU6NGjZLNZpPNZtOoUaN08OBBnzY7duzQ0KFDFRsbq5YtW2rChAk6duyYP35sAAAAAJBkcUJWVFSkiy++WHPnzq32/OzZs/Xkk09q7ty5Wr9+vZKSkjRo0CAdOnTI2yYjI0Nvv/22lixZos8//1yHDx/WkCFDVFZW5m0zcuRI5eTkaNmyZVq2bJlycnI0atQo7/mysjJdc801Kioq0ueff64lS5borbfe0uTJk/33wwMAAABo8CydsnjVVVfpqquuqvac2+1WZmampk+fruuvv16S9MorrygxMVGvvfaaxowZI5fLpZdeekmvvvqqBg4cKElatGiRUlNTtWLFCg0ePFgbN27UsmXLlJ2drV69ekmSXnzxRfXu3VubNm1S586dlZWVpe+//147d+5USkqKJOkvf/mLbrvtNj366KM1Tj8sKSlRSUmJ93FhYaEkM1xaWlpaN510hjzf3+o4QhX9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8INOnDih+fPna8OGDXrqqaf0/PPP6w9/+IPVoYWMY8eOafjw4br77rutDiUkvP7668rIyND06dP19ddf67LLLtNVV12lHTt2WB1avVdUVKSLL75Yc+fOtTqUkPTJJ59o3Lhxys7O1vLly3X8+HE5HA4VFRVZHVpIaNWqlR577DF9+eWX+vLLLzVgwABde+212rBhg9WhhZz169frhRde0EUXXWR1KLVG2fsG4sMPP9SkSZP01ltv6cILL9TXX3+t7t27Wx1WSFq6dKmuu+46lZSUKCIiwupwQs7jjz+uefPmacuWLVaHElIWLlyojIwMHTx40OpQ6rVevXrpkksu0bx587zHunTpouuuu06zZs2yMLLQEhYWprffflvXXXed1aGErL179yohIUGffPKJLr/8cqvDCUnx8fF6/PHHdfvtt1sdSsg4fPiwLrnkEj333HN65JFH1L17d2VmZlod1ikxQtYA5Ofn64477tCrr76qmJgYq8MJaQcOHNDf//539enTh2TMT1wul+Lj460OA6ji2LFj+uqrr+RwOHyOOxwOrV692qKogDPjcrkkiddbPygrK9OSJUtUVFSk3r17Wx1OSBk3bpyuueYaDRw40OpQTgsJWYhzu9267bbbdNddd+nSSy+1OpyQ9fvf/16xsbFq0aKFduzYoXfffdfqkELSTz/9pDlz5uiuu+6yOhSgin379qmsrEyJiYk+xxMTE5WXl2dRVMDpc7vdmjRpkn7xi1+oa9euVocTMr799ls1bdpUkZGRuuuuu/T222/rggsusDqskLFkyRL9+9//rpezEUjI6qkZM2YoLCzspB9ffvml5syZo8LCQk2bNs3qkOuV2vavx+9+9zt9/fXXysrKUnh4uG655RYxG7hmp9u/krRnzx5deeWVGj58uEaPHm1R5PXDmfQv6k5YWJjPY7fbXeUYEMzuuece/ec//9HixYutDiWkdO7cWTk5OcrOztbdd9+tW2+9Vd9//73VYYWEnTt3auLEiVq0aJGioqKsDue0sYasntq3b5/27dt30jZt27bVzTffrPfee8/nYqCsrEzh4eH61a9+pVdeecXfodZLte3f6v7od+3apdTUVK1evZqpCDU43f7ds2eP+vfvr169emnhwoVq1Ih7SSdzJr+/rCE7e8eOHVNMTIzefPNN/fKXv/QenzhxonJycvTJJ59YGF1oYQ2Z/4wfP17vvPOOPv30U7Vr187qcELawIED1aFDB82fP9/qUOq9d955R7/85S8VHh7uPVZWVqawsDA1atRIJSUlPueCTWOrA8CZadmypVq2bHnKds8884weeeQR7+M9e/Zo8ODBev3119WrVy9/hliv1bZ/q+O5x1FSUlKXIYWU0+nf3bt3q3///urRo4defvllkrFaOJvfX5y5Jk2aqEePHlq+fLlPQrZ8+XJde+21FkYGnJrb7db48eP19ttv6+OPPyYZCwC32821Qh1JT0/Xt99+63PsN7/5jc4//3z9/ve/D+pkTCIhC3mtW7f2edy0aVNJUocOHdSqVSsrQgop69at07p16/SLX/xCdrtdW7Zs0Z/+9Cd16NCB0bE6sGfPHvXr10+tW7fWE088ob1793rPJSUlWRhZ6NixY4cOHDigHTt2qKyszLtHYceOHb2vF6i9SZMmadSoUbr00kvVu3dvvfDCC9qxYwfrHuvA4cOHtXnzZu/jrVu3KicnR/Hx8VXe63D6xo0bp9dee03vvvuu4uLivOsebTaboqOjLY6u/vvDH/6gq666SqmpqTp06JCWLFmijz/+WMuWLbM6tJAQFxdXZb2jZ21/fVgHSUIGnIXo6Gj985//1AMPPKCioiIlJyfryiuv1JIlSxQZGWl1ePVeVlaWNm/erM2bN1e5gcBs67rxpz/9yWfq8s9+9jNJ0qpVq9SvXz+Loqq/brrpJu3fv18PPfSQcnNz1bVrV/3rX/9SmzZtrA6t3vvyyy/Vv39/7+NJkyZJkm699VYtXLjQoqhCh2erhsp/9y+//LJuu+22wAcUYvLz8zVq1Cjl5ubKZrPpoosu0rJlyzRo0CCrQ0MQYA0ZAAAAAFiExRgAAAAAYBESMgAAAACwCAkZAAAAAFiEhAwAAAAALEJCBgAAAAAWISEDAAAAAIuQkAEAAACARUjIAAAAAMAiJGQAAAAAYBESMgAAAACwCAkZAAAAAFiEhAwAgLO0d+9eJSUlaebMmd5ja9euVZMmTZSVlWVhZACAYBfmdrvdVgcBAEB9969//UvXXXedVq9erfPPP18/+9nPdM011ygzM9Pq0AAAQYyEDACAOjJu3DitWLFCPXv21DfffKP169crKirK6rAAAEGMhAwAgDpSXFysrl27aufOnfryyy910UUXWR0SACDIsYYMAIA6smXLFu3Zs0cnTpzQ9u3brQ4HAFAPMEIGAEAdOHbsmH7+85+re/fuOv/88/Xkk0/q22+/VWJiotWhAQCCGAkZAAB14He/+53+8Y9/6JtvvlHTpk3Vv39/xcXF6f3337c6NABAEGPKIgAAZ+njjz9WZmamXn31VTVr1kyNGjXSq6++qs8//1zz5s2zOjwAQBBjhAwAAAAALMIIGQAAAABYhIQMAAAAACxCQgYAAAAAFiEhAwAAAACLkJABAAAAgEVIyAAAAADAIiRkAAAAAGAREjIAAAAAsAgJGQAAAABYhIQMAAAAACxCQgYAAAAAFvn/Jx8hh9P2+OwAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Make some data\n", - "data_df = generate_data()\n", - "print(\"Data generated with {} samples.\".format(len(data_df)))\n", - "\n", - "print(data_df.head())\n", - "\n", - "# Plot the data\n", - "plt.figure(figsize=(10, 6))\n", - "sns.scatterplot(data=data_df, x='x', y='y', color='blue', label='Data')\n", - "plt.title('Generated Data')\n", - "plt.xlabel('x')\n", - "plt.ylabel('y')\n", - "plt.legend()\n", - "plt.grid()\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "580a2f7a", - "metadata": {}, - "outputs": [], - "source": [ - "conc = data_df['x'].values\n", - "vel = data_df['y'].values" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "7172aa46", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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TRs0btwYQFm+p8FgwIcffogPP/zQaRudERERgcGDB2Pw4MEAgLNnz6Jz585444038Oyzz6JixYps2fKvo3mb+XU0mUzo2rUr/vnnH0ydOhVNmzZFhQoVYDKZkJycjKKiIgBlImY0Gl2+Zv/++y927NhhN5+O6/U5Ijo6GiNGjGD/SDhw4AB69OiB8ePHs6+FmVatWqFVq1YAgNLSUrz66qv44IMP8N5771l1GAsKCmLLucP169cRExNj88dYVFQUtFqt1X06cuRIbNq0CZmZmejWrRv7x45ZgAHu964ZR/nFfKhcubLVunnkB/N7/++//wIApkyZgilTpnBqX3m43mfeYPPmzRg4cCAef/xxvPzyy4iJiYFWq8WyZcvs9sov//oAZa+R5WfDZDI5/KwJgZzfo1OnTqFLly6oV68edu7cqaiRRcTmzp07aN68OUaMGIH+/fu7fbzRaERwcDDGjRuHTZs22S1z8eJF9OzZE88++yzWrl2LH3/8ES+++CKqVq3K65z+Akmtn6HRaNCxY0d89913+Pvvv+3K0N9//40TJ06gR48eVlEIoKyzUfXq1dl1g8GA69ev2/2CMVOlShVUrlwZ3333nd395miLOdL4999/C9oDd8SIEdi4cSMyMzMRFxeHY8eOYdmyZez+SpUqQaPRYMiQIQ6jxAkJCW6ft3HjxnjiiSewcOFC/PHHH2xnDKDsdSxPXl4e6tatCwD49ddfcfr0aWRkZGDYsGFsmT///NPqmMjISGg0GpcdPKpUqYJmzZph1qxZdvdXq1aN83W54qGHHkLXrl2xdetWXL16FVFRUXbLBQQEYNq0afjggw8E6yVfuXJl/PTTT2AYxkpsr169CoPBgCpVqrDbunXrhmrVqmHVqlXo1q0bVq1ahbZt21qN3sH13jXDZexToTBfS3p6ulXHNkvq16/vtA6u95k3WLt2LRISErBhwwar19Gyg587VKpUCSqVyuFnzRtI9T06deoUOnfujPj4eOzevRsRERG86/JHevTowf7KZQ+9Xo8333wTX3zxBW7duoUmTZpg7ty5bAfqChUqsN9BP/74I27dumVTx/LlyxEXF8eOk9ywYUMcP34c8+bNI6l1AkmtH5Keno5vv/0WL774IrZs2WIlrkajES+88AIYhkF6errNsV988QWSkpLY9a+++goGg8HpZAuPPPIIvvzySxiNRrRt29Zhua5du0Kj0WDZsmVISUlxWM4yGsOFrl27onr16li1ahXi4uIQFBRkFUEMCQlBx44dcerUKTRr1sxhVM4R169fR1hYmN3jfv/9dwC20vjFF19YPZgOHz6My5cv45lnngFwX47KR09WrFhhtR4cHIz27dtj48aNmDVrlpW0WfLII49g586dqFOnDipVquTW9Tni33//RdWqVW16vBuNRly4cAEhISFsdDo3N9duFNP806lQUt2pUyd89dVX2Lp1K/r27ctuX7NmDbvfjPkPmYULF+LgwYM4fvy4zevL9d7lg7v3cXnq16+PevXq4fTp05g9e7bLcwGwOR/X+8wbqFQqBAYGWgltXl6e3dEPuFChQgW0adMGmzdvxvvvv8+mINy+fRs7duzgVIcS36OsrCx07twZNWrUQGZmpmDPA+I+I0aMwKVLl/Dll1+iWrVq2LJlC7p3745ffvkF9erV41THkSNH0LVrV6tt3bp1w8qVK1FaWurwVzd/h6TWD0lLS8PChQsxYcIEtGvXDmPHjkVcXBw7+cJPP/2EhQsXIjU11ebYzZs3Q6vVokuXLjh79iymTp2K5s2bY+DAgQ7P98QTT+CLL75Az549MX78eLRp0wYBAQH4+++/sXfvXvTp0wd9+/ZFrVq18Prrr2PmzJkoKirC4MGDERERgXPnzuHatWvs8EhNmzbF5s2bsWzZMiQlJUGtVjv9qVqj0WDo0KFYsGABwsPD0a9fP5vIxKJFi9CuXTs8+OCDeOGFF1CrVi3cvn0bf/75J3bs2IE9e/Y4rH/v3r0YP348nnrqKaSmpqJy5cq4evUq1q9fj++++w5Dhw61iYgfP34czzzzDB5//HHk5OTgjTfeQPXq1fHiiy8CABo0aIA6dergtddeA8MwiIyMxI4dO5CZmWlz/gULFqBdu3Zo27YtXnvtNdStWxf//vsvtm/fjhUrViAsLAxvv/02MjMzkZqainHjxqF+/fooLi7GpUuXsHPnTixfvpxt46hRo7B69Wr89ddfTvNqP//8c6xYsQJPPvkkWrdujYiICPz999/49NNPcfbsWbz11lus6Hfr1g01atRA79690aBBA5hMJmRlZWH+/PkIDQ3F+PHjreouKipymMfsbPzaoUOHYsmSJRg2bBguXbqEpk2b4tChQ5g9ezZ69uyJzp07W5UfOXIk5s6diyeffBLBwcEYNGiQ1X6u9y4f3L2P7bFixQr06NED3bp1w/Dhw1G9enXcuHEDv/32G06ePImNGzcCAJo0aQIA+PjjjxEWFoagoCAkJCS4dZ9x4dy5czh37hyAMiG9e/cu/u///g9A2fjVzsawNg+H9uKLL2LAgAHIycnBzJkzERsbiwsXLvBqz8yZM9G9e3d06dIFkydPhtFoxNy5c1GhQgXcuHHD5fFKe4/Onz/PfgZmzZqFCxcuWL22derUcZqbT7jmr7/+wvr16/H333+zf6xPmTIF3333HVatWuXyjxszeXl5iI6OttoWHR0Ng8GAa9euCZrqpCh82UuN8C1HjhxhBgwYwERHRzNarZaJiopi+vXrxxw+fNimrHn0gxMnTjC9e/dmQkNDmbCwMGbw4MHsCAlm2rdvz3To0MFqW2lpKTNv3jymefPmTFBQEBMaGso0aNCAef7555kLFy5YlV2zZg3TunVrtlxiYiI79A3DlI1eMGDAAKZixYqMSqWy6sWMcqMfmPnjjz/YHvSZmZl2X4+LFy8yI0eOZKpXr84EBAQwVatWZVJTUx2OSGAmJyeHefPNN9nhf7RaLRMWFsa0bduW+fDDD616R5tHP9i9ezczZMgQpmLFikxwcDDTs2dPm9fh3LlzTJcuXZiwsDCmUqVKzOOPP85kZ2fbvcZz584xjz/+OFO5cmUmMDCQiYuLY4YPH84UFxezZf777z9m3LhxTEJCAhMQEMBERkYySUlJzBtvvMEUFhay5bgO6XXu3Dlm8uTJTKtWrZiqVasyWq2WqVSpEtO+fXvm888/tyq7YcMG5sknn2Tq1avHhIaGMgEBAUxcXBwzZMgQ5ty5c1ZlnY1+AMCmF3l5rl+/zowePZqJjY1ltFotEx8fz6Snp1u9FpakpqYyAByOusH13o2Pj2d69erltG2WOLqPzT3r33//fZtj7L33p0+fZoeoCwgIYGJiYpiHH36YWb58uVW5hQsXMgkJCYxGo7EaTsqd+8wV5ueEvYVLXe+++y5Tq1YtRqfTMQ0bNmQ++eQTts7yr8OYMWNsjo+Pj2eGDRtmtW379u1Ms2bN2M/Fu+++a7dOeyjtPTI/fxwtls9ZghsAmC1btrDrX331FQOAqVChgtWi1WqZgQMH2hw/bNgwpk+fPjbb69Wrx8yePdtqm3kYxdzcXKEvQzGoGOZeN3eCEIjExETUqVOHjdAQ98nIyMCIESNw7NgxXh2hCIIgCOmgUqmwZcsWdgSDDRs24KmnnsLZs2dt+qSEhobadFIcPnw4bt26ZTOCwkMPPYTExEQsWrSI3bZlyxYMHDgQd+/epfQDB1D6ASEYf/zxBw4ePIhffvkFTz/9tK+bQxAEQRBeJTExEUajEVevXrU7ayFXUlJSbHK/d+/ejVatWpHQOoGklhCMOXPmYMeOHRg6dCibG0oQhPxxNZWyWq0WfLpjwj3oPfIehYWFVqNPXLx4EVlZWYiMjMQDDzyAp556CkOHDsX8+fORmJiIa9euYc+ePWjatCl69uwJoCz/XK/X48aNG7h9+zaysrIAAC1atAAAjB49Gh999BEmTZqEZ599FkeOHMHKlSutxv8m7ODr/AeCIAhCupjzR50t7ubeEsJC75F32bt3r93X2JzPrdfrmbfeeoupVasWm0Pdt29f5syZM2wd8fHxduuwZN++fUxiYiITGBjI1KpVi1m2bJk3L1OWyCands6cOdi8eTN+//13BAcHIzU1FXPnznU5xt/+/fsxadIknD17FtWqVcMrr7yC0aNHe6nVBEEQ8kav1+PMmTNOy1SrVk3QsY4J96D3iCDKkI3Udu/eHU888QRat24Ng8GAN954A7/88gvOnTuHChUq2D3m4sWLaNKkCZ599lk8//zz7Iwc69evp8GLCYIgCIIgFIRspLY8//33H6KiorB//3489NBDdsu8+uqr2L59u9Xc2KNHj8bp06dx5MgRbzWVIAiCIAiCEBnZdhTLz88HUDZNqCP4zMhRUlJiNS2jyWTCjRs3ULlyZa9OgUkQBEEQBH8YhsHt27dRrVo1n3SSKy4uhl6vF6XuwMBAdpY84j6ylFqGYTBp0iS0a9eOnYXFHnxm5JgzZw47cxVBEARBEPImJyfHZlZHsSkuLkZCfCjyrhpFqT8mJgYXL14ksS2HLKV27NixOHPmDA4dOuSybPnoqjnbwlHUNT09HZMmTWLX8/PzERcXhxafvwhNiM7uMSVG1y9jiV7jsozR4LqMgUM9AMAY3firVO9G2VL3o9VqI78It0rvWWRczaOtzlCVClqdU9TOR+chRMTkxaciI/Bwk6YAz7LJmEB+x5s0PI5zt62BJk7FVBpu5bSB3GRDo3VdTsehLp3G+Yc6OMB5RC9Y6/j4EK3zh1MFbbHDfaEax8eGaYvcri9cY39fmNp+XREOtoep7dcTqi6xuz1CbXsdhYUmtGtzDWFhYXaPERO9Xo+8q0b8ebwmwsOEjRIX3Dahbqsc6PV6ktpyyE5qX3rpJWzfvh0HDhxw+ZdXTEwM8vLyrLZdvXoVWq0WlStXtnuMTqeDTmcrr5oQHbQVdCg22L5klppZorf/kmosNhscyKs60KKMA3lVl6ueMdj/sNjonDNxDS637kwG7Vye2uBCHh18cbuUViefVU7C6sL/7TwDPaqPd70enMsd1OL8CuZTTIGuy7iLpy+9SaRx0bnUy+Wr0xPxdSS9rs5r0rp5TnfayFV2tdblHB1VXnbttURbTnTt6aYu0FCujO33SpCFqJba2W8puvb2m2W2FLYfBEvR1ZfbHxpQ7Hif5v45S8o9vMPvSa7BzkM99J7o6svti9CYj7EVyzB1EfR2tlfU3IURth3Aw9XFYBBip55iGMu9PhUtHsS+TB0MD1MLLrWEY2QjtQzD4KWXXsKWLVuwb98+JCQkuDxGyBk5SoxaGMoJrSOBNeNIXq3KcI28OpBXG0SKuroUVzvwjbR6GmEVRCpFrM/puRQonmIi1uvliSy7e79wlWCu9bqqz9Xny5n0uvpMO5ReB88Ph7LrqI322ubomVdOdh0GAMrJrqNnsqXsOnq2W8quve+H8qJrL0hiKbpFpbY3oqXo3jVYv9mWIlt+n+X+wlLbiIFZdAuNtuc0i26BwToCEm4RyS00WNdpltx8o/UxZskFgNsm633maO4to7W4VtTcLTu/yfoc4feiubfLbQ9TF+OWKQCFJm5/8BDKQTZSO2bMGKxbtw7btm1DWFgYG4GNiIhAcHDZByM9PR1XrlzBmjVrAAg7I0eJXgON1vHLJZTACi6vEhRXT6RVKMEUS1SlKKXelHJvI1ZU1JP30V0hduf94RSt5VCfs3rEkl57wuvsmWNXeCUmu+Wjuva+BzwV3aByaQflRdeZ5ALORddyX3nRtYzmlhddR5IL3BddrpIL3BddoSX3jkmcfFZCushGapctWwYA6NChg9X2VatWYfjw4QCA3NxcZGdns/sSEhKwc+dOTJw4EUuWLEG1atWwePFij8eodSWwSpNXd8XVl9IqeJTWi5KqZPkUC7FeM09k2d17xh0J9lRYudbDV3r5CK8g0V1PZddOCoO9Z7QvRFcO0VzLlAVH0dzykgu4juZ6Krka3LE5J6FsZCO1XIbTzcjIsNnWvn17nDx50uPzGw0aMHYeToIJrI/l1Vvi6omECBalFVFUpSqmTvqCyBKjSBFaM568j+4KsTv3IxcBFkJ8ndUhlPCqAIQFBKCCRgt7KY/udqJj3OmsxjXHN4DDz9da12W0HOrRaCxk2E7xwACL/Xaar9M6Pl5n2ZHMTt3Blg+IcsFNq0ixIcJqX4i2xO4xAFDBfBOVVrLerrXo6FXuPgvRlO0rLdfGsHudz6y3MwhS34RRdceh5JZPSyCUj2ykVgp4VWAlIK98xNXX0iq0sHpbUpUmn2Ih5uvkqTCLlVMLcLu/hRBf5+LK71jL50klXSAG1a2FxlUioVWr7fRsFQ6Gc90cRZdDfUL0S1KpnLfH9TmcH692crzKybHO2uXsOEfnU1seU06O2XOVk9yyYxiYGCNuqS4gJ+A7lKoLbCK5RSYaRsbfIKnliEGvsRp5wBfRV6nIK1/R8zi1QCBhFVtU5SCmUo0oO0Ks3Fl78H3/+MqwUB3A2PoEEF++kVpnx5qP06hUeDmxCWpGVkRweEVAo3HsiS7Ezros96KcRZdzOWEm5nQpqi72uxJhtZP9zvY5q1ftVGTdP06jchzVtmoHAxgNDIKvR6BCSTX8qvvQJl1Bi9sO6yKUCUktRxij2rnIChh9lbO8ehSpFUBahZY1Xwmq3KRTbMR+PYSQZnfvFXclWKh8WsD5Z00s4TUfFx2iQ8UgHUIqRkIdUHYy7tHUe3gou45Ox6kdQoquh5JaVoZ/Hc6k09V+PvvUToRVw0qu7S+ijkQ3IIiBRhuGu9kRKDHEoEh9A4DjnFxfcJspARhhh/S6zdCoDo4gqeWDDwRWLHn1prh6Kq1Cio3YsqoUKdXohYlA2cMYKJ1pp72ZQ2vGnXuQqwALkk/r4nPqTHq5CK9apYIKKisbc+RHDiXT3g6HldjZ5qBee1XYnIprfVzaWL6ucocwduooL6nlu5uUl9zydVgebyq3r7yMOtvPZ5/JjtyZRddY7uI1Fi+O0eI4S8E1MSowUAFQo8gYzA6YbO54VmxUyIOY4AxJLVf0akDjQGY5SKTc5NUX4iqECIolq76WVDHl0lf46pqElmkxc2jNcLmvhRBfTiMn8Izyms+rMtxzN+be4iy30x3ZdWTAdk3V0Qk5Hi6U6LqSXDv1OJPUsv3lDvdAcgHPRdb1PnW5fc4l12gjxvcTccuPsKAt3xONUDwkte7iA4GVmrzyFVepSau3RFWJQipnPH0/PJVioXNozbj6bHCRXrGE12lKgxuCye7iIprOdngY1RVMdPlEc8vV4yqaa2/gIJWT48tLsjgiy01yLdMVnEmuCSrcMehQoAq2mhDijp1hxAhlQ1LLlVIVoLXzVywHgRUj+iq2vPpKXIWSVjGFVUqS6usIslQRs2MZn/efjwgLmUMLeC69HnUes3ieqEtxP0rrDDdl1+OorsCia+8Uxw4dxjP9+uPgH78jPCLCbl3b1n+F9998C4f+PO+4XW6kLVzJzkHPlm3x1b5daNC0yb395Q4vJ7lL352PPTu/w/8dyLy3X2yR5ZauYE9yTVDBZHE9luPk6u2M8UsoG3rH3UBIgRUr+ip1eRVCWsUQOW+LKsmouAj1+golx1zvL3flV0jxdfbZFE14eURprY4xGlHhp6PQ/ncVhqgo3GmbDGisOxpxjupyFN1rV6/i08WLcfCHH/Bvbi5Cw8IQXzsBvfr3R+/HH0dwSIjD87Zo3Qo//HIaYeHh9q/HHnba1TwqFgDw+bc70KxVEluHvqQEnZu2RP7Nm/h06/+hdbtUxFSvhh/OZqFi5UhWdl2lLAwfOxpPPjfCYj+/vFxvSu4dUwAKcf8nAcsJIQj/gaSWI2qjCij3cBZaYKUmr74SV0E7hIksq3KSUylFmN3FV53K+Ly/nogwl/dISPH1VHj5pDSoDRAkShu+8xvETHsTgbm57DZ9bCzyZryDgp69bMpbVcNTdP++fBlD+/RGWHg4xqWno16DBjAYjbj811/Y+uWXqBodg47dutk9d2lpKQIDAlG1apTVNTpMW7Bso522xVSvhq3rNqBZUiv2gn7Y+S1CKoQg/+ZNtg6NWoMq0VHWp3CRchBcoQKCK1RgZVeozmdiSK6JMYGBCncNOiujKTQGQk+z5AIA5syZg82bN+P3339HcHAwUlNTMXfuXNSvX9/hMZs3b8ayZcuQlZWFkpISNG7cGNOnT0c38/2NsgmvRowYYXNsUVERgoJ8k/oh7DgTCkalV9ks9lCXqmwW++VsF0e4VVZvf3GGvfq5fJlrSu0vXHB0TnclQqNnnC58cNY2T9rKBVfX48kiZ+T0moh9/wh5TZ62zdEzgMtzQMXYX5xyL20hfOc3qPn8MwiwEFoACMjLQ83nn0H4zm+sylstbrSnPO+kvwaNRov13+1Ct959ULtefTzQoBG6PPIIlqxdiw5du7Jlm8XE4quM1Rg3bDjaJNTGxx8sxLEfD6NZTCwK8vPZctvXb0C3lkloWysBE4ePwC2zkNq5bstr6D1oIHZt3YbioqIyM2ZU2PrFl+g9cKDVoVeyc9C8SjX8fuZXgClLgWhepRp+OnAQgzt1R9uatTGk+6O4+MdfYBgVm37wePsubB1vvDgB454aiY/nL0b7+s2RWqshls1dAIPBgPlvzURqQhM83KgVNn++gRXenw8dRpNKNXDrVgFMjAomRoVzZ86hUcWauHI5BwCwae1GtK7ZBHu+/QHdkzqgRcwDGDfkedy9cxebvvg/dGiShlY1m2LGlGkwGu8bqrm+8rJbWBpktRBl7N+/H2PGjMHRo0eRmZkJg8GArl274s4dx9MIHzhwAF26dMHOnTtx4sQJdOzYEb1798apU6esyoWHhyM3N9dq8ZXQAhSp9QihI7BiR1/5fIl6EnUVpGOYgOLhzaiq3CXSX+D7PgkVORY6bxZwfU1c2+5phJfvs8NlFNVoRMy0NwGGsQlgqhgGjEqFmOlTUdCtu00qQlll9k7qui23btzAkf37MO611xESUsFuA1VQWdW/dN48jH/9dbwyYwbUajWu5OTcbwMDnDl1Em9NnIhxr6ejU8+e+HHvXix9f57VuR11gGvUtBmqx8Xh+6+/wSOPD0DelSs4efQnvD53Dj5e8AEruo4q+HDWXEyeMQ2VqlTGO1NexbTxk7B653bry2KPVeHngz8iulosVu3YhKyfj2PauMnIOnYCSSltsS5zB77bsh1vT34NKR0eREyN6ux57XVkK8uDLRuOq6ioCGtXfIZ5K5fgbmEhxg15Di89/RzCIsLx8cYM5FzKxrgho5GU3Ao9+z/K1sFGa1Em4sUGLe4yAQixmBKYOoqV8d1331mtr1q1ClFRUThx4gQeeughu8csXLjQan327NnYtm0bduzYgcTERHa7SqVCTEyM4G3mC0ktR9SlKqg1HEY+EEFgpSyvHncMk4m0Sk1SpdYeqSF2uoK7r78n7fFkSlt7OGu7p8LLaYSE8kN6meE42kHIT0etUg5syzII/OcfVPjpKO6kpJXb6eAgDqKbfekSGIZBQp06Vu15sEkjlJQUAwCeGD4CE9+cyu7r2bcf+j7xJHsRrNTe44tPPkVqhw4YNfYlAECt2nVw+thx/Lh3r8X1OLxU9HliELau+xKPDBiAres3oF2nh1EpsrKDa7SW3JdefxWt0lIAACPHjcXYJ4egpKgYOgdRtohKFfHqnHegVqtRq249rFq8FMVFRXh20jgAwKgJL2HloiU4+dNx9KxR3frUrODa1msoLcWb8+cgLqEWAKBrn17YsWETDvxxChVCK6B2/fpo+2AKjh48aiW1JgfSfNdw/yYsNSj7OVlQUGC1rtPpoNPpXB6Xf++XgsjISM7nMplMuH37ts0xhYWFiI+Ph9FoRIsWLTBz5kwr6fU2JLUeIEeB9YW8CiVgSugg5qtz+hu+HrarPGJ1FAOElV5PhdcT2eUaQdVevcqhMkD7r51yLkYNcNkewCbBdN0334IxmfDaSy+itEQPFXM/ONq4eXOL+iyiuPfk8uKFC3i4Rw+r+polJZVJrbmsoygygEf698eiWbPx96XL2P7lBrw66x3r9jtJuajXsBHb0CrR0QCAG9euIbZGDevj7/2/Tv36UKvvZyxWrloVdRvWZ6VSo9GgYqVKuPHfNTDMfYG1J7LmNAeGAYJDglmhBYDIqlVQLa4mgiuEsg2oXLUqbvx3zSrdwDLnloEKRcYA3L13o1lGa33NbZMJEHgCsNumsgpr1qxptX3atGmYPn2602MZhsGkSZPQrl07NGnShPM558+fjzt37mCgRXpLgwYNkJGRgaZNm6KgoACLFi1CWloaTp8+jXr16nG/IAEhqeWIqhRQ2/klqzxiCazU5VUIURN8ilsvyKMSBFWt9/2Ui6ZAaaX3e2vYLnfPK7T0CiG87squeUgvTjPd2ovsRUXZbrSDISrK5U/47qQixNWqBZVKhYsX/gS63S9bMz4eAKwinObzBgeHWEmuzelNzD15VFkf6KyNFnVVjIzEQ507Y/rESdCXlODBhx/GncJC+ycz13WvPm3A/TdfZR4eywiHKQvaAK1VW1QqlVUdDKOCSqWC6d74WiqzADMMK7aleoNtvdoAq2irSqWCVlumJqzEWtRrxryvLLfWuk5ztNZg8P2zTUxycnIQbjGSBpco7dixY3HmzBkcOnSI83nWr1+P6dOnY9u2bYiy+PwlJycjOTmZXU9LS0PLli3x4YcfYvHixZzrFxKSWg+Qs8D6Sl6FElcxZVJKoioF4fQG3rhOscVZzGgs13P4ZGQED2TX7elxAdxtnYzS2Fho8/KgshMGZFQqlMbE4m6b+1+27k3WYK+hQMVKkUh5qD3WZ3yGJ0eOLMurZVwcV+785f+t/cADOHPyhFWjzpw4eb+BziT3nqA+NvgJjHnqaYwcOxYaixxil53vXHScAxzn49qto9xYt5UqVwEAXM37D+EVKwIAfv/17L399yK49s5fLq2A68gKJYYAFBnvD+kVHKD8Ib3Cw8OtpNYVL730ErZv344DBw6ghjki74INGzZg1KhR2LhxIzp37uy0rFqtRuvWrXHhwgXObRIaklo34JxuIJLAykVepSyuvhBWfxFTqcP3fRBahsUYtotr3e7U61EqAYe2OMOphGo0yJ32Dmq+8AwYlcpKbJl7qQF502a6/GmNy2QJ93eW/fPmO+9iSL/eeKJnd7w4aTIeaNgIKrUav2Zl4eJff6JRs2Zuie5TI5/BkD6PYNWSj9Cxew8c2b8PP+7ba3G8yvagcrTr+DD2//orQsPCOI/u4PQ6nUqwkxeJsf63ZkItxFSvhuXvzceY9FeQ/b+LWLNkhf1DnbSJYVT3MykYlY3klomuCiUGjZVYF5UGwlAqnQCFL2EYBi+99BK2bNmCffv2ISEhgdNx69evx8iRI7F+/Xr06tWL03mysrLQtGlTT5vMG5JajqgNAOw8I6UisHKUV6EF01vCKkdJ1ciwzUaJpCS4+34LIcFipCE4q9ebsqsutbAfRwOh2sFSxgq798Lfyz5FzIw3rYb1Ko2JRd60mbjdoxd7CutKuNVvprzD1axVCxu//R6ffLQIC9+djX9zcxEYGIg69R7A8OdfwKBhw+1U4uD/AJonJWHGvPlYMm8els2fj+QHH8Tz4yZgxaIP7DfSskFsJFOFSpUtOoe5IdWchlBzhb2IMgMEaAPw7oqlmPVKOgZ26ILGLZpj7OuvYsrI5+7n1Np5Q9i7w8GtYZ2qYH3eYosZxIK0tqkO/sqYMWOwbt06bNu2DWFhYcjLywMAREREIDi4bAa29PR0XLlyBWvWrAFQJrRDhw7FokWLkJyczB4THByMiHuz4c2YMQPJycmoV68eCgoKsHjxYmRlZWHJkiU+uMoyVAzj7G8koqCgABEREaj38mwEqLgPDyI1gVWCvIo+kYJExE+OAioXpCLKYqdCCNnRzdO6ystudMVgTOrXElGx1aDWuDBhV7JrNCLk56PQXi2bUexum2QwWg6dH6zOwb2oq1/jedXLsRync3NJVOZQj8tzudzvoh3O/rhwcWz5W8KkN+C/v69g1j8/4oY632qf8W4Jfh34PvLz8936mV4IzO6QdS4KYWHCft5v3zahRaOrnK9L5eBztGrVKgwfPhwAMHz4cFy6dAn79u0DAHTo0AH79++3OWbYsGHIyMgAAEycOBGbN29GXl4eIiIikJiYiOnTpyMlJYXXdQkBRWo5otYDcJCDrRSBlcIIB6INiO8DUSQ5lR583xOhZZjL/eiJ+AoxbJeruvgO/8VpRjEz9mIull/QGg3ulhu2y638WThoC4dxa13WzbVejuU4pUtwSFfgEr12eS5Xdbhqh5PjXc12ZnlLlHe1Ev19pdEFUqTWDJfYpVlUzZjl1hkffPABPvjAwa8KPoKk1k2kJLBylVehxdVbwip3SZVKJNoVUhsJAXDvvRdKgF29X3xfJyFSEBzV404dKpOdn5a5XJIr0bV3LnfyZwGP0hbcEmiuQiwhybV/Hhd1uCO5TtINAGvJNXc2YxgVjEbrCH2JXgujndEWCGVDUssRdSmgdvHAdUdipS6wUpNXsYVMSsIqF/kUCzGu35uizOVeEkJ8nb1OfK5XCNn1tA6VnUviJbpuSi4gkIzaqVtpksvtPI6PtznIjSgu4Dyn1mC4L7ZarRGE/0FSyxOpCayvoq9yEFdfCau/y6mUkMrIB2Zc3ZOeSq+Qwiu07GpKOY5Rew9eoit2NNeDlAXBJdeT87orub5OVbAjuOa32lBqfVMYDBqYDG7mVxOyh6SWIxoDoOHwXSBlgZWCvIohet6UVqWLqrpEvJ/rTDr5PW7ceb+FFGAxpdfRNXldds3jNFnC8dDyouuNaK5QKQuCS66Q5/UgF9beIR6nKrh5foPeIlIbKI1Ibb4pAEaTsH8cF5qU/T3kCfL7lpEYYkusXAVWSPnzhrRKWVbFFE1v4q3r8JU8i935yxJnnwm+wium7LoluuXhcKg3orlipSzwllwPUhXKn9dxZzcngsnhXB6nKnCUbHtvpUGvgUlPkVp/g6TWDZQmsP4kr76WVqWIqRzg+1p7Q4bF6vxliaPPkZCy64noqksZ7qMfAIKJrs+juUJLrtTzccVOVShfmUENxnD/TVZppRuoIMSDpJYj6lIAgY73K11ghZJCscTVF9JKoqos3Hk/xRJgoTt/WSKk7AoR1bU3+D/ncWDLHadWq2ByMWyRINFcklz7G70xqoIjwWVUdv/wYQxqMEbpjaRCiAtJLU+8IbG+EFgpy6u3xFWusqoqkUYOmdAwOun9hMjlHhFafMUSXrFl113RLY8r0dUFapFQozIu/n0dJZZDOIkRzfWW5AoxuoJInc4kEcW114ZSNaC/9wYGUpTWXyGp5YhGz0DD8TczfxJYoeVVbHGVorAqVUaFQqjXx9ty7E3xFSof1hJ7n20hRFdd6t5n3JXsRIQGQaVSITw0CP/dKLQoWL4iDufyouSKMYSYN/JxJRHFZRz834xZbvUUqfU3SGoFwFtjzvpSYIWUV6WLK0mqNHH3ffGGBDu7V4UQXqFlV7ioLmM9+oEb8z6Ud6Tw0GD2XyuptXNK64o4nMvichvViXVatk//gZg9b1G5Crh3PHNHct+YPA7b/u8rAIBWq0VMbDV06tETYya9jJCQCq7rlHEU1/41qQCDCihVAQHCjNRDyBOSWjfxVhRWCQIrlrz6QlpJVP0PLu+5mOIrpvB6Q3bdEl2encF0gVoEBJS9B4EBGgQFaFGiN3DLzXVTcvcfPc3+/7uvt+HDhe/j6z2H2G1BuiCr8qWlpQgICCh3DoEkF0C79h3xzrxFKDWU4uSxnzDtlckounsXb81+z+06GRMDo9EIrVYr+Siuq1G+UKqy/3/CL6DYPEfUpdyEVqNnbBYxjmHbpTfZLO6g0ZtsFnex1wZPhVZdYnC4CI2qxOhykRrqklK/W6SIr+4dsT4bQn6OPX2usJHce0tggAZhoUFWS2SlCuy89gzDILJSBYSFBiG8wv1Fp+X4h0e585WnatUodgkNC4dKpUJU5ShEVY5CaVEJkpvXx3dfb8fwJ/ohsX4tfL11E5YsnId+PTtbnIPBmpUr0CWtlVXqwpav1qN3pweR+EA8Hnm4HdZ/vortSGevQx0ABOp0qBIVhdhq1dGrTz/0eqwf9uz6DgCwY/P/YWCvrmjTsA7aJzXFKy+9gOvX/mPrOnb4RzStGYMf9+3FoJ5d0bJOHE7+fBQ5ly7hpRHD0L5FE7R5oDae6NkNRw4esDpvt+RWWLHoA7w+biza1KuNrm2SsGfXd7hx/RpeGjEMberVRt9OHXD2dBZ7vtycHIwdOgRpDeujTZ0E9O3wEA7+8P29Tl4Wi6v3xQ7sa2QkgSUoUusx3ozCevoFIwRCR1+9EXWVopQCkKyoSRVPXi+TLsB1IZFwdv8JHel19HnyJLIrxJBewP1nkLrUdE9E3HsOVokMQ3hYkM12xqKeiLBgRIQFW+0vKCzGP3m3rI8RIZILAAvmvoNXXp+GWXMXIjAwEF9tWOviHAw2rl+LJQvn4Y23Z6Nh4yb47eyvmPbaFAQHh+CxAYPun97Fy6ULCoLBYAAYoFSvx0uTX0WtOnVx4/o1vPf2W3hz8ngsW73Our2zZ2LKG9NQIy4eYRXD8W9uLh58uBNeevk16IJ02LbxK7w0fCh27D+E2Oo12Nfg808+xrjX0vH8+En4/NMVeH3cWLRo1Rp9nxiMyW++hQ9mv4PXx7+ErXsPQKVSYdbr6SgtLUXGpq0IDgnBXxfOI7hCBduLcCeKa+f9UBvubzRpKQ3BHyGpdRN3hdQXAlt2Xg8jpTKTVymIK0mqdHH3vfGWBHtLeO19/qQguuXFlnHy83ze1XwADMLDgsEwDFT3ypb/FwC7P/92Ef79r8DOea3XeUmuHYYOfxZduvWyOUZlctzpbPlHH+DlN6ahS7eeAIAaNeLw1x/nsXHd51ZSa9MWiwjumdMnsXPbFrRNawcA6DfoSbZozbh4vDb9HQx+tAfu3rmDEAuZHDv5FaQ+1J5dr1QxEg0aNmZfj3GvvIY9u3Zib+YuPDl8FHs9Dz7cCQOfGgqogNETJmPDmtVo0rwFuj3yKABg5Atj8XSfXrh+9T9UiY5C7j9X0KVnLzzQsGFZm+LjrV4fj9IUHLwvaoMKkED0ttCkA2MS9o/XOybff99JFZJajqhLuY1+IMcorJACK6a8+kpcSVb9Dy7vudji6+h+F0p2pSi69qK3ZtE1mRj8k5ePO3f1iK4aDoCxElm2PMOAYYC8f/ORX1jE8bzlz8mxweXEqnHT5o7PYbI9143r15D3zz9469VJmJY+hd1uNBgRFhZ2P0XBznXu35OJVo1qw2gwwmAoxcNduuON6bMAAL/9+guWLpyH38/9ivxbt8Dcm1Y19++/UeeB+vfb28y6vXfv3sGyD+Zj/w+Z+O/qvzAYDCgpLkbelStW5cxyCgaoXKUqAKCeeRuAylWrAACuX7uGKlFReGrEM3jn9VdxeP9+JD/4IDr3fAT1GzW6/9oI0NlMVQqo9GXlmECK0vorJLUewkdiSWCd4215VYy06hVwHYG+SxNwF1f3jVjSK6bsii26QkRz8wuKUFSkR624Knb7XTEMcCn7GvSldl4njrLKeZiscgQHh5QJ471j1Gq1zbBfpaVlr7HKBDDGsn0z5sxD0xYtrcppNBbvpx3Zb5OShqnvzEWAVouq0TFsp7S7d+7guSGDkPpgB8z9YAkqVq6M3H+u4PkhT6C01PqeDQ4KsRqBYv6st/Hj/n2Y8uY0xNVKQFBQECaOfgal+lKr10SrvX9vm/+w0GoC7kem721jmLL3v/+TTyGtQwcc+OF7HN6/H59+9CGmvDUNT418xua63J6+1w5muTX/S/gPJLVu4q8SK1YHLW8gC2lVgpAKgRCvg0TE2Nl9J4bwiiW7QoquWm+6P00uz2CaimEAhoFabV9Y1GqV46r5DOvlQapCZKXKuPbfVat0id9/+5UtVqVKVUTHxOLvy5fR+9H+9w/n4P7BwcGIj69lE8W9+NefuHnjBia++gZiq1UHAJw7c9pODbZtPvnzT3hswCB07l6WCnH3zh3883eOTVFz5yyXQ4ZZvHYx1apj4JBhGDhkGBbOmYVNX3yBp0ZYSC2vobzu7WAANY10QICkljMaPQMNx44NfEVSCgIrV3mVnLiSpPoOd157Hwmwo/vVW7IrGdG198jiIHRhoUGsKNr7Nyw0CDdu3nFdEYdxWMtjORqBU7ED0LptCm7cuI6VK5aga/dHcOjAXhzcvxehoaFsmTHjJmP2228iNDQMD3Z4GHq9Hr/+choF+bcwfNRotyeAiK1WHQGBgfhi9UoMemoYLpz/Hcs//IC9XkejKQBAzVoJ+P67nejQuSugUuGj+XNhMjn+XnHVec18zrnTp6Jdh4cRX7s2Cgry8fOPh1C7Xj2bcvcrdn0ue6+7pdiaaLxav4SkVgB8IbFSFFix5VUS4kqyqiy4vJ9eFF9vRXe9Ibq80xbKP9rsSF3YvVEQGIbB3SI9/vuvAFWrhiMkOBAAEB6qw80bhU47ntnAI4oLOJfEOnUfwNQZc/DxssVYtuQDdO3WCyNGjcbGDWvZ8w0Y9BSCgoPx2SfLMO+9dxAcHIIH6jfA0OHPltXv5ixnkZGVMev9hVj0/hx8sWolGjVpiimvT8PYZ4Y6bTujAl6dOgNTX56Ip/v1RsXISIwaPQaFhbfvFXDxOsBa9i0xGo2Y9WY6/s3LRWhoKNI6dMQr0952XBmHPzbYdjuoQl2qonFq/RAVw7g5roqfUVBQgIiICCT3mgltQBBFYe8hpsD6VF5JWgl38WG6g9id1YQcgcEsuVWjKuD5F9siOroa1Gr3268NVKNO7WgwDINr125bRWQjK1VAlSphUKlU+Ot//8JgsH5uuiW5lvA8zJ18XD7n4ZKmcL9u7pVzbjfHcpzq41nGZCjF1StXMOvwKfxzpwgmi1vKVFyM/739OvLz8xEeHs6tsQJhdodvztRGhTCBRz+4bUSvZv/zyXVJHYrUckStN0HNcBdLJUVhxRtA3gcCqSRpLdH7ugXioAv0dQvcw9k9JbLw2vsMiRnR9URyzc8ktd5gt+MTZ0xAYWExrl8rRHG51/7GzTu4W6RH5chQu4e6M4SYdcHyFXE7zO0OZ26exzKK61aagovr5txujukb3HJjOdTFoYzlJEniTshOSBGSWoFQisQqQmDlJK5KFVNP8OQ1kZoQ+0B4xRRdISUX5SZg4CqYBoMJV/6+aX+nGiguLsWVfxzsLwef85cVtqyE2yG8RlRw4zx+K7hO/j5SyeirgBAGklqe+FJiSWDvIVV5JVH1HVxfeynIr6P7VwTZFUt0hZRc3lFUSzjk4wp+fi+PqMDlHG7l4ZaPmju5bqkKrgqAylAWpTVJY/ATwkeQ1HJEU2qCxo30A0uUKrF+Ka8krMqAy/voK/G1d797QXQVL7luDpEr6Sium+cQI4orVcG1TD9gxJ+F3SW3TUEwCjyj2F2aUcwhJLUiIAWJFSMKK7rESkFeSVoJM87uBW8LrxdEV4xorj3Jve9M7uXV8pZMMwJFcUlw7dTpS8E1lTWTurwTAEmtIChRYkUVWF/KK0lrGcUlwtYXpBO2PqkjBeH1gegKIbmF/91Fqd4Ik7EUGh6jHwC+jeIKkqZAgiuY4DIGPUqNRhTc1kN976vUJIHsIsI3kNTyQGkSq0iBVYq8Ci2fYiFWO+Uoy/buPV+JrgQlt6TYgBOHLiO4SwAqVQLUai1Yq+E75JYlfKqwfKR70ARecs3jEFGGCrP4SnFrqDCOFyD4MGEoE9pbN67jwF//oNhw/wLU9z6C9CO9/0FSyxG13gS1k5lVnB7rLxLrC4GVk7zKRVClhLuvmVQl2NF9KrbsihzN5Su5+3b+AQBIaleKgACNRyLpEk9E2SPB9dJJ3R3bVuSxc4Ws01lGAQPAYDTiwJ//YMd526l8gftyS/gPspLaAwcO4P3338eJEyeQm5uLLVu24LHHHnNYft++fejYsaPN9t9++w0NGjQQrZ0ksSIgdXklYZUGrt4HqUmvL6K6IkZzLZ81zgSXYYC93/yBH7//C2EVg6B2IZ5MoJu9vBxgCuT/lWcK4G93pgB+7Xf3OHfbaHTzrTe58fJxbQvX0QrKn9vEAPlFehQbjGWjH7hZH6FMZCW1d+7cQfPmzTFixAj079+f83Hnz5+3mnWjatWqgrZLShIre4GVqryStCoDOUivt0VXJMnlEsXVlxhx/d87NttdIcRMZ7yn8TUfz1O0jTyPc/d8xkA3BdfN8u7II9e6udbpTMYtRz+g9AP/Q1ZS26NHD/To0cPt46KiolCxYkVOZUtKSlBScv+Lr6CgwKYMSaxASElgSVoJwPF94GvZLf9Z8Zbk+iCKywXL5ydfwbV8jvMRXMu+Fe4Ip+UY5+4Irvl8XM+l0d//8Z6LVLpb3mrmLhdvJ9e6udapsRRXjoJL+Aeyklq+JCYmori4GI0aNcKbb75pNyXBzJw5czBjxgyb7eoSA9RG/jIraYn1J4EleSX4IDXZ9ZbkeiGKqyTBdTeaykdw+ci0twSXS6TVXLereoUWXMI/ULTUxsbG4uOPP0ZSUhJKSkrw+eefo1OnTti3bx8eeughu8ekp6dj0qRJ7HpBQQFq1qzp9rlJYn0ssSSvLEyJ+K+FSieBn+19gVRk1xeS68U0Ba74WnD5Rm8BZQiuGNFbd+olwSUULbX169dH/fr12fWUlBTk5ORg3rx5DqVWp9NBx/MLWrIiK7bE+lJgFSqv3hBRIRGqvYqRY3v3pTdF1xuSK/EoLgkul/MoXHAlMKNYvikYeqOwqlVkksCFSRRFS609kpOTsXbtWkHqIon1MjIXWLmJqi/g+hrJUn7L379KllwSXOtjBRBcPvm37pyPa1oAn/JiCy6NeECY8TupPXXqFGJjY3kdSxLrRWQmsCSs3sXV6y0L6ZWK5JLg8miL4V47qIOZnDqYEcpHVlJbWFiIP//8k12/ePEisrKyEBkZibi4OKSnp+PKlStYs2YNAGDhwoWoVasWGjduDL1ej7Vr12LTpk3YtGmT2+dW6U0Az1FkZCWxJLAOIXGVD87eK8kKr68kV8aC6+tOZtTBzLPyYncwoyG9/A9ZSe3x48etRi4wd+gaNmwYMjIykJubi+zsbHa/Xq/HlClTcOXKFQQHB6Nx48b45ptv0LNnT9HbKhuR9bbESlxgSVyVj6P3WHKy6wvJFTtNQWDBFWMUBUpPcHQe+aYnEP6DimEYZzPR+T0FBQWIiIjAw01fhVbj+EtFNhILeFdkJSqxJK8EFyQnumZ8MZSYmGPjCjgeLuC54JrxdJIHOU3wwOdcUp/gwagvxplVryM/P99qAiZvYHaHFSeTEBwqcEexQgOeb3nCJ9cldYSZe9BPUZeUsovH6EutFyEp0VsvYlJcYr1IAKakxGYhCC5I9r7xxedMzGeIwM8+oZ7NqhIju/Brh4FdeB2vN1lFVbmi0ZvYxd1zuXM+jZ5hFzHKq0u5R1vdqdffmDNnDlq3bo2wsDBERUXhsccew/nz510et3//fiQlJSEoKAi1a9fG8uXLbcps2rQJjRo1gk6nQ6NGjbBlyxYxLoEzJLVuIprICokfSywJLCEmkr2/fCW4YiDwM1Go57UnclvWDv6Cy0c4zbgrt3zP565U8pFbLoLrrjj7A/v378eYMWNw9OhRZGZmwmAwoGvXrrhzx/EU1RcvXkTPnj3x4IMP4tSpU3j99dcxbtw4qz5JR44cwaBBgzBkyBCcPn0aQ4YMwcCBA/HTTz9547LsQukHLjD/hND5gUlO0w84I/fcWAmIqxnJCAVBWCCplAVvpilQegKPdvD/WZpvagLgP+kJRn0xTn3xhmLTD3Jycqyui+s4+//99x+ioqKwf/9+h2P2v/rqq9i+fTt+++03dtvo0aNx+vRpHDlyBAAwaNAgFBQU4Ntvv2XLdO/eHZUqVcL69ev5Xp5HyKqjmCwhiRUEEtj7mIqKfN0Ep6iDg33dBJ9iea/6XHAtP79iC66YoyiYn6MSHT1BTkODAdLvXMb1GDmMU3vbFAyDSZzJF8rPdjpt2jRMnz7d5fH5+fkAgMjISIdljhw5gq5du1pt69atG1auXInS0lIEBATgyJEjmDhxok2ZhQsXcrgKcSCpFQM5iyxJrNeRuqS6izvXo3QBLn8f+1RyfSG4fjJ6gi9HTgC8OzQYn/O5K6uWxwg9eoKSsBepdQXDMJg0aRLatWuHJk2aOCyXl5eH6Ohoq23R0dEwGAy4du0aYmNjHZbJy8tz80qEg6RWKMQQWT+KxipVYpUmrELj7PVRovBKJopr/sxT9JZFiOitXCd2ACh6K0fCw8PdTqsYO3Yszpw5g0OHDrksq1JZv97mbFXL7fbKlN/mTUhq+SLnaCzgc5FVksSSuIqDo9dVKbIrCcFVUvRWQnILyD96627erRSjtwyNU2vFSy+9hO3bt+PAgQOoUaOG07IxMTE2EderV69Cq9WicuXKTsuUj956Exr9wB28MVqBWPh4lAJJ9hh3E1NRkd2F8C5KfA8k8dnw1rNBZsOCeYqnoyaUtUUew4LxPR/fkRNohANuMAyDsWPHYvPmzdizZw8SEhJcHpOSkoLMzEyrbbt370arVq0QEBDgtExqaqpwjXcTitRypbQUUAsYyVB4fqxcxdWMEkTJn7D3fsk1omv+7Pg8eivXyC0gaPRW6LxbgFITHJ9H3OitvzJmzBisW7cO27ZtQ1hYGBtdjYiIQPC952R6ejquXLmCNWvWACgb6eCjjz7CpEmT8Oyzz+LIkSNYuXKl1agG48ePx0MPPYS5c+eiT58+2LZtG77//ntOqQ1iQVLrTUhkJQkJrDIp/77KTXJ9np7grdQEP8u7BXw7agIg/dSEsnOJm3vrTyxbtgwA0KFDB6vtq1atwvDhwwEAubm5yM7OZvclJCRg586dmDhxIpYsWYJq1aph8eLF6N+/P1smNTUVX375Jd58801MnToVderUwYYNG9C2bVvRr8kRJLVio2CRlaPEksD6L5bvvVwFl6K3PFG43Ja1RT6jJrhzTo+it5xbpmy4TEeQkZFhs619+/Y4efKk0+MGDBiAAQMG8G2a4JDUioE3ZvHyEXITWZJYwh5yFVySWw9RqNyWtcXz1AQ+EyxIOXqrLqWcW3+DpFYoKCIrCUhiCXeRo+D6ldxKPOcWUJ7cAspKTSD8B5JaTyCRlQQksoRQmO8lkluOFJfIN2oLkNw6O16hqQnepsAYBL1R2EFzi400VpkjSGrdhUTW55DEEmJDcusGck9JAEhunR2v0NQEQpmQ1HKlRA+oRfywkMg6hUSW8AVylFu/SEkAxJNbgcQWILk14wu5BQAD+a3fQVLrS0hknUIiS0gFOcmtX6QkALLJtwXK5NZTsQVIbt1PhaCOYv4GSa23oZELnEIiS0gZucktRW09QKIpCQDJLd/zEsqHpNZbUFTWISSyhNwwFRXJRmwBP4naAn6VkgD4r9x6el5CuZDUiglFZR1CIkvIHYracsRbUVtAdikJAMktwH/EBE/PSygPugvEoLjEJ0LLlJSwi1QxFRWR0BKKQi73s8+fC956Joo5Qo2+9L7gCoRZboXALLeeoC4xWM1U5vbxepNVmoC7aPQmK8n11nkJZUCRWqGgqKxT5PLFTxB8kFM6gs8itoAy0hEAxacklLXJd5FbwPudyghlQFLrKZQr6xASWcKfILHliLfEFhAvHQHwi5SEsjbJV27VpRS59TdIavlAUVmnkMwShLQhsRUQgaO2gHBDgAEkt77mjiEIBoOw90eJwbP3UsnI6+7wNT7KlQUg+VxZgPJlCUJO97/PnyfefJaW6MXPtRUYdUmp5PJtAXiUbwv4LueW8A9IarlS7IXpce1AMksQhGLxdpBAZp3IAOE7kkmhMxlAckuIA0mtBJHDKAYAySxByB1JPGOUJLaAbKK2JLeEEiGplRByEFkzJLMEQQgGiS0nhBRbQNiUBJJbQgqQ1EoAucksCS1BKAfJPHuUKLZ+FLUFSG4J30NS60NIZgmCIHyI2GIL+F3UFvC8MxkgkNzSkF5+B0mtD5CTzAKUakAQXJHDOLWSxhejy5DYskgtagvQTGGEe5DUehk5ySxAQksQXCGhJZwiotiS3BJEGSS1XkKO0VkSWoLgBgmtgCg1WguIJraA8FFbQHopCQDJLeEcmlFMZOQksmZIZgmCOyS0CkHsmcfMiDADmRkhZyIzI9SMZIDns5JZ1aU38Z6dzJvcNgSjROAZxfQGUjdHSP+OkClyi8yaIaElCO6Q0CoMhURs5RC1pZQEQgxIakVAjjILkNASBFfUwcGKEVqVTufrJvgnIootIP10BIBSEgjhIakVELlGZwmC4I5SZBaQsND6Iq/WjLeitYBsxVaKUVuA5JagnFpBUILIUpSWIJyjJJklJISIObaAOHm2QJncCpFna0bofNuy/3hcFSEz6C33EBJaglA2Sko1sESyUVoACPJx27wZrfUCYkRsAeGjtoBwKQkAKGrrh1CklidKkFmCIOyjRIm1RNJC64+IHK0FxIvYAtKO2hL+BUVqeUBCSxDKRKlRWUtIaCWKyPm1gHgRW0D4TmSAsPm2hH9AUusmJLQEoSzMIqt0mQVkIrS+Tj0w44sUBAWIrVhySxBcoNg+Rxh9CRgV4+tmEAQhAP4gsJbIQmYJryFmKgIgfDoCQCkJBDfo7iCgDg6mzmKEovE3ibVEVkIrlSitL/FCfi0gT7EFyuRWTmJbaAxAoFHYmer0wgfDFYN87gyCIAiO+LPEmpGVzBI+wRtiCwgzxa4lFLUlHEF3BAGAorWEvCGJvY9sZZaitPfxUrQWEF9sAYraEt5DVh3FDhw4gN69e6NatWpQqVTYunWry2P279+PpKQkBAUFoXbt2li+fLn4DZUp/tJZhpA3lh276J69j0qnI6EVEp2wPxlLGTE7j5kRowMZQCMkENbISmrv3LmD5s2b46OPPuJU/uLFi+jZsycefPBBnDp1Cq+//jrGjRuHTZs2idxSeUOSQEgFEljXyFpmAWkKrRTwwkgIlshZbAEaIYEoQ1Zx+x49eqBHjx6cyy9fvhxxcXFYuHAhAKBhw4Y4fvw45s2bh/79+4vUSmVglgdKSSC8Acmqe8haYi0hoZUU3kpFAITPswUo15aQWaTWXY4cOYKuXbtabevWrRuOHz+O0lL7f5WWlJSgoKDAavFnKEJGCIm9yCvdW9yRfVTWTJBO2kLrR6kHvkLsqC1Fbq1xN31z+PDhUKlUNkvjxo3ZMhkZGXbLFBcXi3w1jlG01Obl5SE6OtpqW3R0NAwGA65du2b3mDlz5iAiIoJdatas6Y2mygKSEIILjsSV7ht+mEVWETILSFtmCa+kIZgRU2wBSkmwxN30zUWLFiE3N5ddcnJyEBkZiccff9yqXHh4uFW53NxcBAUFiXEJnFB8jF6lUlmtMwxjd7uZ9PR0TJo0iV0vKCggsbVDeUGhNAX/gMTUOyhGYC2Ri8xKKUrrxVEQLPFGGoIZsUZGIKxxN33THNgzs3XrVty8eRMjRoywKqdSqRATEyNYOz1F0VIbExODvLw8q21Xr16FVqtF5cqV7R6j0+mgU+IXisjYkx0SXXlBwuo7FCmxlshFaAkWElvpUz49Ukx/WblyJTp37oz4+Hir7YWFhYiPj4fRaESLFi0wc+ZMJCYmitIGLihaalNSUrBjxw6rbbt370arVq0QEOD9v379DWeSRMIrPiSp0kXxEmtGbjIrpSitn6FUsb1jCIK+VNj7qtRQljla/lfkadOmYfr06YKeCwByc3Px7bffYt26dVbbGzRogIyMDDRt2hQFBQVYtGgR0tLScPr0adSrV0/wdnBBVlJbWFiIP//8k12/ePEisrKyEBkZibi4OKSnp+PKlStYs2YNAGD06NH46KOPMGnSJDz77LM4cuQIVq5cifXr1/vqEoh7cBUuf5ZfklLl4DcSa0ZuMguQ0NrBm9FaQLliKxY5OTkIDw9n18WK0mZkZKBixYp47LHHrLYnJycjOTmZXU9LS0PLli3x4YcfYvHixaK0xRWyktrjx4+jY8eO7Lo593XYsGHIyMhAbm4usrOz2f0JCQnYuXMnJk6ciCVLlqBatWpYvHgxDeclI0jsCDnidxILyFNkzZDQSgYSW+6Eh4dbSa0YMAyDzz77DEOGDEFgoPPPiVqtRuvWrXHhwgVR2+QMWUlthw4d2I5e9sjIyLDZ1r59e5w8eVLEVhEE4c/4pcBaImeZBaQttD7oJFYeb0drAXHHsiXcY//+/fjzzz8xatQol2UZhkFWVhaaNm3qhZbZR1ZSSxAE4Uv8XmDNyF1kzUhZaAmK2gqIu+mbZlauXIm2bduiSZMmNnXOmDEDycnJqFevHgoKCrB48WJkZWVhyZIlol+PI0hqCYIg7EACaweSWb/EF9FaMyS2wuBu+iYA5OfnY9OmTVi0aJHdOm/duoXnnnsOeXl5iIiIQGJiIg4cOIA2bdqIdyEuIKklCMKvIXl1gVJE1oxchFYCqQdSgcTWc/ikb0ZERODu3bsOj/nggw/wwQcfCNE8wSCpJQhC8ZC4uoHSJNaMXGRWovgyWguQ2BLcIKklCEIxkLzyRKkiC8hTZilKaxcSW8IVJLUEQcgGklaBULLEmpGjzBIukZvY3jUEIMAg7B8ppQbHaQT+DkktQRCSgaRVJPxBYs3IXWYlHKX1dQqCGbmJLeE9SGoJgvAKJKxewp8E1hK5yywgaaGVGiS2hD1IagmC8AiSVR/irwJrRgkia4aE1m1IbInykNQSBGEDiaoE8XeBtURJMguQ0HoAiS1hCUktQfgBJKkygwTWFqWJrBkSWo8hsSXMkNRyRBWog0p9/6HKlJT4sDWEv0JyqjBIXp2jVJEFSGYJQgRIanliTy5IdAkukJj6GSSu3FGyxFpCQis4FK2VF+fPn8f69etx8OBBXLp0CXfv3kXVqlWRmJiIbt26oX///tDx+K4kqRUQZ7JCwit/SEYJh5C48sNfJNYMyayokNhKn1OnTuGVV17BwYMHkZqaijZt2uCxxx5DcHAwbty4gV9//RVvvPEGXnrpJbzyyiuYMGGCW3JLUusl3BEiEmD+kHgSokHi6jn+JrFmSGa9BomttHnsscfw8ssvY8OGDYiMjHRY7siRI/jggw8wf/58vP7665zrJ6mVICRmBOEDSFqFx18l1ozCZFYKEy9wQUpiW2TQolTgGcUMBpOg9XmTCxcuIDDQ9XMhJSUFKSkp0Ov1btVPUksQhH9A0iou/i6wlihMZuWIqsQISMNrCQu4CK0n5dVulSYIgpAaQTpuCyEcukDbhSiTWYUKrVyitJao9PKNaCqZnj17Ij8/n12fNWsWbt26xa5fv34djRo14lU3SS1BENKFZNX3kMA6xyyyCpVZghCaXbt2ocSi79DcuXNx48YNdt1gMOD8+fO86qb0A4IgvAuJqDQhWeWOnwmsHKO0hHRhGMbpuieQ1BIE4TkkqvKB5JUffiayZkhoCTlBUksQhH1IVOULiasw+KnIEoSYqFQqqFQqm21CQFJLEP4CSaqyIHEVHpJYKyhKS4gBwzAYPnw4O6lCcXExRo8ejQoVKgCAVb6tu5DUEoQcIUFVPiSt4kMSaxeSWUJMhg0bZrX+9NNP25QZOnQor7pJagnC15Cg+ickrd6HJNYlJLSE2KxatUq0uklqCUJISFAJgIRVCpDAug0JrfAUlQZCWyrs88BQKtxoAVLi8uXLuHPnDho0aAC1mt+IsyS1BGEPklPCHiSr0oQE1iNIZglvsnr1aty8eRMTJkxgtz333HNYuXIlAKB+/frYtWsXatas6XbdNPkCoWy4zjZFA/r7N/YmGKBJB6SJ5WQHNOmBR5h0ASS0hNdZvnw5IiIi2PXvvvsOq1atwpo1a3Ds2DFUrFgRM2bM4FU3RWoJeUCiSfCBRFSekKiKCoks4Uv++OMPtGrVil3ftm0bHn30UTz11FMAgNmzZ2PEiBG86iapJbwLySnhKSSqyoHk1auQzBJSoKioCOHh4ez64cOHMXLkSHa9du3ayMvL41U3SS3BD5JTQkhIVJULiavPIZklpER8fDxOnDiB+Ph4XLt2DWfPnkW7du3Y/Xl5eVbpCe5AUkuQoBLiQKLqH5C0ShISWUKqDB06FGPGjMHZs2exZ88eNGjQAElJSez+w4cPo0mTJrzqJqlVGiSohFiQpPofJKyygkSWkAOvvvoq7t69i82bNyMmJgYbN2602v/jjz9i8ODBvOomqZUyJKiEmJCk+jckrIqARJaQG2q1GjNnzsTMmTPt7i8vue5AUutNSFIJMSFJJQCSVYVDEksokeLiYmzYsAF37txB165dUbduXV71kNR6AkkqISYkqYQlJKt+Bwms/CkxamEwCKtaRqNR0Pq8zcsvvwy9Xo9FixYBAPR6PVJSUnD27FmEhITglVdeQWZmJlJSUtyumyZf4EpQIA3QT3gO10H+SWj9A3sTCThaCEVjngjBciEIJfLtt9+iU6dO7PoXX3yBy5cv48KFC7h58yYef/xxvPPOO7zqpkgtQXgKCShhCQko4QISVsKfyc7ORqNGjdj13bt3Y8CAAYiPjwcAjB8/Hj179uRVN0ktQdiDRJUwQ5JK8IDElSDso1arwTAMu3706FFMnTqVXa9YsSJu3rzJr26PW0cQcoF++icA937yJ6ElnGAvZYBSBwjCOQ0aNMCOHTsAAGfPnkV2djY6duzI7r98+TKio6N51U2RWkL+kIT6NySehEiQnBKE8Lz88ssYPHgwvvnmG5w9exY9e/ZEQkICu3/nzp1o06YNr7opUktIF4qq+icUSSW8gLMoK0VbCaVx4MAB9O7dG9WqVYNKpcLWrVudlt+3bx9UKpXN8vvvv1uV27RpExo1agSdTodGjRphy5YtLtvSv39/7Ny5E82aNcPEiROxYcMGq/0hISF48cUX3b5GgCK1hC8gEfUvSDwJL0IyShC23LlzB82bN8eIESPQv39/zsedP38e4eHh7HrVqlXZ/x85cgSDBg3CzJkz0bdvX2zZsgUDBw7EoUOH0LZtW6f1du7cGZ07d7a7b9q0aZzbVx6SWkJYSFiVD0kq4UVIUgnCc3r06IEePXq4fVxUVBQqVqxod9/ChQvRpUsXpKenAwDS09Oxf/9+LFy4EOvXr7d7THZ2NuLi4jif/8qVK6hevTrn8pR+QLgHpQIoE/q5n/ASXH72pxQAgnBNQUGB1VJSUiL4ORITExEbG4tOnTph7969VvuOHDmCrl27Wm3r1q0bDh8+7LC+1q1b49lnn8XPP//ssEx+fj4++eQTNGnSBJs3b3arvRSpJe5DUqosSEAJESHhJAjXlOg10GgFnlFMbwAA1KxZ02r7tGnTMH36dEHOERsbi48//hhJSUkoKSnB559/jk6dOmHfvn146KGHAAB5eXk2oxRER0cjLy/PYb2//fYbZs+eje7duyMgIACtWrVCtWrVEBQUhJs3b+LcuXM4e/YsWrVqhffff9/t6DJJrb9B4ipvSFQJgSE5JQh5kpOTY5XvqtMJN9Np/fr1Ub9+fXY9JSUFOTk5mDdvHiu1AKBSqayOYxjGZpslkZGRmDdvHt555x3s3LkTBw8exKVLl1BUVIQqVargqaeeQrdu3dCkSRNe7Zad1C5duhTvv/8+cnNz0bhxYyxcuBAPPvig3bL79u2zGvvMzG+//YYGDRqI3VTfQNIqT0hWCQ8hOSUI/yI8PNxKasUmOTkZa9euZddjYmJsorJXr17lNMZsUFAQ+vXrh379+gnaRllJ7YYNGzBhwgQsXboUaWlpWLFiBXr06IFz5845TTx21ntPlpC4ygeSVcINSEwJgpAqp06dQmxsLLuekpKCzMxMTJw4kd22e/dupKam+qJ5AGQmtQsWLMCoUaPwzDPPACjrebdr1y4sW7YMc+bMcXics957koXEVdqQrBIOIDElCEJqFBYW4s8//2TXL168iKysLERGRiIuLg7p6em4cuUK1qxZA6DMr2rVqoXGjRtDr9dj7dq12LRpEzZt2sTWMX78eDz00EOYO3cu+vTpg23btuH777/HoUOHvH59ZmQjtXq9HidOnMBrr71mtb1r165Oe9oBZb33iouL0ahRI7z55pt2UxLMlJSUWPUgLCgo8KzhriB5lR4krARITgmCUA7Hjx+3cp9JkyYBAIYNG4aMjAzk5uYiOzub3a/X6zFlyhRcuXIFwcHBaNy4Mb755hv07NmTLZOamoovv/wSb775JqZOnYo6depgw4YNLseoFRPZSO21a9dgNBrd6mnHpfdeeebMmYMZM2YI3n6SV4lAwup3kJwSBOHvdOjQAQzDONyfkZFhtf7KK6/glVdecVnvgAEDMGDAAE+bJxiykVoz7vS049p7z5L09HT2LxigLFJbftgMp5C8+haSVkVDgkoQBEE4QjaTL1SpUgUajYZ3TzszycnJuHDhgsP9Op2O7VHosmchTT7gfWhiAEVBA/ETBEH4J6tXr8Y333zDrr/yyiuoWLEiUlNTcfnyZV51ykZqAwMDkZSUhMzMTKvtmZmZbvW0K997jzMksN6DpFW2kKQSBEEQXJg9ezaCg4MBlM1O9tFHH+G9995DlSpVrEZUcAdZpR9MmjQJQ4YMQatWrZCSkoKPP/4Y2dnZGD16NADw6r1H+ACSU1lB8kkQBMEPo0EDxqARtE6TwPX5ipycHNStWxcAsHXrVgwYMADPPfcc0tLS0KFDB151ykpqBw0ahOvXr+Ptt99Gbm4umjRpgp07dyI+Ph4AePXeI0SE5FWykKgSBEEQviQ0NBTXr19HXFwcdu/ezUZng4KCUFRUxKtOWUktALz44ot48cUX7e7j23uP8AASV0lBskoQBEHIgS5duuCZZ55BYmIi/vjjD/Tq1QsAcPbsWdSqVYtXnbLJqSV8DOW4+hTKUSUIgiCUxJIlS5Camor//vsPmzZtQuXKlQEAJ06cwODBg3nVKbtILSEyJKpeh2SUIGxhdMrIG/QmqhKjr5tAEJwwGAxYtGgRXnnlFZthUz2ZK4Ck1l8hefUaJK2ElCF5VA7eeC9JnAkh0Gq1eP/99zFs2DBh6xW0NkKakMCKCkkrIRYknITU4HNPkggT9ujcuTP27duH4cOHC1YnSa2SIHkVBZJWggskoARhH1efDZJe/6RHjx5IT0/Hr7/+iqSkJFSoUMFq/6OPPup2nSS1coUEVlBIXP0bElKC8B2OPn8ku8rmhRdeAAAsWLDAZp9KpYLR6P77T1IrF0hiPYbEVfmQnBKEcij/eZaj5Br0Gqi1Ak++oFfGc85kMgleJ0mtFCGB5Q2JqzIgOSUIojxKkFxCXGicWilAY7+6DY3TKi8YncathSAIwhX0vJA/+/fvR+/evVG3bl3Uq1cPjz76KA4ePMi7PpJab0MTGLgFyat0IUklCEIK0LNGnqxduxadO3dGSEgIxo0bh7FjxyI4OBidOnXCunXreNVJ6QdiQ9LKCRJV6UBfDARByBVGp6G0BJkwa9YsvPfee5g4cSK7bfz48ViwYAFmzpyJJ5980u06KVIrNBSFdQlFXn0HRVUJglA69CyTB//73//Qu3dvm+2PPvooLl68yKtOitR6ComrQ0hWvQs9xAmCIO7DBFLcTsrUrFkTP/zwA+rWrWu1/YcffrCZOpcrJLV8IJG1gQRWfEhaCYIgCKUwefJkjBs3DllZWUhNTYVKpcKhQ4eQkZGBRYsW8aqTpJYrAQGAhsQNIIEVC5JWgiAIwl944YUXEBMTg/nz5+Orr74CADRs2BAbNmxAnz59eNVJUku4hCRWOEhcCYIgCH/HYDBg1qxZGDlyJA4dOiRYvZRwQlhBnbg8hzphEQRBEADAGNVgDAIvRvmrm1arxfvvv89rKlxnyP+VITyCBJY/JK4EQRAEwY/OnTtj3759gtZJ6Qd+Bomre5CkEgRBEITw9OjRA+np6fj111+RlJSEChUqWO1/9NFH3a6TpFbhkMRyhwSW4INJR49RLqhLDL5uAkEQEuKFF14AACxYsMBmn0ql4pWaQE9jhUES6xqSV/+GJNQ3CPG6kxgThHIwmUyC10lPd5lDEuscElhlQmLqn7jzvpMAE4R0MRgMCAoKQlZWFpo0aSJYvfTNIENIZO1DAitPSFAJMeByX5H4EoRv0Gq1iI+Pp9EP/BEaocAWGnVA+ph0Wk4LQfgKui8Jwne8+eabSE9Px40bNwSrkz65EoXk9T4krNKCvvAJf8DRfU7RXYIQhsWLF+PPP/9EtWrVEB8fbzP6wcmTJ92uk76dJASJbBkksb6FpJUgHGPv80GiSxDu89hjjwleJ317+RgSWZJYb0PSShDCUv4zRZJLsOjVgEbgTE+9MjJHp02bJnidynhlZIY/58dSLqz4UA4rQfgW+swRhGN+/vlnqw5iDMNY7S8pKcFXX33Fq25Bpfbff//F22+/LWSVioFElgRWaEhaCUIe0GeUIO6TkpKC69evs+sRERH43//+x67funULgwcP5lW3oFKbl5eHGTNmCFmlrPFXkaVIrHBQxJUglAd9jgl/pnxktvy6o21ccOsTdebMGaf7z58/z6sRSsLfBBagnFihoC84gvA/LD/3lItLEGWoVCpex7n1LdqiRQuoVCq7Bm3ezrchcoZElnAHkleCIOxhfjaQ3BIEP9xKP6hcuTI++eQTXLx40Wb53//+h6+//lqsdkoSf0otoJQCflDaAEEQ7kLPCkJoDhw4gN69e6NatWpQqVTYunWr0/KbN29Gly5dULVqVYSHhyMlJQW7du2yKpORkQGVSmWzFBcXu2zPuXPncObMGZw5cwYMw+D3339n18+ePcv7Ot361CQlJeGff/5BfHy83f23bt3inQchF/xFYgGKxroLfQkRBCEkFLklhOLOnTto3rw5RowYgf79+7ssf+DAAXTp0gWzZ89GxYoVsWrVKvTu3Rs//fQTEhMT2XLh4eE2qadBQUEu6+/UqZOVLz7yyCMAPP/V361v4eeffx537txxuD8uLg6rVq3i1RCpY9IFwKRRvtCSyHKDBJYgCG9Bckt4So8ePdCjRw/O5RcuXGi1Pnv2bGzbtg07duywklqVSoWYmBi32nLx4kW3yruDW9/Mffv2dbq/UqVKGDZsmEcNIrwPiaxrSGIJgvA1JLeEJQUFBVbrOp0OOp1OlHOZTCbcvn0bkZGRVtsLCwsRHx8Po9GIFi1aYObMmVbSaw9Hv/YLgaiTL4SHh1uNPUZIB8qPdQ7lwRIEIVXomSQjSlXiLABq1qyJiIgIdpkzZ45olzF//nzcuXMHAwcOZLc1aNAAGRkZ2L59O9avX4+goCCkpaXhwoULorXDFaJ+MpSeXys3SGAdQ18SBEHICYraEjk5OQgPD2fXxYrSrl+/HtOnT8e2bdsQFRXFbk9OTkZycjK7npaWhpYtW+LDDz/E4sWLRWmLK+ib3A8gmbWFJJYgCCVg0mlJbP2U8PBwK6kVgw0bNmDUqFHYuHEjOnfu7LSsWq1G69atfRqpFTX9gPAdlF5gDaUTEAShVOiZRojB+vXrMXz4cKxbtw69evVyWZ5hGGRlZSE2NtYLrbMPfRIUBAmsNfSgJ9zBFOjbv/HVepNPz0/IG4rYEs4oLCzEn3/+ya5fvHgRWVlZiIyMRFxcHNLT03HlyhWsWbMGQJnQDh06FIsWLUJycjLy8vIAAMHBwYiIiAAAzJgxA8nJyahXrx4KCgqwePFiZGVlYcmSJd6/wHuI+q3vj7OL+QKS2TJIYv0TX8uoUHh6HSTFBIkt4Yjjx4+jY8eO7PqkSZMAAMOGDUNGRgZyc3ORnZ3N7l+xYgUMBgPGjBmDMWPGsNvN5YGyuQmee+455OXlISIiAomJiThw4ADatGnjsB2JiYmc3fDkyZPuXCIA6igma0hmSWSVilJE1Ztwec1IfJUPiS1hjw4dOjh1MrOomtm3b5/LOj/44AN88MEHbrXjscceY/9fXFyMpUuXolGjRkhJSQEAHD16FGfPnsWLL77oVr1mRDWCb7/9FtWrVxfzFH4HiSyJrNwhYfUdzl57El6CIMRm2rRp7P+feeYZjBs3DjNnzrQpk5OTw6t+3nbw999/Y/v27cjOzoZer7fat2DBAgBAu3bt+FZPlMPfZZZEVj6QtMoTe+8bia48oWgtIQc2btyI48eP22x/+umn0apVK3z22Wdu18nLFH744Qc8+uijSEhIwPnz59GkSRNcunQJDMOgZcuWfKokHODPMksiK21IXpUPiS5BEGIRHByMQ4cOoV69elbbDx06hKCgIF518rKG9PR0TJ48GW+//TbCwsKwadMmREVF4amnnkL37t15NYSwhmSWkAIkrkR5LO8JElzpQtFaaaA2qqA2CNxp3qiMTvgTJkzACy+8gBMnTrCTOBw9ehSfffYZ3nrrLV518vrG+u233zBs2DAAgFarRVFREUJDQ/H2229j7ty5vBrClaVLlyIhIQFBQUFISkrCwYMHnZbfv38/kpKSEBQUhNq1a2P58uWits9T/HVsWRpD1veYAtU2C0E4g+4XgiD48tprr2HNmjU4deoUxo0bh3HjxuHUqVPIyMjAa6+9xqtOXgZRoUIFlJSUAACqVauGv/76C40bNwYAXLt2jVdDuLBhwwZMmDABS5cuRVpaGlasWIEePXrg3LlziIuLsyl/8eJF9OzZE88++yzWrl2LH3/8ES+++CKqVq2K/v37i9ZOPviryBK+gQSEEAPzfUURXIIguDBw4EAMHDhQsPp4fbMlJyfjxx9/BAD06tULkydPxqxZszBy5EireYCFZsGCBRg1ahSeeeYZNGzYEAsXLkTNmjWxbNkyu+WXL1+OuLg4LFy4EA0bNsQzzzyDkSNHYt68eaK10V38MTJLEVnvQxE1wpvQvUYQBBdu3bqFTz/9FK+//jpu3LgBoGx82itXrvCqj5dZLFiwAIWFhQCA6dOno7CwEBs2bEDdunXdHrOMK3q9HidOnLAJSXft2hWHDx+2e8yRI0fQtWtXq23dunXDypUrUVpaioCAAJtjSkpK2Cg0ABQUFAjQelv8TWQBisx6E5IJQipQ9JYgCHucOXMGnTt3RkREBC5duoRnnnkGkZGR2LJlCy5fvszObuYOvCyjdu3a7P9DQkKwdOlSPtW4xbVr12A0GhEdHW21PTo6mp2+rTx5eXl2yxsMBly7ds3u/MRz5szBjBkzhGt4OUhmCTEgiSWkDskt4W1UdK9JmkmTJmH48OF47733EBYWxm7v0aMHnnzySV518vomrF27Nq5fv26z/datW1bCKwblp1djGMbplGv2ytvbbiY9PR35+fnswncAYHv4m9BSmoG40E+8hByh+5XwBqoSo6+bQLjg2LFjeP755222V69e3WGw0hW8jOPSpUswGm1vmJKSEt55EK6oUqUKNBqNzYVevXrVJhprJiYmxm55rVaLypUr2z1Gp9NBp9MJ0+h7+KPMEsJDMkAoBVOgmiK2BOHnBAUF2U3xPH/+PKpWrcqrTrfsY/v27ez/d+3ahYiICHbdaDTihx9+QK1atXg1xBWBgYFISkpCZmYm+vbty27PzMxEnz597B6TkpKCHTt2WG3bvXs3WrVqZTefVgz8SWhJZoWHRJZQKiS2hFhQlFYe9OnTB2+//Ta++uorAGW/oGdnZ+O1117jPUKVWxby2GOPsSc2j1NrJiAgALVq1cL8+fN5NYQLkyZNwpAhQ9CqVSukpKTg448/RnZ2NkaPHg2gLHXgypUrbHLx6NGj8dFHH2HSpEl49tlnceTIEaxcuRLr168XrY1mSGYJTyCZJfwBEltCaKQmtCq9Ciq1sJMlqPTKmHxh3rx56NmzJ6KiolBUVIT27dsjLy8PKSkpmDVrFq863bIRk6ns4ZOQkIBjx46hSpUqvE7Kl0GDBuH69et4++23kZubiyZNmmDnzp2Ij48HAOTm5iI7O5stn5CQgJ07d2LixIlYsmQJqlWrhsWLF4s6Ri3JLMEXElnCHyGxJQj/JDw8HIcOHcKePXtw8uRJmEwmtGzZEp07d+Zdp4ox95ziSXFxMe85euVAQUEBIiIi8HDTV6HVOM+19RehJZkVFpJZwt8hqRUef5wit3yU1mAswZ5f5iI/Px/h4eFebYvZHWrNnAW1wI5kKi7Gpalv+OS6hMJgMCAoKAhZWVlo0qSJYPXy+jY1mUyYOXMmqlevjtDQUPzvf/8DAEydOhUrV64UrHFygoSWcAcauYAg7kOfA8JTpJZ2QDhHq9UiPj7e7qADnsDrSfLOO+8gIyMD7733HgIDA9ntTZs2xaeffipY4+SAv8wIRsNzCQOJLEEQYuNvUVoSWnny5ptvIj09nZ1JTAh4WcqaNWvw8ccfo1OnTmwnLQBo1qwZfv/9d8EaJ3X8QWYBis4KAYksQRCE8JDQypfFixfjzz//RLVq1RAfH48KFSpY7T958qTbdfKylStXrqBu3bo2200mE0pLS/lUKTtIaAkukMwSBOFN/C1KS8gX84haQsLLWBo3boyDBw+yow6Y2bhxIxITEwVpmFQhmSW4QkJLEAQhHhSllTfTpk0TvE5e5jJt2jQMGTIEV65cgclkwubNm3H+/HmsWbMGX3/9tdBtlAwktAQXSGYJgvAF/hSlJaEl7MHr27d3797YsGEDdu7cCZVKhbfeegu//fYbduzYgS5dugjdRknA+ImokNB6BgktQbgPDenlOSS0hNwwGo2YN28e2rRpg5iYGERGRlotfOBtMN26dUO3bt34Hk5IEBJazyChJQjCF5DQShd1qQpqjcAzgJUqY0axGTNm4NNPP8WkSZMwdepUvPHGG7h06RK2bt2Kt956i1edHlmMXq/H1atX2ZnGzMTFxXlSLeEDSGg9g4SWIPhBUVrPIKEl5MoXX3yBTz75BL169cKMGTMwePBg1KlTB82aNcPRo0cxbtw4t+vkZTIXLlzAyJEjcfjwYavtDMNApVIJPpguIS4ktJ5BQksQ/CCh9QwSWkLO5OXloWnTpgCA0NBQ5OfnAwAeeeQRTJ06lVedvGxm+PDh0Gq1+PrrrxEbGwuVShmhcH+EhNYzSGgJgh8ktJ7hL0JLMqtcatSogdzcXMTFxaFu3brYvXs3WrZsiWPHjkGn0/Gqk5fRZGVl4cSJE2jQoAGvkxLSgITWM0hoCYIfJLSeQUJLKIG+ffvihx9+QNu2bTF+/HgMHjwYK1euRHZ2NiZOnMirTl5W06hRI1y7do3XCQlpQEJLEIQvIKH1DBJaQim8++677P8HDBiAGjVq4PDhw6hbty4effRRXnVyNpuCggL2/3PnzsUrr7yC2bNno2nTpggICLAqGx4ezqsxhHcgofUcitIShHuQzHoOCS2hZJKTk5GcnOxRHZztpmLFila5swzDoFOnTlZlqKMYQRAEUR4SWs8hoSWUxpo1a5zuHzp0qNt1cpbavXv3sv+/dOkSatasCY3GeoYtk8mE7OxstxtBeA+K0hIE4S1IZj2HZJZQKuPHj7daLy0txd27dxEYGIiQkBBxpbZ9+/bs/x9++GHk5uYiKirKqsz169fRuXNnDBs2zO2GEARBEMqAZFYYSGgJJXPz5k2bbRcuXMALL7yAl19+mVedvMJ25jSD8hQWFiIoKIhXQwjxoSgtQRBiQ0LrOf4is4DyhVZVCqg1rsu5A1MqbH1Sol69enj33Xfx9NNP4/fff3f7eLcsZ9KkSQAAlUqFqVOnIiQkhN1nNBrx008/oUWLFm43giAIgpAvJLLC4S9Cq3SZJfij0Wjwzz//8DrWLak9deoUgLJI7S+//ILAwEB2X2BgIJo3b44pU6bwagghLhSlFRa13kQjIBB+D8mscPiLzAIktEQZ27dvt1pnGAa5ubn46KOPkJaWxqtOt0zH3FlsxIgRWLRoEQ3dRRAE4YeQzAoHySzhrzz22GNW6yqVClWrVsXDDz+M+fPn86qTV/hu1apVvE5GEEqCorWEP0EiKzwktIQ/YzIJ/0yh36QJwgNIbAklQyIrDiSzBCEOJLUE4SEktoSSIJEVD5JZwlccOHAA77//Pk6cOIHc3Fxs2bLF5uf/8uzfvx+TJk3C2bNnUa1aNbzyyisYPXq0VZlNmzZh6tSp+Ouvv1CnTh3MmjULffv25dQm8+ADXFiwYAGnciS1BCEAJLaEnCGRFRd/klmAhFaK3LlzB82bN8eIESPQv39/l+UvXryInj174tlnn8XatWvx448/4sUXX0TVqlXZ448cOYJBgwZh5syZ6Nu3L7Zs2YKBAwfi0KFDaNu2rctznDp1CidPnoTBYED9+vUBAH/88Qc0Gg1atmzJlrM3hKwjSGoJQiDMYkByS0gdkljvQDJLSIUePXqgR48enMsvX74ccXFxWLhwIQCgYcOGOH78OObNm8dK7cKFC9GlSxekp6cDANLT07F//34sXLgQ69evd3mO3r17IywsDKtXr0alSpUAlE3IMGLECDz44IOYPHmym1cJ0LcvQQiMWm8iaSAkh/m+pHtTfNQlBr8SWlWJkYTWBxQUFFgtJSUlgtV95MgRdO3a1Wpbt27dcPz4cZSWljotc/jwYU7nmD9/PubMmcMKLQBUqlQJ77zzDu/RD0hqCUIkSCAIX2EpsHQfegezyJLMEpaoDYC6VODl3i1Ws2ZNREREsMucOXMEa3deXh6io6OttkVHR8NgMODatWtOy+Tl5XE6R0FBAf7991+b7VevXsXt27d5tZvSDwhCZCgtgRAbklbf4U8Sa4ZEVhrk5ORYzReg0+kErb98LivDMDbb7ZXhmgPbt29fjBgxAvPnz0dycjIA4OjRo3j55ZfRr18/Xm0mqSUIL2EpHiS4BF9IYH2PP4osQDIrNcLDw0WbBCsmJsYm4nr16lVotVpUrlzZaZny0VtHLF++HFOmTMHTTz/NpjRotVqMGjUK77//Pq920zern+CvD2GpQj8LE1ygNAJp4W/pBWYozcD/SElJQWZmptW23bt3o1WrVggICHBaJjU1ldM5QkJCsHTpUly/fp0dCeHGjRtYunQpKlSowKvdJLUE4WNIWgh78kr3gjTwx1xZMySzyqGwsBBZWVnIysoCUDZkV1ZWFrKzswGUjVwwdOhQtvzo0aNx+fJlTJo0Cb/99hs+++wzrFy5ElOmTGHLjB8/Hrt378bcuXPx+++/Y+7cufj+++8xYcIEt9pWoUIFNGvWDBUrVsTly5c9mmmMpNaP8MeHshwhuVEmjsSV3l/p4c8iC5DMKpHjx48jMTERiYmJAMomPkhMTMRbb70FAMjNzWUFFwASEhKwc+dO7Nu3Dy1atMDMmTOxePFiqzFuU1NT8eWXX2LVqlVo1qwZMjIysGHDBpdj1K5evZodKszMc889h9q1a6Np06Zo0qQJcnJyeF2nijFn/hJ2KSgoQEREBDompUOrDfJ1czzGpKM0aqVAebnSgwRVvvirwFqiNJE1GEuw55e5yM/PFy331BFmd6j38mxodMK6g7GkGBfef90n1yUEKSkpeO655zBixAgAwHfffYfevXsjIyMDDRs2xNixY9GoUSN8+umnbtdNhuNnqEsMJLYKwZlAkfAKC8mqMiGRVZ7ImlGXlEJtLPV1Mwg7/PHHH2jVqhW7vm3bNjz66KN46qmnAACzZ89mhdddyG78EBJb5cNVwvxZfklU/RMS2TKULLOEtCkqKrKKMB8+fBgjR45k12vXrs15rNvykNn4KSS2BCCM2HlLjElCCb6QyN6HZJbwNfHx8Thx4gTi4+Nx7do1nD17Fu3atWP35+XlISIiglfdZDV+DIktIQQkm4TUIIm1RqkiC0hfZtV6QM1tLgLOMHph6/M2Q4cOxZgxY3D27Fns2bMHDRo0QFJSErv/8OHDaNKkCa+6yWj8HBJbgiDkDkmsLUoWWUD6Mks45tVXX8Xdu3exefNmxMTEYOPGjVb7f/zxRwwePJhX3WQzBIktQRCyg0TWPiSzhNRRq9WYOXMmZs6caXd/ecl1BzIZAsD9LwiSW4IgpAhJrGNIZAmiDDIYwgqK2hIE4WtIYF2jdJEFSGYJ9yF7IWygqC1BEN6EJJYb/iCyAMkswR+yFsIhJLcEQQgNCax7kMgSSqKgoEDUWdD8d+R1gjP+PAc6QRD8MT87LBfCOaoSo9WidNQlpSS0fkSlSpVw9epVAMDDDz+MW7duCVo/heAIzlh+IVH0liAIS0hY+eMP8moJSaz/EhoaiuvXryMqKgr79u1Daamw9wKZCcELSk0gCP+E5FUYSGQJf6Rz587o2LEjGjZsCADo27cvAgMD7Zbds2eP2/XLxkhu3ryJcePGYfv27QCARx99FB9++CEqVqzo8Jjhw4dj9erVVtvatm2Lo0ePitlUv4KitwShXEhghcPfJNaMv8usuhRQC5zoycj4JV27di1Wr16Nv/76C/v370fjxo0REhIiWP2ysZAnn3wSf//9N7777jsAwHPPPYchQ4Zgx44dTo/r3r07Vq1axa47+ouA8JzyX4AkuQQhfUhcxcFfJRYgkSUcExwcjNGjRwMAjh8/jrlz5zoNTrqLLKzjt99+w3fffYejR4+ibdu2AIBPPvkEKSkpOH/+POrXr+/wWJ1Oh5iYGM7nKikpQUlJCbteUFDAv+F+DkVxCUIakLiKjz9LLEAiS7jP3r172f8zDAMAUKlUHtUpi9EPjhw5goiICFZoASA5ORkRERE4fPiw02P37duHqKgoPPDAA3j22WfZXneOmDNnDiIiItilZs2aglyDv0M9oAlCXOyNNECfN/Hwt1EK7GEeuYCEluDLmjVr0LRpUwQHByM4OBjNmjXD559/zrs+WYTP8vLyEBUVZbM9KioKeXl5Do/r0aMHHn/8ccTHx+PixYuYOnUqHn74YZw4cQI6nc7uMenp6Zg0aRK7XlBQQGIrAva+aCmaSxCOITn1Lf4qruUhgSWEYsGCBZg6dSrGjh2LtLQ0MAyDH3/8EaNHj8a1a9cwceJEt+v0qUVMnz4dM2bMcFrm2LFjAOyHpBmGcRqqHjRoEPv/Jk2aoFWrVoiPj8c333yDfv362T1Gp9M5FF5CXEh0CX+GpFVakMSWQRJLiMWHH36IZcuWYejQoey2Pn36oHHjxpg+fbr8pHbs2LF44oknnJapVasWzpw5g3///ddm33///Yfo6GjO54uNjUV8fDwuXLjgdlsJ3+Dsi56El5ADJKvShwTWGhJZwhvk5uYiNTXVZntqaipyc3N51elTK6hSpQqqVKnislxKSgry8/Px888/o02bNgCAn376Cfn5+XZfEEdcv34dOTk5iI2N5d1mQjqQ8BK+gkRVvpDA2odElvA2devWxVdffYXXX3/davuGDRtQr149XnXK4pu/YcOG6N69O5599lmsWLECQNmQXo888ojVyAcNGjTAnDlz0LdvXxQWFmL69Ono378/YmNjcenSJbz++uuoUqUK+vbt66tLIbwEF+kg8SXMkKQqExJYx5DEEr5mxowZGDRoEA4cOIC0tDSoVCocOnQIP/zwA7766itedcrmW/2LL77AuHHj0LVrVwBlky989NFHVmXOnz+P/Px8AIBGo8Evv/yCNWvW4NatW4iNjUXHjh2xYcMGhIWFeb39hPRwV2RIgqULSSlBAuscv5RYgadg5YPGAGiEHmdKIY+7/v3746effsIHH3yArVu3gmEYNGrUCD///DMSExN51Smbb+nIyEisXbvWaRnzOGdA2QC/u3btErtZhB8hpDj5qyCTfBKeQvLKDb+UWADQ++l1y5SkpCSXbucO/vnNShA+huSOIJxD8uoefiuxAIkswUJSSxAEQfgMkld++LXEAiSyhF1IagmCIAjRIXn1DL+XWIBElnAJSS1BEAQhCCSuwkESew8SWcINSGoJgiAIzpC4Cg8JrAUksYQHkNQSBEEQLCSt4kICawcSWb+kuLgYH374Ifbu3YurV6/CZDJZ7T958qTbdZLUEgRB+BEkrd6DBNYBJLEEgJEjRyIzMxMDBgxAmzZtoFKpPK6TpJYgCEIhkLD6DhJYJ5DEEnb45ptvsHPnTqSlpQlWJ0ktQRCEDCBhlQYkrxwgiWVRlwJqzwOQVjAKeXmrV68u+AyvQk/eplhUehNUJUb6YiEIQjDMzxQuC+Fd1CWldhfCDvpS64UgODB//ny8+uqruHz5smB1UqSWB+W/YBidxkctIQhCapCAygsSVR6QuBIC0KpVKxQXF6N27doICQlBQECA1f4bN264XSdJrQCQ5BKEciFJVQYkrzwhgSVEYvDgwbhy5Qpmz56N6Oho6igmVRx9CZLsEoTvIDlVPiSuAkASS3iJw4cP48iRI2jevLlgdZLUehFnX6okvAThGhJTgsRVQEhgCR/SoEEDFBUVCVondRSTCNRRhFAy7nSIos8A4aiTFgmtB5TvzEVC63csXboUCQkJCAoKQlJSEg4ePOiw7PDhw6FSqWyWxo0bs2UyMjLslikuLubUnnfffReTJ0/Gvn37cP36dRQUFFgtfKBIrYzg86VOEWDCHUgcCW9AcioyJKxEOTZs2IAJEyZg6dKlSEtLw4oVK9CjRw+cO3cOcXFxNuUXLVqEd999l103GAxo3rw5Hn/8caty4eHhOH/+vNW2oKAgTm3q3r07AKBTp05W2xmGgUqlgtHo/vcRSa3CEUtSSJbFgaSSUAIkrV6C5JXgyIIFCzBq1Cg888wzAICFCxdi165dWLZsGebMmWNTPiIiAhEREez61q1bcfPmTYwYMcKqnEqlQkxMDK827d27l9dxziCpJXhB8kUQ/gtJqw8ggSXKUf4nep1OB51OZ1NOr9fjxIkTeO2116y2d+3aFYcPH+Z0rpUrV6Jz586Ij4+32l5YWIj4+HgYjUa0aNECM2fORGJiIqc627dvz6mcO5DUEgRBECwkrD6G5NVzSvRl/5r0vm0HAI2egQaMsJXqy+qrWbOm1eZp06Zh+vTpNsWvXbsGo9GI6Ohoq+3R0dHIy8tzebrc3Fx8++23WLdundX2Bg0aICMjA02bNkVBQQEWLVqEtLQ0nD59GvXq1XNZ74EDB5zuf+ihh1zWUR6SWoIgCD+AZFVCkLgKR4nvxdVX5OTkIDw8nF23F6W1pPw4sObcVVdkZGSgYsWKeOyxx6y2JycnIzk5mV1PS0tDy5Yt8eGHH2Lx4sUu6+3QoYPTNlJOLUEQhJ9BsiphSF6Fx48ltjzh4eFWUuuIKlWqQKPR2ERlr169ahO9LQ/DMPjss88wZMgQBAYGOi2rVqvRunVrXLhwwXXjAdy8edNqvbS0FKdOncLUqVMxa9YsTnWUh6SWIAhCYpCoyggSV/EggRWEwMBAJCUlITMzE3379mW3Z2Zmok+fPk6P3b9/P/7880+MGjXK5XkYhkFWVhaaNm3KqV2WHdHMdOnSBTqdDhMnTsSJEyc41WMJSS1BEIQXIFGVMSSu4kMCKyqTJk3CkCFD0KpVK6SkpODjjz9GdnY2Ro8eDQBIT0/HlStXsGbNGqvjVq5cibZt26JJkyY2dc6YMQPJycmoV68eCgoKsHjxYmRlZWHJkiUetbVq1ao2w4RxhaSWIAiCBySpCoKk1buQwHqdQYMG4fr163j77beRm5uLJk2aYOfOnexoBrm5ucjOzrY6Jj8/H5s2bcKiRYvs1nnr1i0899xzyMvLQ0REBBITE3HgwAG0adOGU5vOnDljtc4wDHJzc/Huu+/ynjpXxTCMwN3ylEVBQQEiIiLwcNNXodU4T8ImCEKekKD6ASSu3sfH8mowleD7f1YgPz+fU+6pkJjdIfGpWdAEcpuMgCtGfTFOffGGT65LSNRqNVQqFcpraHJyMj777DM0aNDA7TopUksQhKIgQfVDSFh9D0VfCTe5ePGi1bparUbVqlU5z0hmD5JagiAkCckpwULSKh1IXgmBKD+RgxCoBa+RIAjiHuqSUt4L4SfoS10vhHcp0TteCMJDfvrpJ3z77bdW29asWYOEhARERUXhueeeQ0lJCa+6KVJLEIRTSDAJXpCMSh+SVNFRlwJq1/MbuAUj84/W9OnT0aFDB/To0QMA8Msvv2DUqFEYPnw4GjZsiPfffx/VqlWzOzuaK0hqCULhkJQSgkKyKi9IXAmJkZWVhZkzZ7LrX375Jdq2bYtPPvkEQNn0v46m/HUFSS1BSBySUsIrkKzKE5JWQmbcvHnTaiaz/fv3o3v37ux669atkZOTw6tuklqC8AIkpoRPIFFVBiSuhIKIjo7GxYsXUbNmTej1epw8eRIzZsxg99++fRsBAQG86iapJQg3IDklfA6JqrIgYSX8jO7du+O1117D3LlzsXXrVoSEhODBBx9k9585cwZ16tThVTdJLeGXkJwSkoJEVbmQtBKEFe+88w769euH9u3bIzQ0FKtXr0ZgYCC7/7PPPkPXrl151U1SSygCklRCUpCk+gckrAThNlWrVsXBgweRn5+P0NBQaDQaq/0bN25EaGgor7pJagnJQqJKSAaSVP+DhJUgRCUiIsLu9sjISN51ktQSPoGElfAZJKj+DckqQSgWklpCFEhaCa9BkkoAJKsEQZDUEvwgaSVEgySVMEOiSnCl2M60qibf3z/qUgYaMILWyZQKW5+SIKklnELySngMSSphCYkq4S72hJUg7EBSS7CQwBKcIEklykOiSvCBZJUQGJJaP4UElrCCRJUoD4kqwReSVcJHkNT6CSSxfgiJKmEJSSrhKSSrhMQhqVUoJLEKhmSVAEhSCc8hSSUUBkmtgiCRlTkkq/4NSSohBCSqhB9DUitzSGRlBEmr/0GiSngCCSpBuIXa1w3gyqxZs5CamoqQkBBUrFiR0zEMw2D69OmoVq0agoOD0aFDB5w9e1bchnoBdUkpuxASQV/qeiHkT4nevYUgLCkucW8hCMItZCO1er0ejz/+OF544QXOx7z33ntYsGABPvroIxw7dgwxMTHo0qULbt++LWJLxYNE1seQsCoTklSCD+4KKkkqQYiObNIPZsyYAQDIyMjgVJ5hGCxcuBBvvPEG+vXrBwBYvXo1oqOjsW7dOjz//PNiNVVwSGS9CAmqMiABJbhCskmIiEbPQMPQjGLeQjZS6y4XL15EXl4eunbtym7T6XRo3749Dh8+7FBqS0pKUFJy/yFXUFAgelsdQTIrIiSv8oNElXAFCSpB+DWKldq8vDwAQHR0tNX26OhoXL582eFxc+bMYaPCvoJkVkBIXqUPySphDxJUgiDcxKc5tdOnT4dKpXK6HD9+3KNzqFQqq3WGYWy2WZKeno78/Hx2ycnJ8ej87kJC6wGU6yotKE+VAPjlnpLQEgTBA59GaseOHYsnnnjCaZlatWrxqjsmJgZAWcQ2NjaW3X716lWb6K0lOp0OOp2O1zk9hYTWDUhYfQvJqH9CskkQhITxqdRWqVIFVapUEaXuhIQExMTEIDMzE4mJiQDKRlDYv38/5s6dK8o5PYGE1gUksd6FpFX5kKASBKEwZJNTm52djRs3biA7OxtGoxFZWVkAgLp16yI0NBQA0KBBA8yZMwd9+/aFSqXChAkTMHv2bNSrVw/16tXD7NmzERISgieffNKHV2ILCa0dSGLFhaRVeZCkEgTh58hGat966y2sXr2aXTdHX/fu3YsOHToAAM6fP4/8/Hy2zCuvvIKioiK8+OKLuHnzJtq2bYvdu3cjLCzMq213BgntPUhihYWkVf6QpBIEQbiFimEEHkBNYRQUFCAiIgIPN30VWo2wubZ+L7Qksp5D8iofSFIJwqsYTHp8f2MV8vPzER4e7tVzm90huddMaAOCBK3bUFqMo99M9cl1SR3ZRGoJhUAi6z4krtKFRJUgCCeo9SaoGZOwdZYKW5+SIKn1EX4VpSWR5QbJq3QgWSUIgpAdJLWEeJDMOoYE1jeQrBIEQSgWklofoOgoLYmsLSSw3oGElSAIwq8hqSWEgWS2DBJYcSBhJXwIU0L3HxdUPpq4iCDMkNQSnuHPMksCKxwkrYQHkHRKA3feBxJgQgxIagl++KPMksR6BokrYQGJqH/j7P0n4SX4ovZ1AwgZ4k9CW6K/vxCuKS5xvBCKgSkp8XghCEfQ/SIOS5cuRUJCAoKCgpCUlISDBw86LLtv3z6oVCqb5ffff7cqt2nTJjRq1Ag6nQ6NGjXCli1bxL4Mp1CkluCOP8gsyatrSFAVA8kCIRfK36sUzXWPDRs2YMKECVi6dCnS0tKwYsUK9OjRA+fOnUNcXJzD486fP281wUPVqlXZ/x85cgSDBg3CzJkz0bdvX2zZsgUDBw7EoUOH0LZtW1GvxxE0o5gLxJhRTJajHyhZaElk7UPyKitIUAl/xZHgSmFGsdQuM0SZUexw5jTk5ORYXZdOp4POwWvRtm1btGzZEsuWLWO3NWzYEI899hjmzJljU37fvn3o2LEjbt68iYoVK9qtc9CgQSgoKMC3337LbuvevTsqVaqE9evX87w6z6D0A8I1ShRaSiuwhtIFJAf9nE8Q3JDyZ0BTaoJGL/Byb0axmjVrIiIigl3sySkA6PV6nDhxAl27drXa3rVrVxw+fNhp+xMTExEbG4tOnTph7969VvuOHDliU2e3bt1c1ikmlH5AOEdJQksCS7LqY6T6xUsQSoApKfGrtAR7kVp7XLt2DUajEdHR0Vbbo6OjkZeXZ/eY2NhYfPzxx0hKSkJJSQk+//xzdOrUCfv27cNDDz0EAMjLy3OrTm9AUks4RilC688ySxLrFUhWCUIamD+L/iC34eHhbqVVqFQqq3WGYWy2malfvz7q16/PrqekpCAnJwfz5s1jpdbdOr0BSa0PMOkCpJ9XK3eh9UeRJYEVBRJWgiDkTJUqVaDRaGwiqFevXrWJtDojOTkZa9euZddjYmI8rlNoKKeWsEXOQutPebKUAysIlKtKEMqDPrv3CQwMRFJSEjIzM622Z2ZmIjU1lXM9p06dQmxsLLuekpJiU+fu3bvdqlNoKFJLKAN/EFkSV97QFxxB+B+Mnj73ZiZNmoQhQ4agVatWSElJwccff4zs7GyMHj0aAJCeno4rV65gzZo1AICFCxeiVq1aaNy4MfR6PdauXYtNmzZh06ZNbJ3jx4/HQw89hLlz56JPnz7Ytm0bvv/+exw6dMgn1wiQ1PoMyaYgyDFKq1ShJYl1CxJXgiAI+wwaNAjXr1/H22+/jdzcXDRp0gQ7d+5EfHw8ACA3NxfZ2dlseb1ejylTpuDKlSsIDg5G48aN8c0336Bnz55smdTUVHz55Zd48803MXXqVNSpUwcbNmzw2Ri1AI1T6xIxxqk1Q1LrIUqUWRJZp5C4EgTBFQOjxw+F63w6Tu2DHaZBqxV4nFpDMQ7um+GT65I6FKn1IZKL1spFaJUmsySyNpC8EgRBEO5CUkvIC6UILYksCwksQRAEIQQktT5GctFaKSN3ofVzkSV5JQjCm6gCfT9WrVpvgtpkErZOg7D1KQmSWkIeyFlo/VRmSWL9C1NRka+bIDjq4GBfN4EgCDcgqZUAFK11gVyF1o9klgRWnihRRIWEz+tDIiwNVDodYJLpdwfBG5JaiUBi6wA5Cq0fyCxJrPQgQZUGrt4Hkl7x8Ycpcgn7kNQS0kVuQqtwmSWR9T4kqsrD3ntKoksQwkBSKyEoWmuBnIRWoTJLEisuJKyEGRJd4aAorX9DUisxSGxlhAJllkRWOEhaCU+wvH9IcLlBQkuQ1HKECVQDRu+cy+/FVg5RWgUJLYksf0hcCW9AgusaEloCIKl1C0angarEO2brE7ENDJDPrGK+RCFCSzLLHZJXQiqY70WS2/uQ0BJmSGrdhNFpAMBrcktIDJkLLYmsc0heCblAclsGCS1hCUktT7wRtfX7NAQpQTKrOEhgCSVgKiryW7GVg9CqSwxQGw3C1mkQtj4lQVLrAYoUW1+nIMghn1ZGkMyWQQJLKBl/FFs5CC3hfUhqPcQb6QgUsfUxMozS+rvMksQS/oa/iC3JLOEMklqBEDtq61Wx9XW0VkrITGj9VWZJYglC+ZDQEq5Q+7oBSsIctRULky5A1PqtCPTiuaSKjISWKSnxO6E1FRWxC0EQyv7jjoSW4AJFagVG7HQExaci6AIpr9ZN/ElmlfylTRCELSSzhDuQ1IqEmOkIXhNbSkOQPP4gtCSyBOGfkNAS7kJSKyIktjJGBqkHShZaElmCcB+ldBQjmSX4Qjm1IsPoNKLl2notx9bb+bW6QO+eT4YoVWgpR5Yg/BsSWsITKFLrJcSK2prFVtF5toQVShRaElmC8Ay5R2lJZgkhIKn1ImJ2IhM9HcHbaQjUYcwuShNaklmC8BwSWumi0pugMgr7na8ymgStT0lQ+oEPkG06Ag3zRQgEpRkQBKHS6RQttIT3IanliEmnhUknXGBbrFxbRYkt5dZaoZQoLcksQQiHHKO0JLOEWJDUuomQYguIE7U16QLElVuK2BI8oOistAgODfJ1EwgPkZvQkswSYkNSywOK2sJ7YuuraG0QPXiFhGRWWtRpUQv/9++nqNOilq+bQvBAHRwsS6ElCLEhqfUAMeRWaEhslYGcUw9IaKVHx0GpCAjUosPAVF83hXATOcosCS3hLUhqBUBIuRUjaitqOoKSxVZC0Vr6UiCEpP09me0ysA06mC6jmekq1Az1qJY6chJan8tskA4IooCIvyEbqZ01axZSU1MREhKCihUrcjpm+PDhUKlUVktycrJobfTbqG1ggHfkliK2soOitNKjTotaiI6rAgCIjI/B602LMM+0F58bv0aa6W8ft46wh5zSDaQhsxQE8FdkM06tXq/H448/jpSUFKxcuZLzcd27d8eqVavY9cBAccXILLbqEoPHdYkxrq2o49l6Yyxbb49fG6STxZS5BGGPmvWroXazeKttvR9pCMZggEqrBQwGYMoUYMcOVAbwFoBN6gfw7S+FyDn/j0/aTFgjJ5n1KSSyBGQktTNmzAAAZGRkuHWcTqdDTEyMCC1yjpTlVtRZyEhsiXtQlNb3DJ8xCA/2b2uznWGYsv9oNMDTTwNPP83+bDcAQPT/HcHMwYu81k7CFpJZDpDIEuWQjdTyZd++fYiKikLFihXRvn17zJo1C1FRUQ7Ll5SUoMSiU05BQYFH5xdabmURtVWi2EoAlU4n6w5jhPeZ/9xyGI1GdBiYCpOJgVqtAgCoVGX/wvwvAJhMgFoNrF+PXS+uA1DB+w0mSGa5ICOZVZeUQq0RNtNTbfTi7J4yQzY5tXzo0aMHvvjiC+zZswfz58/HsWPH8PDDD1tJa3nmzJmDiIgIdqlZsyYAwBTo2UslVGcyoTuSidaJzBt5tt7MsZXRQ5QgzNwtKMLspxZj3jPLYCgphbHUwR/XpaVASQkwfDjw5JMIKbjm1XYS8sibNefL+kxoKV+WcIFPpXb69Ok2HbnKL8ePH+dd/6BBg9CrVy80adIEvXv3xrfffos//vgD33zzjcNj0tPTkZ+fzy45OTnsPk/FFhCuM5kYcisKJLaC4vO8NTeQ+he0P7F79X6MbvWqc6lt0QJYvRoAcAP03nkLOcmsTzCLrASev4T08Wn6wdixY/HEE084LVOrVi3BzhcbG4v4+HhcuHDBYRmdTgedkw+vpdiq9fyGwJFqSoJoubZipyN4MxVBAvm1lIZA8MFkNCEwxMEsYiEhgMEAE4BrCMavqipebZs/InWRBSjFgJAfPpXaKlWqoEoV7z08r1+/jpycHMTGxgpSn1lwfS23suhIZo7YiiW3JLaSRB0cTB3GJEK7vm1hMpqg1qjBlJZCFRBQFqENCACMRpj694fq/fexTN0SJpWiM9N8CsmsE0hkCQ+RzZMrOzsbWVlZyM7OhtFoRFZWFrKyslBYWMiWadCgAbZs2QIAKCwsxJQpU3DkyBFcunQJ+/btQ+/evVGlShX07dtX0LaZAtUepSZIOd9WcMRMR9AFei8dgX4O44wcvsT9gfYDU6BSq8AwDC4ePIObLVOBgwcBhgHUahgHPYG31Wn4UV3D101VJFJPM/Bpviw9TwmBkI3UvvXWW0hMTMS0adNQWFiIxMREJCYmWuXcnj9/Hvn5+QAAjUaDX375BX369MEDDzyAYcOG4YEHHsCRI0cQFhYmShuVKLeidCQTuxOZn+TZ+nyQc0I2VK1ZGfUSE2AymvBp+jq80H0eBp+pgZe7zsKe9KUwGU0ISGqJP+Ka+7qpisIssnKQWa/jjVxZmrDHiqVLlyIhIQFBQUFISkrCwYMHHZbdvHkzunTpgqpVqyI8PBwpKSnYtWuXVZmMjAy7faGKi4vFvhSHyGZIr4yMDJdj1LJjLwIIDg62eQO8hRLTEkRLSRAzHQHwTkqCj9MR5JCKQGkIvoUxMfhp50msfWcTzh/7q2ybSo3TqIrT8w9i68FcPPVGP6tnKMEfKUss4Ae5subnv0naz0VvsmHDBkyYMAFLly5FWloaVqxYgR49euDcuXOIi4uzKX/gwAF06dIFs2fPRsWKFbFq1Sr07t0bP/30ExITE9ly4eHhOH/+vNWxQUEOcve9gIqhp5hTCgoKEBERgQc7TINWy++N4iu37PECdCgDhMu5FWVsWzE7knkr19bHebZSF1szJLeEEpG6yAIKz5W1E5U1mErw/cUPkZ+fj/DwcPHbYIHZHTo/MAlajbDXbzCW4Ps/FiAnJ8fqupx1dG/bti1atmyJZcuWsdsaNmyIxx57DHPmzOF03saNG2PQoEF46623AJQFGydMmIBbt27xvxiBkU36ga8xBqhh5JlaIKW0BCGQXUqCt3JtfZwXJpdUBDl8+RMEV+SSXuD154O30gu82ZeCD6WlZUEbIZfSsiBQzZo1rcbVdySner0eJ06cQNeuXa22d+3aFYcPH+Z0GSaTCbdv30ZkZKTV9sLCQsTHx6NGjRp45JFHcOrUKR4vknDIJv1AKpjFVsMj+iqFtAS/T0lQeDqC+YtL6lFbswRQ1JaQI1KWWMD/IrL+ir1IrT2uXbsGo9GI6Ohoq+3R0dHIy8vjdK758+fjzp07GDhwILutQYMGyMjIQNOmTVFQUIBFixYhLS0Np0+fRr169XhckeeQ1PKE5NayPQLLrZjDf3kr19b8cPeh3EpdbAHKtSXkg9RFFiCZ9TfCw8PdSqtQWU6LjbJ+SOW32WP9+vWYPn06tm3bhqioKHZ7cnIykpOT2fW0tDS0bNkSH374IRYvXsy5XUJCUushJLeW7SG5tcGHcktRW4LgjxwkFiCRJVxTpUoVaDQam6js1atXbaK35dmwYQNGjRqFjRs3onPnzk7LqtVqtG7d2ukEV2JDObUCYQxUs4u7SCHnVtLDgImdb+sNaOgvl8hh+CNC2cjlHqQ8WcIdAgMDkZSUhMzMTKvtmZmZSE1NdXjc+vXrMXz4cKxbtw69evVyeR6GYZCVlSXYBFd8oEitCPCN3no6BS9FbnniB1FbQD4pCQBFbwnvIHV5tYQism4SGAAYPRt5SElMmjQJQ4YMQatWrZCSkoKPP/4Y2dnZGD16NAAgPT0dV65cwZo1awCUCe3QoUOxaNEiJCcns1He4OBgREREAABmzJiB5ORk1KtXDwUFBVi8eDGysrKwZMkS31wkSGo5YwpUA24Ofuar1ATLqC1fwSW5FREJpCQA0k9LAKylgwSXEAISWQ7IWWQJuwwaNAjXr1/H22+/jdzcXDRp0gQ7d+5EfHw8ACA3NxfZ2dls+RUrVsBgMGDMmDEYM2YMu33YsGHsnAG3bt3Cc889h7y8PERERCAxMREHDhxAmzZtvHptltA4tS4wjzWX3GsmtAH3x6nlI5t85NaT81kdL8BYt5Id51as0RJofFtJQnJLuANJLEcUKLLm8Vx9Ok5twkvQqgUep9aH4+9KHYrU8oRPJNUy35ZvaoISOpVR5LYcEkhLAOQjt+UlhSSXMCMngTVDIssDisgSDiCp9RC+skl5tyS3NpDc8oJSFPwXOUosQCLLCxJZggMktQLBVzZ9Fb2VUt4tyW05LL90KO/WLSiKq0zkKq9mSGJ5ogSRLdEDatdjwbqFyUupcTKEpFYEfBW99VVqgt/KLeA30VtAfoIL2JchEl1pI3eBBSQwZTWJLAAIP507IXlIajliDFRBFVD215ZGz61vnafRW7mlJliOc+uJ4Fo+iAQRXMuHpNyjtz7sVCbX9ITykOhKAyXIqxm/kFhAfiJrlPezinAfkloeGAPdk1tAXh3LKDWBB96K3vo4NQGw/QKXu+QCjgWLZJc/SpLW8vhcYgF5iyxFYwmRIKn1ALPcAhS9dYTko7dKmIIXkEQEF1CG4FriSsz8WXqVLK3lIYkVABJZwguQ1AoERW9dI8norTdSEwASXIXijthJWYD9SVBdIQmBNUMiy0IiS3CBpJYjpgBuvRcpeusaoeW2rC0UvWWRQP4toMw0BU8gcZQmJLECIvBoBSSyhLuQ1LqBu9FYTwTXH6K3QqUmlLWForc2lP+CJMkl/BxJCSwgf4kFJBmNNX+3MAa1i5KE0iCp5QEfWXVXiP+/vTuPjqo6wAD+PWCSCQIja5YaQoAKpWglAUkiSpBj2KRAK0u1CKfKESzaQC2glgZaLYayaFG2U4x/0KOcUxIPIiqhJoGWaFli2YNiACFJEQ4EypZlbv+IM5193nuzvGW+3zlzTF7uve9ebmbel+udN9G+761eVm8Bne69BYwdcAHdbFFw8BUwGHQpHHQXXh2iFWKBmFqNdb1+UGxjqA2R0oBrpO0J3HvrgQE34hh0SSkG2O/E6GoskSuG2jCKZsDl6q2SfoR59RYwb8AFdBVyAQZd0nFwdcUQ61dMr8beagTCvQuCnyjmF0OtTHYLIH33vGwjI8Oo3X9rxu0J4Vy9BRhwI07nIRfwH3IYdo3LEMHVIdoBFoi5EAuEHmRdrz0UGzjjKthdnq/BAq6ZtycoPR/AgBsSz4saQ66XQMGIgVdbhgqtrrQIsABDrKp+eESaZnXXGDIuhtoQ2VWs3gL6CrhGvXsCEMMBF9BmFRcwVMh1JSdUMfiqY9jA6smMARYIe4gFdBxkKabxtyFMlKzeAtx/61WfATc0Wq3iAr6DgEGCriel4cyMIdg0ATUQrcKrA0NsCP1gbCH/+NshU0ucBMjc96o24Ebq/rdG2n8LxFjABcwXcgFTBd1AYiIAGp3ZAyxg6hALMMiSfPxNUUFJqIzk/lvXOmZ8gxmg34Db2h+DrOIC2odcwH+4MGHYpSjTOrg6RCPAAgyxgeq6XHPsbfjhC7GGoTZEegm4WrzBrPVcsRlwW/tj0FVcQB8h14Fhl+TQS3B1MHCABcwZYokYamWyW4BgT10GXAbc1v6EMYhqFXIBbYMuEDjEMPCak96Cq0O0AizAECunPoMs+cFQq0CkgigDrr4CLqDTbQpA9EIuoM+g6xAs/DD06o9eA6uraIZXQPcBFjB2iG2xMPzGGoZalRhwg50r9ICr9JxAeAIuELlVXMDAIRfQd9B1JTdAMfyGxghB1Zdoh1cgYgEWYIh1aPGsF+GXQzlE420ISd71VnabQoevuTrBUBsGDLjBzhX6fXCVnhPwfmHVwyouEOWQC2gTdAF9hl1PakOZmcKwUYOpHFqEV8AwARYwWYilmMdQK1NLOwDfvZa0DZARjB5w5dYxWsAF9LmKC0Q45ALRX811MHLYDcbMQdBotAquDhEMsABDrCcGWQqEoVaFFpfXGLMFXDV11G4Z8Hxx0mqbAqCfVVxAg5ALRC/oAoFDiBkCL4WX1qHVIcLhFdBngAWMF2Id57NLDMCxhqE2REYNuHLaVtoXZ58MvooLxFjIBfxfsKMZdoHgAYah13z0ElodohBegfAHWIAhloihVia7BZAsgYOjkQKu0rbVlAe0D7hKz+tsIwJbFYDIhFwgQkEX0H5V15OcAMTgqw96C6ueDBxeAf0EWIAhlvSDoVYhu8frk7/wqCbgBmoP0G/AlVtHi20KnufVchUX8H0hMkXQBbQNu66UhimG4OD0HlD9iVJwddB7gAW0v0dstEJsS5yEFkkKXpBMhaE2RHLCY4vH61w4VnHVBtxg7SptO5Q64VjFbT1f9PbiAuENuUBkVnOBKAddIHCA0Evg9SWcgU1PAdmoQVSpKAdXIHLhFdBXgAW0eVOX2hBLxFArkz0OkL67RrTxc92SHUjDvE1B6aqp3vfhAsbdquBsR4eruYD/i3FEwy4QPHjoOfQqEStBMlo0CKyuIhleAf0FWIAhloyNoVYFu8t1S28BFzD+NgVAm1Vcz/MqPbdbOwZZzXWI+qqup1gJvfR/GgdWV0YKrw5ar8IC+g+xdguDb6xhqA2R0oALaLcPFwgcKkPZphCs7VDqhGsVt/V85gy5DuEMu4Eu9FENvID8AMTwqy0dBVVPkQ6uDuEOsHpYgQVCuz9stEKsVx0d7Aay37wFuxTmRQjB1zl/GGplsrdrvfsB4D/syQm4gHb7cAF9reKqrWPGkAuEHnSByG5dcKWrwOtKbahiGPam44DqS7RCq4NeV1+dbRloFbb1fMpCLLcfkC8MtSrICXt2j611WmxTCNpmlN5sJqd9tXUAfYVcped3ayuKQReITNgFdBx4A4lWgAs1PBssaIZTtEMrEJng6mCGABvKuSMdYu0WwC7vEkImwlArk/Dzeio37EVqmwKg/ZvNgrWtpn21dQBtQ66v8yvtg1tbEQq6QPTDLiAvmOg2+IZDDIfSQLQIrK5iJbwCxgiwaup4XpMoNjHUKiBrhVbhKm6o2xQA7ffieratdKuCnPbV1gHCG3Jbzxt60FUbcgH/F0kjh11XcgOOqcOvCWgdVD1FMrgC4Q2vgPYBNpQ+MMSSVhhqVZITEGWVieA2BUD7vbhy2lbavq86SuqFGjD1tprrbDOCq7pA8FAQrdDroCY0MQiro7eA6kukQ6tDuMMrwAArh5IQ62i/Bdx3G2sM8Vlzp0+fxlNPPYX09HQkJCSgT58+KCgoQGNj4Lc2CiGwZMkSpKSkICEhAbm5uTh69KiqPtgtAnZL4DsHOB4hlYn7/0NOO8Ge6C2W/z8CUdRmnOT2CEZJ22raD7WePa6N10OJlrg2Xg81Qu2Hzzbj2/l8RIKIbxvwoQf2eEtYH3oU7jHqYZzBfrcicceBSDx3fD3H1d0ZILTXnFD6oOZ1NtRrRrivSbFq7dq1SE9Ph9VqRWZmJvbs2ROwfEVFBTIzM2G1WtG7d2+sX7/eq8zWrVsxYMAAxMfHY8CAASgpKYlU92UxxErtiRMnYLfbsWHDBvTt2xdHjhzBrFmzcP36daxYscJvveXLl2PVqlV45513cPfdd+OVV17BI488gurqanTs2FFVXzyDbZsm7ydQJLYpAPrciwvocz9uKPWA8K/mtp4/PCu6avrj1W6Ai3M4V3ddyQke0V7tDZUeAp/RafUHT6T+uAPCs/LqoNUKbOu59bcKq/YcsW7Lli3Iz8/H2rVr8cADD2DDhg0YM2YMjh07hp49e3qVr6mpwdixYzFr1ixs3rwZ//znP/Hss8+ie/fu+OlPfwoAqKysxNSpU/GHP/wBkyZNQklJCaZMmYJ//OMfGDp0aLSHCACQhBCGfH/gn/70J6xbtw5ff/21z58LIZCSkoL8/HwsXLgQAHD79m0kJiaisLAQzzzzjKzzXL16FTabDWmFr6Btm4SAZX0FXO8ywc8pq4zM++/JaQsIHHDVtulsW0GYVNO+mnOEWg8IPVi2nj/0NlyFo08B249Q4FXDaAE4VuhlVR6IbHAF9BVegegHWDX1IhlgPdtuabyFIxtfQkNDAzp16qTsxCFyZIcRbX+CdlJ4//htFk0oaylWNK6hQ4ciIyMD69atcx77wQ9+gIkTJ2LZsmVe5RcuXIht27bh+PHjzmOzZ8/Gv//9b1RWVgIApk6diqtXr+Kjjz5ylhk9ejQ6d+6Md999V+3wQmKIlVpfGhoa0KVLF78/r6mpQX19PfLy8pzH4uPjMXz4cOzdu9dvqL19+zZu377tdh4AsN+6BVhbj0mNvp9kjjgRKNw6ykiB9sU62gmQH5xlgoRbZ7lgq6EuX7cNklvktulZXvYKq8L23esoC6nN302VqnDrMs1qw2SzSxttm8IQSF2uaREJuB55RdOQGyA7SREO97FMBAtOzdrsW/YZYJvD+/vpFRpDbL7F4tKeyn82tz4pbMMtMCqo6/ZJXTIXWJyBU2Z5Z99klPfXdkvjLQCti1xaaUYTEObTN383WVevXnU7Hh8fj/j4eK/yjY2NOHDgABYtWuR2PC8vD3v37vV5jsrKSrf8BACjRo3Cpk2b0NTUBIvFgsrKSsybN8+rzOuvv650SGFjyFB76tQprFmzBitXrvRbpr6+HgCQmJjodjwxMRFnzpzxW2/ZsmVYunSp1/FvCl5R2VsiIiLSyqVLl2Cz2aJ6zri4OCQlJWFP/QcRab9Dhw5ITU11O1ZQUIAlS5Z4lb148SJaWlp85iFHVvJUX1/vs3xzczMuXryI5ORkv2X8tRkNmobaJUuW+AyQrvbt24fBgwc7v6+trcXo0aMxefJkPP3000HPIUnuq6ZCCK9jrl588UXMnz/f+f2VK1eQlpaGs2fPRv1JoaWrV68iNTUV33zzTdT/t42WOG6OOxZw3Bx3LGhoaEDPnj0D/l/dSLFaraipqQn6hna1fGUZX6u0rpTmIV/lPY8rbTPSNA21c+fOxbRp0wKW6dWrl/Pr2tpajBgxAtnZ2di4cWPAeklJSQBa/9pITk52Hr9w4YLXXxau/C3f22y2mHoxcOjUqRPHHUM47tjCcceWWB13mzba3OjJarXCarVqcm5X3bp1Q9u2bb1WUAPloaSkJJ/l27Vrh65duwYsEyhjRZqmt/Tq1q0b+vfvH/Dh+IU4f/48cnNzkZGRgaKioqC/pOnp6UhKSkJpaanzWGNjIyoqKpCTkxPRcRERERHpQVxcHDIzM93yEACUlpb6zUPZ2dle5Xfu3InBgwfDYrEELKNlxjLEfWpra2uRm5uL1NRUrFixAt9++y3q6+u9/kLo37+/8x5pkiQhPz8ff/zjH1FSUoIjR45g5syZaN++PR5//HEthkFEREQUdfPnz8df/vIXvP322zh+/DjmzZuHs2fPYvbs2QBat14++eSTzvKzZ8/GmTNnMH/+fBw/fhxvv/02Nm3ahBdeeMFZ5le/+hV27tyJwsJCnDhxAoWFhdi1axfy8/OjPTwnQ7xRbOfOnfjqq6/w1Vdf4a677nL7meu7Gqurq513KwCABQsW4ObNm3j22Wdx+fJlDB06FDt37lR0j9r4+HgUFBQE3atiNhw3xx0LOG6OOxZw3LE1bl+mTp2KS5cu4fe//z3q6uowcOBA7NixA2lpaQCAuro6nD171lk+PT0dO3bswLx58/DWW28hJSUFf/7zn533qAWAnJwcvPfee/jtb3+LxYsXo0+fPtiyZYtm96gFDHyfWiIiIiIiB0NsPyAiIiIiCoShloiIiIgMj6GWiIiIiAyPoZaIiIiIDI+h1sPp06fx1FNPIT09HQkJCejTpw8KCgqCfiqIEAJLlixBSkoKEhISkJubi6NHj0ap1+Hx6quvIicnB+3bt8edd94pq87MmTMhSZLbIysrK7IdDTM14zbDfF++fBnTp0+HzWaDzWbD9OnTceXKlYB1jDjfa9euRXp6OqxWKzIzM7Fnz56A5SsqKpCZmQmr1YrevXtj/fr1UeppeCkZd3l5ude8SpKEEydORLHHodu9ezfGjx+PlJQUSJKE999/P2gdM8y30nGbYb6XLVuGIUOGoGPHjujRowcmTpyI6urqoPXMMN/kH0OthxMnTsBut2PDhg04evQoVq9ejfXr1+Oll14KWG/58uVYtWoV3nzzTezbtw9JSUl45JFHcO3atSj1PHSNjY2YPHky5syZo6je6NGjUVdX53zs2LEjQj2MDDXjNsN8P/744/jiiy/w8ccf4+OPP8YXX3yB6dOnB61npPnesmUL8vPz8fLLL6OqqgoPPvggxowZ43brGlc1NTUYO3YsHnzwQVRVVeGll17C888/j61bt0a556FROm6H6upqt7n9/ve/H6Ueh8f169fxox/9CG+++aas8maZb6XjdjDyfFdUVOCXv/wlPvvsM5SWlqK5uRl5eXm4fv263zpmmW8KQFBQy5cvF+np6X5/brfbRVJSknjttdecx27duiVsNptYv359NLoYVkVFRcJms8kqO2PGDDFhwoSI9ida5I7bDPN97NgxAUB89tlnzmOVlZUCgDhx4oTfekab7/vvv1/Mnj3b7Vj//v3FokWLfJZfsGCB6N+/v9uxZ555RmRlZUWsj5GgdNxlZWUCgLh8+XIUehcdAERJSUnAMmaZb1dyxm3G+b5w4YIAICoqKvyWMeN8kzuu1MrQ0NCALl26+P15TU0N6uvrkZeX5zwWHx+P4cOHY+/evdHooqbKy8vRo0cP3H333Zg1axYuXLigdZciygzzXVlZCZvN5naT7KysLNhstqBjMMp8NzY24sCBA27zBAB5eXl+x1hZWelVftSoUdi/fz+ampoi1tdwUjNuh0GDBiE5ORkjR45EWVlZJLupC2aY71CYab4dH7wU6Fod6/MdCxhqgzh16hTWrFnj/Cg5Xxwf15uYmOh2PDEx0eujfM1mzJgx+Otf/4pPP/0UK1euxL59+/Dwww/j9u3bWnctYsww3/X19ejRo4fX8R49egQcg5Hm++LFi2hpaVE0T/X19T7LNzc34+LFixHrazipGXdycjI2btyIrVu3ori4GP369cPIkSOxe/fuaHRZM2aYbzXMNt9CCMyfPx/Dhg3DwIED/ZaL1fmOJTETapcsWeJzY7zrY//+/W51amtrMXr0aEyePBlPP/100HNIkuT2vRDC61i0qRm3ElOnTsW4ceMwcOBAjB8/Hh999BFOnjyJDz/8MIyjUC7S4waMP9+++hpsDHqd70CUzpOv8r6O652Scffr1w+zZs1CRkYGsrOzsXbtWowbNw4rVqyIRlc1ZZb5VsJs8z137lwcOnQI7777btCysTjfsaSd1h2Ilrlz52LatGkBy/Tq1cv5dW1tLUaMGIHs7Gxs3LgxYL2kpCQArX8FJicnO49fuHDB66/CaFM67lAlJycjLS0NX375ZdjaVCOS4zbDfB86dAj/+c9/vH727bffKhqDXubbl27duqFt27Zeq5OB5ikpKcln+Xbt2qFr164R62s4qRm3L1lZWdi8eXO4u6crZpjvcDHqfD/33HPYtm0bdu/ejbvuuitgWc63+cVMqO3WrRu6desmq+z58+cxYsQIZGZmoqioCG3aBF7QTk9PR1JSEkpLSzFo0CAArfvaKioqUFhYGHLfQ6Fk3OFw6dIlfPPNN25hTwuRHLcZ5js7OxsNDQ3417/+hfvvvx8A8Pnnn6OhoQE5OTmyz6eX+fYlLi4OmZmZKC0txaRJk5zHS0tLMWHCBJ91srOz8cEHH7gd27lzJwYPHgyLxRLR/oaLmnH7UlVVpct5DSczzHe4GG2+hRB47rnnUFJSgvLycqSnpwetw/mOAVq9Q02vzp8/L/r27Ssefvhhce7cOVFXV+d8uOrXr58oLi52fv/aa68Jm80miouLxeHDh8XPfvYzkZycLK5evRrtIah25swZUVVVJZYuXSo6dOggqqqqRFVVlbh27ZqzjOu4r127Jn7961+LvXv3ipqaGlFWViays7PF9773PVOPWwhzzPfo0aPFvffeKyorK0VlZaW45557xKOPPupWxujz/d577wmLxSI2bdokjh07JvLz88Udd9whTp8+LYQQYtGiRWL69OnO8l9//bVo3769mDdvnjh27JjYtGmTsFgs4m9/+5tWQ1BF6bhXr14tSkpKxMmTJ8WRI0fEokWLBACxdetWrYagyrVr15zPXwBi1apVoqqqSpw5c0YIYd75VjpuM8z3nDlzhM1mE+Xl5W7X6Rs3bjjLmHW+yT+GWg9FRUUCgM+HKwCiqKjI+b3dbhcFBQUiKSlJxMfHi4ceekgcPnw4yr0PzYwZM3yOu6yszFnGddw3btwQeXl5onv37sJisYiePXuKGTNmiLNnz2ozAJWUjlsIc8z3pUuXxBNPPCE6duwoOnbsKJ544gmvW/yYYb7feustkZaWJuLi4kRGRobbLX9mzJghhg8f7la+vLxcDBo0SMTFxYlevXqJdevWRbnH4aFk3IWFhaJPnz7CarWKzp07i2HDhokPP/xQg16HxnGrKs/HjBkzhBDmnW+l4zbDfPu7Tru+Tpt1vsk/SYjvdkkTERERERlUzNz9gIiIiIjMi6GWiIiIiAyPoZaIiIiIDI+hloiIiIgMj6GWiIiIiAyPoZaIiIiIDI+hloiIiIgMj6GWiIiIiAyPoZaIDKO8vBySJOHKlStad4WIiHSGoZaIdCs3Nxf5+flhb1eSJLz//vtha6+pqQkLFy7EPffcgzvuuAMpKSl48sknUVtbG7ZzEBFRYAy1REQhunHjBg4ePIjFixfj4MGDKC4uxsmTJ/HjH/9Y664REcUMhloi0qWZM2eioqICb7zxBiRJgiRJOH36NADgwIEDGDx4MNq3b4+cnBxUV1e71f3ggw+QmZkJq9WK3r17Y+nSpWhubgYA9OrVCwAwadIkSJLk/P7UqVOYMGECEhMT0aFDBwwZMgS7du2S1VebzYbS0lJMmTIF/fr1Q1ZWFtasWYMDBw7g7NmzYfn3ICKiwBhqiUiX3njjDWRnZ2PWrFmoq6tDXV0dUlNTAQAvv/wyVq5cif3796Ndu3b4xS9+4az3ySef4Oc//zmef/55HDt2DBs2bMA777yDV199FQCwb98+AEBRURHq6uqc3//3v//F2LFjsWvXLlRVVWHUqFEYP3686lDa0NAASZJw5513hvCvQEREcklCCKF1J4iIfMnNzcV9992H119/HUDrG8VGjBiBXbt2YeTIkQCAHTt2YNy4cbh58yasViseeughjBkzBi+++KKznc2bN2PBggXOPa6SJKGkpAQTJ04MeP4f/vCHmDNnDubOnauo37du3cKwYcPQv39/bN68WVFdIiJSp53WHSAiUuree+91fp2cnAwAuHDhAnr27IkDBw5g3759zpVZAGhpacGtW7dw48YNtG/f3meb169fx9KlS7F9+3bU1taiubkZN2/eVLxS29TUhGnTpsFut2Pt2rUqRkdERGow1BKR4VgsFufXkiQBAOx2u/O/S5cuxU9+8hOvelar1W+bv/nNb/DJJ59gxYoV6Nu3LxISEvDYY4+hsbFRdr+ampowZcoU1NTU4NNPP0WnTp1k1yUiotAw1BKRbsXFxaGlpUVRnYyMDFRXV6Nv375+y1gsFq929+zZg5kzZ2LSpEkAWvfYOt6YJocj0H755ZcoKytD165dFfWbiIhCw1BLRLrVq1cvfP755zh9+jQ6dOjgXI0N5He/+x0effRRpKamYvLkyWjTpg0OHTqEw4cP45VXXnG2+/e//x0PPPAA4uPj0blzZ/Tt2xfFxcUYP348JEnC4sWLZZ0PAJqbm/HYY4/h4MGD2L59O1paWlBfXw8A6NKlC+Li4tT/IxARkSy8+wER6dYLL7yAtm3bYsCAAejevbus/a2jRo3C9u3bUVpaiiFDhiArKwurVq1CWlqas8zKlStRWlqK1NRUDBo0CACwevVqdO7cGTk5ORg/fjxGjRqFjIwMWf08d+4ctm3bhnPnzuG+++5DcnKy87F37151gyciIkV49wMiIiIiMjyu1BIRERGR4THUEhEFsWfPHnTo0MHvg4iItMftB0REQdy8eRPnz5/3+/NAd1ogIqLoYKglIiIiIsPj9gMiIiIiMjyGWiIiIiIyPIZaIiIiIjI8hloiIiIiMjyGWiIiIiIyPIZaIiIiIjI8hloiIiIiMrz/Adu/tIK90B4XAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Analyze the objective space by evaluating the sum of squared errors (SSE)\n", - "# over a grid of theta_1 and theta_2 values\n", - "theta1_range = np.linspace(-2, 2, 200)\n", - "theta2_range = np.linspace(-2, 2, 200)\n", - "sse_grid = np.zeros((len(theta1_range), len(theta2_range)))\n", - "\n", - "# Use the model function from cell 5\n", - "for i, t1 in enumerate(theta1_range):\n", - " for j, t2 in enumerate(theta2_range):\n", - " y_sim = np.array([model(x, t1, t2) for x in conc])\n", - " sse = np.sum((vel - y_sim) ** 2)\n", - " sse_grid[i, j] = sse\n", - "\n", - "# Plot the objective space\n", - "plt.figure(figsize=(8, 6))\n", - "X, Y = np.meshgrid(theta2_range, theta1_range)\n", - "cp = plt.contourf(X, Y, sse_grid, levels=50, cmap='viridis')\n", - "plt.colorbar(cp, label='Sum of Squared Errors (SSE)')\n", - "plt.xlabel('theta_2')\n", - "plt.ylabel('theta_1')\n", - "plt.title('Objective Space: SSE over theta_1 and theta_2')\n", - "# Optionally, mark the minimum SSE location on the grid\n", - "min_idx = np.unravel_index(np.argmin(sse_grid), sse_grid.shape)\n", - "plt.scatter([theta2_range[min_idx[1]]], [theta1_range[min_idx[0]]], color='red', label='Grid Minimum')\n", - "plt.scatter([true_params['theta2']], [true_params['theta1']], color='white', marker='*', s=100, label='True Params')\n", - "plt.legend()\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "5eb58543", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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RkhIiEPfEwAANwLjzpyKwrjTMAxj27ZthpeXl9GzZ8+rnlucx53OFG2zMe4Eipdi3R7hzz//VLdu3RQWFiaLxaLFixc79fzU1FQNGDBAderUkdVq1Z133nnJ81auXKlGjRrJ09NTlSpV0vvvv3/94YF8UqpUKa1atUobNmzQG2+8oR49emjv3r0aPXq06tSpk+NjQF26dFF0dLQWLVqkUaNGqVatWlq8eLG6d+9+yZ1vn3jiCW3YsOGiW/369a+YadCgQUpJScmxIcWsWbPk4eGhvn37SpJKliypypUra9KkSZoyZYq2bNlyyf5m16JNmzby8/Oz3w8JCVFwcLD942Opqan67bff1LNnT3l7eyszM9N+69Kli1JTUy/5Ua3cEhMT9eyzz6pKlSqyWq2yWq3y9fVVUlKSdu/enSffiyOOHz8uSQoODnb6uV27dpWrq6v9ft26dSXJ/l7t379f//zzj+6//35Juui9iomJ0Z49e676OnFxcRo6dKjCw8NltVrl5uamiIgISbqu92rz5s3q3bu3mjZtqgkTJlzzdS7n6aefVteuXdWnTx999tlnevfdd1WnTh374z/++KNq166t+vXr53hvOnbsmONjb3/88Yck2d/HbNl/Hy4lODhYcXFxyszMzPPvCwCAa8G482KFfdx56NAh3XHHHQoPD9fHH3981fOL87gzvzHuBAq/Yl20TUpKUr169fTee+9d0/OzsrLk5eWl4cOHq127dpc8JyoqSl26dFHLli21ZcsWPf/88xo+fLi+/fbb64kO5LvGjRvr2Wef1YIFC3T8+HE9+eSTOnTo0EU7gXp5eenOO+/UpEmTtHLlSu3fv181a9bU9OnTFRkZmePccuXKqXHjxhfdfH19r5ilVq1aatKkiWbNmiXpwt+9L774Qj169FDJkiUlyd5/rGPHjpo4caIaNmyooKAgDR8+XOfPn7+u96JUqVIXHfPw8FBKSoqkC33WMjMz9e6778rNzS3HrUuXLpLkUM+rvn376r333tOQIUO0dOlSrV+/Xhs2bFBQUJD9tW6E7Nfy9PR0+rm53ysPD48c1zxx4oSkCzsE536vhg0bJunq75XNZlOHDh20cOFCPfPMM/rtt9+0fv16+wTlWt+rLVu2qH379qpataqWLFliz56XLBaLBgwYoNTUVIWGhuboKSZdeH+2b99+0Xvj5+cnwzDs783p06dltVover9DQ0Mv+9qenp4yDEOpqal5/n0BAHA9GHf+v8I87jx8+LDatGkjq9Wq3377zf5+XUlxHXfeCIw7gcLv4o7vxUjnzp0v2nXxv9LT0/Xiiy/qyy+/1Llz51S7dm29+eabat26taQLTddnzpwpSfrrr7907ty5i67x/vvvq3z58po6daokqUaNGtq4caPeeust3X333Xn9LQH5ws3NTWPGjNHbb7991R1Oy5cvr4cfflgjRoxQZGSkatWqlScZBg4cqGHDhmn37t06ePCgYmJiNHDgwBznRERE6JNPPpEk7d27V/Pnz9fYsWOVnp6eryvcS5QoIVdXVz344IN67LHHLnlOxYoVr3iN+Ph4/fjjjxozZoyee+45+/G0tDSdOXMmT/NeTenSpSUpX143+9qjR4/WXXfddclzqlWrdsVr7Ny5U9u2bdPs2bPVv39/+/H9+/dfc64tW7aoXbt2ioiI0LJlyxQQEHDN17qSmJgYPfbYY6pfv74iIyM1atQovfPOO/bHS5cuLS8vL3366aeXfH72+1eqVCllZmbq9OnTOQbQsbGxl33tM2fOyMPD46qTVQAAzMS488oK6rjz8OHDat26tQzD0IoVK1SuXDmHnlccx503CuNOoPAr1kXbqxk4cKAOHTqkr7/+WmFhYVq0aJE6deqkHTt2qGrVqg5dY+3aterQoUOOYx07dtQnn3yijIyMS+5aDpgpJibmkjvzZn/0JywsTJJ0/vx5WSyWS/5DnPvcvNCnTx+NHDlSs2fP1sGDB1W2bNmL/m7910033aQXX3xR3377rTZv3nzFa//3t/JeXl5OZ/P29labNm20ZcsW1a1bV+7u7g691n9ZLBYZhnHR6s6PP/5YWVlZTme6HhEREfLy8tKBAwcueuy/Kz2uRbVq1VS1alVt27ZN48ePv+K5V3qv/vt4tg8++OCaMm3dulXt2rVTuXLltHz5cpUoUeKarnM1WVlZ6tOnjywWi37++Wd9+eWXGjVqlFq3bm2fSNxxxx0aP368SpUqdcUJV5s2bTRx4kR9+eWXGj58uP34V199ddnnHDx4UDVr1sy7bwgAgOvEuLNojDujo6PVunVrZWVlacWKFfbWAY4obuPOG4VxJ1A0ULS9jAMHDmju3Lk6evSofQAwatQo/fLLL5o1a9ZVf+hni42NVUhISI5jISEhyszM1KlTpy45SAHM1LFjR5UrV07dunVT9erVZbPZtHXrVk2ePFm+vr564oknJEl79uxRx44ddd9996lVq1YqU6aMzp49q59++kkffvihWrdurebNm+e4dnR09CV7bAUFBaly5cpXzBUYGKiePXtq9uzZOnfunEaNGiUXl//v8LJ9+3Y9/vjjuueee1S1alW5u7vr999/1/bt23OsILiU7N5Ob775pjp37ixXV9erDoJzmzZtmm699Va1bNlSjz76qCpUqKDz589r//79+uGHH/T7779LkipXriwvLy99+eWXqlGjhnx9fRUWFqawsDDddtttmjRpkkqXLq0KFSpo5cqV+uSTTxQYGOhwjmyHDx/Whg0bJMk+CP7mm28kSRUqVFDjxo0v+1x3d3c1a9bskv+v6tSpo4ULF2rmzJlq1KiRXFxcrnitS/nggw/UuXNndezYUQMGDFDZsmV15swZ7d69W5s3b9aCBQskSbVr15Ykffjhh/Lz85Onp6cqVqyo6tWrq3LlynruuedkGIZKliypH374QcuXL3cqh3Thz3F2e5vXX39d+/bt0759++yPV65cWUFBQU5f91LGjBmjVatWadmyZQoNDdVTTz2llStXavDgwWrQoIEqVqyoESNG6Ntvv9Vtt92mJ598UnXr1pXNZlN0dLSWLVump556Srfccos6dOig2267Tc8884ySkpLUuHFj/fXXX/r8888v+do2m03r16/X4MGD8+R7AQAgLzDuLPzjzri4OLVp00YxMTH65JNPFBcXp7i4OPvj5cqVu+Kq2+I07pSkXbt2adeuXZIu1AqSk5PtY/SaNWvmWaGTcSdQRJi2BVoBo393Vcw2f/58Q5Lh4+OT42a1Wo3evXtf9Pz+/fsbPXr0uOh41apVjfHjx+c4tnr1akOSERMTk9ffBnDd5s2bZ/Tt29eoWrWq4evra7i5uRnly5c3HnzwQWPXrl32886ePWu89tprxu23326ULVvWcHd3N3x8fIz69esbr732mpGcnGw/92q7+N5///0OZVu2bJn9OXv37s3x2IkTJ4wBAwYY1atXN3x8fAxfX1+jbt26xttvv51jV9lLSUtLM4YMGWIEBQUZFovFkGRERUUZhnHpHVoNwzAiIiKM/v375zgWFRVlDBo0yChbtqzh5uZmBAUFGc2bNzdee+21HOfNnTvXqF69uuHm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THsEPz8/+fn55enrZzMMQ1u3blWdOnUkyd7yYvny5erZs6f9vOXLl6tHjx6SLrSLCA0N1fLly9WgQQNJF3rhrly5Um+++Wa+5JQo2gIAAKAAifq3aFux9PV/DA8AAOB6DR06VOHh4XrxxReVnp6uhg0batSoUZo+fbratWunZs2a6c4779Sbb76patWq6fjx41qyZInuvPNONW7cWE888YT69++vxo0b69Zbb9WXX36pyMhIVapU6bKvGRERIYvFoh9//FFdunSRl5dXjv67l+NIngoVKigqKkpbt25VuXLl5Ofnp8qVKyszM1PvvvuuunXrpr/++kvvv/++U+/Trl27lJ6erjNnzuj8+fP2Am39+vUlOdce4XLOnDmj6OhoHT9+XNKFjdqkCyths1fD9uvXT2XLltWECRMkSePGjVPTpk1VtWpVJSQk6J133tHWrVs1ffp0+3VHjhypBx98UI0bN1azZs304YcfKjo62t7WwmKxaMSIERo/fryqVq2qqlWravz48fL29lbfvn2v63u6Eoq2KDBshk3R8dGSpPIB5eVicTE5EQAAuNEOnszuZ0vRFgBQfDAfLpjmzJmjJUuWaMuWLbJarbJarfryyy/VvHlzde3aVV26dNGSJUv0wgsvaNCgQTp58qRCQ0N122232T82f++99+rAgQN69tlnlZqaqrvvvluPPvqoli69/IZtZcuW1bhx4/Tcc89p4MCB6tevn2bPnn3VvBaL5ap57r77bi1cuFBt2rTRuXPnNGvWLA0YMEBTpkzRm2++qdGjR+u2227ThAkTcqwOvpouXbrk2JQre0WqYRgOX+Nqvv/+ew0cONB+/7777pMkjRkzRmPHjpUkRUdH21cLS9K5c+f08MMPKzY2VgEBAWrQoIH+/PNP3XzzzfZz7r33Xp0+fVqvvPKKYmJiVLt2bS1ZskQRERH2c5555hmlpKRo2LBhOnv2rG655RYtW7Ys31YES5LFyMt3rxBISEhQQECA4uPj5e/vb3Yc/EdSepJ8J1z4zVHi6ET5uDNZAwCguBk+d4u+33ZcoztX1yOtKt/Q187rcSLjTgCAowrjfDg1NVVRUVGqWLGiPD09zY4DFChX+vvh6BiRX90AAACgwKA9AgAAAEDRFgAAAAWEYRj2om2lIIq2AAAABUHnzp3l6+t7ydv48ePNjldk0dMWAAAABcLJxDQlpmXKxSKFl/Q2Ow4AAAAkffzxx0pJSbnkYyVLlrzBaYoPirYAAAAoEKL+3YSsXAlveVhdTU4DAAAA6cLGaLjxaI8AAACAAoF+tgAAAMAFFG0BAABQIFC0BQAAAC6gPQIKDKuLVcMaD7N/DQAAipeDbEIGACimmA8DyI2fBCgwPKwemt51utkxAACASVhpCwAorpgPA8iN9ggAAAAwXZbN0OHTFG0BAAAAiaItChDDMHQy6aROJp2UYRhmxwEAADfQsbMpysgy5G51UViAl9lxAAC4oZgPI9uKFStksVh07tw5s6PAZBRtUWAkZyQr+K1gBb8VrOSMZLPjAACAG+jgqURJUsVSPnJxsZicBgCAG4v58I1jsViueBswYMANy9K6dWuNGDEiX65tsVi0ePHiPLteRkaGnn32WdWpU0c+Pj4KCwtTv379dPz48Tx7DeRET1sAAACYjn62AADgRoiJibF/PW/ePL388svas2eP/ZiXV85P/GRkZMjNze2G5SuokpOTtXnzZr300kuqV6+ezp49qxEjRqh79+7auHGj2fGKJFbaAgAAwHTZRdtKQRRtAQBA/gkNDbXfAgICZLFY7PdTU1MVGBio+fPnq3Xr1vL09NQXX3yhsWPHqn79+jmuM3XqVFWoUCHHsVmzZqlGjRry9PRU9erVNWPGjMvmGDBggFauXKlp06bZV/keOnTI/vimTZvUuHFjeXt7q3nz5jkKy5L0ww8/qFGjRvL09FSlSpU0btw4ZWZmSpI9V8+ePWWxWOz3Dxw4oB49eigkJES+vr5q0qSJfv31V4fet4CAAC1fvly9e/dWtWrV1LRpU7377rvatGmToqOjHboGnEPRFgAAAKY7ePJC0bYCK20BACj0ktKTLntLzUx1+NyUjBSHzs1rzz77rIYPH67du3erY8eODj3no48+0gsvvKDXX39du3fv1vjx4/XSSy/ps88+u+T506ZNU7NmzfTQQw8pJiZGMTExCg8Ptz/+wgsvaPLkydq4caOsVqsGDRpkf2zp0qV64IEHNHz4cO3atUsffPCBZs+erddff12StGHDBkkXisgxMTH2+4mJierSpYt+/fVXbdmyRR07dlS3bt2uuegaHx8vi8WiwMDAa3o+roz2CAAAADDdwZMXetpWZqUtAACFnu8E38s+1qVqF/3U9yf7/Sv18W0V0UorBqyw368wrYJOJZ+66DxjTN5u3jZixAjdddddTj3n1Vdf1eTJk+3Pq1ixor2g2r9//4vODwgIkLu7u7y9vRUaGnrR46+//rpatWolSXruuefUtWtXpaamytPTU6+//rqee+45+3UrVaqkV199Vc8884zGjBmjoKAgSVJgYGCOa9erV0/16tWz33/ttde0aNEiff/993r88ced+n5TU1P13HPPqW/fvvL393fquXAMRVsAAACYKjk9U8fjL6y6qVT68pM8AACAG6Fx48ZOnX/y5EkdOXJEgwcP1kMPPWQ/npmZqYCAgGvKULduXfvXZcqUkSTFxcWpfPny2rRpkzZs2GBfWStJWVlZSk1NVXJysry9vS95zaSkJI0bN04//vijjh8/rszMTKWkpDi90jYjI0P33XefbDbbFVtA4PpQtAUAAICpslsjlPRxVwkfd5PTAACA65U4OvGyj7m6uOa4Hzcq7rLnulhydvU89MSh68rlKB+fnJ/8cXFxkWHkXM2bkZFh/9pms0m60CLhlltuyXGeq2vO79dR/938zGKx5Hgdm82mcePGXXI1sKen52Wv+fTTT2vp0qV66623VKVKFXl5ealXr15KT093OFdGRoZ69+6tqKgo/f7776yyzUcUbVFgWF2s6l+vv/1rAABQPBygNQIAoJgravNhH3fH/03Pr3PzUlBQkGJjY2UYhr2AunXrVvvjISEhKlu2rA4ePKj777/f4eu6u7srKyvL6TwNGzbUnj17VKVKlcue4+bmdtG1V61apQEDBqhnz56SLvS4/e/mZ1eTXbDdt2+f/vjjD5UqVcrp7HBc4f9JgCLDw+qh2XfONjsGAAC4wQ78u9K2chCtEQAAxRPz4YKtdevWOnnypCZOnKhevXrpl19+0c8//5xjlenYsWM1fPhw+fv7q3PnzkpLS9PGjRt19uxZjRw58pLXrVChgv7++28dOnRIvr6+KlmypEN5Xn75Zd1xxx0KDw/XPffcIxcXF23fvl07duzQa6+9Zr/2b7/9phYtWsjDw0MlSpRQlSpVtHDhQnXr1k0Wi0UvvfSSffXu1WRmZqpXr17avHmzfvzxR2VlZSk2NlaSVLJkSbm782mpvOZy9VMAAACA/JO9CVklVtoCAIACqEaNGpoxY4amT5+uevXqaf369Ro1alSOc4YMGaKPP/5Ys2fPVp06ddSqVSvNnj1b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uB4OF22ffvpppaena9q0aZKk9PR0NWvWTJGRkfL29tYzzzyj5cuXq1mzZvkWFkWft5u32REAAMA1yG6NUK6ElwK83UxOAwBA4cN8GMB/Obyt788//6y2bdva73/55Zc6fPiw9u3bp7Nnz+qee+7Ra6+95nSAGTNmqGLFivL09FSjRo20atWqK57/5Zdfql69evL29laZMmU0cOBAnT592unXRcHj4+6jpOeTlPR8knzcfcyOAwAAnJDdGqEWrREAAHAa82EAuTlctI2OjlbNmjXt95ctW6ZevXopIiJCFotFTzzxhLZs2eLUi8+bN08jRozQCy+8oC1btqhly5bq3LmzoqOjL3n+6tWr1a9fPw0ePFiRkZFasGCBNmzYoCFDhjj1ugAAAMhbkcfjJUm1wmiNAAAAAFwvh4u2Li4uMgzDfn/dunVq2rSp/X5gYKDOnj3r1ItPmTJFgwcP1pAhQ1SjRg1NnTpV4eHhmjlz5iXPX7dunSpUqKDhw4erYsWKuvXWW/XII49o48aNTr0uAAAA8hYrbQEAAIC843DRtnr16vrhhx8kSZGRkYqOjlabNm3sjx8+fFghISEOv3B6ero2bdqkDh065DjeoUMHrVmz5pLPad68uY4ePaolS5bIMAydOHFC33zzjbp27erw66LgSs1MVdevuqrrV12VmplqdhwAAOCglPQsHTiZKImVtgAAXAvmwwByc2ojsj59+uinn35SZGSkunTpoooVK9ofX7JkiW6++WaHX/jUqVPKysq6qNAbEhKi2NjYSz6nefPm+vLLL3XvvfcqNTVVmZmZ6t69u959993Lvk5aWprS0tLs9xMSEhzOiBsry5alJfuW2L8GAACFwz+xCbIZUikfd4X4e5gdxzSMOwEA14r5MIDcHF5pe/fdd2vJkiWqW7eunnzySc2bNy/H497e3ho2bJjTASwWS477hmFcdCzbrl27NHz4cL388svatGmTfvnlF0VFRWno0KGXvf6ECRMUEBBgv4WHhzudEQAAAJeX3RqhZpj/ZcdxxQHjTgAAAOQVh1faSlK7du3Url27Sz42ZswYp164dOnScnV1vWhVbVxc3GXbLEyYMEEtWrTQ008/LUmqW7eufHx81LJlS7322msqU6bMRc8ZPXq0Ro4cab+fkJDAABoAACAP/X8/2+LdGoFxJwAAAPKKQytto6Ojnbro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59O3334ryOVy4bPPPhOSkpKEOXPmCC4uLkJqaqogCIIwf/58YfLkyeb1k5OTBWdnZ+GZZ54RkpKShM8++0yQy+XCDz/8INZHaBL1bad3331X2LJli3DhwgXh9OnTwvz58wUAwqZNm8T6CI2utLTU/LsHgLB8+XIhMTFRSEtLEwSB59J19W0nezyXZs2aJahUKiEuLq5aflReXm5eh+eT5ZhzWo55Z92Yc1qGOefNmHNahjln3ZhzWoY5Z92aQ87Jom0jWbt2rQCgxseNAAhr1641vzaZTMLChQuFgIAAwdHRURgwYIBw6tSpJo6+6UydOrXGNtqzZ495nRvbqLy8XBg2bJjg6+sryOVyISQkRJg6daqQnp4uzgdoIvVtJ0Gwv3NJEAShsLBQmDRpkuDm5ia4ubkJkyZNEoqKiqqtY4/n00cffSSEhoYKCoVC6N69u7B3717ze1OnThUGDhxYbf24uDghKipKUCgUQlhYmPDxxx83ccTiqE87vf3220JERISgVCoFT09P4Y477hB+/vlnEaJuOnv27Knx99DUqVMFQeC5dF1928kez6Xa8qMb/4bxfLIcc07LMe+sG3NOyzDnrBlzTssw57w15pyWYc5Zt+aQc0oE4dqIukREREREREREREQkulsPeEVERERERERERERETYpFWyIiIiIiIiIiIiIrwqItERERERERERERkRVh0ZaIiIiIiIiIiIjIirBoS0RERERERERERGRFWLQlIiIiIiIiIiIisiIs2hIRERERERERERFZERZtiYiIiIiIiIiIiKwIi7ZERDYkLi4OEokExcXFYodCRERERM0Uc04iIvGxaEtEZMUGDRqEOXPmNPh+JRIJfvzxxwbd5+bNmzF8+HD4+PhAIpHg+PHjDbp/IiIiImoctpJz6vV6zJs3D507d4aLiwuCgoIwZcoUZGdnN9gxiIisBYu2RETUIDQaDfr164e33npL7FCIiIiIqBkqLy/HsWPH8Morr+DYsWPYvHkzLly4gHvuuUfs0IiIGhyLtkREVio2NhZ79+7Fe++9B4lEAolEgtTUVABAQkICevToAWdnZ/Tt2xfnz5+vtu22bdsQHR0NpVKJVq1aYfHixTAYDACAsLAwAMC4ceMgkUjMry9fvoyxY8fC398frq6u6NmzJ3bv3m1xvJMnT8arr76KoUOH/uvPTkRERERNw5ZyTpVKhV27duGBBx5Au3bt0KdPH3zwwQdISEhAenp6g7QHEZG1YNGWiMhKvffee4iJicGMGTOQk5ODnJwcBAcHAwBeeuklLFu2DEePHoWDgwMee+wx83Y7d+7EI488gqeeegpJSUlYvXo11q1bhzfffBMAcOTIEQDA2rVrkZOTY35dVlaGUaNGYffu3UhMTMTw4cMxZswYJsBEREREzZit55xqtRoSiQQeHh7/ohWIiKyPRBAEQewgiIioZoMGDUK3bt2wYsUKAFWTQgwePBi7d+/GkCFDAAA7duzA6NGjUVFRAaVSiQEDBmDkyJF48cUXzftZv349XnjhBfN4XxKJBFu2bMG99957y+N37NgRs2bNwhNPPGFxzKmpqQgPD0diYiK6detWr89LRERERE3PFnNOANBqtbjjjjvQvn17rF+/vl7bEhFZOwexAyAiovrr0qWL+XlgYCAAIC8vDyEhIUhISMCRI0fMvRwAwGg0QqvVory8HM7OzjXuU6PRYPHixdi+fTuys7NhMBhQUVHBnrZEREREdsqac069Xo8HH3wQJpMJK1euvI1PR0Rk3Vi0JSKyQXK53PxcIpEAAEwmk/nn4sWLcd999920nVKprHWfzz//PHbu3ImlS5eidevWcHJywv333w+dTtfA0RMRERGRLbDWnFOv1+OBBx5ASkoK/vjjD7i7u1u8LRGRrWDRlojIiikUChiNxnpt0717d5w/fx6tW7eudR25XH7Tfvfv34/Y2FiMGzcOQNV4Y9cnoSAiIiKi5suWcs7rBduLFy9iz5498Pb2rlfcRES2gkVbIiIrFhYWhkOHDiE1NRWurq7mng238uqrr+Luu+9GcHAwJkyYAKlUipMnT+LUqVN44403zPv9/fff0a9fPzg6OsLT0xOtW7fG5s2bMWbMGEgkErzyyisWHe+6q1evIj093TyG2fXZhQMCAhAQEHAbn56IiIiImoKt5JwGgwH3338/jh07hu3bt8NoNCI3NxcA4OXlBYVCcfuNQERkZaRiB0BERLV77rnnIJPJEBkZCV9fX4vG+ho+fDi2b9+OXbt2oWfPnujTpw+WL1+O0NBQ8zrLli3Drl27EBwcjKioKADAu+++C09PT/Tt2xdjxozB8OHD0b17d4tj3bp1K6KiojB69GgAwIMPPoioqCisWrWqnp+aiIiIiJqSreScmZmZ2Lp1KzIzM9GtWzcEBgaaHwcOHLi9D09EZKUkgiAIYgdBRERERERERERERFXY05aIiIiIiIiIiIjIirBoS0REddq/fz9cXV1rfRARERER/VvMOYmI/sbhEYiIqE4VFRXIysqq9f1bzRpMRERERGQJ5pxERH9j0ZaIiIiIiIiIiIjIinB4BCIiIiIiIiIiIiIrwqItERERERERERERkRVh0ZaIiIiIiIiIiIjIirBoS0RERERERERERGRFWLQlIiIiIiIiIiIisiIs2hIRERERERERERFZERZtiYiIiIiIiIiIiKwIi7ZEREREREREREREVuT/AbV6d16DARXiAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Plot the effect of varying each parameter (theta_1 and theta_2) one at a time\n", - "\n", - "fig, axes = plt.subplots(1, 2, figsize=(14, 5), sharey=True)\n", - "\n", - "# Vary theta_1, fix theta_2 at true value\n", - "theta1_vals = theta1_range\n", - "theta2_fixed = true_params[\"theta2\"]\n", - "sse_theta1 = []\n", - "for t1 in theta1_vals:\n", - " y_sim = np.array([model(x, t1, theta2_fixed) for x in conc])\n", - " sse = np.sum((vel - y_sim) ** 2)\n", - " sse_theta1.append(sse)\n", - "axes[0].plot(theta1_vals, sse_theta1, label=f'Fixed theta_2={theta2_fixed:.3f}')\n", - "axes[0].axvline(true_params['theta1'], color='green', linestyle='--', label='True theta_1')\n", - "axes[0].set_xlabel('theta_1')\n", - "axes[0].set_ylabel('Sum of Squared Errors (SSE)')\n", - "axes[0].set_title('SSE vs theta_1 (theta_2 fixed)')\n", - "axes[0].legend()\n", - "\n", - "# Vary theta_2, fix theta_1 at true value\n", - "theta2_vals = theta2_range\n", - "theta1_fixed = true_params[\"theta1\"]\n", - "sse_theta2 = []\n", - "for t2 in theta2_vals:\n", - " y_sim = np.array([model(x, theta1_fixed, t2) for x in conc])\n", - " sse = np.sum((vel - y_sim) ** 2)\n", - " sse_theta2.append(sse)\n", - "axes[1].plot(theta2_vals, sse_theta2, label=f'Fixed theta_1={theta1_fixed:.3f}')\n", - "axes[1].axvline(true_params['theta2'], color='green', linestyle='--', label='True theta_2')\n", - "axes[1].set_xlabel('theta_2')\n", - "axes[1].set_title('SSE vs theta_2 (theta_1 fixed)')\n", - "axes[1].legend()\n", - "\n", - "plt.tight_layout()\n", - "plt.show()\n" - ] - }, - { - "cell_type": "markdown", - "id": "be805271-1f41-4066-ad50-f912ba61fa53", - "metadata": {}, - "source": [ - "# PARMEST" - ] - }, - { - "cell_type": "markdown", - "id": "2b95ecb7-a1c7-4b09-b32e-dafe3fca3944", - "metadata": {}, - "source": [ - "## Creating an experiment class for both DOE and ParmEst\n", - "We will use this class for both parmest (to estimate the parameters) and DOE (To calculate the FIM and factorial design)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "a5e84eb1-94a6-40ec-a940-2306778a4f71", - "metadata": {}, - "outputs": [], - "source": [ - "class Simple_Multimodal(experiment.Experiment):\n", - "\n", - " # Defining the constructor for our model\n", - " def __init__(self, data, theta_initial=None):\n", - " \"\"\"\n", - " Arguments:\n", - " data: data from our experiment. type: 'dict'\n", - " theta_initial: initial guess of the parameter values, dtype: dict. pass the values as theta_initial = {1 : , 2 : }\n", - " default: {1: 100, 2: 0.05}\n", - " \n", - " \"\"\"\n", - " self.conc = data[\"x\"]\n", - " self.vel = data[\"y\"]\n", - " self.model = None \n", - " self.theta_initial = theta_initial\n", - " if self.theta_initial is None:\n", - " self.theta_initial = {1: -1.5, 2: 0.5} # default initial guess of theta[1] & theta[2]\n", - " else:\n", - " self.theta_initial = theta_initial\n", - "\n", - " # Creating the get_labeled_model which is a must for ``DOE`` and ``ParmEst``\n", - " def get_labeled_model(self):\n", - " if self.model is None:\n", - " self.create_model()\n", - " self.label_model()\n", - " self.finalize_model()\n", - " return self.model\n", - "\n", - " \n", - " def create_model(self):\n", - " \"\"\"\n", - " Here, we will create different variables, parameters, and constraints.\n", - " The index set for data points will be the actual substrate concentrations (x values).\n", - " \"\"\"\n", - " m = self.model = pyo.ConcreteModel()\n", - "\n", - " # theta_1 and theta_2 as parameters to be estimated\n", - " m.theta_1 = pyo.Var(initialize=self.theta_initial[1], bounds=(-2, 2))\n", - " m.theta_2 = pyo.Var(initialize=self.theta_initial[2], bounds=(-2, 2))\n", - "\n", - " # Use the actual conc values as the index set\n", - " m.x_set = pyo.Set(initialize=[float(val) for val in self.conc], ordered=True)\n", - "\n", - " # Substrate concentration (x) as a parameter, indexed by x_set\n", - " m.x = pyo.Param(m.x_set, initialize={float(val): float(val) for val in self.conc}, mutable=False)\n", - "\n", - " # Measured variable for each data point (indexed by x_set)\n", - " m.measured_var = pyo.Var(m.x_set)\n", - "\n", - " # Constraint for each data point\n", - " def meas_con(m, xval):\n", - " return m.measured_var[xval] == (m.theta_1 * m.x[xval]**3 - m.theta_2 * m.x[xval]**2 + 2 * m.x[xval] - 1)**2 + (m.theta_1 - m.theta_2)**2 + (m.x[xval]**2 - 1)**2\n", - " m.meas_con = pyo.Constraint(m.x_set, rule=meas_con)\n", - "\n", - " # Objective function: sum of squared errors over all data points\n", - " m.FirstStageCost = pyo.Expression(initialize=0)\n", - " m.SecondStageCost = pyo.Expression(expr=sum((self.vel[i] - m.measured_var[float(self.conc[i])]) ** 2 for i in range(len(self.conc))))\n", - " m.Total_Cost_Obj = pyo.Objective(expr=(m.FirstStageCost + m.SecondStageCost), sense=pyo.minimize)\n", - "\n", - " return m\n", - "\n", - " \n", - " def finalize_model(self):\n", - " \"\"\"\n", - " Finalizing the model. Here, we will set the experimental conditions (e.g, initial conditions),\n", - " fixing the parameter values (if needed), update `t` values, and discretize the model (if model is dynamic). \n", - " It makes a solvable model.\n", - " \"\"\" \n", - " m=self.model\n", - "\n", - " # fixing the parameters\n", - " m.theta_1.fix(self.theta_initial[1]) \n", - " m.theta_2.fix(self.theta_initial[2]) \n", - "\n", - "\n", - " return m\n", - "\n", - " \n", - " def label_model(self):\n", - " \"\"\"\n", - " The model is updated with outputs, and unknown parameters. This makes the model labeled with full experiment.\n", - " In `ParmEst` output (given data) is the most important. For `DOE` input is most important.\n", - " \"\"\"\n", - " m = self.model\n", - "\n", - " m.experiment_outputs = pyo.Suffix(direction = pyo.Suffix.LOCAL) \n", - " m.experiment_outputs.update([(m.measured_var, self.vel)]) # Pass the data as a list of `tuple`\n", - " # If we only use ``DOE``, we could use ``m.experiment_ouputs.update([(m.x, None)])``.\n", - " # Output is not important for ``DOE``\n", - "\n", - " # m.experiment_inputs = pyo.Suffix(direction = pyo.Suffix.LOCAL) \n", - " # # m.experiment_inputs[m.x] = self.conc\n", - " # m.experiment_inputs.update([(m.x, self.conc)])\n", - " # # If we only use ``DOE``, we could use ``m.experiment_inputs.update([(m.x, None)])``\n", - "\n", - " m.unknown_parameters = pyo.Suffix(direction = pyo.Suffix.LOCAL)\n", - " m.unknown_parameters.update((p, pyo.value(p)) for p in [m.theta_1, m.theta_2])\n", - " # m.unknown_parameters[m.theta_1]= self.theta_initial[1]\n", - " # m.unknown_parameters[m.theta_2]= self.theta_initial[2]\n", - "\n", - " m.measurement_error = pyo.Suffix(direction = pyo.Suffix.LOCAL)\n", - " # m.measurement_error[m.measured_var] = 0.03\n", - " m.measurement_error.update([(m.measured_var, 0.03**2)]) # variance of the measurement error, b/c in doe, the measurement error is passed as variance, not std\n", - " # this will be fixed in later update \n", - "\n", - " return m" - ] - }, - { - "cell_type": "markdown", - "id": "c303c406-ac5a-4ff6-9535-48967393acc4", - "metadata": {}, - "source": [ - "## Parmest Example\n", - "We will evaluate diffent parameters, visualize pairwise plots and show bootstrap table" - ] - }, - { - "cell_type": "markdown", - "id": "32d11b62-0040-4a65-b4f7-035730272094", - "metadata": {}, - "source": [ - "### Treated velocity\n", - "Here, we will calculate objective value at optimum parameter value, paramater values, $\\theta$, and covariance matrix for treated velocity." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "09b0eae6-e1d1-404c-be2a-98a1a8e776bf", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.10e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.51e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 2.77e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 1.50e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 1.4985094187954244e-12 2.8984606156203206e-10\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "\n", - "theta values:\n", - "theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "\n", - "SSE value: 428163.2965187811\n", - "\n", - "Covariance matrix:\n", - " theta_1 theta_2\n", - "theta_1 4.667923e-08 3.978519e-08\n", - "theta_2 3.978519e-08 6.376757e-07\n" - ] - } - ], - "source": [ - "exp_list = [] \n", - "conc = data_df[\"x\"].values # substrate concentration (control variable)\n", - "vel = data_df[\"y\"].values # reaction velocity (output variable)\n", - "n_exp = 1\n", - "\n", - "# exp_list to separate each experiment\n", - "# for i in range(n_exp):\n", - "exp_list.append(Simple_Multimodal(data_df))\n", - "\n", - "# Creating an Estimator object\n", - "pest = parmest.Estimator(exp_list, tee = True) \n", - "\n", - "# Estimating d\n", - "obj, theta, cov = pest.theta_est(calc_cov=True, cov_n=len(conc),)\n", - "\n", - "# ``parmest`` can mess up the order of the theta estimates and also the covariance. So we need to fix the order so that we can manipulate it properly.\n", - "t_order = [\"theta_1\", \"theta_2\"]\n", - "theta_perm = theta.loc[t_order] # ``theta`` in the order we want\n", - "cov_perm = cov.loc[t_order, t_order] # ``covariance`` matrix in the order we want\n", - "\n", - "print(\"\\ntheta values:\")\n", - "print(theta_perm)\n", - "\n", - "print(\"\\nSSE value: \", obj)\n", - "\n", - "print(\"\\nCovariance matrix:\")\n", - "print(cov_perm)" - ] - }, - { - "cell_type": "markdown", - "id": "fe378b08", - "metadata": {}, - "source": [ - "### Manual multistart test\n", - "\n", - "Made a for loop version of multistart, to see expected results from solver being accessed each time. Sobol sampling, n = 50, seed = 12345" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "5a2cc375", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 8.33e+03 9.73e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.9834030e+07 2.32e+03 1.15e+05 -1.0 9.25e+03 - 2.54e-01 1.00e+00f 1\n", - " 2 2.6443991e+07 1.71e+02 1.35e+04 -1.0 9.35e+01 - 8.83e-01 1.00e+00h 1\n", - " 3 2.7180925e+07 1.23e+00 3.23e+02 -1.0 1.06e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186293e+07 5.91e-05 4.09e-02 -1.0 7.54e-02 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 3.89e-12 1.48e-10 -2.5 1.72e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 5.57e-12 6.31e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 1.10e-09 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 7.61e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027403e+05 2.7186293738994990e+07\n", - "Dual infeasibility......: 7.6089379903002177e-10 1.4717429743825483e-07\n", - "Constraint violation....: 7.7375360819269268e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Applications/anaconda3/envs/parmest-dev-mac2/lib/python3.13/site-packages/scipy/stats/_qmc.py:993: UserWarning: The balance properties of Sobol' points require n to be a power of 2.\n", - " sample = self._random(n, workers=workers)\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 2.15e+04 9.85e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 9.7588988e+06 2.78e+03 5.57e+04 -1.0 9.41e+03 - 1.46e-02 1.00e+00f 1\n", - " 2 2.6386162e+07 2.49e+02 1.19e+04 -1.0 2.49e+02 - 9.29e-01 1.00e+00h 1\n", - " 3 2.7175624e+07 2.55e+00 5.81e+02 -1.0 1.51e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186293e+07 2.61e-04 1.56e-01 -1.0 1.51e-01 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 5.40e-12 3.64e-09 -2.5 3.02e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.41e-12 1.03e-09 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 1.23e-09 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 5.64e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 5.6444294344696339e-10 1.0917620008427717e-07\n", - "Constraint violation....: 6.8047436072523522e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.10e+03 1.06e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.2271200e+09 1.06e+04 5.22e+06 -1.0 1.41e+04 - 1.55e-01 2.75e-01f 1\n", - " 2 4.9620454e+06 1.15e+03 1.42e+06 -1.0 6.05e+03 - 1.49e-02 1.00e+00f 1\n", - " 3 4.3909756e+05 6.85e+01 8.18e+04 -1.0 3.03e+02 - 9.74e-01 1.00e+00f 1\n", - " 4 4.2816904e+05 2.93e-01 4.24e+02 -1.0 1.76e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 4.2816330e+05 6.80e-06 1.39e-02 -1.0 1.19e-01 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 5.03e-12 1.55e-10 -2.5 2.53e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 4.18e-12 4.43e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 8 4.2816330e+05 5.09e-12 2.61e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 4.2816330e+05 3.50e-12 6.22e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", - "Dual infeasibility......: 6.2153811273360234e-12 1.2021971422198111e-09\n", - "Constraint violation....: 3.4631683699249438e-13 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.07e+03 8.68e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.4414889e+09 1.02e+03 2.34e+05 -1.0 1.25e+04 - 2.26e-01 5.25e-02f 1\n", - " 2 4.4306624e+09 1.02e+03 2.34e+05 -1.0 7.54e+03 - 9.36e-01 1.31e-03f 1\n", - " 3 4.4294973e+09 1.02e+03 6.00e+06 -1.0 3.07e+03 - 1.00e+00 6.02e-04f 1\n", - " 4 3.0552690e+09 9.12e+02 1.82e+07 -1.0 2.98e+03 - 1.00e+00 9.96e-01f 1\n", - " 5 1.5613347e+09 1.89e+03 3.20e+07 -1.0 6.63e+03 -2.0 4.47e-01 1.00e+00f 1\n", - " 6 1.0074442e+09 2.86e+01 4.84e+06 -1.0 1.43e+03 - 1.37e-02 1.00e+00f 1\n", - " 7 9.7365090e+08 1.54e+00 4.43e+06 -1.0 2.29e+02 - 1.36e-04 1.00e+00f 1\n", - " 8 1.4779113e+08 2.15e+03 2.83e+07 -1.0 3.47e+03 -1.6 1.90e-02 1.00e+00f 1\n", - " 9 2.9134338e+06 2.92e+01 1.03e+06 -1.0 1.61e+03 - 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.2930909e+05 2.52e+00 2.09e+04 -1.0 2.46e+02 - 1.00e+00 1.00e+00f 1\n", - " 11 4.2816335e+05 2.53e-03 1.42e+01 -1.0 5.43e+00 - 1.00e+00 1.00e+00f 1\n", - " 12 4.2816330e+05 1.59e-09 7.66e-06 -1.0 3.76e-03 - 1.00e+00 1.00e+00h 1\n", - " 13 4.2816330e+05 3.21e-12 2.17e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 14 4.2816330e+05 4.18e-12 2.30e-03 -3.8 7.13e-07 - 1.00e+00 5.00e-01h 2\n", - " 15 4.2816330e+05 4.01e-12 1.68e-11 -3.8 3.56e-07 - 1.00e+00 1.00e+00h 1\n", - " 16 4.2816330e+05 5.09e-12 2.77e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00h 1\n", - " 17 4.2816330e+05 3.50e-12 9.85e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 17\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 9.8533599348512529e-12 1.9058656118194543e-09\n", - "Constraint violation....: 2.9162136132700857e-13 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597866419e-09 4.8469917395800629e-07\n", - "Overall NLP error.......: 2.5059035597866419e-09 4.8469917395800629e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 20\n", - "Number of objective gradient evaluations = 18\n", - "Number of equality constraint evaluations = 20\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 18\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 17\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.010\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.72e+03 9.63e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.6711997e+07 4.94e+01 4.67e+03 -1.0 9.15e+03 - 8.25e-01 1.00e+00f 1\n", - " 2 2.7185876e+07 1.30e-01 3.12e+01 -1.0 5.38e+00 - 1.00e+00 1.00e+00h 1\n", - " 3 2.7186294e+07 8.26e-07 2.97e-04 -1.0 7.99e-03 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186294e+07 3.41e-12 2.29e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 4.41e-12 4.78e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 3.67e-12 9.05e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.12e-12 2.65e-10 -8.6 3.89e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 7\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027403e+05 2.7186293738994990e+07\n", - "Dual infeasibility......: 2.6501622456984170e-10 5.1260210965743845e-08\n", - "Constraint violation....: 4.6417226757976225e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597868338e-09 4.8469917395804345e-07\n", - "Overall NLP error.......: 2.5059035597868338e-09 4.8469917395804345e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 8\n", - "Number of objective gradient evaluations = 8\n", - "Number of equality constraint evaluations = 8\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 8\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 7\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 2.37e+03 9.51e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 5.2544727e+08 1.26e+04 4.35e+05 -1.0 9.02e+03 - 2.75e-01 6.86e-01f 1\n", - " 2 2.2794582e+07 1.25e+03 9.75e+04 -1.0 2.97e+03 - 2.39e-02 1.00e+00f 1\n", - " 3 2.7074814e+07 3.89e+01 6.86e+03 -1.0 5.61e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186179e+07 4.02e-02 1.85e+01 -1.0 1.74e+00 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 3.87e-08 4.24e-05 -1.0 3.08e-03 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.58e-12 3.65e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.41e-12 3.77e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.21e-12 9.78e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 2.7186294e+07 4.12e-12 7.89e-10 -8.6 3.89e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 7.8853941762349164e-10 1.5252159360353654e-07\n", - "Constraint violation....: 1.8412683274148882e-13 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597868338e-09 4.8469917395804345e-07\n", - "Overall NLP error.......: 2.5059035597868338e-09 4.8469917395804345e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 8.36e+03 1.01e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 3.6567139e+06 2.70e+03 6.69e+04 -1.0 9.84e+03 - 3.42e-01 1.00e+00f 1\n", - " 2 4.3352737e+05 1.69e+02 6.65e+03 -1.0 1.86e+02 - 8.09e-01 1.00e+00f 1\n", - " 3 4.2816873e+05 8.05e-01 4.30e+01 -1.0 7.01e+00 - 1.00e+00 1.00e+00f 1\n", - " 4 4.2816330e+05 1.82e-05 3.52e-03 -1.0 3.07e-02 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 3.69e-12 7.46e-11 -2.5 2.58e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 4.18e-12 7.82e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 5.09e-12 1.10e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 4.2816330e+05 3.50e-12 2.88e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", - "Dual infeasibility......: 2.8795658903932589e-12 5.5697403157450258e-10\n", - "Constraint violation....: 9.8520816457861569e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 8.43e+03 1.01e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.1035343e+07 5.64e+03 1.01e+06 -1.0 9.86e+03 - 1.52e-01 1.00e+00f 1\n", - " 2 7.7062599e+05 7.40e+02 1.98e+05 -1.0 4.05e+02 - 6.58e-01 1.00e+00f 1\n", - " 3 4.2910167e+05 2.42e+01 8.77e+03 -1.0 8.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 4.2816393e+05 3.08e-02 1.65e+01 -1.0 3.60e+00 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.42e-08 4.48e-05 -1.0 5.94e-03 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.89e-12 2.24e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 5.31e-12 1.87e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", - " 8 4.2816330e+05 3.04e-12 1.45e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 4.2816330e+05 3.50e-12 2.62e-11 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 2.6224264566340445e-11 5.0723737245673013e-09\n", - "Constraint violation....: 1.6351447811689176e-13 3.4958702599396925e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 11\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 11\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 8.08e+02 9.23e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 3.5436370e+08 1.58e+04 3.23e+06 -1.0 9.13e+03 - 4.82e-01 7.24e-01f 1\n", - " 2 3.0476400e+07 1.98e+03 6.74e+05 -1.0 2.56e+03 - 3.12e-02 1.00e+00f 1\n", - " 3 2.7331790e+07 9.12e+01 5.74e+04 -1.0 5.85e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 2.7186712e+07 2.48e-01 3.36e+02 -1.0 7.25e+00 - 1.00e+00 1.00e+00f 1\n", - " 5 2.7186294e+07 3.56e-06 7.20e-03 -1.0 4.95e-02 - 1.00e+00 1.00e+00f 1\n", - " 6 2.7186294e+07 3.58e-12 1.45e-10 -2.5 2.01e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.41e-12 2.03e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.69e-12 2.62e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 2.7186294e+07 4.12e-12 7.32e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 7.3178996857371158e-10 1.4154494968219492e-07\n", - "Constraint violation....: 1.6008713042790100e-13 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.21e+04 9.67e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.3904826e+07 7.92e+02 1.65e+04 -1.0 9.20e+03 - 6.85e-01 1.00e+00f 1\n", - " 2 2.7078421e+07 2.47e+01 2.40e+03 -1.0 4.93e+01 - 1.00e+00 1.00e+00h 1\n", - " 3 2.7186180e+07 2.61e-02 8.33e+00 -1.0 1.57e+00 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186294e+07 2.61e-08 2.15e-05 -1.0 1.65e-03 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 3.58e-12 2.84e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.41e-12 8.12e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 1.17e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 6.44e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 6.4447847720351047e-10 1.2465690641376951e-07\n", - "Constraint violation....: 5.4622972811557702e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 2.11e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.8316028e+09 2.06e+03 8.87e+03 -1.0 6.09e+03 - 3.06e-01 2.48e-02f 1\n", - " 2 4.8286802e+09 2.06e+03 2.41e+04 -1.0 6.72e+03 - 6.43e-01 3.26e-04f 1\n", - " 3 4.8221153e+09 2.05e+03 5.20e+06 -1.0 1.77e+03 - 1.00e+00 4.84e-03f 1\n", - " 4 3.6291264e+09 1.18e+01 2.25e+06 -1.0 1.75e+03 - 1.00e+00 1.00e+00f 1\n", - " 5 3.6164199e+09 1.93e-02 1.33e+04 -1.0 1.77e+01 0.0 1.00e+00 1.00e+00f 1\n", - " 6 3.6142797e+09 9.44e-02 3.42e+04 -1.0 2.49e+01 -0.5 1.00e+00 1.00e+00f 1\n", - " 7 3.6063319e+09 1.26e+00 6.91e+03 -1.0 9.04e+01 -1.0 1.00e+00 1.00e+00f 1\n", - " 8 3.5609956e+09 4.91e+01 2.62e+05 -1.0 5.47e+02 -1.4 1.00e+00 1.00e+00f 1\n", - " 9 3.4536087e+09 1.18e+01 3.09e+05 -1.0 2.54e+02 -1.0 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 3.1279033e+09 4.24e+02 2.06e+06 -1.0 1.38e+03 -1.5 1.00e+00 1.00e+00f 1\n", - " 11 3.4934385e+09 1.21e+02 2.69e+07 -1.0 1.18e+04 -2.0 3.42e-01 5.36e-02H 1\n", - " 12 2.9025111e+09 9.96e+02 5.96e+06 -1.0 2.40e+03 -1.5 1.00e+00 1.00e+00f 1\n", - " 13 3.0988933e+09 8.23e+02 3.70e+07 -1.0 3.37e+04 - 3.57e-01 1.95e-02H 1\n", - " 14 1.4289790e+09 1.38e+03 1.82e+07 -1.0 5.41e+03 -2.0 7.49e-01 1.00e+00f 1\n", - " 15 9.1847716e+08 2.03e+00 4.74e+06 -1.0 1.66e+03 - 6.80e-02 1.00e+00f 1\n", - " 16 9.1753645e+08 3.84e-02 4.80e+06 -1.0 3.84e+01 - 7.33e-04 1.00e+00f 1\n", - " 17 2.6734760e+08 8.34e+02 1.25e+07 -1.0 2.22e+03 -1.6 4.98e-04 1.00e+00f 1\n", - " 18 3.1392273e+07 4.23e+01 1.36e+06 -1.0 1.71e+03 - 9.07e-01 1.00e+00f 1\n", - " 19 2.7168841e+07 4.01e+00 3.90e+04 -1.0 3.38e+02 - 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 2.7186259e+07 7.87e-03 4.66e+01 -1.0 9.43e+00 - 1.00e+00 1.00e+00h 1\n", - " 21 2.7186294e+07 1.60e-08 7.92e-05 -1.0 1.13e-02 - 1.00e+00 1.00e+00h 1\n", - " 22 2.7186294e+07 4.09e-12 4.46e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 23 2.7186294e+07 4.41e-12 1.77e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 24 2.7186294e+07 4.69e-12 4.44e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 25 2.7186294e+07 4.12e-12 9.32e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 25\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027403e+05 2.7186293738994990e+07\n", - "Dual infeasibility......: 9.3170592537955412e-10 1.8021327701920809e-07\n", - "Constraint violation....: 2.8906604310374570e-13 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 28\n", - "Number of objective gradient evaluations = 26\n", - "Number of equality constraint evaluations = 28\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 26\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 25\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.018\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 3.71e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 3.6253900e+06 7.03e+03 4.94e+05 -1.0 9.73e+03 - 5.66e-01 1.00e+00f 1\n", - " 2 6.3155920e+05 9.68e+02 1.03e+05 -1.0 2.11e+02 - 3.06e-01 1.00e+00f 1\n", - " 3 4.2943835e+05 3.66e+01 6.18e+03 -1.0 6.27e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 4.2816462e+05 6.43e-02 1.50e+01 -1.0 3.60e+00 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 2.08e-07 6.53e-05 -1.0 7.59e-03 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.92e-12 2.10e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 4.18e-12 3.09e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 8 4.2816330e+05 5.09e-12 6.41e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 4.2816330e+05 3.50e-12 4.40e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 4.3995938736571737e-12 8.5098227662596132e-10\n", - "Constraint violation....: 1.2311475077887451e-13 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 2.36e+04 9.68e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.9411233e+07 2.24e+03 2.14e+04 -1.0 9.12e+03 - 9.31e-02 1.00e+00f 1\n", - " 2 2.7249209e+07 1.10e+02 1.53e+03 -1.0 2.59e+01 - 9.65e-01 1.00e+00f 1\n", - " 3 2.7186190e+07 3.26e-01 3.14e+00 -1.0 1.24e+00 - 1.00e+00 1.00e+00f 1\n", - " 4 2.7186294e+07 2.93e-06 8.94e-05 -1.0 5.33e-03 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 4.32e-12 6.52e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.41e-12 6.15e-11 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 2.62e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 1.03e-09 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027398e+05 2.7186293738994978e+07\n", - "Dual infeasibility......: 1.0262933743643622e-09 1.9850865722675085e-07\n", - "Constraint violation....: 4.3964831775156199e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 5.50e+03 9.77e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.5759216e+08 1.17e+04 2.18e+05 -1.0 9.43e+03 - 1.70e-01 8.24e-01f 1\n", - " 2 2.3277921e+07 1.37e+03 9.11e+04 -1.0 1.41e+03 - 3.04e-02 1.00e+00f 1\n", - " 3 2.7051971e+07 4.76e+01 1.10e+03 -1.0 6.63e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186107e+07 6.48e-02 2.18e+00 -1.0 2.12e+00 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 1.19e-07 1.67e-05 -1.0 2.83e-03 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.69e-12 1.19e-09 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.41e-12 3.60e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.69e-12 2.91e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 2.7186294e+07 4.12e-12 5.86e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 5.8627081629004306e-10 1.1339821090148592e-07\n", - "Constraint violation....: 1.7015480447604767e-13 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.08e+04 9.98e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 9.8648968e+05 4.31e+02 1.25e+04 -1.0 9.71e+03 - 5.64e-01 1.00e+00f 1\n", - " 2 4.2829757e+05 9.37e+00 2.57e+02 -1.0 7.16e+01 - 1.00e+00 1.00e+00f 1\n", - " 3 4.2816336e+05 3.72e-03 4.88e-01 -1.0 2.97e-01 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 5.74e-10 2.35e-07 -1.7 1.82e-04 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.51e-12 6.63e-12 -3.8 5.28e-06 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 1.88e-12 2.17e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00H 1\n", - " 7 4.2816330e+05 3.50e-12 3.72e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 7\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 3.7174728473274775e-12 7.1904443859138779e-10\n", - "Constraint violation....: 6.7272184213622484e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597866419e-09 4.8469917395800629e-07\n", - "Overall NLP error.......: 2.5059035597866419e-09 4.8469917395800629e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 8\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 8\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 7\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.51e+04 9.87e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.4591296e+05 4.94e+02 3.70e+03 -1.0 9.66e+03 - 6.72e-01 1.00e+00f 1\n", - " 2 4.2820756e+05 6.55e+00 1.50e+02 -1.0 1.56e+01 - 1.00e+00 1.00e+00f 1\n", - " 3 4.2816331e+05 1.24e-03 2.54e-02 -1.0 2.82e-01 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.29e-11 1.22e-08 -2.5 4.22e-05 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 4.49e-12 2.73e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 5.09e-12 1.09e-11 -5.7 3.95e-08 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 3.50e-12 1.67e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 7\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", - "Dual infeasibility......: 1.6711097683383890e-12 3.2323092448766719e-10\n", - "Constraint violation....: 4.4162799930954544e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597866419e-09 4.8469917395800629e-07\n", - "Overall NLP error.......: 2.5059035597866419e-09 4.8469917395800629e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 8\n", - "Number of objective gradient evaluations = 8\n", - "Number of equality constraint evaluations = 8\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 8\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 7\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 3.14e+03 9.52e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 3.2143856e+07 3.08e+03 8.73e+04 -1.0 9.13e+03 - 7.71e-01 1.00e+00f 1\n", - " 2 2.7516639e+07 2.13e+02 1.12e+04 -1.0 4.02e+01 - 8.52e-01 1.00e+00f 1\n", - " 3 2.7187562e+07 1.86e+00 1.48e+02 -1.0 3.04e+00 - 1.00e+00 1.00e+00f 1\n", - " 4 2.7186294e+07 1.48e-04 1.42e-02 -1.0 2.39e-02 - 1.00e+00 1.00e+00f 1\n", - " 5 2.7186294e+07 5.83e-12 4.05e-10 -2.5 1.58e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.60e-12 7.46e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 1.22e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 6.01e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 6.0082273151840992e-10 1.1621288477955682e-07\n", - "Constraint violation....: 7.9483276450609387e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 2.03e+04 9.73e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.2603904e+07 2.57e+03 2.37e+04 -1.0 9.24e+03 - 2.68e-01 1.00e+00f 1\n", - " 2 2.6435802e+07 1.99e+02 7.37e+03 -1.0 8.27e+01 - 9.14e-01 1.00e+00h 1\n", - " 3 2.7178955e+07 1.68e+00 2.58e+02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186293e+07 1.18e-04 5.10e-02 -1.0 1.04e-01 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 4.18e-12 4.94e-10 -2.5 1.35e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 5.57e-12 3.19e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 3.46e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 7.83e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 7.8272167187299556e-10 1.5139630825544308e-07\n", - "Constraint violation....: 5.4622972811557702e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 6.27e+03 1.05e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.8071968e+08 1.32e+04 5.04e+06 -1.0 1.14e+04 - 1.01e-01 7.28e-01f 1\n", - " 2 2.1061322e+06 1.58e+03 1.08e+06 -1.0 1.60e+03 - 3.02e-02 1.00e+00f 1\n", - " 3 4.3722926e+05 7.27e+01 7.33e+04 -1.0 2.26e+02 - 1.00e+00 1.00e+00f 1\n", - " 4 4.2816494e+05 2.11e-01 3.44e+02 -1.0 1.68e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 4.2816330e+05 2.17e-06 5.34e-03 -1.0 7.53e-02 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.81e-12 1.86e-10 -2.5 2.47e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 5.31e-12 3.37e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", - " 8 4.2816330e+05 3.04e-12 7.53e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 4.2816330e+05 3.50e-12 5.59e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 5.5912355767736014e-12 1.0814730897694733e-09\n", - "Constraint violation....: 2.6290081223123707e-13 3.4958702599396925e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 11\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 11\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.08e+03 1.04e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.9442460e+09 2.90e+02 1.62e+06 -1.0 8.40e+01 0.0 9.06e-01 1.00e+00f 1\n", - " 2 3.8682267e+09 4.36e+03 3.75e+06 -1.0 7.36e+03 - 2.57e-01 2.22e-01f 1\n", - " 3 1.0445680e+09 2.36e+03 1.30e+07 -1.0 8.06e+03 - 5.91e-02 1.00e+00f 1\n", - " 4 1.8847235e+09 1.86e+03 8.68e+06 -1.0 1.76e+04 - 1.00e+00 1.41e-01H 1\n", - " 5 1.8845015e+09 1.84e+03 8.61e+06 -1.0 2.22e+02 -0.5 1.00e+00 8.89e-03f 1\n", - " 6 1.8845004e+09 1.84e+03 8.61e+06 -1.0 2.48e+02 -1.0 1.00e+00 8.80e-05f 1\n", - " 7 1.0031971e+09 1.86e+01 4.64e+06 -1.0 2.13e+03 - 6.41e-02 1.00e+00f 1\n", - " 8 9.8333743e+08 5.43e-01 4.40e+06 -1.0 1.34e+02 - 7.30e-04 1.00e+00f 1\n", - " 9 3.6753899e+08 8.32e+02 1.39e+07 -1.0 2.13e+03 -1.4 1.80e-02 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 1.6993277e+07 9.18e+01 2.49e+06 -1.0 2.09e+03 - 8.49e-01 1.00e+00f 1\n", - " 11 4.7911844e+05 1.48e+01 1.42e+05 -1.0 6.73e+02 - 1.00e+00 1.00e+00f 1\n", - " 12 4.2816647e+05 1.06e-01 6.23e+02 -1.0 3.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 13 4.2816330e+05 2.92e-06 1.44e-02 -1.0 1.64e-01 - 1.00e+00 1.00e+00h 1\n", - " 14 4.2816330e+05 3.58e-12 1.88e-10 -2.5 2.55e-05 - 1.00e+00 1.00e+00h 1\n", - " 15 4.2816330e+05 4.18e-12 6.06e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 16 4.2816330e+05 5.09e-12 3.46e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00h 1\n", - " 17 4.2816330e+05 3.50e-12 5.36e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 17\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 5.3638619013303694e-12 1.0374938104246155e-09\n", - "Constraint violation....: 4.9127553950366949e-13 3.4958702599396933e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 19\n", - "Number of objective gradient evaluations = 18\n", - "Number of equality constraint evaluations = 19\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 18\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 17\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.011\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.50e+04 9.72e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.1140621e+07 5.69e+02 1.74e+04 -1.0 9.20e+03 - 9.48e-02 1.00e+00f 1\n", - " 2 2.7192445e+07 1.01e+01 6.77e+02 -1.0 6.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 3 2.7186294e+07 2.68e-03 2.93e-01 -1.0 3.18e-01 - 1.00e+00 1.00e+00f 1\n", - " 4 2.7186294e+07 1.79e-10 9.00e-08 -1.7 1.58e-04 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 5.57e-12 6.03e-10 -3.8 4.19e-06 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.69e-12 1.24e-09 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.12e-12 7.28e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 7\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 7.2797911218231232e-10 1.4080784272619497e-07\n", - "Constraint violation....: 5.4978276510060899e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 8\n", - "Number of objective gradient evaluations = 8\n", - "Number of equality constraint evaluations = 8\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 8\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 7\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.70e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.6387946e+09 1.63e+03 2.20e+04 -1.0 7.94e+03 - 2.58e-01 4.56e-02f 1\n", - " 2 4.6312518e+09 1.62e+03 2.19e+04 -1.0 8.01e+03 - 7.47e-01 8.57e-04f 1\n", - " 3 4.6299809e+09 1.62e+03 6.03e+06 -1.0 1.30e+03 - 1.00e+00 9.08e-04f 1\n", - " 4 3.4045767e+09 1.71e+02 8.63e+06 -1.0 1.24e+03 - 1.00e+00 1.00e+00f 1\n", - " 5 3.2357580e+09 1.04e-06 1.04e+07 -1.0 1.71e+02 0.0 3.67e-01 1.00e+00f 1\n", - " 6 3.2335364e+09 7.43e-03 1.67e+07 -1.0 5.07e+02 - 1.00e+00 1.34e-02f 1\n", - " 7 3.0814424e+09 4.30e+01 1.10e+07 -1.0 5.19e+02 - 1.00e+00 1.00e+00f 1\n", - " 8 3.0074467e+09 1.00e+00 2.28e+05 -1.0 1.35e+02 -0.5 1.00e+00 1.00e+00f 1\n", - " 9 2.8905662e+09 1.28e+01 3.92e+05 -1.0 3.38e+02 -1.0 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 2.4797474e+09 1.64e+02 1.29e+06 -1.0 1.31e+03 -1.4 1.00e+00 1.00e+00f 1\n", - " 11 2.7418252e+09 5.14e+01 1.73e+07 -1.0 8.37e+04 - 2.44e-01 2.23e-02H 1\n", - " 12 1.9145132e+09 1.64e+03 9.70e+06 -1.0 4.53e+03 -1.9 7.97e-01 1.00e+00f 1\n", - " 13 1.0117309e+09 5.41e+01 4.54e+06 -1.0 3.05e+03 - 3.70e-02 1.00e+00f 1\n", - " 14 9.9642132e+08 4.47e-01 4.35e+06 -1.0 8.39e+01 - 4.55e-04 1.00e+00f 1\n", - " 15 2.6824003e+08 1.38e+03 2.06e+07 -1.0 2.71e+03 -1.5 1.25e-03 1.00e+00f 1\n", - " 16 3.7706102e+06 2.82e+01 1.15e+06 -1.0 1.91e+03 - 1.00e+00 1.00e+00f 1\n", - " 17 4.3043555e+05 3.35e+00 2.95e+04 -1.0 2.95e+02 - 1.00e+00 1.00e+00f 1\n", - " 18 4.2816340e+05 4.89e-03 2.80e+01 -1.0 7.70e+00 - 1.00e+00 1.00e+00f 1\n", - " 19 4.2816330e+05 6.04e-09 2.94e-05 -1.0 7.38e-03 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 4.2816330e+05 3.69e-12 1.91e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 21 4.2816330e+05 4.18e-12 4.47e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 22 4.2816330e+05 1.88e-12 2.88e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00H 1\n", - " 23 4.2816330e+05 3.50e-12 6.44e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 23\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", - "Dual infeasibility......: 6.4351411026732109e-12 1.2447037574879725e-09\n", - "Constraint violation....: 3.8099280283971188e-13 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 26\n", - "Number of objective gradient evaluations = 24\n", - "Number of equality constraint evaluations = 26\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 24\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 23\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.015\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 5.14e+03 9.96e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 5.1361724e+05 1.16e+03 5.52e+03 -1.0 9.68e+03 - 7.33e-01 1.00e+00f 1\n", - " 2 4.2850802e+05 3.35e+01 5.98e+02 -1.0 3.02e+01 - 1.00e+00 1.00e+00f 1\n", - " 3 4.2816351e+05 3.18e-02 2.65e+00 -1.0 1.13e+00 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 2.81e-08 6.99e-06 -1.0 1.21e-03 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 3.47e-12 2.02e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 5.31e-12 1.01e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", - " 7 4.2816330e+05 3.04e-12 1.11e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 4.2816330e+05 3.50e-12 7.58e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.5828253298624225e-12 1.4666921874539710e-09\n", - "Constraint violation....: 8.0852985719428312e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 8.79e+03 9.90e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.3423860e+05 1.42e+02 3.82e+03 -1.0 9.65e+03 - 9.02e-01 1.00e+00f 1\n", - " 2 4.2817922e+05 8.43e-01 1.02e+02 -1.0 4.91e+00 - 1.00e+00 1.00e+00f 1\n", - " 3 4.2816330e+05 2.99e-05 1.09e-02 -1.0 4.22e-02 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 3.18e-12 1.14e-10 -2.5 2.42e-05 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 2.76e-12 2.30e-03 -3.8 7.13e-07 - 1.00e+00 5.00e-01h 2\n", - " 6 4.2816330e+05 3.69e-12 1.15e-03 -3.8 3.56e-07 - 1.00e+00 5.00e-01h 2\n", - " 7 4.2816330e+05 4.18e-12 2.30e-11 -5.7 2.18e-07 - 1.00e+00 1.00e+00H 1\n", - " 8 4.2816330e+05 3.50e-12 1.89e-11 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", - "Dual infeasibility......: 1.8948306952157019e-11 3.6650367855318503e-09\n", - "Constraint violation....: 5.8616380029777494e-14 3.4958702599396925e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 14\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 14\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 2.01e+03 1.03e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 3.1611112e+09 1.31e+04 1.30e+07 -1.0 5.97e+03 -2.0 8.06e-02 3.16e-01f 1\n", - " 2 1.7336542e+07 2.79e+03 2.12e+06 -1.0 7.56e+03 - 1.17e-02 1.00e+00f 1\n", - " 3 2.7661414e+07 1.95e+02 2.35e+05 -1.0 7.82e+02 - 8.45e-01 1.00e+00h 1\n", - " 4 2.7187779e+07 1.42e+00 3.85e+03 -1.0 6.38e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 2.7186293e+07 2.57e-04 9.05e-01 -1.0 1.01e+00 - 1.00e+00 1.00e+00f 1\n", - " 6 2.7186294e+07 1.00e-11 4.03e-08 -1.7 2.25e-04 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 3.52e-12 6.33e-10 -3.8 4.19e-06 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.69e-12 1.07e-09 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 2.7186294e+07 4.12e-12 7.17e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 7.1723805334492121e-10 1.3873027580404212e-07\n", - "Constraint violation....: 3.9907987116676576e-13 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.28e+03 9.77e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 8.7268227e+06 3.80e+03 3.76e+04 -1.0 9.35e+03 - 2.32e-01 1.00e+00f 1\n", - " 2 2.6617881e+07 3.09e+02 1.04e+04 -1.0 2.12e+02 - 7.03e-01 1.00e+00h 1\n", - " 3 2.7179492e+07 2.60e+00 1.35e+02 -1.0 1.25e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186293e+07 1.89e-04 3.26e-02 -1.0 1.05e-01 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 4.97e-12 8.21e-10 -2.5 2.46e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 3.75e-12 3.04e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 6.58e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 9.83e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027403e+05 2.7186293738994990e+07\n", - "Dual infeasibility......: 9.8263762867883811e-10 1.9006463559245624e-07\n", - "Constraint violation....: 1.0134854702842251e-13 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 4.05e+02 7.12e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2427232e+09 1.39e+03 1.78e+06 -1.0 6.75e+03 -2.0 2.33e-01 1.21e-01f 1\n", - " 2 4.2335006e+09 1.39e+03 1.77e+06 -1.0 1.56e+04 - 3.72e-01 7.80e-04f 1\n", - " 3 4.2319049e+09 1.39e+03 2.67e+06 -1.0 5.42e+03 - 7.99e-01 4.52e-04f 1\n", - " 4 2.4661840e+09 1.62e+03 1.40e+07 -1.0 5.45e+03 - 1.00e+00 8.02e-01f 1\n", - " 5 1.4734739e+09 1.44e+03 1.59e+07 -1.0 7.78e+03 - 2.47e-01 1.00e+00f 1\n", - " 6 9.7692393e+08 2.37e+02 5.76e+06 -1.0 2.22e+03 - 5.27e-03 1.00e+00f 1\n", - " 7 6.1520348e+08 7.93e+01 5.07e+06 -1.0 9.78e+02 - 5.43e-05 1.00e+00f 1\n", - " 8 1.7354679e+08 2.47e+03 1.42e+07 -1.0 1.01e+04 - 9.76e-02 5.00e-01f 2\n", - " 9 3.1087330e+07 3.84e+02 1.69e+06 -1.0 1.44e+03 - 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 2.7129946e+07 1.89e+01 7.70e+04 -1.0 3.15e+02 - 1.00e+00 1.00e+00f 1\n", - " 11 2.7186030e+07 6.02e-02 2.49e+02 -1.0 1.83e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 2.7186294e+07 6.36e-07 2.66e-03 -1.0 6.05e-02 - 1.00e+00 1.00e+00h 1\n", - " 13 2.7186294e+07 3.58e-12 1.12e-09 -2.5 2.04e-05 - 1.00e+00 1.00e+00h 1\n", - " 14 2.7186294e+07 4.41e-12 4.03e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 15 2.7186294e+07 4.69e-12 8.72e-11 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 16 2.7186294e+07 4.12e-12 5.21e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 16\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 5.2078719776239223e-10 1.0073217845016686e-07\n", - "Constraint violation....: 3.0797477427240214e-13 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 20\n", - "Number of objective gradient evaluations = 17\n", - "Number of equality constraint evaluations = 20\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 17\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 16\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.010\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 4.47e+03 9.77e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.8483214e+09 1.07e+03 1.08e+07 -1.0 3.06e+02 0.0 1.33e-01 1.00e+00f 1\n", - " 2 2.7753495e+09 2.82e+03 8.80e+06 -1.0 1.07e+04 - 3.66e-01 3.05e-01f 1\n", - " 3 2.6846467e+09 2.73e+03 8.51e+06 -1.0 5.59e+03 - 1.00e+00 3.18e-02f 1\n", - " 4 2.6837149e+09 2.72e+03 8.51e+06 -1.0 5.41e+03 - 1.00e+00 3.43e-04f 1\n", - " 5 2.6591967e+09 2.70e+03 8.42e+06 -1.0 4.45e+03 - 1.00e+00 1.08e-02f 1\n", - " 6 1.2784608e+09 1.22e+02 1.09e+07 -1.0 4.43e+03 - 1.00e+00 1.00e+00f 1\n", - " 7 1.1089604e+09 3.44e+02 6.21e+06 -1.0 3.45e+03 - 2.95e-01 1.00e+00f 1\n", - " 8 1.0049821e+09 2.85e+01 4.47e+06 -1.0 8.11e+02 - 5.20e-03 1.00e+00f 1\n", - " 9 3.7408506e+08 2.96e+03 1.10e+07 -1.0 4.03e+03 - 2.70e-05 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 5.0448479e+06 1.49e+02 9.10e+05 -1.0 2.54e+03 - 1.00e+00 1.00e+00f 1\n", - " 11 4.2998863e+05 4.45e+00 3.44e+04 -1.0 2.81e+02 - 1.00e+00 1.00e+00f 1\n", - " 12 4.2816332e+05 3.34e-03 2.10e+01 -1.0 6.77e+00 - 1.00e+00 1.00e+00f 1\n", - " 13 4.2816330e+05 1.51e-09 8.78e-06 -1.0 4.22e-03 - 1.00e+00 1.00e+00h 1\n", - " 14 4.2816330e+05 3.69e-12 2.07e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 15 4.2816330e+05 5.31e-12 2.82e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", - " 16 4.2816330e+05 3.04e-12 2.81e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 17 4.2816330e+05 3.50e-12 5.99e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 17\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 5.9912096017597981e-12 1.1588372320399661e-09\n", - "Constraint violation....: 1.1815048168495169e-12 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 19\n", - "Number of objective gradient evaluations = 18\n", - "Number of equality constraint evaluations = 19\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 18\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 17\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.010\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.25e+04 9.65e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.7174519e+07 6.12e+02 8.07e+03 -1.0 9.16e+03 - 6.72e-01 1.00e+00f 1\n", - " 2 2.7157675e+07 1.43e+01 5.15e+02 -1.0 1.08e+01 - 1.00e+00 1.00e+00f 1\n", - " 3 2.7186261e+07 8.71e-03 1.33e+00 -1.0 5.48e-01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186294e+07 3.15e-09 1.28e-06 -1.0 4.74e-04 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 3.52e-12 3.69e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.41e-12 8.31e-11 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 3.86e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 7.90e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 7.8999762948675547e-10 1.5280364519439663e-07\n", - "Constraint violation....: 4.7101559432420681e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 4.14e+03 9.57e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.4927485e+07 2.77e+03 5.05e+04 -1.0 9.14e+03 - 6.25e-01 1.00e+00f 1\n", - " 2 2.6826558e+07 1.63e+02 5.13e+03 -1.0 3.63e+01 - 8.14e-01 1.00e+00h 1\n", - " 3 2.7184194e+07 7.34e-01 6.95e+01 -1.0 5.26e+00 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186294e+07 1.49e-05 3.78e-03 -1.0 3.04e-02 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 2.47e-12 8.83e-10 -2.5 2.11e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.41e-12 6.32e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 2.33e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 8.30e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 8.2984251878098616e-10 1.6051055987271177e-07\n", - "Constraint violation....: 8.3214129700933826e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 2.01e+04 1.01e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 5.1232904e+06 2.26e+03 2.68e+04 -1.0 9.80e+03 - 1.37e-01 1.00e+00f 1\n", - " 2 4.4576929e+05 1.76e+02 6.61e+03 -1.0 2.13e+02 - 1.00e+00 1.00e+00f 1\n", - " 3 4.2819162e+05 1.33e+00 2.00e+02 -1.0 1.07e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 4.2816330e+05 7.39e-05 3.52e-02 -1.0 7.94e-02 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 3.84e-12 2.26e-10 -2.5 2.16e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 4.18e-12 1.33e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 1.88e-12 1.97e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00H 1\n", - " 8 4.2816330e+05 3.50e-12 8.34e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", - "Dual infeasibility......: 8.3365341010308284e-12 1.6124767358510909e-09\n", - "Constraint violation....: 6.5831840901751260e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 2.29e+04 9.88e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 7.8310154e+05 1.91e+03 9.41e+03 -1.0 9.72e+03 - 6.19e-02 1.00e+00f 1\n", - " 2 4.3005112e+05 8.54e+01 1.56e+03 -1.0 6.58e+01 - 1.00e+00 1.00e+00f 1\n", - " 3 4.2816476e+05 2.09e-01 6.47e+00 -1.0 3.77e+00 - 1.00e+00 1.00e+00f 1\n", - " 4 4.2816330e+05 1.24e-06 1.73e-04 -1.0 8.41e-03 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 3.92e-12 2.06e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 4.18e-12 2.30e-03 -3.8 7.13e-07 - 1.00e+00 5.00e-01h 2\n", - " 7 4.2816330e+05 3.69e-12 1.15e-03 -3.8 3.56e-07 - 1.00e+00 5.00e-01h 2\n", - " 8 4.2816330e+05 4.18e-12 2.66e-11 -5.7 2.18e-07 - 1.00e+00 1.00e+00H 1\n", - " 9 4.2816330e+05 3.50e-12 4.40e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", - "Dual infeasibility......: 4.3963917237901670e-12 8.5036290746094841e-10\n", - "Constraint violation....: 3.5289081297329319e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 15\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 15\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 4.99e+03 9.57e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.8459805e+07 9.05e+02 3.08e+03 -1.0 9.14e+03 - 8.90e-01 1.00e+00f 1\n", - " 2 2.7214552e+07 2.03e+01 2.33e+02 -1.0 1.11e+01 - 1.00e+00 1.00e+00f 1\n", - " 3 2.7186309e+07 1.13e-02 3.06e-01 -1.0 2.51e-01 - 1.00e+00 1.00e+00f 1\n", - " 4 2.7186294e+07 3.47e-09 1.40e-07 -1.7 1.44e-04 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 4.43e-12 5.75e-10 -3.8 4.19e-06 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.69e-12 6.00e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.12e-12 7.10e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 7\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 7.0996209573073779e-10 1.3732293886500667e-07\n", - "Constraint violation....: 6.4371955330339621e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 8\n", - "Number of objective gradient evaluations = 8\n", - "Number of equality constraint evaluations = 8\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 8\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 7\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.30e+04 9.67e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.6124087e+07 9.63e+02 1.22e+04 -1.0 9.18e+03 - 6.10e-01 1.00e+00f 1\n", - " 2 2.7077188e+07 3.41e+01 1.82e+03 -1.0 2.77e+01 - 1.00e+00 1.00e+00h 1\n", - " 3 2.7186081e+07 5.00e-02 9.45e+00 -1.0 1.70e+00 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186294e+07 1.02e-07 5.14e-05 -1.0 2.98e-03 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 2.67e-12 4.46e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.41e-12 3.04e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 5.16e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 5.64e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 5.6444294344749279e-10 1.0917620008437956e-07\n", - "Constraint violation....: 5.0470631526657618e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 4.15e+03 1.10e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.9476936e+09 1.04e+03 3.45e+05 -1.0 1.14e+02 0.0 5.04e-01 1.00e+00f 1\n", - " 2 3.7919093e+09 2.35e+03 8.76e+05 -1.0 6.79e+03 - 5.62e-01 4.46e-01f 1\n", - " 3 3.4291421e+09 5.47e+02 1.25e+07 -1.0 6.72e+02 -0.5 1.00e+00 1.00e+00f 1\n", - " 4 1.4862561e+09 1.08e+03 2.19e+07 -1.0 2.79e+03 - 7.85e-01 1.00e+00f 1\n", - " 5 1.0803970e+09 6.74e+03 3.96e+07 -1.0 1.93e+04 - 1.00e+00 5.85e-01f 1\n", - " 6 7.1117865e+07 1.32e+03 7.64e+06 -1.0 3.91e+03 - 1.70e-01 1.00e+00f 1\n", - " 7 1.2641918e+06 1.32e+02 7.40e+05 -1.0 1.21e+03 - 1.00e+00 1.00e+00f 1\n", - " 8 4.2836369e+05 1.99e+00 1.09e+04 -1.0 1.45e+02 - 1.00e+00 1.00e+00f 1\n", - " 9 4.2816330e+05 4.66e-04 2.53e+00 -1.0 2.20e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.2816330e+05 2.83e-11 1.37e-07 -1.0 5.11e-04 - 1.00e+00 1.00e+00h 1\n", - " 11 4.2816330e+05 4.92e-12 2.04e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 12 4.2816330e+05 5.31e-12 1.30e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", - " 13 4.2816330e+05 3.04e-12 1.29e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 14 4.2816330e+05 3.50e-12 1.17e-11 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 14\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 1.1672349337973593e-11 2.2576998464963993e-09\n", - "Constraint violation....: 7.6028072726330720e-13 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 16\n", - "Number of objective gradient evaluations = 15\n", - "Number of equality constraint evaluations = 16\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 15\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 14\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.009\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 4.57e+02 9.29e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.9537123e+09 3.20e+02 4.79e+05 -1.0 1.07e+02 0.0 6.34e-01 1.00e+00f 1\n", - " 2 4.7229788e+09 2.17e+02 2.38e+06 -1.0 2.42e+02 -0.5 7.40e-01 1.00e+00f 1\n", - " 3 4.6081291e+09 1.51e+01 1.98e+05 -1.0 8.20e+01 -0.1 1.00e+00 1.00e+00f 1\n", - " 4 3.3364039e+09 4.66e+03 3.38e+06 -1.0 1.97e+04 - 1.21e-01 1.01e-01f 1\n", - " 5 8.5294751e+08 1.47e+03 1.28e+07 -1.0 6.99e+03 - 1.00e+00 1.00e+00f 1\n", - " 6 1.7203645e+09 1.37e+03 8.91e+06 -1.0 2.40e+04 - 3.10e-01 9.05e-02H 1\n", - " 7 1.7200201e+09 1.35e+03 8.82e+06 -1.0 1.79e+02 -0.5 1.00e+00 1.03e-02f 1\n", - " 8 1.7199986e+09 1.35e+03 8.82e+06 -1.0 2.26e+02 -1.0 1.00e+00 1.29e-04f 1\n", - " 9 1.0216189e+09 7.78e+01 5.04e+06 -1.0 1.88e+03 - 1.92e-01 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 9.9725562e+08 3.93e+00 4.37e+06 -1.0 3.37e+02 - 2.74e-03 1.00e+00f 1\n", - " 11 2.7996079e+08 1.31e+03 1.96e+07 -1.0 2.64e+03 -1.5 1.29e-03 1.00e+00f 1\n", - " 12 4.8482859e+06 2.85e+01 1.31e+06 -1.0 1.93e+03 - 8.31e-01 1.00e+00f 1\n", - " 13 4.3209489e+05 4.39e+00 3.90e+04 -1.0 3.41e+02 - 1.00e+00 1.00e+00f 1\n", - " 14 4.2816348e+05 8.48e-03 4.87e+01 -1.0 1.02e+01 - 1.00e+00 1.00e+00f 1\n", - " 15 4.2816330e+05 1.82e-08 8.87e-05 -1.0 1.28e-02 - 1.00e+00 1.00e+00h 1\n", - " 16 4.2816330e+05 4.18e-12 2.22e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 17 4.2816330e+05 5.31e-12 1.01e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", - " 18 4.2816330e+05 3.04e-12 1.54e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 19 4.2816330e+05 3.50e-12 4.40e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 19\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 4.3995938736571737e-12 8.5098227662596132e-10\n", - "Constraint violation....: 4.6942418461511737e-13 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 22\n", - "Number of objective gradient evaluations = 20\n", - "Number of equality constraint evaluations = 22\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 20\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 19\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.013\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 8.99e+03 9.64e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.5839765e+07 3.16e+02 8.96e+03 -1.0 9.16e+03 - 6.70e-01 1.00e+00f 1\n", - " 2 2.7166753e+07 4.34e+00 8.37e+01 -1.0 1.51e+01 - 1.00e+00 1.00e+00h 1\n", - " 3 2.7186290e+07 8.47e-04 9.25e-02 -1.0 2.86e-01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186294e+07 3.28e-11 9.72e-09 -2.5 3.34e-05 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 5.43e-12 1.38e-09 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.69e-12 1.41e-09 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.12e-12 8.95e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 7\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 8.9532613730863700e-10 1.7317659232403083e-07\n", - "Constraint violation....: 5.0554756559712512e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 8\n", - "Number of objective gradient evaluations = 8\n", - "Number of equality constraint evaluations = 8\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 8\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 7\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 2.98e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.0130337e+09 1.42e+04 3.05e+06 -1.0 9.58e+03 - 2.26e-02 1.43e-01f 1\n", - " 2 2.0683948e+07 6.26e+02 4.78e+05 -1.0 8.07e+03 - 2.73e-02 1.00e+00f 1\n", - " 3 2.7200387e+07 8.95e+00 1.34e+04 -1.0 1.07e+02 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186293e+07 2.26e-03 2.41e+00 -1.0 3.61e+00 - 1.00e+00 1.00e+00f 1\n", - " 5 2.7186294e+07 4.02e-10 1.02e-06 -1.0 9.28e-04 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 3.18e-12 1.31e-09 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.41e-12 7.76e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.69e-12 3.74e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 2.7186294e+07 4.12e-12 8.08e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 8.0801464593843588e-10 1.5628854905560542e-07\n", - "Constraint violation....: 1.3908096331519524e-12 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.84e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.7575504e+06 9.13e+02 1.38e+04 -1.0 9.75e+03 - 4.47e-01 1.00e+00f 1\n", - " 2 4.2824668e+05 2.49e+01 1.18e+03 -1.0 1.05e+02 - 1.00e+00 1.00e+00f 1\n", - " 3 4.2816335e+05 1.64e-02 2.86e+00 -1.0 6.45e-01 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 6.88e-09 3.30e-06 -1.0 4.97e-04 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 3.58e-12 2.27e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 4.18e-12 1.86e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 1.88e-12 6.52e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00H 1\n", - " 8 4.2816330e+05 3.50e-12 8.34e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349154e+03 4.2816329651878146e+05\n", - "Dual infeasibility......: 8.3365341010308284e-12 1.6124767358510909e-09\n", - "Constraint violation....: 7.9278799075454343e-14 3.4958702599396933e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 5.18e+03 9.94e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.4742544e+05 1.01e+03 5.01e+03 -1.0 9.66e+03 - 8.96e-01 1.00e+00f 1\n", - " 2 4.2822932e+05 2.50e+01 3.20e+02 -1.0 1.24e+01 - 1.00e+00 1.00e+00f 1\n", - " 3 4.2816333e+05 1.69e-02 4.70e-01 -1.0 3.08e-01 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 7.77e-09 5.77e-07 -1.7 1.95e-04 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.83e-12 6.32e-12 -3.8 5.28e-06 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 5.09e-12 5.58e-12 -5.7 3.95e-08 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 3.50e-12 2.86e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 7\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 2.8627514714548167e-12 5.5372173763117912e-10\n", - "Constraint violation....: 7.8113496119784019e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 8\n", - "Number of objective gradient evaluations = 8\n", - "Number of equality constraint evaluations = 8\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 8\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 7\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.70e+03 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.8345448e+09 1.66e+03 6.22e+02 -1.0 7.58e+03 - 3.85e-01 2.30e-02f 1\n", - " 2 4.8321364e+09 1.66e+03 6.32e+04 -1.0 7.40e+03 - 9.64e-01 2.63e-04f 1\n", - " 3 4.7840829e+09 1.64e+03 4.48e+06 -1.0 4.93e+03 - 1.00e+00 1.38e-02f 1\n", - " 4 2.5854958e+09 1.81e+03 2.34e+07 -1.0 5.10e+03 - 1.00e+00 1.00e+00f 1\n", - " 5 2.4006679e+09 2.48e+03 3.67e+07 -1.0 1.01e+04 - 2.59e-01 1.00e+00f 1\n", - " 6 1.0935406e+09 5.82e+02 7.41e+06 -1.0 3.94e+03 - 6.77e-03 1.00e+00f 1\n", - " 7 6.7957486e+08 5.18e+01 5.05e+06 -1.0 9.85e+02 - 8.72e-05 1.00e+00f 1\n", - " 8 2.6794664e+08 3.62e+03 1.93e+07 -1.0 2.03e+04 - 3.53e-02 2.81e-01f 2\n", - " 9 3.6194377e+07 6.17e+02 2.61e+06 -1.0 1.73e+03 - 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 2.7100647e+07 4.15e+01 1.63e+05 -1.0 4.49e+02 - 1.00e+00 1.00e+00f 1\n", - " 11 2.7185103e+07 2.75e-01 1.11e+03 -1.0 3.84e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 2.7186294e+07 1.30e-05 5.36e-02 -1.0 2.71e-01 - 1.00e+00 1.00e+00h 1\n", - " 13 2.7186294e+07 3.52e-12 3.60e-10 -2.5 1.90e-05 - 1.00e+00 1.00e+00h 1\n", - " 14 2.7186294e+07 4.41e-12 1.67e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 15 2.7186294e+07 4.69e-12 1.53e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 16 2.7186294e+07 4.12e-12 6.92e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 16\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 6.9159932411192459e-10 1.3377115803112010e-07\n", - "Constraint violation....: 1.6697754290362354e-13 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 20\n", - "Number of objective gradient evaluations = 17\n", - "Number of equality constraint evaluations = 20\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 17\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 16\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.009\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.40e+04 9.84e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 6.7882418e+06 2.02e+03 4.86e+04 -1.0 9.42e+03 - 1.15e-01 1.00e+00f 1\n", - " 2 2.7335745e+07 1.17e+02 1.07e+04 -1.0 2.72e+02 - 9.36e-01 1.00e+00h 1\n", - " 3 2.7186688e+07 3.81e-01 7.08e+01 -1.0 1.50e+00 - 1.00e+00 1.00e+00f 1\n", - " 4 2.7186294e+07 4.25e-06 1.56e-03 -1.0 8.68e-03 - 1.00e+00 1.00e+00f 1\n", - " 5 2.7186294e+07 4.12e-12 8.98e-10 -2.5 2.03e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.41e-12 1.60e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 8.78e-11 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 5.06e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 5.0623528253402496e-10 9.7917504572095877e-08\n", - "Constraint violation....: 8.9958290210069930e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 5.24e+02 1.06e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.8138975e+09 9.77e+03 5.01e+06 -1.0 1.59e+04 - 1.46e-01 1.92e-01f 1\n", - " 2 1.2458106e+07 2.49e+03 2.37e+06 -1.0 6.91e+03 - 1.10e-02 1.00e+00f 1\n", - " 3 5.9638509e+05 2.45e+02 2.68e+05 -1.0 5.41e+02 - 8.34e-01 1.00e+00f 1\n", - " 4 4.2833613e+05 3.87e+00 6.05e+03 -1.0 7.33e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 4.2816332e+05 1.27e-03 2.81e+00 -1.0 1.76e+00 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 1.69e-10 4.83e-07 -1.0 7.86e-04 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 3.38e-12 1.99e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 8 4.2816330e+05 4.18e-12 2.79e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 9 4.2816330e+05 5.09e-12 4.90e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.2816330e+05 3.50e-12 6.96e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 10\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 6.9554776294329938e-12 1.3453487658386204e-09\n", - "Constraint violation....: 4.1257311072239357e-13 3.4958702599396933e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 11\n", - "Number of objective gradient evaluations = 11\n", - "Number of equality constraint evaluations = 11\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 11\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 10\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.006\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 5.14e+03 1.01e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.2558366e+07 9.25e+03 1.72e+06 -1.0 9.81e+03 - 3.06e-01 1.00e+00f 1\n", - " 2 1.4246827e+06 1.46e+03 3.89e+05 -1.0 4.34e+02 - 2.34e-01 1.00e+00f 1\n", - " 3 4.3546419e+05 8.26e+01 3.35e+04 -1.0 1.54e+02 - 9.56e-01 1.00e+00f 1\n", - " 4 4.2817095e+05 3.63e-01 2.26e+02 -1.0 1.32e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 4.2816330e+05 7.79e-06 7.54e-03 -1.0 7.81e-02 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.69e-12 1.66e-10 -2.5 2.53e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 4.18e-12 4.88e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 8 4.2816330e+05 5.09e-12 4.37e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 4.2816330e+05 3.50e-12 1.42e-11 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 1.4181073467955190e-11 2.7429445833665322e-09\n", - "Constraint violation....: 1.7763568394002505e-13 3.4958702599396925e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.81e+04 9.66e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.9003335e+07 1.13e+03 1.55e+04 -1.0 9.14e+03 - 3.32e-01 1.00e+00f 1\n", - " 2 2.7238948e+07 3.20e+01 1.01e+03 -1.0 1.69e+01 - 1.00e+00 1.00e+00f 1\n", - " 3 2.7186331e+07 4.27e-02 2.05e+00 -1.0 5.65e-01 - 1.00e+00 1.00e+00f 1\n", - " 4 2.7186294e+07 7.75e-08 3.69e-06 -1.0 5.69e-04 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 3.21e-12 5.51e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.41e-12 1.76e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 2.40e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 8.01e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 8.0073868832425246e-10 1.5488121211656997e-07\n", - "Constraint violation....: 3.7925743719988039e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 3.55e+03 9.62e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.5339484e+08 1.19e+04 3.21e+05 -1.0 9.18e+03 - 2.52e-01 7.84e-01f 1\n", - " 2 2.2997591e+07 1.30e+03 4.50e+04 -1.0 1.97e+03 - 2.63e-02 1.00e+00f 1\n", - " 3 2.7064893e+07 4.24e+01 5.28e+03 -1.0 6.00e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186154e+07 4.87e-02 1.67e+01 -1.0 1.89e+00 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 5.94e-08 4.87e-05 -1.0 2.66e-03 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 2.79e-12 3.95e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.41e-12 1.99e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.69e-12 3.32e-11 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 2.7186294e+07 4.12e-12 5.94e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 5.9354677390422649e-10 1.1480554784052137e-07\n", - "Constraint violation....: 1.6765154534897615e-13 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.41e+04 1.01e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.9401960e+06 1.02e+03 1.97e+04 -1.0 9.77e+03 - 3.26e-01 1.00e+00f 1\n", - " 2 4.2927250e+05 4.60e+01 1.72e+03 -1.0 1.52e+02 - 1.00e+00 1.00e+00f 1\n", - " 3 4.2816494e+05 8.94e-02 1.45e+01 -1.0 1.80e+00 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 3.28e-07 1.56e-04 -1.0 4.73e-03 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 3.58e-12 2.16e-10 -2.5 2.58e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 5.31e-12 6.42e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00H 1\n", - " 7 4.2816330e+05 3.04e-12 1.36e-11 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 4.2816330e+05 3.50e-12 6.22e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 6.2153811273360234e-12 1.2021971422198111e-09\n", - "Constraint violation....: 7.1908036628402804e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 1.12e+04 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.4982169e+05 6.60e+01 4.87e+03 -1.0 9.66e+03 - 7.20e-01 1.00e+00f 1\n", - " 2 4.2816538e+05 2.24e-01 6.53e+01 -1.0 1.30e+01 - 1.00e+00 1.00e+00f 1\n", - " 3 4.2816330e+05 1.71e-06 1.54e-03 -1.0 1.79e-02 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 3.64e-12 1.98e-10 -2.5 2.58e-05 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 4.18e-12 7.60e-12 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 5.09e-12 3.60e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 7 4.2816330e+05 3.50e-12 3.49e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 7\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 3.4900991718842455e-12 6.7506515924652994e-10\n", - "Constraint violation....: 5.1473574040930074e-14 3.4958702599396925e-12\n", - "Complementarity.........: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "Overall NLP error.......: 2.5059035597864302e-09 4.8469917395796542e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 8\n", - "Number of objective gradient evaluations = 8\n", - "Number of equality constraint evaluations = 8\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 8\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 7\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 5.28e+03 9.78e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 1.9323923e+07 7.90e+03 4.80e+05 -1.0 9.33e+03 - 2.42e-01 1.00e+00f 1\n", - " 2 2.3574045e+07 1.13e+03 1.06e+05 -1.0 1.29e+02 - 6.53e-01 1.00e+00h 1\n", - " 3 2.6987010e+07 4.63e+01 1.05e+04 -1.0 5.24e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7185919e+07 8.56e-02 5.03e+01 -1.0 2.77e+00 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 2.43e-07 3.68e-04 -1.0 1.09e-02 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 3.52e-12 9.77e-10 -2.5 2.05e-05 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.41e-12 3.25e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.69e-12 4.15e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 9 2.7186294e+07 4.12e-12 7.50e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 9\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027401e+05 2.7186293738994986e+07\n", - "Dual infeasibility......: 7.4980698502496848e-10 1.4502985354332181e-07\n", - "Constraint violation....: 1.1133569257438686e-13 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 10\n", - "Number of objective gradient evaluations = 10\n", - "Number of equality constraint evaluations = 10\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 10\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 9\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - "Ipopt 3.13.2: bound_relax_factor=0\n", - "honor_original_bounds=no\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 2.18e+04 9.74e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 2.2432629e+07 2.91e+03 2.66e+04 -1.0 9.25e+03 - 1.74e-01 1.00e+00f 1\n", - " 2 2.6283816e+07 2.45e+02 8.03e+03 -1.0 8.73e+01 - 8.79e-01 1.00e+00h 1\n", - " 3 2.7175244e+07 2.54e+00 3.60e+02 -1.0 1.33e+01 - 1.00e+00 1.00e+00h 1\n", - " 4 2.7186293e+07 2.70e-04 1.09e-01 -1.0 1.57e-01 - 1.00e+00 1.00e+00h 1\n", - " 5 2.7186294e+07 5.40e-12 1.77e-09 -2.5 1.89e-05 - 1.00e+00 1.00e+00h 1\n", - " 6 2.7186294e+07 4.41e-12 1.55e-10 -3.8 5.65e-07 - 1.00e+00 1.00e+00h 1\n", - " 7 2.7186294e+07 4.69e-12 6.07e-10 -5.7 3.14e-08 - 1.00e+00 1.00e+00h 1\n", - " 8 2.7186294e+07 4.12e-12 9.83e-10 -8.6 3.90e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 8\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.4055363392027403e+05 2.7186293738994990e+07\n", - "Dual infeasibility......: 9.8263762867873223e-10 1.9006463559243576e-07\n", - "Constraint violation....: 5.4622972811557702e-14 4.1211478674085811e-12\n", - "Complementarity.........: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "Overall NLP error.......: 2.5059035597865472e-09 4.8469917395798797e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 9\n", - "Number of objective gradient evaluations = 9\n", - "Number of equality constraint evaluations = 9\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 9\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 8\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.005\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Warning: estimated values of mu do not seem consistent - using mu=10^(-8.6)\n", - " run theta1_init theta2_init theta1_est theta2_est objective\n", - "0 0 0.904117 -1.570500 1.204754 -0.646637 2.718629e+07\n", - "1 1 1.646200 1.969240 1.204754 -0.646637 2.718629e+07\n", - "2 2 -0.500088 -0.410770 -1.500300 0.501315 4.281633e+05\n", - "3 3 -0.032914 1.388731 -1.500300 0.501315 4.281633e+05\n", - "4 4 1.175866 -0.947448 1.204754 -0.646637 2.718629e+07\n", - "5 5 0.434035 0.596308 1.204754 -0.646637 2.718629e+07\n", - "6 6 -1.290840 -1.037834 -1.500300 0.501315 4.281633e+05\n", - "7 7 -1.114986 1.637305 -1.500300 0.501315 4.281633e+05\n", - "8 8 0.218859 -0.196021 1.204754 -0.646637 2.718629e+07\n", - "9 9 1.477024 0.343782 1.204754 -0.646637 2.718629e+07\n", - "10 10 -0.372907 -1.785309 1.204754 -0.646637 2.718629e+07\n", - "11 11 -0.840302 0.764188 -1.500300 0.501315 4.281633e+05\n", - "12 12 1.947122 -1.322903 1.204754 -0.646637 2.718629e+07\n", - "13 13 0.689208 1.220790 1.204754 -0.646637 2.718629e+07\n", - "14 14 -1.582145 -0.662319 -1.500300 0.501315 4.281633e+05\n", - "15 15 -1.744031 1.077411 -1.500300 0.501315 4.281633e+05\n", - "16 16 0.605718 -0.511126 1.204754 -0.646637 2.718629e+07\n", - "17 17 1.847797 0.909993 1.204754 -0.646637 2.718629e+07\n", - "18 18 -0.985865 -1.476522 -1.500300 0.501315 4.281633e+05\n", - "19 19 -0.453270 0.450540 -1.500300 0.501315 4.281633e+05\n", - "20 20 1.317900 -1.884256 1.204754 -0.646637 2.718629e+07\n", - "21 21 0.076058 1.533004 -1.500300 0.501315 4.281633e+05\n", - "22 22 -1.211183 -0.099532 -1.500300 0.501315 4.281633e+05\n", - "23 23 -1.379087 0.702927 -1.500300 0.501315 4.281633e+05\n", - "24 24 0.267140 -1.136644 1.204754 -0.646637 2.718629e+07\n", - "25 25 1.025302 1.284538 1.204754 -0.646637 2.718629e+07\n", - "26 26 -0.137004 -0.851065 1.204754 -0.646637 2.718629e+07\n", - "27 27 -0.669836 1.826000 -1.500300 0.501315 4.281633e+05\n", - "28 28 1.554977 -0.259714 1.204754 -0.646637 2.718629e+07\n", - "29 29 0.797052 0.157482 1.204754 -0.646637 2.718629e+07\n", - "30 30 -1.911667 -1.724012 -1.500300 0.501315 4.281633e+05\n", - "31 31 -1.986316 1.915811 -1.500300 0.501315 4.281633e+05\n", - "32 32 0.848017 -0.482338 1.204754 -0.646637 2.718629e+07\n", - "33 33 1.605694 0.067732 1.204754 -0.646637 2.718629e+07\n", - "34 34 -0.743749 -1.501449 -1.500300 0.501315 4.281633e+05\n", - "35 35 -0.211159 0.542803 -1.500300 0.501315 4.281633e+05\n", - "36 36 1.075776 -1.109333 1.204754 -0.646637 2.718629e+07\n", - "37 37 0.318351 1.444601 1.204754 -0.646637 2.718629e+07\n", - "38 38 -1.453490 -0.878315 -1.500300 0.501315 4.281633e+05\n", - "39 39 -1.136904 0.290293 -1.500300 0.501315 4.281633e+05\n", - "40 40 0.024975 -1.856822 1.204754 -0.646637 2.718629e+07\n", - "41 41 1.267545 1.693189 1.204754 -0.646637 2.718629e+07\n", - "42 42 -0.379231 -0.126904 -1.500300 0.501315 4.281633e+05\n", - "43 43 -0.912072 1.167345 -1.500300 0.501315 4.281633e+05\n", - "44 44 1.797196 -0.733872 1.204754 -0.646637 2.718629e+07\n", - "45 45 0.554877 0.820121 1.204754 -0.646637 2.718629e+07\n", - "46 46 -1.669509 -1.253837 -1.500300 0.501315 4.281633e+05\n", - "47 47 -1.500417 0.979125 -1.500300 0.501315 4.281633e+05\n", - "48 48 0.646298 -1.420653 1.204754 -0.646637 2.718629e+07\n", - "49 49 1.903972 1.005914 1.204754 -0.646637 2.718629e+07\n", - "\n", - "Unique estimated theta_1 values:\n", - "[ 1.20475361 -1.50030035]\n", - "\n", - "Unique estimated theta_2 values:\n", - "[-0.64663711 0.5013147 -0.64663711]\n" - ] - } - ], - "source": [ - "\n", - "# Run parmest estimation for multiple random initial guesses of theta within bounds\n", - "\n", - "num_runs = 50 # Number of random initializations\n", - "theta_names = ['theta_1', 'theta_2']\n", - "theta1_bounds = (-2, 2)\n", - "theta2_bounds = (-2, 2)\n", - "\n", - "results = []\n", - "\n", - "for run in range(num_runs):\n", - " # Sobol sampling for initial values\n", - " if run == 0:\n", - " sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed = 12345)\n", - " sobol_samples = sampler.random(num_runs + 1)[1:]\n", - " sobol_theta1 = theta1_bounds[0] + (theta1_bounds[1] - theta1_bounds[0]) * sobol_samples[:, 0]\n", - " sobol_theta2 = theta2_bounds[0] + (theta2_bounds[1] - theta2_bounds[0]) * sobol_samples[:, 1]\n", - " theta1_init = sobol_theta1[run]\n", - " theta2_init = sobol_theta2[run]\n", - " theta_initial = {1: theta1_init, 2: theta2_init}\n", - " # Create experiment and estimator\n", - " exp = Simple_Multimodal(data_df, theta_initial=theta_initial)\n", - " pest = parmest.Estimator([exp], tee=True)\n", - " \n", - " # Estimate parameters\n", - " obj, theta, cov = pest.theta_est(calc_cov=True, cov_n=len(conc))\n", - " results.append({\n", - " 'run': run,\n", - " 'theta1_init': theta1_init,\n", - " 'theta2_init': theta2_init,\n", - " 'theta1_est': theta['theta_1'],\n", - " 'theta2_est': theta['theta_2'],\n", - " 'objective': obj\n", - " })\n", - "\n", - "# Convert results to DataFrame for inspection\n", - "random_init_results_df = pd.DataFrame(results)\n", - "print(random_init_results_df)\n", - "\n", - "# Print unique values of estimated parameters\n", - "print(\"\\nUnique estimated theta_1 values:\")\n", - "print(random_init_results_df['theta1_est'].unique())\n", - "print(\"\\nUnique estimated theta_2 values:\")\n", - "print(random_init_results_df['theta2_est'].unique())\n" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "44c57a03", - "metadata": {}, - "outputs": [], - "source": [ - "# # Print the model ef_instance from the Estimator\n", - "# ef_instance = pest.ef_instance\n", - "\n", - "# ef_instance.pprint()" - ] - }, - { - "cell_type": "markdown", - "id": "7301ae3c", - "metadata": {}, - "source": [ - "### Integrated Multistart test\n", - "\n", - "Now checking results against embedded feature version of multistart. Same settings" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "e6841131", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting multistart optimization with 50 restarts using sobol sampling method.\n", - "Setting theta_2 to -1.570499699562788\n", - "Current value of theta_1 is 0.9041174054145813\n", - "Current value of theta_2 is -1.570499699562788\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 1/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Applications/anaconda3/envs/parmest-dev-mac2/lib/python3.13/site-packages/scipy/stats/_qmc.py:993: UserWarning: The balance properties of Sobol' points require n to be a power of 2.\n", - " sample = self._random(n, workers=workers)\n", - "/Users/scini/Documents/GitHub/pyomo/pyomo/contrib/parmest/parmest.py:1208: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`\n", - " results_df.at[i, f'converged_{name}'] = converged_theta[j] if not np.isnan(converged_theta_vals[i, j]) else np.nan\n", - "/Users/scini/Documents/GitHub/pyomo/pyomo/contrib/parmest/parmest.py:1212: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value 'successful' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.\n", - " results_df.at[i, \"solver termination\"] = solver_termination if 'solver_termination' in locals() else np.nan\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Setting theta_2 to 1.9692404232919216\n", - "Current value of theta_1 is 1.6461998745799065\n", - "Current value of theta_2 is 1.9692404232919216\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 2/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.4107704162597656\n", - "Current value of theta_1 is -0.5000881142914295\n", - "Current value of theta_2 is -0.4107704162597656\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 3/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/scini/Documents/GitHub/pyomo/pyomo/contrib/parmest/parmest.py:1208: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`\n", - " results_df.at[i, f'converged_{name}'] = converged_theta[j] if not np.isnan(converged_theta_vals[i, j]) else np.nan\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Setting theta_2 to 1.3887314423918724\n", - "Current value of theta_1 is -0.03291422128677368\n", - "Current value of theta_2 is 1.3887314423918724\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 4/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.9474484585225582\n", - "Current value of theta_1 is 1.1758659072220325\n", - "Current value of theta_2 is -0.9474484585225582\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 5/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.5963075272738934\n", - "Current value of theta_1 is 0.4340350441634655\n", - "Current value of theta_2 is 0.5963075272738934\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 6/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.03783418238163\n", - "Current value of theta_1 is -1.2908396199345589\n", - "Current value of theta_2 is -1.03783418238163\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 7/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.637305174022913\n", - "Current value of theta_1 is -1.114986129105091\n", - "Current value of theta_2 is 1.637305174022913\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 8/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.19602123647928238\n", - "Current value of theta_1 is 0.21885917708277702\n", - "Current value of theta_2 is -0.19602123647928238\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 9/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.34378181397914886\n", - "Current value of theta_1 is 1.4770240969955921\n", - "Current value of theta_2 is 0.34378181397914886\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 10/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.7853094227612019\n", - "Current value of theta_1 is -0.37290745973587036\n", - "Current value of theta_2 is -1.7853094227612019\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 11/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.764187891036272\n", - "Current value of theta_1 is -0.8403021283447742\n", - "Current value of theta_2 is 0.764187891036272\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 12/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.3229034766554832\n", - "Current value of theta_1 is 1.9471220299601555\n", - "Current value of theta_2 is -1.3229034766554832\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 13/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.2207895517349243\n", - "Current value of theta_1 is 0.6892080903053284\n", - "Current value of theta_2 is 1.2207895517349243\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 14/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.6623185910284519\n", - "Current value of theta_1 is -1.5821445994079113\n", - "Current value of theta_2 is -0.6623185910284519\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 15/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.077410764992237\n", - "Current value of theta_1 is -1.7440308779478073\n", - "Current value of theta_2 is 1.077410764992237\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 16/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.5111263506114483\n", - "Current value of theta_1 is 0.6057177819311619\n", - "Current value of theta_2 is -0.5111263506114483\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 17/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.909992840141058\n", - "Current value of theta_1 is 1.84779679402709\n", - "Current value of theta_2 is 0.909992840141058\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 18/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.4765218794345856\n", - "Current value of theta_1 is -0.9858651980757713\n", - "Current value of theta_2 is -1.4765218794345856\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 19/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.4505395218729973\n", - "Current value of theta_1 is -0.45326995477080345\n", - "Current value of theta_2 is 0.4505395218729973\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 20/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.8842555843293667\n", - "Current value of theta_1 is 1.3178998976945877\n", - "Current value of theta_2 is -1.8842555843293667\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 21/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.5330041460692883\n", - "Current value of theta_1 is 0.07605770975351334\n", - "Current value of theta_2 is 1.5330041460692883\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 22/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.09953175485134125\n", - "Current value of theta_1 is -1.211183074861765\n", - "Current value of theta_2 is -0.09953175485134125\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 23/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.7029270566999912\n", - "Current value of theta_1 is -1.3790867365896702\n", - "Current value of theta_2 is 0.7029270566999912\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 24/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.136644072830677\n", - "Current value of theta_1 is 0.2671399489045143\n", - "Current value of theta_2 is -1.136644072830677\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 25/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.2845380455255508\n", - "Current value of theta_1 is 1.0253018885850906\n", - "Current value of theta_2 is 1.2845380455255508\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 26/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.8510647006332874\n", - "Current value of theta_1 is -0.13700413331389427\n", - "Current value of theta_2 is -0.8510647006332874\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 27/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.8259997852146626\n", - "Current value of theta_1 is -0.6698363646864891\n", - "Current value of theta_2 is 1.8259997852146626\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 28/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.25971441715955734\n", - "Current value of theta_1 is 1.5549770556390285\n", - "Current value of theta_2 is -0.25971441715955734\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 29/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.1574823558330536\n", - "Current value of theta_1 is 0.7970522679388523\n", - "Current value of theta_2 is 0.1574823558330536\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 30/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.7240123488008976\n", - "Current value of theta_1 is -1.9116670340299606\n", - "Current value of theta_2 is -1.7240123488008976\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 31/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.9158114604651928\n", - "Current value of theta_1 is -1.9863164275884628\n", - "Current value of theta_2 is 1.9158114604651928\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 32/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.4823381155729294\n", - "Current value of theta_1 is 0.8480171598494053\n", - "Current value of theta_2 is -0.4823381155729294\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 33/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.06773220747709274\n", - "Current value of theta_1 is 1.6056938730180264\n", - "Current value of theta_2 is 0.06773220747709274\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 34/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.5014492236077785\n", - "Current value of theta_1 is -0.7437494024634361\n", - "Current value of theta_2 is -1.5014492236077785\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 35/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.5428028963506222\n", - "Current value of theta_1 is -0.21115940436720848\n", - "Current value of theta_2 is 0.5428028963506222\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 36/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.1093328893184662\n", - "Current value of theta_1 is 1.0757764726877213\n", - "Current value of theta_2 is -1.1093328893184662\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 37/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.4446007087826729\n", - "Current value of theta_1 is 0.3183508887887001\n", - "Current value of theta_2 is 1.4446007087826729\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 38/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.8783153407275677\n", - "Current value of theta_1 is -1.4534900821745396\n", - "Current value of theta_2 is -0.8783153407275677\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 39/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.29029324650764465\n", - "Current value of theta_1 is -1.1369038261473179\n", - "Current value of theta_2 is 0.29029324650764465\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 40/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.8568222858011723\n", - "Current value of theta_1 is 0.024974681437015533\n", - "Current value of theta_2 is -1.8568222858011723\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 41/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.6931888945400715\n", - "Current value of theta_1 is 1.2675453573465347\n", - "Current value of theta_2 is 1.6931888945400715\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 42/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.12690448015928268\n", - "Current value of theta_1 is -0.37923091277480125\n", - "Current value of theta_2 is -0.12690448015928268\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 43/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.1673445254564285\n", - "Current value of theta_1 is -0.912072204053402\n", - "Current value of theta_2 is 1.1673445254564285\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 44/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -0.7338721342384815\n", - "Current value of theta_1 is 1.7971962057054043\n", - "Current value of theta_2 is -0.7338721342384815\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 45/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.8201205767691135\n", - "Current value of theta_1 is 0.5548769868910313\n", - "Current value of theta_2 is 0.8201205767691135\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 46/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.253836639225483\n", - "Current value of theta_1 is -1.669509395956993\n", - "Current value of theta_2 is -1.253836639225483\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 47/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 0.9791254512965679\n", - "Current value of theta_1 is -1.500417035073042\n", - "Current value of theta_2 is 0.9791254512965679\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 48/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to -1.420653060078621\n", - "Current value of theta_1 is 0.6462979316711426\n", - "Current value of theta_2 is -1.420653060078621\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 49/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "Setting theta_2 to 1.0059135183691978\n", - "Current value of theta_1 is 1.9039716646075249\n", - "Current value of theta_2 is 1.0059135183691978\n", - "Ipopt 3.13.2: \n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma27.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 3000\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 1003\n", - "\n", - "Total number of variables............................: 1002\n", - " variables with only lower bounds: 0\n", - " variables with lower and upper bounds: 2\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 1000\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0538096e+09 9.64e+03 9.89e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - " 1 4.2816331e+05 1.62e-03 1.13e+01 -1.0 9.65e+03 - 1.00e+00 1.00e+00f 1\n", - " 2 4.2816330e+05 1.19e-09 1.27e-05 -1.0 5.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 3 4.2816330e+05 4.18e-12 2.00e-10 -2.5 2.59e-05 - 1.00e+00 1.00e+00h 1\n", - " 4 4.2816330e+05 4.18e-12 1.42e-11 -3.8 7.13e-07 - 1.00e+00 1.00e+00h 1\n", - " 5 4.2816330e+05 5.09e-12 4.36e-12 -5.7 3.96e-08 - 1.00e+00 1.00e+00h 1\n", - " 6 4.2816330e+05 3.50e-12 7.21e-12 -8.6 4.91e-10 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.2136120434349150e+03 4.2816329651878134e+05\n", - "Dual infeasibility......: 7.2074760468434291e-12 1.3940910345825789e-09\n", - "Constraint violation....: 5.6153732331586577e-14 3.4958702599396929e-12\n", - "Complementarity.........: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "Overall NLP error.......: 2.5059035597864260e-09 4.8469917395796457e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.004\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Restart 50/50: Objective Value = 428163.2965187811, Theta = theta_1 -1.500300\n", - "theta_2 0.501315\n", - "dtype: float64\n", - "\n", - "\n", - "Results DataFrame:\n", - " theta_1 theta_2 converged_theta_1 converged_theta_2 \\\n", - "0 0.904117 -1.570500 -1.5003 0.501315 \n", - "1 1.646200 1.969240 -1.5003 0.501315 \n", - "2 -0.500088 -0.410770 -1.5003 0.501315 \n", - "3 -0.032914 1.388731 -1.5003 0.501315 \n", - "4 1.175866 -0.947448 -1.5003 0.501315 \n", - "5 0.434035 0.596308 -1.5003 0.501315 \n", - "6 -1.290840 -1.037834 -1.5003 0.501315 \n", - "7 -1.114986 1.637305 -1.5003 0.501315 \n", - "8 0.218859 -0.196021 -1.5003 0.501315 \n", - "9 1.477024 0.343782 -1.5003 0.501315 \n", - "10 -0.372907 -1.785309 -1.5003 0.501315 \n", - "11 -0.840302 0.764188 -1.5003 0.501315 \n", - "12 1.947122 -1.322903 -1.5003 0.501315 \n", - "13 0.689208 1.220790 -1.5003 0.501315 \n", - "14 -1.582145 -0.662319 -1.5003 0.501315 \n", - "15 -1.744031 1.077411 -1.5003 0.501315 \n", - "16 0.605718 -0.511126 -1.5003 0.501315 \n", - "17 1.847797 0.909993 -1.5003 0.501315 \n", - "18 -0.985865 -1.476522 -1.5003 0.501315 \n", - "19 -0.453270 0.450540 -1.5003 0.501315 \n", - "20 1.317900 -1.884256 -1.5003 0.501315 \n", - "21 0.076058 1.533004 -1.5003 0.501315 \n", - "22 -1.211183 -0.099532 -1.5003 0.501315 \n", - "23 -1.379087 0.702927 -1.5003 0.501315 \n", - "24 0.267140 -1.136644 -1.5003 0.501315 \n", - "25 1.025302 1.284538 -1.5003 0.501315 \n", - "26 -0.137004 -0.851065 -1.5003 0.501315 \n", - "27 -0.669836 1.826000 -1.5003 0.501315 \n", - "28 1.554977 -0.259714 -1.5003 0.501315 \n", - "29 0.797052 0.157482 -1.5003 0.501315 \n", - "30 -1.911667 -1.724012 -1.5003 0.501315 \n", - "31 -1.986316 1.915811 -1.5003 0.501315 \n", - "32 0.848017 -0.482338 -1.5003 0.501315 \n", - "33 1.605694 0.067732 -1.5003 0.501315 \n", - "34 -0.743749 -1.501449 -1.5003 0.501315 \n", - "35 -0.211159 0.542803 -1.5003 0.501315 \n", - "36 1.075776 -1.109333 -1.5003 0.501315 \n", - "37 0.318351 1.444601 -1.5003 0.501315 \n", - "38 -1.453490 -0.878315 -1.5003 0.501315 \n", - "39 -1.136904 0.290293 -1.5003 0.501315 \n", - "40 0.024975 -1.856822 -1.5003 0.501315 \n", - "41 1.267545 1.693189 -1.5003 0.501315 \n", - "42 -0.379231 -0.126904 -1.5003 0.501315 \n", - "43 -0.912072 1.167345 -1.5003 0.501315 \n", - "44 1.797196 -0.733872 -1.5003 0.501315 \n", - "45 0.554877 0.820121 -1.5003 0.501315 \n", - "46 -1.669509 -1.253837 -1.5003 0.501315 \n", - "47 -1.500417 0.979125 -1.5003 0.501315 \n", - "48 0.646298 -1.420653 -1.5003 0.501315 \n", - "49 1.903972 1.005914 -1.5003 0.501315 \n", - "\n", - " initial objective final objective solver termination solve_time \n", - "0 7.220190e+08 428163.296519 successful NaN \n", - "1 1.136218e+10 428163.296519 successful NaN \n", - "2 4.193775e+09 428163.296519 successful NaN \n", - "3 4.072387e+09 428163.296519 successful NaN \n", - "4 8.684940e+07 428163.296519 successful NaN \n", - "5 3.426209e+09 428163.296519 successful NaN \n", - "6 1.655079e+09 428163.296519 successful NaN \n", - "7 9.394389e+08 428163.296519 successful NaN \n", - "8 4.087402e+09 428163.296519 successful NaN \n", - "9 1.685132e+09 428163.296519 successful NaN \n", - "10 3.826184e+09 428163.296519 successful NaN \n", - "11 2.305593e+09 428163.296519 successful NaN \n", - "12 1.052740e+10 428163.296519 successful NaN \n", - "13 2.766225e+09 428163.296519 successful NaN \n", - "14 1.074960e+09 428163.296519 successful NaN \n", - "15 1.255159e+09 428163.296519 successful NaN \n", - "16 2.216156e+09 428163.296519 successful NaN \n", - "17 9.265699e+09 428163.296519 successful NaN \n", - "18 2.791493e+09 428163.296519 successful NaN \n", - "19 4.117223e+09 428163.296519 successful NaN \n", - "20 1.783957e+09 428163.296519 successful NaN \n", - "21 3.932326e+09 428163.296519 successful NaN \n", - "22 9.345576e+08 428163.296519 successful NaN \n", - "23 1.248299e+08 428163.296519 successful NaN \n", - "24 3.404587e+09 428163.296519 successful NaN \n", - "25 2.374101e+09 428163.296519 successful NaN \n", - "26 4.522286e+09 428163.296519 successful NaN \n", - "27 2.285725e+09 428163.296519 successful NaN \n", - "28 1.544874e+09 428163.296519 successful NaN \n", - "29 1.609095e+09 428163.296519 successful NaN \n", - "30 7.979763e+09 428163.296519 successful NaN \n", - "31 7.531637e+09 428163.296519 successful NaN \n", - "32 1.022801e+09 428163.296519 successful NaN \n", - "33 2.387392e+09 428163.296519 successful NaN \n", - "34 3.402058e+09 428163.296519 successful NaN \n", - "35 4.564792e+09 428163.296519 successful NaN \n", - "36 2.227816e+08 428163.296519 successful NaN \n", - "37 3.700507e+09 428163.296519 successful NaN \n", - "38 1.293657e+09 428163.296519 successful NaN \n", - "39 1.049181e+09 428163.296519 successful NaN \n", - "40 3.409571e+09 428163.296519 successful NaN \n", - "41 4.407327e+09 428163.296519 successful NaN \n", - "42 4.488860e+09 428163.296519 successful NaN \n", - "43 1.760318e+09 428163.296519 successful NaN \n", - "44 5.155549e+09 428163.296519 successful NaN \n", - "45 3.009035e+09 428163.296519 successful NaN \n", - "46 2.948710e+09 428163.296519 successful NaN \n", - "47 1.650676e+08 428163.296519 successful NaN \n", - "48 1.612714e+09 428163.296519 successful NaN \n", - "49 1.129338e+10 428163.296519 successful NaN \n", - "\n", - "Unique converged_theta_1 values: [-1.50030035]\n", - "Unique converged_theta_2 values: [0.5013147]\n" - ] - } - ], - "source": [ - "exp_list = [] \n", - "conc = data_df[\"x\"].values # substrate concentration (control variable)\n", - "vel = data_df[\"y\"].values # reaction velocity (output variable)\n", - "n_exp = 1\n", - "\n", - "# exp_list to separate each experiment\n", - "# for i in range(n_exp):\n", - "exp_list.append(Simple_Multimodal(data_df))\n", - "\n", - "# Creating an Estimator object\n", - "pest = parmest.Estimator(exp_list, tee = True) \n", - "\n", - "# obj, theta = pest.theta_est()\n", - "results_df = pest.theta_est_multistart(multistart_sampling_method=\"sobol\", n_restarts=50, seed = 12345)\n", - "\n", - "print(\"\\n\\nResults DataFrame:\")\n", - "print(results_df)\n", - "\n", - "# # Print unique parameter values\n", - "print(\"\\nUnique converged_theta_1 values:\", results_df['converged_theta_1'].unique())\n", - "print(\"Unique converged_theta_2 values:\", results_df['converged_theta_2'].unique())" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "parmest-dev-mac2", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.13.3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py index 90c6791c188..033c0ddcdc5 100644 --- a/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py +++ b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py @@ -40,14 +40,9 @@ def main(): # Parameter estimation with multistart to avoid local minima obj, theta = pest.theta_est_multistart( - num_starts=10, - start_method='random', - random_seed=42, - max_iter=1000, - tol=1e-6, + num_starts=10, start_method='random', random_seed=42, max_iter=1000, tol=1e-6 ) - if __name__ == "__main__": main() diff --git a/pyomo/contrib/parmest/experiment.py b/pyomo/contrib/parmest/experiment.py index 16411858095..349226e824f 100644 --- a/pyomo/contrib/parmest/experiment.py +++ b/pyomo/contrib/parmest/experiment.py @@ -32,8 +32,7 @@ def get_labeled_model(self): def reinitialize_unknown_parameters(self): raise NotImplementedError( - "The reinitialize_unknown_parameters method should implemented in the subclass." \ + "The reinitialize_unknown_parameters method should implemented in the subclass." "Thi method will take new values for the unknown parameters from the Suffix " "and allow users to reinitialize the model." ) - diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 2764983942a..6cc9e108f08 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -91,7 +91,7 @@ def ef_nonants(ef): def _experiment_instance_creation_callback( - scenario_name, node_names=None, cb_data=None, fix_vars=False, + scenario_name, node_names=None, cb_data=None, fix_vars=False ): """ This is going to be called by mpi-sppy or the local EF and it will call into @@ -253,6 +253,8 @@ def SSE(model): '''Adding pseudocode for draft implementation of the estimator class, incorporating multistart. ''' + + class Estimator(object): """ Parameter estimation class @@ -292,8 +294,7 @@ def __init__( diagnostic_mode=False, solver_options=None, ): - - '''first theta would be provided by the user in the initialization of + '''first theta would be provided by the user in the initialization of the Estimator class through the unknown parameter variables. Additional would need to be generated using the sampling method provided by the user. ''' @@ -470,44 +471,59 @@ def TotalCost_rule(model): parmest_model = utils.convert_params_to_vars(model, theta_names, fix_vars=False) return parmest_model - + # Make new private method, _generate_initial_theta: # This method will be used to generate the initial theta values for multistart # optimization. It will take the theta names and the initial theta values # and return a dictionary of theta names and their corresponding values. - def _generate_initial_theta(self, parmest_model=None, seed=None, n_restarts=None, multistart_sampling_method=None, user_provided=None): + def _generate_initial_theta( + self, + parmest_model=None, + seed=None, + n_restarts=None, + multistart_sampling_method=None, + user_provided=None, + ): """ Generate initial theta values for multistart optimization using selected sampling method. - """ + """ if n_restarts == 1: # If only one restart, return an empty list - return print("No multistart optimization needed. Please use normal theta_est()") - + return print( + "No multistart optimization needed. Please use normal theta_est()" + ) + # Get the theta names and initial theta values theta_names = self._return_theta_names() initial_theta = [parmest_model.find_component(name)() for name in theta_names] # Get the lower and upper bounds for the theta values - lower_bound = np.array([parmest_model.find_component(name).lb for name in theta_names]) - upper_bound = np.array([parmest_model.find_component(name).ub for name in theta_names]) + lower_bound = np.array( + [parmest_model.find_component(name).lb for name in theta_names] + ) + upper_bound = np.array( + [parmest_model.find_component(name).ub for name in theta_names] + ) # Check if the lower and upper bounds are defined - if any(bound is None for bound in lower_bound) and any(bound is None for bound in upper_bound): + if any(bound is None for bound in lower_bound) and any( + bound is None for bound in upper_bound + ): raise ValueError( "The lower and upper bounds for the theta values must be defined." ) - + # Check the length of theta_names and initial_theta, and make sure bounds are defined if len(theta_names) != len(initial_theta): raise ValueError( "The length of theta_names and initial_theta must be the same." ) - + if multistart_sampling_method == "uniform": # Generate random theta values using uniform distribution, with set seed for reproducibility np.random.seed(seed) # Generate random theta values for each restart (n_restarts x len(theta_names)) theta_vals_multistart = np.random.uniform( - low=lower_bound, high=upper_bound, size=(n_restarts, len(theta_names)) + low=lower_bound, high=upper_bound, size=(n_restarts, len(theta_names)) ) elif multistart_sampling_method == "latin_hypercube": @@ -523,10 +539,10 @@ def _generate_initial_theta(self, parmest_model=None, seed=None, n_restarts=None sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) # Generate theta values using Sobol sampling # The first value of the Sobol sequence is 0, so we skip it - samples = sampler.random(n=n_restarts+1)[1:] + samples = sampler.random(n=n_restarts + 1)[1:] elif multistart_sampling_method == "user_provided": - # Add user provided dataframe option + # Add user provided dataframe option if user_provided is not None: if isinstance(user_provided, np.ndarray): @@ -540,9 +556,9 @@ def _generate_initial_theta(self, parmest_model=None, seed=None, n_restarts=None raise ValueError( "The user provided numpy array must have the same number of columns as the number of theta names." ) - # Check if the user provided numpy array has the same theta names as the model - # if not, raise an error - # if not all(theta in theta_names for theta in user_provided.columns): + # Check if the user provided numpy array has the same theta names as the model + # if not, raise an error + # if not all(theta in theta_names for theta in user_provided.columns): raise ValueError( "The user provided numpy array must have the same theta names as the model." ) @@ -559,14 +575,16 @@ def _generate_initial_theta(self, parmest_model=None, seed=None, n_restarts=None raise ValueError( "The user provided dataframe must have the same number of columns as the number of theta names." ) - # Check if the user provided dataframe has the same theta names as the model - # if not, raise an error - # if not all(theta in theta_names for theta in user_provided.columns): + # Check if the user provided dataframe has the same theta names as the model + # if not, raise an error + # if not all(theta in theta_names for theta in user_provided.columns): raise ValueError( "The user provided dataframe must have the same theta names as the model." ) # If all checks pass, return the user provided dataframe - theta_vals_multistart = user_provided.iloc[0: len(initial_theta)].values + theta_vals_multistart = user_provided.iloc[ + 0 : len(initial_theta) + ].values else: raise ValueError( "The user must provide a numpy array or pandas dataframe from a previous attempt to use the 'user_provided' method." @@ -576,11 +594,16 @@ def _generate_initial_theta(self, parmest_model=None, seed=None, n_restarts=None raise ValueError( "Invalid sampling method. Choose 'uniform', 'latin_hypercube', 'sobol' or 'user_provided'." ) - - if multistart_sampling_method == "sobol" or multistart_sampling_method == "latin_hypercube": + + if ( + multistart_sampling_method == "sobol" + or multistart_sampling_method == "latin_hypercube" + ): # Scale the samples to the range of the lower and upper bounds for each theta in theta_names - theta_vals_multistart = np.array([lower_bound + (upper_bound - lower_bound) * theta for theta in samples]) - + theta_vals_multistart = np.array( + [lower_bound + (upper_bound - lower_bound) * theta for theta in samples] + ) + # Create a DataFrame where each row is an initial theta vector for a restart, # columns are theta_names, and values are the initial theta values for each restart if multistart_sampling_method == "user_provided": @@ -837,7 +860,7 @@ def _Q_at_theta(self, thetavals, initialize_parmest_model=False): # start block of code to deal with models with no constraints # (ipopt will crash or complain on such problems without special care) - instance = _experiment_instance_creation_callback("FOO0", None, dummy_cb,) + instance = _experiment_instance_creation_callback("FOO0", None, dummy_cb) try: # deal with special problems so Ipopt will not crash first = next(instance.component_objects(pyo.Constraint, active=True)) active_constraints = True @@ -854,7 +877,9 @@ def _Q_at_theta(self, thetavals, initialize_parmest_model=False): for snum in scenario_numbers: sname = "scenario_NODE" + str(snum) - instance = _experiment_instance_creation_callback(sname, None, dummy_cb, fix_vars=True) + instance = _experiment_instance_creation_callback( + sname, None, dummy_cb, fix_vars=True + ) model_theta_names = self._expand_indexed_unknowns(instance) if initialize_parmest_model: @@ -1093,7 +1118,7 @@ def theta_est_multistart( save_results=False, theta_vals=None, solver="ef_ipopt", - file_name = "multistart_results.csv", + file_name="multistart_results.csv", return_values=[], ): """ @@ -1143,26 +1168,31 @@ def theta_est_multistart( assert isinstance(multistart_sampling_method, str) assert isinstance(solver, str) assert isinstance(return_values, list) - + if n_restarts > 1 and multistart_sampling_method is not None: - + # Find the initialized values of theta from the labeled parmest model # and the theta names from the estimator object # print statement to indicate multistart optimization is starting - print(f"Starting multistart optimization with {n_restarts} restarts using {multistart_sampling_method} sampling method.") + print( + f"Starting multistart optimization with {n_restarts} restarts using {multistart_sampling_method} sampling method." + ) # @Reviewers, pyomo team: Use this or use instance creation callback? theta_names = self._return_theta_names() # Generate theta values using the sampling method parmest_model_for_bounds = self._create_parmest_model(experiment_number=0) results_df = self._generate_initial_theta( - parmest_model_for_bounds, seed=seed, n_restarts=n_restarts, - multistart_sampling_method=multistart_sampling_method, user_provided=user_provided + parmest_model_for_bounds, + seed=seed, + n_restarts=n_restarts, + multistart_sampling_method=multistart_sampling_method, + user_provided=user_provided, ) results_df = pd.DataFrame(results_df) # Extract theta_vals from the dataframe - theta_vals = results_df.iloc[:, :len(theta_names)] + theta_vals = results_df.iloc[:, : len(theta_names)] converged_theta_vals = np.zeros((n_restarts, len(theta_names))) timer = TicTocTimer() @@ -1187,7 +1217,7 @@ def theta_est_multistart( # for name in theta_names: # current_value = parmest_model.find_component(name)() # print(f"Current value of {name} is {current_value}") - + # Call the _Q_opt method with the generated theta values qopt_result = self._Q_opt( ThetaVals=theta_vals_current, @@ -1196,9 +1226,8 @@ def theta_est_multistart( return_values=return_values, ) - # Unpack results + # Unpack results objectiveval, converged_theta = qopt_result - # Since _Q_opt does not return the solver result object, we cannot check # solver termination condition directly here. Instead, we can assume @@ -1218,7 +1247,11 @@ def theta_est_multistart( # plan to add solve time if available, @Reviewers, recommendations on how from current pyomo examples would # be appreciated - solve_time = converged_theta.solve_time if hasattr(converged_theta, 'solve_time') else np.nan + solve_time = ( + converged_theta.solve_time + if hasattr(converged_theta, 'solve_time') + else np.nan + ) # # Check if the objective value is better than the best objective value # # Set a very high initial best objective value @@ -1226,12 +1259,14 @@ def theta_est_multistart( # Initialize best objective value and theta best_objectiveval = np.inf best_theta = np.inf - # Check if the final objective value is better than the best found so far + # Check if the final objective value is better than the best found so far if final_objectiveval < best_objectiveval: best_objectiveval = objectiveval best_theta = converged_theta.values - - print(f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}") + + print( + f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}" + ) # Stop the timer for this restart solve_time = timer.toc(f"Restart {i+1}/{n_restarts}") @@ -1239,12 +1274,24 @@ def theta_est_multistart( # Store the results in the DataFrame for this restart # Fill converged theta values for j, name in enumerate(theta_names): - results_df.at[i, f'converged_{name}'] = converged_theta[j] if not np.isnan(converged_theta_vals[i, j]) else np.nan + results_df.at[i, f'converged_{name}'] = ( + converged_theta[j] + if not np.isnan(converged_theta_vals[i, j]) + else np.nan + ) # Fill initial and final objective values, solver termination, and solve time - results_df.at[i, "initial objective"] = init_objectiveval if 'init_objectiveval' in locals() else np.nan - results_df.at[i, "final objective"] = objectiveval if 'objectiveval' in locals() else np.nan - results_df.at[i, "solver termination"] = solver_termination if 'solver_termination' in locals() else np.nan - results_df.at[i, "solve_time"] = solve_time if 'solve_time' in locals() else np.nan + results_df.at[i, "initial objective"] = ( + init_objectiveval if 'init_objectiveval' in locals() else np.nan + ) + results_df.at[i, "final objective"] = ( + objectiveval if 'objectiveval' in locals() else np.nan + ) + results_df.at[i, "solver termination"] = ( + solver_termination if 'solver_termination' in locals() else np.nan + ) + results_df.at[i, "solve_time"] = ( + solve_time if 'solve_time' in locals() else np.nan + ) # Diagnostic: print the table after each restart # print(results_df) @@ -1253,9 +1300,7 @@ def theta_est_multistart( if save_results and (i + 1) % buffer == 0: mode = 'w' if i + 1 == buffer else 'a' header = i + 1 == buffer - results_df.to_csv( - file_name, mode=mode, header=header, index=False - ) + results_df.to_csv(file_name, mode=mode, header=header, index=False) print(f"Intermediate results saved after {i + 1} iterations.") # Final save after all iterations @@ -1265,8 +1310,6 @@ def theta_est_multistart( return results_df, best_theta, best_objectiveval - - def theta_est_bootstrap( self, bootstrap_samples, From 6b3ee40a350c2d4c0d56bf8979e22efb7314116f Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Fri, 27 Jun 2025 08:29:52 -0400 Subject: [PATCH 17/32] Added utility to update model using suffix values --- pyomo/contrib/doe/utils.py | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/pyomo/contrib/doe/utils.py b/pyomo/contrib/doe/utils.py index 24be6fd696a..bd991747319 100644 --- a/pyomo/contrib/doe/utils.py +++ b/pyomo/contrib/doe/utils.py @@ -100,3 +100,45 @@ def rescale_FIM(FIM, param_vals): # pass # ToDo: Write error for suffix keys that aren't ParamData or VarData # # return param_list + +# Adding utility to update parameter values in a model based on the suffix +def update_model_from_suffix(model, suffix_name, values): + """"" + Iterate over the components (variables or parameters) referenced by the + given suffix in the model, and assign each a new value from the provided iterable. + + Parameters + ---------- + model : pyomo.environ.ConcreteModel + The Pyomo model containing the suffix and components to update. + suffix_name : str + The name of the Suffix attribute on the model whose items will be updated. + Must be one of: 'experiment_outputs', 'experiment_inputs', 'unknown_parameters', or 'measurement_error'. + values : iterable of numbers + The new values to assign to each component referenced by the suffix. The length of this + iterable must match the number of items in the suffix. + + """ + # Allowed suffix names + allowed = { + 'experiment_outputs', 'experiment_inputs', + 'unknown_parameters', 'measurement_error' + } + # Validate input is an allowed suffix name + if suffix_name not in allowed: + raise ValueError(f"suffix_name must be one of {sorted(allowed)}") + # Check if the model has the specified suffix + suffix_obj = getattr(model, suffix_name, None) + if suffix_obj is None: + raise AttributeError(f"Model has no attribute '{suffix_name}'") + # Check if the suffix is a Suffix object + items = list(suffix_obj.items()) + if len(items) != len(values): + raise ValueError("values length does not match suffix length") + # Set the new values for the suffix items + for (comp, _), new_val in zip(items, values): + # Update the variable/parameter itself if it is VarData or ParamData + if isinstance(comp, (VarData, ParamData)): + comp.set_value(new_val) + else: + raise TypeError(f"Unsupported component type: {type(comp)}") From 5cadfac59294b19981d57912023b157958444298 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Fri, 27 Jun 2025 15:33:16 -0400 Subject: [PATCH 18/32] Work on Friday 6/27 applying PR comments --- pyomo/contrib/parmest/parmest.py | 58 ++++++++++++++++---------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 6cc9e108f08..897e19d35ac 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -482,7 +482,7 @@ def _generate_initial_theta( seed=None, n_restarts=None, multistart_sampling_method=None, - user_provided=None, + user_provided_df=None, ): """ Generate initial theta values for multistart optimization using selected sampling method. @@ -512,13 +512,7 @@ def _generate_initial_theta( "The lower and upper bounds for the theta values must be defined." ) - # Check the length of theta_names and initial_theta, and make sure bounds are defined - if len(theta_names) != len(initial_theta): - raise ValueError( - "The length of theta_names and initial_theta must be the same." - ) - - if multistart_sampling_method == "uniform": + if multistart_sampling_method == "uniform_random": # Generate random theta values using uniform distribution, with set seed for reproducibility np.random.seed(seed) # Generate random theta values for each restart (n_restarts x len(theta_names)) @@ -541,58 +535,58 @@ def _generate_initial_theta( # The first value of the Sobol sequence is 0, so we skip it samples = sampler.random(n=n_restarts + 1)[1:] - elif multistart_sampling_method == "user_provided": + elif multistart_sampling_method == "user_provided_values": # Add user provided dataframe option - if user_provided is not None: + if user_provided_df is not None: - if isinstance(user_provided, np.ndarray): + if isinstance(user_provided_df, np.ndarray): # Check if the user provided numpy array has the same number of rows as the number of restarts - if user_provided.shape[0] != n_restarts: + if user_provided_df.shape[0] != n_restarts: raise ValueError( "The user provided numpy array must have the same number of rows as the number of restarts." ) # Check if the user provided numpy array has the same number of columns as the number of theta names - if user_provided.shape[1] != len(theta_names): + if user_provided_df.shape[1] != len(theta_names): raise ValueError( "The user provided numpy array must have the same number of columns as the number of theta names." ) # Check if the user provided numpy array has the same theta names as the model # if not, raise an error - # if not all(theta in theta_names for theta in user_provided.columns): + # if not all(theta in theta_names for theta in user_provided_df.columns): raise ValueError( "The user provided numpy array must have the same theta names as the model." ) # If all checks pass, return the user provided numpy array - theta_vals_multistart = user_provided - elif isinstance(user_provided, pd.DataFrame): + theta_vals_multistart = user_provided_df + elif isinstance(user_provided_df, pd.DataFrame): # Check if the user provided dataframe has the same number of rows as the number of restarts - if user_provided.shape[0] != n_restarts: + if user_provided_df.shape[0] != n_restarts: raise ValueError( "The user provided dataframe must have the same number of rows as the number of restarts." ) # Check if the user provided dataframe has the same number of columns as the number of theta names - if user_provided.shape[1] != len(theta_names): + if user_provided_df.shape[1] != len(theta_names): raise ValueError( "The user provided dataframe must have the same number of columns as the number of theta names." ) # Check if the user provided dataframe has the same theta names as the model # if not, raise an error - # if not all(theta in theta_names for theta in user_provided.columns): + # if not all(theta in theta_names for theta in user_provided_df.columns): raise ValueError( "The user provided dataframe must have the same theta names as the model." ) # If all checks pass, return the user provided dataframe - theta_vals_multistart = user_provided.iloc[ + theta_vals_multistart = user_provided_df.iloc[ 0 : len(initial_theta) ].values else: raise ValueError( - "The user must provide a numpy array or pandas dataframe from a previous attempt to use the 'user_provided' method." + "The user must provide a numpy array or pandas dataframe from a previous attempt to use the 'user_provided_values' method." ) else: raise ValueError( - "Invalid sampling method. Choose 'uniform', 'latin_hypercube', 'sobol' or 'user_provided'." + "Invalid sampling method. Choose 'uniform_random', 'latin_hypercube', 'sobol_sampling' or 'user_provided_values'." ) if ( @@ -606,10 +600,10 @@ def _generate_initial_theta( # Create a DataFrame where each row is an initial theta vector for a restart, # columns are theta_names, and values are the initial theta values for each restart - if multistart_sampling_method == "user_provided": - # If user_provided is a DataFrame, use its columns and values directly - if isinstance(user_provided, pd.DataFrame): - df_multistart = user_provided.copy() + if multistart_sampling_method == "user_provided_values": + # If user_provided_values is a DataFrame, use its columns and values directly + if isinstance(user_provided_df, pd.DataFrame): + df_multistart = user_provided_df.copy() df_multistart.columns = theta_names else: df_multistart = pd.DataFrame(theta_vals_multistart, columns=theta_names) @@ -1112,7 +1106,7 @@ def theta_est_multistart( self, n_restarts=20, buffer=10, - multistart_sampling_method="uniform", + multistart_sampling_method="uniform_random", user_provided=None, seed=None, save_results=False, @@ -1129,8 +1123,8 @@ def theta_est_multistart( n_restarts: int, optional Number of restarts for multistart. Default is 1. multistart_sampling_method: string, optional - Method used to sample theta values. Options are "uniform", "latin_hypercube", "sobol", or "user_provided". - Default is "uniform". + Method used to sample theta values. Options are "uniform_random", "latin_hypercube", "sobol", or "user_provided". + Default is "uniform_random". buffer: int, optional Number of iterations to save results dynamically. Default is 10. user_provided: pd.DataFrame or np.ndarray, optional @@ -1207,6 +1201,12 @@ def theta_est_multistart( # # Create a fresh model for each restart # parmest_model = self._create_parmest_model(experiment_number=0) theta_vals_current = theta_vals.iloc[i, :].to_dict() + # If theta_vals is provided, use it to set the current theta values + # # Convert values to a list + # theta_vals_current = list(theta_vals.iloc[i, :]) + + # # Update the model with the current theta values + # update_model_from_suffix(parmest_model, 'experiment_inputs', theta_vals_current) # # Set current theta values in the model # for name, value in theta_vals_current.items(): From 1be2d9e98f965d0f381f0d09a11784f6049c965c Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:45:20 -0400 Subject: [PATCH 19/32] Addressed some reviewer comments and ran black. --- pyomo/contrib/parmest/parmest.py | 66 ++++++++++++++------------------ 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 897e19d35ac..5a937683cd0 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -487,12 +487,6 @@ def _generate_initial_theta( """ Generate initial theta values for multistart optimization using selected sampling method. """ - if n_restarts == 1: - # If only one restart, return an empty list - return print( - "No multistart optimization needed. Please use normal theta_est()" - ) - # Get the theta names and initial theta values theta_names = self._return_theta_names() initial_theta = [parmest_model.find_component(name)() for name in theta_names] @@ -539,26 +533,7 @@ def _generate_initial_theta( # Add user provided dataframe option if user_provided_df is not None: - if isinstance(user_provided_df, np.ndarray): - # Check if the user provided numpy array has the same number of rows as the number of restarts - if user_provided_df.shape[0] != n_restarts: - raise ValueError( - "The user provided numpy array must have the same number of rows as the number of restarts." - ) - # Check if the user provided numpy array has the same number of columns as the number of theta names - if user_provided_df.shape[1] != len(theta_names): - raise ValueError( - "The user provided numpy array must have the same number of columns as the number of theta names." - ) - # Check if the user provided numpy array has the same theta names as the model - # if not, raise an error - # if not all(theta in theta_names for theta in user_provided_df.columns): - raise ValueError( - "The user provided numpy array must have the same theta names as the model." - ) - # If all checks pass, return the user provided numpy array - theta_vals_multistart = user_provided_df - elif isinstance(user_provided_df, pd.DataFrame): + if isinstance(user_provided_df, pd.DataFrame): # Check if the user provided dataframe has the same number of rows as the number of restarts if user_provided_df.shape[0] != n_restarts: raise ValueError( @@ -581,7 +556,7 @@ def _generate_initial_theta( ].values else: raise ValueError( - "The user must provide a numpy array or pandas dataframe from a previous attempt to use the 'user_provided_values' method." + "The user must provide a pandas dataframe to use the 'user_provided_values' method." ) else: @@ -594,6 +569,7 @@ def _generate_initial_theta( or multistart_sampling_method == "latin_hypercube" ): # Scale the samples to the range of the lower and upper bounds for each theta in theta_names + # The samples are in the range [0, 1], so we scale them to the range of the lower and upper bounds theta_vals_multistart = np.array( [lower_bound + (upper_bound - lower_bound) * theta for theta in samples] ) @@ -1126,7 +1102,7 @@ def theta_est_multistart( Method used to sample theta values. Options are "uniform_random", "latin_hypercube", "sobol", or "user_provided". Default is "uniform_random". buffer: int, optional - Number of iterations to save results dynamically. Default is 10. + Number of iterations to save results dynamically if save_results=True. Default is 10. user_provided: pd.DataFrame or np.ndarray, optional User provided array or dataframe of theta values for multistart optimization. seed: int, optional @@ -1158,18 +1134,32 @@ def theta_est_multistart( "Multistart is not supported in the deprecated parmest interface" ) - assert isinstance(n_restarts, int) - assert isinstance(multistart_sampling_method, str) - assert isinstance(solver, str) - assert isinstance(return_values, list) + # Validate input types + if not isinstance(n_restarts, int): + raise TypeError("n_restarts must be an integer") + if not isinstance(multistart_sampling_method, str): + raise TypeError("multistart_sampling_method must be a string") + if not isinstance(solver, str): + raise TypeError("solver must be a string") + if not isinstance(return_values, list): + raise TypeError("return_values must be a list") + + if n_restarts <= 1: + # If n_restarts is 1 or less, no multistart optimization is needed + logger.warning( + "No multistart optimization needed. Please use normal theta_est()." + ) + return self.theta_est( + solver=solver, return_values=return_values, calc_cov=False, cov_n=None + ) if n_restarts > 1 and multistart_sampling_method is not None: # Find the initialized values of theta from the labeled parmest model # and the theta names from the estimator object - # print statement to indicate multistart optimization is starting - print( + # logger statement to indicate multistart optimization is starting + logger.info( f"Starting multistart optimization with {n_restarts} restarts using {multistart_sampling_method} sampling method." ) @@ -1264,7 +1254,7 @@ def theta_est_multistart( best_objectiveval = objectiveval best_theta = converged_theta.values - print( + logger.info( f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}" ) @@ -1294,19 +1284,19 @@ def theta_est_multistart( ) # Diagnostic: print the table after each restart - # print(results_df) + logger.debug(results_df) # Add buffer to save the dataframe dynamically, if save_results is True if save_results and (i + 1) % buffer == 0: mode = 'w' if i + 1 == buffer else 'a' header = i + 1 == buffer results_df.to_csv(file_name, mode=mode, header=header, index=False) - print(f"Intermediate results saved after {i + 1} iterations.") + logger.info(f"Intermediate results saved after {i + 1} iterations.") # Final save after all iterations if save_results: results_df.to_csv(file_name, mode='a', header=False, index=False) - print("Final results saved.") + logger.info("Final results saved.") return results_df, best_theta, best_objectiveval From 05381c5e921960f6ae3c605de6a60c5aa44ed986 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Sun, 6 Jul 2025 17:37:49 -0400 Subject: [PATCH 20/32] Updated argument for theta_est_multistart --- pyomo/contrib/parmest/parmest.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 9f891875641..337881144de 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -1082,7 +1082,7 @@ def theta_est_multistart( n_restarts=20, buffer=10, multistart_sampling_method="uniform_random", - user_provided=None, + user_provided_df=None, seed=None, save_results=False, theta_vals=None, @@ -1102,7 +1102,7 @@ def theta_est_multistart( Default is "uniform_random". buffer: int, optional Number of iterations to save results dynamically if save_results=True. Default is 10. - user_provided: pd.DataFrame or np.ndarray, optional + user_provided_df: pd.DataFrame, optional User provided array or dataframe of theta values for multistart optimization. seed: int, optional Random seed for reproducibility. @@ -1171,7 +1171,7 @@ def theta_est_multistart( seed=seed, n_restarts=n_restarts, multistart_sampling_method=multistart_sampling_method, - user_provided=user_provided, + user_provided_df=user_provided_df, ) results_df = pd.DataFrame(results_df) # Extract theta_vals from the dataframe From 07ae1e83a322148f21499317034995597ed57297 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:26:27 -0400 Subject: [PATCH 21/32] Addressed majority of review comments. State before 7/8 dev meeting --- pyomo/contrib/parmest/parmest.py | 70 ++++++++++++++++---------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 0b33e28c58b..6c7b18c63b1 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -68,6 +68,7 @@ # Add imports for HierchicalTimer import time from pyomo.common.timing import TicTocTimer +from enum import Enum from pyomo.common.deprecation import deprecated from pyomo.common.deprecation import deprecation_warning @@ -250,9 +251,15 @@ def SSE(model): return expr -'''Adding pseudocode for draft implementation of the estimator class, -incorporating multistart. -''' +class MultistartSamplingMethodLib(Enum): + """ + Enum class for multistart sampling methods. + """ + + uniform_random = "uniform_random" + latin_hypercube = "latin_hypercube" + sobol_sampling = "sobol_sampling" + user_provided_values = "user_provided_values" class Estimator(object): @@ -486,19 +493,20 @@ def _generate_initial_theta( """ Generate initial theta values for multistart optimization using selected sampling method. """ - # Get the theta names and initial theta values - theta_names = self._return_theta_names() - initial_theta = [parmest_model.find_component(name)() for name in theta_names] + # Locate the unknown parameters in the model from the suffix + suffix_params = parmest_model.unknown_parameters + + # Get the VarData objects from the suffix + theta_vars = list(suffix_params.keys()) + + # Extract names, starting values, and bounds for the theta variables + theta_names = [v.name for v in theta_vars] + initial_theta = np.array([v.value for v in theta_vars]) + lower_bound = np.array([v.lb for v in theta_vars]) + upper_bound = np.array([v.ub for v in theta_vars]) - # Get the lower and upper bounds for the theta values - lower_bound = np.array( - [parmest_model.find_component(name).lb for name in theta_names] - ) - upper_bound = np.array( - [parmest_model.find_component(name).ub for name in theta_names] - ) # Check if the lower and upper bounds are defined - if any(bound is None for bound in lower_bound) and any( + if any(bound is None for bound in lower_bound) or any( bound is None for bound in upper_bound ): raise ValueError( @@ -522,7 +530,7 @@ def _generate_initial_theta( samples = sampler.random(n=n_restarts) # Resulting samples should be size (n_restarts, len(theta_names)) - elif multistart_sampling_method == "sobol": + elif multistart_sampling_method == "sobol_sampling": sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) # Generate theta values using Sobol sampling # The first value of the Sobol sequence is 0, so we skip it @@ -545,7 +553,7 @@ def _generate_initial_theta( ) # Check if the user provided dataframe has the same theta names as the model # if not, raise an error - # if not all(theta in theta_names for theta in user_provided_df.columns): + if not all(theta in theta_names for theta in user_provided_df.columns): raise ValueError( "The user provided dataframe must have the same theta names as the model." ) @@ -564,7 +572,7 @@ def _generate_initial_theta( ) if ( - multistart_sampling_method == "sobol" + multistart_sampling_method == "sobol_sampling" or multistart_sampling_method == "latin_hypercube" ): # Scale the samples to the range of the lower and upper bounds for each theta in theta_names @@ -613,6 +621,7 @@ def _Q_opt( return_values=[], bootlist=None, calc_cov=False, + multistart=False, cov_n=None, ): """ @@ -774,6 +783,8 @@ def _Q_opt( if calc_cov: return objval, thetavals, cov + if multistart: + return objval, thetavals, solve_result else: return objval, thetavals @@ -1098,7 +1109,7 @@ def theta_est_multistart( n_restarts: int, optional Number of restarts for multistart. Default is 1. multistart_sampling_method: string, optional - Method used to sample theta values. Options are "uniform_random", "latin_hypercube", "sobol", or "user_provided". + Method used to sample theta values. Options are "uniform_random", "latin_hypercube", "sobol_sampling", or "user_provided_values". Default is "uniform_random". buffer: int, optional Number of iterations to save results dynamically if save_results=True. Default is 10. @@ -1213,16 +1224,16 @@ def theta_est_multistart( bootlist=None, solver=solver, return_values=return_values, + multistart=True, ) # Unpack results - objectiveval, converged_theta = qopt_result + objectiveval, converged_theta, solver_info = qopt_result - # Since _Q_opt does not return the solver result object, we cannot check - # solver termination condition directly here. Instead, we can assume - # that if converged_theta contains NaN, the solve failed. - if converged_theta.isnull().any(): - solver_termination = "not successful" + # Added an extra option to Q_opt to return the full solver result if multistart=True + solver_termination = solver_info.solver.termination_condition + if solver_termination != pyo.TerminationCondition.optimal: + # If the solver did not converge, set the converged theta to NaN solve_time = np.nan final_objectiveval = np.nan init_objectiveval = np.nan @@ -1232,15 +1243,6 @@ def theta_est_multistart( # Use the _Q_at_theta method to evaluate the objective at these theta values init_objectiveval, _, _ = self._Q_at_theta(theta_vals_current) final_objectiveval = objectiveval - solver_termination = "successful" - - # plan to add solve time if available, @Reviewers, recommendations on how from current pyomo examples would - # be appreciated - solve_time = ( - converged_theta.solve_time - if hasattr(converged_theta, 'solve_time') - else np.nan - ) # # Check if the objective value is better than the best objective value # # Set a very high initial best objective value @@ -1264,7 +1266,7 @@ def theta_est_multistart( # Fill converged theta values for j, name in enumerate(theta_names): results_df.at[i, f'converged_{name}'] = ( - converged_theta[j] + converged_theta.iloc[j] if not np.isnan(converged_theta_vals[i, j]) else np.nan ) From 33d838ff5a81f3ef27ed3cabe55bd9d7bf6c4b10 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:37:33 -0400 Subject: [PATCH 22/32] Fixing conflict --- pyomo/contrib/doe/utils.py | 41 -------------------------------------- 1 file changed, 41 deletions(-) diff --git a/pyomo/contrib/doe/utils.py b/pyomo/contrib/doe/utils.py index bd991747319..2af5472703b 100644 --- a/pyomo/contrib/doe/utils.py +++ b/pyomo/contrib/doe/utils.py @@ -101,44 +101,3 @@ def rescale_FIM(FIM, param_vals): # # return param_list -# Adding utility to update parameter values in a model based on the suffix -def update_model_from_suffix(model, suffix_name, values): - """"" - Iterate over the components (variables or parameters) referenced by the - given suffix in the model, and assign each a new value from the provided iterable. - - Parameters - ---------- - model : pyomo.environ.ConcreteModel - The Pyomo model containing the suffix and components to update. - suffix_name : str - The name of the Suffix attribute on the model whose items will be updated. - Must be one of: 'experiment_outputs', 'experiment_inputs', 'unknown_parameters', or 'measurement_error'. - values : iterable of numbers - The new values to assign to each component referenced by the suffix. The length of this - iterable must match the number of items in the suffix. - - """ - # Allowed suffix names - allowed = { - 'experiment_outputs', 'experiment_inputs', - 'unknown_parameters', 'measurement_error' - } - # Validate input is an allowed suffix name - if suffix_name not in allowed: - raise ValueError(f"suffix_name must be one of {sorted(allowed)}") - # Check if the model has the specified suffix - suffix_obj = getattr(model, suffix_name, None) - if suffix_obj is None: - raise AttributeError(f"Model has no attribute '{suffix_name}'") - # Check if the suffix is a Suffix object - items = list(suffix_obj.items()) - if len(items) != len(values): - raise ValueError("values length does not match suffix length") - # Set the new values for the suffix items - for (comp, _), new_val in zip(items, values): - # Update the variable/parameter itself if it is VarData or ParamData - if isinstance(comp, (VarData, ParamData)): - comp.set_value(new_val) - else: - raise TypeError(f"Unsupported component type: {type(comp)}") From e7b2df189fa5db48ffeaae4977225643d24a1eca Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 17 Jul 2025 14:03:53 -0400 Subject: [PATCH 23/32] Added in TODO items based on Dan morning meeting --- pyomo/contrib/parmest/parmest.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 6c7b18c63b1..0ee63e8cb8e 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -478,6 +478,7 @@ def TotalCost_rule(model): return parmest_model + # TODO: Make so this generates the initial DATAFRAME, not the entire list of values. # Make new private method, _generate_initial_theta: # This method will be used to generate the initial theta values for multistart # optimization. It will take the theta names and the initial theta values @@ -614,6 +615,11 @@ def _instance_creation_callback(self, experiment_number=None, cb_data=None): model = self._create_parmest_model(experiment_number) return model + # TODO: Add a way to pass in a parmest_model to this function, currently cannot + # access the model within the build function. + + # I need to check, if I use the update model utility BEFORE calling _Q_opt, does it still + # work? If so, then I can remove the parmest_model argument. def _Q_opt( self, ThetaVals=None, @@ -1088,12 +1094,16 @@ def theta_est( cov_n=cov_n, ) + # TODO: Make the user provide a list of values, not the whole data frame + # TODO: Add a way to print the empty data_frame before solve so it can be previewed beforehand + # TODO: Fix so the theta values are generated at each iteration, not all beforehand in _generate_initial_theta + # Fix _generate_initial_theta to return an empty DataFrame first + # TODO: Add save model option to save the model after each iteration or at the end of the multistart def theta_est_multistart( self, n_restarts=20, - buffer=10, multistart_sampling_method="uniform_random", - user_provided_df=None, + user_provided_list=None, seed=None, save_results=False, theta_vals=None, From c55143df7dc934a239e3592802131923e355f768 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 19 Feb 2026 00:16:48 -0500 Subject: [PATCH 24/32] Added in files from main now, removed example --- .../reactor_design/multistart_example.py | 48 - pyomo/contrib/parmest/experiment.py | 23 +- pyomo/contrib/parmest/parmest.py | 1395 +++++++++++------ 3 files changed, 912 insertions(+), 554 deletions(-) delete mode 100644 pyomo/contrib/parmest/examples/reactor_design/multistart_example.py diff --git a/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py deleted file mode 100644 index 033c0ddcdc5..00000000000 --- a/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py +++ /dev/null @@ -1,48 +0,0 @@ -# ___________________________________________________________________________ -# -# Pyomo: Python Optimization Modeling Objects -# Copyright (c) 2008-2025 -# 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 -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 = [] - for i in range(data.shape[0]): - exp_list.append(ReactorDesignExperiment(data, i)) - - # View one model - # exp0_model = exp_list[0].get_labeled_model() - # exp0_model.pprint() - - pest = parmest.Estimator(exp_list, obj_function='SSE') - - # Parameter estimation - obj, theta = pest.theta_est() - - # Parameter estimation with multistart to avoid local minima - obj, theta = pest.theta_est_multistart( - num_starts=10, start_method='random', random_seed=42, max_iter=1000, tol=1e-6 - ) - - -if __name__ == "__main__": - main() diff --git a/pyomo/contrib/parmest/experiment.py b/pyomo/contrib/parmest/experiment.py index 349226e824f..8ad62cb9eb6 100644 --- a/pyomo/contrib/parmest/experiment.py +++ b/pyomo/contrib/parmest/experiment.py @@ -1,13 +1,11 @@ -# ___________________________________________________________________________ +# ____________________________________________________________________________________ # -# Pyomo: Python Optimization Modeling Objects -# Copyright (c) 2008-2025 -# 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. -# ___________________________________________________________________________ +# 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. +# ____________________________________________________________________________________ class Experiment: @@ -29,10 +27,3 @@ def __init__(self, model=None): def get_labeled_model(self): return self.model - - def reinitialize_unknown_parameters(self): - raise NotImplementedError( - "The reinitialize_unknown_parameters method should implemented in the subclass." - "Thi method will take new values for the unknown parameters from the Suffix " - "and allow users to reinitialize the model." - ) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 0ee63e8cb8e..21138d472da 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -1,13 +1,11 @@ -# ___________________________________________________________________________ +# ____________________________________________________________________________________ # -# Pyomo: Python Optimization Modeling Objects -# Copyright (c) 2008-2025 -# 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. -# ___________________________________________________________________________ +# 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. +# ____________________________________________________________________________________ #### Using mpi-sppy instead of PySP; May 2020 #### Adding option for "local" EF starting Sept 2020 #### Wrapping mpi-sppy functionality and local option Jan 2021, Feb 2021 @@ -37,6 +35,7 @@ import pyomo.contrib.parmest.utils.create_ef as local_ef import pyomo.contrib.parmest.utils.scenario_tree as scenario_tree +from enum import Enum import re import importlib as im import logging @@ -60,16 +59,15 @@ from pyomo.opt import SolverFactory from pyomo.environ import Block, ComponentUID +from pyomo.opt.results.solver import assert_optimal_termination +from pyomo.common.flags import NOTSET + +from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp import pyomo.contrib.parmest.utils as utils import pyomo.contrib.parmest.graphics as graphics from pyomo.dae import ContinuousSet -# Add imports for HierchicalTimer -import time -from pyomo.common.timing import TicTocTimer -from enum import Enum - from pyomo.common.deprecation import deprecated from pyomo.common.deprecation import deprecation_warning @@ -92,7 +90,7 @@ def ef_nonants(ef): def _experiment_instance_creation_callback( - scenario_name, node_names=None, cb_data=None, fix_vars=False + scenario_name, node_names=None, cb_data=None ): """ This is going to be called by mpi-sppy or the local EF and it will call into @@ -108,8 +106,6 @@ def _experiment_instance_creation_callback( that is the "callback" value. "BootList" is None or bootstrap experiment number list. (called cb_data by mpisppy) - fix_vars: `bool` If True, the theta variables are fixed to the values - provided in the cb_data["ThetaVals"] dictionary. Returns: @@ -216,11 +212,7 @@ def _experiment_instance_creation_callback( scen_model=instance, ) ] - # @Reviewers, here is where the parmest model is made for each run - # This is the only way I see to pass the theta values to the model - # Can we add an optional argument to fix them or not? - # Curently, thetavals provided are fixed if not None - # Suggested fix in this function and _Q_at_theta + if "ThetaVals" in outer_cb_data: thetavals = outer_cb_data["ThetaVals"] @@ -228,14 +220,9 @@ def _experiment_instance_creation_callback( for name, val in thetavals.items(): theta_cuid = ComponentUID(name) theta_object = theta_cuid.find_component_on(instance) - if val is not None and fix_vars is True: + if val is not None: # print("Fixing",vstr,"at",str(thetavals[vstr])) theta_object.fix(val) - # ADDED OPTION: Set initial value, but do not fix - elif val is not None and fix_vars is False: - # print("Setting",vstr,"to",str(thetavals[vstr])) - theta_object.set_value(val) - theta_object.unfix() else: # print("Freeing",vstr) theta_object.unfix() @@ -245,24 +232,520 @@ def _experiment_instance_creation_callback( def SSE(model): """ - Sum of squared error between `experiment_output` model and data values + Returns an expression that is used to compute the sum of squared errors + ('SSE') objective, assuming Gaussian i.i.d. errors + + Parameters + ---------- + model : ConcreteModel + Annotated Pyomo model """ - expr = sum((y - y_hat) ** 2 for y, y_hat in model.experiment_outputs.items()) + # check if the model has all the required suffixes + _check_model_labels(model) + + # SSE between the prediction and observation of the measured variables + expr = sum((y - y_hat) ** 2 for y_hat, y in model.experiment_outputs.items()) return expr -class MultistartSamplingMethodLib(Enum): +def SSE_weighted(model): + """ + Returns an expression that is used to compute the 'SSE_weighted' objective, + assuming Gaussian i.i.d. errors, with measurement error standard deviation + defined in the annotated Pyomo model + + Parameters + ---------- + model : ConcreteModel + Annotated Pyomo model + """ + # check if the model has all the required suffixes + _check_model_labels(model) + + # Check that measurement errors exist + if not hasattr(model, "measurement_error"): + raise AttributeError( + 'Experiment model does not have suffix "measurement_error". ' + '"measurement_error" is a required suffix for the "SSE_weighted" ' + 'objective.' + ) + + # check if all the values of the measurement error standard deviation + # have been supplied + all_known_errors = all( + model.measurement_error[y_hat] is not None for y_hat in model.experiment_outputs + ) + + if all_known_errors: + # calculate the weighted SSE between the prediction + # and observation of the measured variables + try: + expr = (1 / 2) * sum( + ((y - y_hat) / model.measurement_error[y_hat]) ** 2 + for y_hat, y in model.experiment_outputs.items() + ) + return expr + except ZeroDivisionError: + raise ValueError( + 'Division by zero encountered in the "SSE_weighted" objective. ' + 'One or more values of the measurement error are zero.' + ) + else: + raise ValueError( + 'One or more values are missing from "measurement_error". All values of ' + 'the measurement errors are required for the "SSE_weighted" objective.' + ) + + +def _check_model_labels(model): + """ + Checks if the annotated Pyomo model contains the necessary suffixes + + Parameters + ---------- + model : ConcreteModel + Annotated Pyomo model + """ + required_attrs = ("experiment_outputs", "unknown_parameters") + + # check if any of the required attributes are missing + missing_attr = [attr for attr in required_attrs if not hasattr(model, attr)] + if missing_attr: + missing_str = ", ".join(f'"{attr}"' for attr in missing_attr) + raise AttributeError( + f"Experiment model is missing required attribute(s): {missing_str}" + ) + + logger.info("Model has expected labels.") + + +def _get_labeled_model(experiment): + """ + Returns the annotated Pyomo model from the Experiment class + + Parameters + ---------- + experiment : Experiment class + Experiment class object that contains the Pyomo model + for a particular experimental condition + """ + # check if the Experiment class has a "get_labeled_model" function + get_model = getattr(experiment, "get_labeled_model", None) + if not callable(get_model): + raise AttributeError( + 'The experiment object must have a "get_labeled_model" function.' + ) + + try: + return get_model().clone() + except Exception as exc: + raise RuntimeError(f"Failed to clone labeled model: {exc}") + + +def _count_total_experiments(experiment_list): + """ + Counts the number of data points in the list of experiments + + Parameters + ---------- + experiment_list : list + List of Experiment class objects containing the Pyomo model + for the different experimental conditions + + Returns + ------- + total_number_data : int + The total number of data points in the list of experiments + """ + total_number_data = 0 + for experiment in experiment_list: + total_number_data += len(experiment.get_labeled_model().experiment_outputs) + + return total_number_data + + +class CovarianceMethod(Enum): + finite_difference = "finite_difference" + automatic_differentiation_kaug = "automatic_differentiation_kaug" + reduced_hessian = "reduced_hessian" + + +class ObjectiveType(Enum): + SSE = "SSE" + SSE_weighted = "SSE_weighted" + + +# Compute the Jacobian matrix of measured variables with respect to the parameters +def _compute_jacobian(experiment, theta_vals, step, solver, tee): + """ + Computes the Jacobian matrix of the measured variables with respect to the + parameters using the central finite difference scheme + + Parameters + ---------- + experiment : Experiment class + Experiment class object that contains the Pyomo model + for a particular experimental condition + theta_vals : dict + Dictionary containing the estimates of the unknown parameters + step : float + Float used for relative perturbation of the parameters, + e.g., step=0.02 is a 2% perturbation + solver : str + Solver name specified by the user, e.g., 'ipopt' + tee : bool + Boolean solver option to be passed for verbose output + + Returns + ------- + J : numpy.ndarray + Jacobian matrix of the measured variables + """ + # grab the model + model = _get_labeled_model(experiment) + + # fix the value of the unknown parameters to the estimated values + for param in model.unknown_parameters: + param.fix(theta_vals[param.name]) + + # re-solve the model with the estimated parameters + solver = pyo.SolverFactory(solver) + results = solver.solve(model, tee=tee) + assert_optimal_termination(results) + + # get the estimated parameter values + param_values = [p.value for p in model.unknown_parameters] + + # get the number of parameters and measured variables + n_params = len(param_values) + n_outputs = len(model.experiment_outputs) + + # compute the sensitivity of the measured variables w.r.t the parameters + J = np.zeros((n_outputs, n_params)) + + for i, param in enumerate(model.unknown_parameters): + # store original value of the parameter + orig_value = param_values[i] + + # calculate the relative perturbation + relative_perturbation = step * orig_value + + # Forward perturbation + param.fix(orig_value + relative_perturbation) + + # solve the model + results = solver.solve(model, tee=tee) + assert_optimal_termination(results) + + # forward perturbation measured variables + y_hat_plus = [pyo.value(y_hat) for y_hat, y in model.experiment_outputs.items()] + + # Backward perturbation + param.fix(orig_value - relative_perturbation) + + # re-solve the model + results = solver.solve(model, tee=tee) + assert_optimal_termination(results) + + # backward perturbation measured variables + y_hat_minus = [ + pyo.value(y_hat) for y_hat, y in model.experiment_outputs.items() + ] + + # Restore the original parameter value + param.fix(orig_value) + + # Central difference approximation for the Jacobian + J[:, i] = [ + (y_hat_plus[w] - y_hat_minus[w]) / (2 * relative_perturbation) + for w in range(len(y_hat_plus)) + ] + + return J + + +# Compute the covariance matrix of the estimated parameters +def compute_covariance_matrix( + experiment_list, + method, + obj_function, + theta_vals, + step, + solver, + tee, + estimated_var=None, +): + """ + Computes the covariance matrix of the estimated parameters using + 'finite_difference' or 'automatic_differentiation_kaug' methods + + Parameters + ---------- + experiment_list : list + List of Experiment class objects containing the Pyomo model + for the different experimental conditions + method : str + Covariance calculation method specified by the user, + e.g., 'finite_difference' + obj_function: callable + Built-in objective function selected by the user, e.g., `SSE` + theta_vals : dict + Dictionary containing the estimates of the unknown parameters + step : float + Float used for relative perturbation of the parameters, + e.g., step=0.02 is a 2% perturbation + solver : str + Solver name specified by the user, e.g., 'ipopt' + tee : bool + Boolean solver option to be passed for verbose output + estimated_var: float, optional + Value of the estimated variance of the measurement error + in cases where the user does not supply the + measurement error standard deviation + + Returns + ------- + cov : pd.DataFrame + Covariance matrix of the estimated parameters + """ + # store the FIM of all the experiments + FIM_all_exp = [] + + if method == CovarianceMethod.finite_difference.value: + # loop through the experiments and compute the FIM + for experiment in experiment_list: + FIM_all_exp.append( + _finite_difference_FIM( + experiment, + theta_vals=theta_vals, + step=step, + solver=solver, + tee=tee, + estimated_var=estimated_var, + ) + ) + elif method == CovarianceMethod.automatic_differentiation_kaug.value: + # loop through the experiments and compute the FIM + for experiment in experiment_list: + FIM_all_exp.append( + _kaug_FIM( + experiment, + obj_function=obj_function, + theta_vals=theta_vals, + solver=solver, + tee=tee, + estimated_var=estimated_var, + ) + ) + + FIM = np.sum(FIM_all_exp, axis=0) + + # calculate the covariance matrix + try: + cov = np.linalg.inv(FIM) + except np.linalg.LinAlgError: + cov = np.linalg.pinv(FIM) + logger.warning("The FIM is singular. Using pseudo-inverse instead.") + + cov = pd.DataFrame(cov, index=theta_vals.keys(), columns=theta_vals.keys()) + + return cov + + +# compute the Fisher information matrix of the estimated parameters using +# 'finite_difference' +def _finite_difference_FIM( + experiment, theta_vals, step, solver, tee, estimated_var=None +): + """ + Computes the Fisher information matrix from 'finite_difference' Jacobian matrix + and measurement errors standard deviation defined in the annotated Pyomo model + + Parameters + ---------- + experiment : Experiment class + Experiment class object that contains the Pyomo model + for a particular experimental condition + theta_vals : dict + Dictionary containing the estimates of the unknown parameters + step : float + Float used for relative perturbation of the parameters, + e.g., step=0.02 is a 2% perturbation + solver : str + Solver name specified by the user, e.g., 'ipopt' + tee : bool + Boolean solver option to be passed for verbose output + estimated_var: float or int, optional + Value of the estimated variance of the measurement error + in cases where the user does not supply the + measurement error standard deviation + + Returns + ------- + FIM : numpy.ndarray + Fisher information matrix of the estimated parameters + """ + # compute the Jacobian matrix using finite difference + J = _compute_jacobian(experiment, theta_vals, step, solver, tee) + + # computing the condition number of the Jacobian matrix + cond_number_jac = np.linalg.cond(J) + logger.info(f"The condition number of the Jacobian matrix is {cond_number_jac}") + + # grab the model + model = _get_labeled_model(experiment) + + # extract the measured variables and measurement errors + y_hat_list = [y_hat for y_hat, y in model.experiment_outputs.items()] + + # check if the model has a 'measurement_error' attribute and + # the measurement error standard deviation has been supplied + all_known_errors = all( + model.measurement_error[y_hat] is not None for y_hat in model.experiment_outputs + ) + + if hasattr(model, "measurement_error") and all_known_errors: + error_list = [ + model.measurement_error[y_hat] for y_hat in model.experiment_outputs + ] + + # check if the dimension of error_list is the same with that of y_hat_list + if len(error_list) != len(y_hat_list): + raise ValueError( + "Experiment outputs and measurement errors are not the same length." + ) + + # compute the matrix of the inverse of the measurement error variance + # the following assumes independent and identically distributed + # measurement errors + W = np.diag([1 / (err**2) for err in error_list]) + + # calculate the FIM using the formula in our future paper + # Lilonfe et al. (2025) + FIM = J.T @ W @ J + else: + FIM = (1 / estimated_var) * (J.T @ J) + + return FIM + + +# compute the Fisher information matrix of the estimated parameters using +# 'automatic_differentiation_kaug' +def _kaug_FIM(experiment, obj_function, theta_vals, solver, tee, estimated_var=None): """ - Enum class for multistart sampling methods. + Computes the FIM using 'automatic_differentiation_kaug', a sensitivity-based + approach that uses the annotated Pyomo model optimality condition and + user-defined measurement errors standard deviation + + Disclaimer - code adopted from the kaug function implemented in Pyomo.DoE + + Parameters + ---------- + experiment : Experiment class + Experiment class object that contains the Pyomo model + for a particular experimental condition + obj_function: callable + Built-in objective function selected by the user, e.g., `SSE` + theta_vals : dict + Dictionary containing the estimates of the unknown parameters + solver : str + Solver name specified by the user, e.g., 'ipopt' + tee : bool + Boolean solver option to be passed for verbose output + estimated_var: float or int, optional + Value of the estimated variance of the measurement error + in cases where the user does not supply the + measurement error standard deviation + + Returns + ------- + FIM : numpy.ndarray + Fisher information matrix of the estimated parameters """ + # grab the model + model = _get_labeled_model(experiment) + + # deactivate any existing objective functions + for obj in model.component_objects(pyo.Objective): + obj.deactivate() + + # add the built-in objective function selected by the user + model.objective = pyo.Objective(expr=obj_function, sense=pyo.minimize) - uniform_random = "uniform_random" - latin_hypercube = "latin_hypercube" - sobol_sampling = "sobol_sampling" - user_provided_values = "user_provided_values" + # fix the parameter values to the estimated values + for param in model.unknown_parameters: + param.fix(theta_vals[param.name]) + solver = pyo.SolverFactory(solver) + results = solver.solve(model, tee=tee) + assert_optimal_termination(results) -class Estimator(object): + # Probe the solved model for dsdp results (sensitivities s.t. parameters) + params_dict = {k.name: v for k, v in model.unknown_parameters.items()} + params_names = list(params_dict.keys()) + + dsdp_re, col = get_dsdp(model, params_names, params_dict, tee=tee) + + # analyze result + dsdp_array = dsdp_re.toarray().T + + # store dsdp returned + dsdp_extract = [] + + # get right lines from results + measurement_index = [] + + # loop over measurement variables and their time points + for k, v in model.experiment_outputs.items(): + name = k.name + try: + kaug_no = col.index(name) + measurement_index.append(kaug_no) + # get right line of dsdp + dsdp_extract.append(dsdp_array[kaug_no]) + except ValueError: + # k_aug does not provide value for fixed variables + logger.debug("The variable is fixed: %s", name) + # produce the sensitivity for fixed variables + zero_sens = np.zeros(len(params_names)) + # for fixed variables, the sensitivity are a zero vector + dsdp_extract.append(zero_sens) + + # Extract and calculate sensitivity if scaled by constants or parameters. + jac = [[] for _ in params_names] + + for d in range(len(dsdp_extract)): + for k, v in model.unknown_parameters.items(): + p = params_names.index(k.name) # Index of parameter in np array + sensi = dsdp_extract[d][p] + jac[p].append(sensi) + + # record kaug jacobian + kaug_jac = np.array(jac).T + + # compute FIM + # compute the matrix of the inverse of the measurement error variance + # the following assumes independent and identically distributed + # measurement errors + W = np.zeros((len(model.measurement_error), len(model.measurement_error))) + all_known_errors = all( + model.measurement_error[y_hat] is not None for y_hat in model.experiment_outputs + ) + + count = 0 + for k, v in model.measurement_error.items(): + if all_known_errors: + W[count, count] = 1 / (v**2) + else: + W[count, count] = 1 / estimated_var + count += 1 + + FIM = kaug_jac.T @ W @ kaug_jac + + return FIM + + +class Estimator: """ Parameter estimation class @@ -272,8 +755,8 @@ class Estimator(object): A list of experiment objects which creates one labeled model for each experiment obj_function: string or function (optional) - Built in objective (currently only "SSE") or custom function used to - formulate parameter estimation objective. + Built-in objective ("SSE" or "SSE_weighted") or custom function + used to formulate parameter estimation objective. If no function is specified, the model is used "as is" and should be defined with a "FirstStageCost" and "SecondStageCost" expression that are used to build an objective. @@ -301,32 +784,32 @@ def __init__( diagnostic_mode=False, solver_options=None, ): - '''first theta would be provided by the user in the initialization of - the Estimator class through the unknown parameter variables. Additional - would need to be generated using the sampling method provided by the user. - ''' # check that we have a (non-empty) list of experiments assert isinstance(experiment_list, list) self.exp_list = experiment_list - # check that an experiment has experiment_outputs and unknown_parameters - model = self.exp_list[0].get_labeled_model() - try: - outputs = [k.name for k, v in model.experiment_outputs.items()] - except: - raise RuntimeError( - 'Experiment list model does not have suffix ' + '"experiment_outputs".' - ) - try: - params = [k.name for k, v in model.unknown_parameters.items()] - except: - raise RuntimeError( - 'Experiment list model does not have suffix ' + '"unknown_parameters".' - ) + # get the number of experiments + self.number_exp = _count_total_experiments(self.exp_list) + + # check if the experiment has a ``get_labeled_model`` function + model = _get_labeled_model(self.exp_list[0]) + + # check if the model has all the required suffixes + _check_model_labels(model) # populate keyword argument options - self.obj_function = obj_function + if isinstance(obj_function, str): + try: + self.obj_function = ObjectiveType(obj_function) + except ValueError: + raise ValueError( + f"Invalid objective function: '{obj_function}'. " + f"Choose from: {[e.value for e in ObjectiveType]}." + ) + else: + self.obj_function = obj_function + self.tee = tee self.diagnostic_mode = diagnostic_mode self.solver_options = solver_options @@ -338,7 +821,7 @@ def __init__( # We could collect the union (or intersect?) of thetas when the models are built theta_names = [] for experiment in self.exp_list: - model = experiment.get_labeled_model() + model = _get_labeled_model(experiment) theta_names.extend([k.name for k, v in model.unknown_parameters.items()]) # Utilize list(dict.fromkeys(theta_names)) to preserve parameter # order compared with list(set(theta_names)), which had @@ -431,7 +914,7 @@ def _create_parmest_model(self, experiment_number): Modify the Pyomo model for parameter estimation """ - model = self.exp_list[experiment_number].get_labeled_model() + model = _get_labeled_model(self.exp_list[experiment_number]) if len(model.unknown_parameters) == 0: model.parmest_dummy_var = pyo.Var(initialize=1.0) @@ -456,8 +939,12 @@ 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': + if self.obj_function is ObjectiveType.SSE: second_stage_rule = SSE + self.covariance_objective = second_stage_rule + elif self.obj_function is ObjectiveType.SSE_weighted: + second_stage_rule = SSE_weighted + self.covariance_objective = second_stage_rule else: # A custom function uses model.experiment_outputs as data second_stage_rule = self.obj_function @@ -478,157 +965,18 @@ def TotalCost_rule(model): return parmest_model - # TODO: Make so this generates the initial DATAFRAME, not the entire list of values. - # Make new private method, _generate_initial_theta: - # This method will be used to generate the initial theta values for multistart - # optimization. It will take the theta names and the initial theta values - # and return a dictionary of theta names and their corresponding values. - def _generate_initial_theta( - self, - parmest_model=None, - seed=None, - n_restarts=None, - multistart_sampling_method=None, - user_provided_df=None, - ): - """ - Generate initial theta values for multistart optimization using selected sampling method. - """ - # Locate the unknown parameters in the model from the suffix - suffix_params = parmest_model.unknown_parameters - - # Get the VarData objects from the suffix - theta_vars = list(suffix_params.keys()) - - # Extract names, starting values, and bounds for the theta variables - theta_names = [v.name for v in theta_vars] - initial_theta = np.array([v.value for v in theta_vars]) - lower_bound = np.array([v.lb for v in theta_vars]) - upper_bound = np.array([v.ub for v in theta_vars]) - - # Check if the lower and upper bounds are defined - if any(bound is None for bound in lower_bound) or any( - bound is None for bound in upper_bound - ): - raise ValueError( - "The lower and upper bounds for the theta values must be defined." - ) - - if multistart_sampling_method == "uniform_random": - # Generate random theta values using uniform distribution, with set seed for reproducibility - np.random.seed(seed) - # Generate random theta values for each restart (n_restarts x len(theta_names)) - theta_vals_multistart = np.random.uniform( - low=lower_bound, high=upper_bound, size=(n_restarts, len(theta_names)) - ) - - elif multistart_sampling_method == "latin_hypercube": - # Generate theta values using Latin hypercube sampling or Sobol sampling - # Generate theta values using Latin hypercube sampling - # Create a Latin Hypercube sampler that uses the dimensions of the theta names - sampler = scipy.stats.qmc.LatinHypercube(d=len(theta_names), seed=seed) - # Generate random samples in the range of [0, 1] for number of restarts - samples = sampler.random(n=n_restarts) - # Resulting samples should be size (n_restarts, len(theta_names)) - - elif multistart_sampling_method == "sobol_sampling": - sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) - # Generate theta values using Sobol sampling - # The first value of the Sobol sequence is 0, so we skip it - samples = sampler.random(n=n_restarts + 1)[1:] - - elif multistart_sampling_method == "user_provided_values": - # Add user provided dataframe option - if user_provided_df is not None: - - if isinstance(user_provided_df, pd.DataFrame): - # Check if the user provided dataframe has the same number of rows as the number of restarts - if user_provided_df.shape[0] != n_restarts: - raise ValueError( - "The user provided dataframe must have the same number of rows as the number of restarts." - ) - # Check if the user provided dataframe has the same number of columns as the number of theta names - if user_provided_df.shape[1] != len(theta_names): - raise ValueError( - "The user provided dataframe must have the same number of columns as the number of theta names." - ) - # Check if the user provided dataframe has the same theta names as the model - # if not, raise an error - if not all(theta in theta_names for theta in user_provided_df.columns): - raise ValueError( - "The user provided dataframe must have the same theta names as the model." - ) - # If all checks pass, return the user provided dataframe - theta_vals_multistart = user_provided_df.iloc[ - 0 : len(initial_theta) - ].values - else: - raise ValueError( - "The user must provide a pandas dataframe to use the 'user_provided_values' method." - ) - - else: - raise ValueError( - "Invalid sampling method. Choose 'uniform_random', 'latin_hypercube', 'sobol_sampling' or 'user_provided_values'." - ) - - if ( - multistart_sampling_method == "sobol_sampling" - or multistart_sampling_method == "latin_hypercube" - ): - # Scale the samples to the range of the lower and upper bounds for each theta in theta_names - # The samples are in the range [0, 1], so we scale them to the range of the lower and upper bounds - theta_vals_multistart = np.array( - [lower_bound + (upper_bound - lower_bound) * theta for theta in samples] - ) - - # Create a DataFrame where each row is an initial theta vector for a restart, - # columns are theta_names, and values are the initial theta values for each restart - if multistart_sampling_method == "user_provided_values": - # If user_provided_values is a DataFrame, use its columns and values directly - if isinstance(user_provided_df, pd.DataFrame): - df_multistart = user_provided_df.copy() - df_multistart.columns = theta_names - else: - df_multistart = pd.DataFrame(theta_vals_multistart, columns=theta_names) - else: - # Ensure theta_vals_multistart is 2D (n_restarts, len(theta_names)) - arr = np.atleast_2d(theta_vals_multistart) - if arr.shape[0] == 1 and n_restarts > 1: - arr = np.tile(arr, (n_restarts, 1)) - df_multistart = pd.DataFrame(arr, columns=theta_names) - - # Add columns for output info, initialized as nan - for name in theta_names: - df_multistart[f'converged_{name}'] = np.nan - df_multistart["initial objective"] = np.nan - df_multistart["final objective"] = np.nan - df_multistart["solver termination"] = np.nan - df_multistart["solve_time"] = np.nan - - # Debugging output - # print(df_multistart) - - return df_multistart - def _instance_creation_callback(self, experiment_number=None, cb_data=None): model = self._create_parmest_model(experiment_number) return model - # TODO: Add a way to pass in a parmest_model to this function, currently cannot - # access the model within the build function. - - # I need to check, if I use the update model utility BEFORE calling _Q_opt, does it still - # work? If so, then I can remove the parmest_model argument. def _Q_opt( self, ThetaVals=None, solver="ef_ipopt", return_values=[], bootlist=None, - calc_cov=False, - multistart=False, - cov_n=None, + calc_cov=NOTSET, + cov_n=NOTSET, ): """ Set up all thetas as first stage Vars, return resulting theta @@ -645,6 +993,11 @@ def _Q_opt( else: scen_names = ["Scenario{}".format(i) for i in range(len(bootlist))] + # get the probability constant that is applied to the objective function + # parmest solves the estimation problem by applying equal probabilities to + # the objective function of all the scenarios from the experiment list + self.obj_probability_constant = len(scen_names) + # tree_model.CallbackModule = None outer_cb_data = dict() outer_cb_data["callback"] = self._instance_creation_callback @@ -677,7 +1030,7 @@ def _Q_opt( # Solve the extensive form with ipopt if solver == "ef_ipopt": - if not calc_cov: + if calc_cov is NOTSET or not calc_cov: # Do not calculate the reduced hessian solver = SolverFactory('ipopt') @@ -686,20 +1039,14 @@ def _Q_opt( solver.options[key] = self.solver_options[key] solve_result = solver.solve(self.ef_instance, tee=self.tee) - - # The import error will be raised when we attempt to use - # inv_reduced_hessian_barrier below. - # - # elif not asl_available: - # raise ImportError("parmest requires ASL to calculate the " - # "covariance matrix with solver 'ipopt'") - else: + assert_optimal_termination(solve_result) + elif calc_cov is not NOTSET and calc_cov: # parmest makes the fitted parameters stage 1 variables ind_vars = [] - for ndname, Var, solval in ef_nonants(ef): + for nd_name, Var, sol_val in ef_nonants(ef): ind_vars.append(Var) # calculate the reduced hessian - (solve_result, inv_red_hes) = ( + solve_result, inv_red_hes = ( inverse_reduced_hessian.inv_reduced_hessian_barrier( self.ef_instance, independent_variables=ind_vars, @@ -715,44 +1062,63 @@ def _Q_opt( ) # assume all first stage are thetas... - thetavals = {} - for ndname, Var, solval in ef_nonants(ef): + theta_vals = {} + for nd_name, Var, sol_val in ef_nonants(ef): # process the name # the scenarios are blocks, so strip the scenario name - vname = Var.name[Var.name.find(".") + 1 :] - thetavals[vname] = solval + var_name = Var.name[Var.name.find(".") + 1 :] + theta_vals[var_name] = sol_val - objval = pyo.value(ef.EF_Obj) + obj_val = pyo.value(ef.EF_Obj) + self.obj_value = obj_val + self.estimated_theta = theta_vals - if calc_cov: + if calc_cov is not NOTSET and calc_cov: # Calculate the covariance matrix + if not isinstance(cov_n, int): + raise TypeError( + f"Expected an integer for the 'cov_n' argument. " + f"Got {type(cov_n)}." + ) + num_unknowns = max( + [ + len(experiment.get_labeled_model().unknown_parameters) + for experiment in self.exp_list + ] + ) + assert cov_n > num_unknowns, ( + "The number of datapoints must be greater than the " + "number of parameters to estimate." + ) + # Number of data points considered n = cov_n # Extract number of fitted parameters - l = len(thetavals) + l = len(theta_vals) # Assumption: Objective value is sum of squared errors - sse = objval + sse = obj_val - '''Calculate covariance assuming experimental observation errors are - independent and follow a Gaussian - distribution with constant variance. + '''Calculate covariance assuming experimental observation errors + are independent and follow a Gaussian distribution + with constant variance. - The formula used in parmest was verified against equations (7-5-15) and - (7-5-16) in "Nonlinear Parameter Estimation", Y. Bard, 1974. + The formula used in parmest was verified against equations + (7-5-15) and (7-5-16) in "Nonlinear Parameter Estimation", + Y. Bard, 1974. - This formula is also applicable if the objective is scaled by a constant; - the constant cancels out. (was scaled by 1/n because it computes an - expected value.) + This formula is also applicable if the objective is scaled by a + constant; the constant cancels out. + (was scaled by 1/n because it computes an expected value.) ''' cov = 2 * sse / (n - l) * inv_red_hes cov = pd.DataFrame( - cov, index=thetavals.keys(), columns=thetavals.keys() + cov, index=theta_vals.keys(), columns=theta_vals.keys() ) - thetavals = pd.Series(thetavals) + theta_vals = pd.Series(theta_vals) if len(return_values) > 0: var_values = [] @@ -782,21 +1148,241 @@ def _Q_opt( if len(vals) > 0: var_values.append(vals) var_values = pd.DataFrame(var_values) - if calc_cov: - return objval, thetavals, var_values, cov - else: - return objval, thetavals, var_values + if calc_cov is not NOTSET and calc_cov: + return obj_val, theta_vals, var_values, cov + elif calc_cov is NOTSET or not calc_cov: + return obj_val, theta_vals, var_values - if calc_cov: - return objval, thetavals, cov - if multistart: - return objval, thetavals, solve_result - else: - return objval, thetavals + if calc_cov is not NOTSET and calc_cov: + return obj_val, theta_vals, cov + elif calc_cov is NOTSET or not calc_cov: + return obj_val, theta_vals else: raise RuntimeError("Unknown solver in Q_Opt=" + solver) + def _cov_at_theta(self, method, solver, step): + """ + Covariance matrix calculation using all scenarios in the data + + Parameters + ---------- + method : str + Covariance calculation method specified by the user, + e.g., 'finite_difference' + solver : str + Solver name specified by the user, e.g., 'ipopt' + step : float + Float used for relative perturbation of the parameters, + e.g., step=0.02 is a 2% perturbation + + Returns + ------- + cov : pd.DataFrame + Covariance matrix of the estimated parameters + """ + if method == CovarianceMethod.reduced_hessian.value: + # compute the inverse reduced hessian to be used + # in the "reduced_hessian" method + # parmest makes the fitted parameters stage 1 variables + ind_vars = [] + for nd_name, Var, sol_val in ef_nonants(self.ef_instance): + ind_vars.append(Var) + # calculate the reduced hessian + solve_result, inv_red_hes = ( + inverse_reduced_hessian.inv_reduced_hessian_barrier( + self.ef_instance, + independent_variables=ind_vars, + solver_options=self.solver_options, + tee=self.tee, + ) + ) + + self.inv_red_hes = inv_red_hes + + # Number of data points considered + n = self.number_exp + + # Extract the number of fitted parameters + l = len(self.estimated_theta) + + # calculate the sum of squared errors at the estimated parameter values + sse_vals = [] + for experiment in self.exp_list: + model = _get_labeled_model(experiment) + + # fix the value of the unknown parameters to the estimated values + for param in model.unknown_parameters: + param.fix(self.estimated_theta[param.name]) + + # re-solve the model with the estimated parameters + results = pyo.SolverFactory(solver).solve(model, tee=self.tee) + assert_optimal_termination(results) + + # choose and evaluate the sum of squared errors expression + if self.obj_function == ObjectiveType.SSE: + sse_expr = SSE(model) + elif self.obj_function == ObjectiveType.SSE_weighted: + sse_expr = SSE_weighted(model) + else: + raise ValueError( + f"Invalid objective function for covariance calculation. " + f"The covariance matrix can only be calculated using the built-in " + f"objective functions: {[e.value for e in ObjectiveType]}. Supply " + f"the Estimator object one of these built-in objectives and " + f"re-run the code." + ) + + # evaluate the numerical SSE and store it + sse_val = pyo.value(sse_expr) + sse_vals.append(sse_val) + + sse = sum(sse_vals) + logger.info( + f"The sum of squared errors at the estimated parameter(s) is: {sse}" + ) + + """Calculate covariance assuming experimental observation errors are + independent and follow a Gaussian distribution with constant variance. + + The formula used in parmest was verified against equations (7-5-15) and + (7-5-16) in "Nonlinear Parameter Estimation", Y. Bard, 1974. + + This formula is also applicable if the objective is scaled by a constant; + the constant cancels out. (was scaled by 1/n because it computes an + expected value.) + """ + # check if the user-supplied covariance method is supported + try: + cov_method = CovarianceMethod(method) + except ValueError: + raise ValueError( + f"Invalid method: '{method}'. Choose " + f"from: {[e.value for e in CovarianceMethod]}." + ) + + # check if the user specified 'SSE' or 'SSE_weighted' as the objective function + if self.obj_function == ObjectiveType.SSE: + # check if the user defined the 'measurement_error' attribute + if hasattr(model, "measurement_error"): + # get the measurement errors + meas_error = [ + model.measurement_error[y_hat] + for y_hat, y in model.experiment_outputs.items() + ] + + # check if the user supplied the values of the measurement errors + if all(item is None for item in meas_error): + if cov_method == CovarianceMethod.reduced_hessian: + # in the "reduced_hessian" method, use the objective value + # to calculate the measurement error variance because this + # method scales the objective function by a probability constant + # when computing the inverse of the reduced hessian + measurement_var = self.obj_value / ( + n - l + ) # estimate of the measurement error variance + cov = ( + 2 * measurement_var * self.inv_red_hes + ) # covariance matrix + cov = pd.DataFrame( + cov, + index=self.estimated_theta.keys(), + columns=self.estimated_theta.keys(), + ) + else: + measurement_var = sse / ( + n - l + ) # estimate of the measurement error variance + cov = compute_covariance_matrix( + self.exp_list, + method, + obj_function=self.covariance_objective, + theta_vals=self.estimated_theta, + solver=solver, + step=step, + tee=self.tee, + estimated_var=measurement_var, + ) + elif all(item is not None for item in meas_error): + if cov_method == CovarianceMethod.reduced_hessian: + # in the "reduced_hessian" method, the measurement error + # variance must be scaled by the probability constant that + # was applied to the objective function when computing + # the inverse of the reduced hessian + cov = ( + 2 + * (meas_error[0] ** 2 / self.obj_probability_constant) + * self.inv_red_hes + ) + cov = pd.DataFrame( + cov, + index=self.estimated_theta.keys(), + columns=self.estimated_theta.keys(), + ) + else: + cov = compute_covariance_matrix( + self.exp_list, + method, + obj_function=self.covariance_objective, + theta_vals=self.estimated_theta, + solver=solver, + step=step, + tee=self.tee, + ) + else: + raise ValueError( + "One or more values of the measurement errors have " + "not been supplied." + ) + else: + raise AttributeError( + 'Experiment model does not have suffix "measurement_error".' + ) + elif self.obj_function == ObjectiveType.SSE_weighted: + # check if the user defined the 'measurement_error' attribute + if hasattr(model, "measurement_error"): + meas_error = [ + model.measurement_error[y_hat] + for y_hat, y in model.experiment_outputs.items() + ] + + # check if the user supplied the values for the measurement errors + if all(item is not None for item in meas_error): + if cov_method == CovarianceMethod.reduced_hessian: + # in the "reduced_hessian" method, since the objective function + # was scaled by a probability constant when computing the + # inverse of the reduced hessian, the inverse of the reduced + # hessian must be divided by the probability constant to obtain + # the covariance matrix + cov = (1 / self.obj_probability_constant) * self.inv_red_hes + cov = pd.DataFrame( + cov, + index=self.estimated_theta.keys(), + columns=self.estimated_theta.keys(), + ) + else: + cov = compute_covariance_matrix( + self.exp_list, + method, + obj_function=self.covariance_objective, + theta_vals=self.estimated_theta, + step=step, + solver=solver, + tee=self.tee, + ) + else: + raise ValueError( + 'One or more values of the measurement errors have not been ' + 'supplied. All values of the measurement errors are required ' + 'for the "SSE_weighted" objective.' + ) + else: + raise AttributeError( + 'Experiment model does not have suffix "measurement_error".' + ) + + return cov + def _Q_at_theta(self, thetavals, initialize_parmest_model=False): """ Return the objective function value with fixed theta values. @@ -863,9 +1449,7 @@ def _Q_at_theta(self, thetavals, initialize_parmest_model=False): for snum in scenario_numbers: sname = "scenario_NODE" + str(snum) - instance = _experiment_instance_creation_callback( - sname, None, dummy_cb, fix_vars=True - ) + instance = _experiment_instance_creation_callback(sname, None, dummy_cb) model_theta_names = self._expand_indexed_unknowns(instance) if initialize_parmest_model: @@ -900,7 +1484,7 @@ def _Q_at_theta(self, thetavals, initialize_parmest_model=False): if self.diagnostic_mode: print(' Experiment = ', snum) print(' First solve with special diagnostics wrapper') - (status_obj, solved, iters, time, regu) = ( + status_obj, solved, iters, time, regu = ( utils.ipopt_solve_with_stats( instance, optimizer, max_iter=500, max_cpu_time=120 ) @@ -1018,73 +1602,74 @@ def _get_sample_list(self, samplesize, num_samples, replacement=True): attempts += 1 if attempts > num_samples: # arbitrary timeout limit - raise RuntimeError( - """Internal error: timeout constructing + raise RuntimeError("""Internal error: timeout constructing a sample, the dim of theta may be too - close to the samplesize""" - ) + close to the samplesize""") samplelist.append((i, sample)) return samplelist def theta_est( - self, solver="ef_ipopt", return_values=[], calc_cov=False, cov_n=None + self, solver="ef_ipopt", return_values=[], calc_cov=NOTSET, cov_n=NOTSET ): """ Parameter estimation using all scenarios in the data Parameters ---------- - solver: string, optional + solver: str, optional Currently only "ef_ipopt" is supported. Default is "ef_ipopt". return_values: list, optional - List of Variable names, used to return values from the model for data reconciliation + List of Variable names, used to return values from the model + for data reconciliation calc_cov: boolean, optional - If True, calculate and return the covariance matrix (only for "ef_ipopt" solver). - Default is False. + DEPRECATED. + + If True, calculate and return the covariance matrix + (only for "ef_ipopt" solver). Default is NOTSET cov_n: int, optional + DEPRECATED. + If calc_cov=True, then the user needs to supply the number of datapoints - that are used in the objective function. + that are used in the objective function. Default is NOTSET Returns ------- - objectiveval: float + obj_val: float The objective function value - thetavals: pd.Series + theta_vals: pd.Series Estimated values for theta - variable values: pd.DataFrame - Variable values for each variable name in return_values (only for solver='ef_ipopt') - cov: pd.DataFrame - Covariance matrix of the fitted parameters (only for solver='ef_ipopt') + var_values: pd.DataFrame + Variable values for each variable name in + return_values (only for solver='ef_ipopt') """ + assert isinstance(solver, str) + assert isinstance(return_values, list) + assert (calc_cov is NOTSET) or isinstance(calc_cov, bool) + + if calc_cov is not NOTSET: + deprecation_warning( + "theta_est(): `calc_cov` and `cov_n` are deprecated options and " + "will be removed in the future. Please use the `cov_est()` function " + "for covariance calculation.", + version="6.9.5", + ) + else: + calc_cov = False # check if we are using deprecated parmest - if self.pest_deprecated is not None: + if self.pest_deprecated is not None and calc_cov: return self.pest_deprecated.theta_est( solver=solver, return_values=return_values, calc_cov=calc_cov, cov_n=cov_n, ) - - assert isinstance(solver, str) - assert isinstance(return_values, list) - assert isinstance(calc_cov, bool) - if calc_cov: - num_unknowns = max( - [ - len(experiment.get_labeled_model().unknown_parameters) - for experiment in self.exp_list - ] - ) - assert isinstance(cov_n, int), ( - "The number of datapoints that are used in the objective function is " - "required to calculate the covariance matrix" + elif self.pest_deprecated is not None and not calc_cov: + return self.pest_deprecated.theta_est( + solver=solver, return_values=return_values ) - assert ( - cov_n > num_unknowns - ), "The number of datapoints must be greater than the number of parameters to estimate" return self._Q_opt( solver=solver, @@ -1094,222 +1679,54 @@ def theta_est( cov_n=cov_n, ) - # TODO: Make the user provide a list of values, not the whole data frame - # TODO: Add a way to print the empty data_frame before solve so it can be previewed beforehand - # TODO: Fix so the theta values are generated at each iteration, not all beforehand in _generate_initial_theta - # Fix _generate_initial_theta to return an empty DataFrame first - # TODO: Add save model option to save the model after each iteration or at the end of the multistart - def theta_est_multistart( - self, - n_restarts=20, - multistart_sampling_method="uniform_random", - user_provided_list=None, - seed=None, - save_results=False, - theta_vals=None, - solver="ef_ipopt", - file_name="multistart_results.csv", - return_values=[], - ): + def cov_est(self, method="finite_difference", solver="ipopt", step=1e-3): """ - Parameter estimation using multistart optimization + Covariance matrix calculation using all scenarios in the data Parameters ---------- - n_restarts: int, optional - Number of restarts for multistart. Default is 1. - multistart_sampling_method: string, optional - Method used to sample theta values. Options are "uniform_random", "latin_hypercube", "sobol_sampling", or "user_provided_values". - Default is "uniform_random". - buffer: int, optional - Number of iterations to save results dynamically if save_results=True. Default is 10. - user_provided_df: pd.DataFrame, optional - User provided array or dataframe of theta values for multistart optimization. - seed: int, optional - Random seed for reproducibility. - save_results: bool, optional - If True, intermediate and final results are saved to file_name. - theta_vals: pd.DataFrame, optional - Initial theta values for restarts (overrides sampling). - solver: string, optional - Currently only "ef_ipopt" is supported. Default is "ef_ipopt". - file_name: str, optional - File name for saving results if save_results is True. - return_values: list, optional - List of Variable names, used to return values from the model for data reconciliation. + method : str, optional + Covariance calculation method. Options - 'finite_difference', + 'reduced_hessian', and 'automatic_differentiation_kaug'. + Default is 'finite_difference' + solver : str, optional + Solver name, e.g., 'ipopt'. Default is 'ipopt' + step : float, optional + Float used for relative perturbation of the parameters, + e.g., step=0.02 is a 2% perturbation. Default is 1e-3 Returns ------- - results_df: pd.DataFrame - DataFrame containing initial and converged theta values, objectives, and solver info for each restart. - best_theta: dict - Dictionary of theta values corresponding to the best (lowest) objective value found. - best_objectiveval: float - The best (lowest) objective function value found across all restarts. + cov : pd.DataFrame + Covariance matrix of the estimated parameters """ - - # check if we are using deprecated parmest - if self.pest_deprecated is not None: - return print( - "Multistart is not supported in the deprecated parmest interface" - ) - - # Validate input types - if not isinstance(n_restarts, int): - raise TypeError("n_restarts must be an integer") - if not isinstance(multistart_sampling_method, str): - raise TypeError("multistart_sampling_method must be a string") + # check if the solver input is a string if not isinstance(solver, str): - raise TypeError("solver must be a string") - if not isinstance(return_values, list): - raise TypeError("return_values must be a list") - - if n_restarts <= 1: - # If n_restarts is 1 or less, no multistart optimization is needed - logger.warning( - "No multistart optimization needed. Please use normal theta_est()." - ) - return self.theta_est( - solver=solver, return_values=return_values, calc_cov=False, cov_n=None - ) - - if n_restarts > 1 and multistart_sampling_method is not None: - - # Find the initialized values of theta from the labeled parmest model - # and the theta names from the estimator object + raise TypeError("Expected a string for the solver, e.g., 'ipopt'") - # logger statement to indicate multistart optimization is starting - logger.info( - f"Starting multistart optimization with {n_restarts} restarts using {multistart_sampling_method} sampling method." + # check if the method input is a string + if not isinstance(method, str): + raise TypeError( + "Expected a string for the method, e.g., 'finite_difference'" ) - # @Reviewers, pyomo team: Use this or use instance creation callback? - theta_names = self._return_theta_names() - # Generate theta values using the sampling method - parmest_model_for_bounds = self._create_parmest_model(experiment_number=0) - results_df = self._generate_initial_theta( - parmest_model_for_bounds, - seed=seed, - n_restarts=n_restarts, - multistart_sampling_method=multistart_sampling_method, - user_provided_df=user_provided_df, - ) - results_df = pd.DataFrame(results_df) - # Extract theta_vals from the dataframe - theta_vals = results_df.iloc[:, : len(theta_names)] - converged_theta_vals = np.zeros((n_restarts, len(theta_names))) - - timer = TicTocTimer() - - # Each restart uses a fresh model instance - for i in range(n_restarts): - - # Add a timer for each restart - timer.tic(f"Restart {i+1}/{n_restarts}") - - # No longer needed, keeping until confirming update works as expected - # # Create a fresh model for each restart - # parmest_model = self._create_parmest_model(experiment_number=0) - theta_vals_current = theta_vals.iloc[i, :].to_dict() - # If theta_vals is provided, use it to set the current theta values - # # Convert values to a list - # theta_vals_current = list(theta_vals.iloc[i, :]) - - # # Update the model with the current theta values - # update_model_from_suffix(parmest_model, 'experiment_inputs', theta_vals_current) - - # # Set current theta values in the model - # for name, value in theta_vals_current.items(): - # parmest_model.find_component(name).set_value(value) - - # # Optional: Print the current theta values being set - # print(f"Setting {name} to {value}") - # for name in theta_names: - # current_value = parmest_model.find_component(name)() - # print(f"Current value of {name} is {current_value}") - - # Call the _Q_opt method with the generated theta values - qopt_result = self._Q_opt( - ThetaVals=theta_vals_current, - bootlist=None, - solver=solver, - return_values=return_values, - multistart=True, - ) - - # Unpack results - objectiveval, converged_theta, solver_info = qopt_result - - # Added an extra option to Q_opt to return the full solver result if multistart=True - solver_termination = solver_info.solver.termination_condition - if solver_termination != pyo.TerminationCondition.optimal: - # If the solver did not converge, set the converged theta to NaN - solve_time = np.nan - final_objectiveval = np.nan - init_objectiveval = np.nan - else: - converged_theta_vals[i, :] = converged_theta.values - # Calculate the initial objective value using the current theta values - # Use the _Q_at_theta method to evaluate the objective at these theta values - init_objectiveval, _, _ = self._Q_at_theta(theta_vals_current) - final_objectiveval = objectiveval - - # # Check if the objective value is better than the best objective value - # # Set a very high initial best objective value - if i == 0: - # Initialize best objective value and theta - best_objectiveval = np.inf - best_theta = np.inf - # Check if the final objective value is better than the best found so far - if final_objectiveval < best_objectiveval: - best_objectiveval = objectiveval - best_theta = converged_theta.values - - logger.info( - f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}" - ) - - # Stop the timer for this restart - solve_time = timer.toc(f"Restart {i+1}/{n_restarts}") - - # Store the results in the DataFrame for this restart - # Fill converged theta values - for j, name in enumerate(theta_names): - results_df.at[i, f'converged_{name}'] = ( - converged_theta.iloc[j] - if not np.isnan(converged_theta_vals[i, j]) - else np.nan - ) - # Fill initial and final objective values, solver termination, and solve time - results_df.at[i, "initial objective"] = ( - init_objectiveval if 'init_objectiveval' in locals() else np.nan - ) - results_df.at[i, "final objective"] = ( - objectiveval if 'objectiveval' in locals() else np.nan - ) - results_df.at[i, "solver termination"] = ( - solver_termination if 'solver_termination' in locals() else np.nan - ) - results_df.at[i, "solve_time"] = ( - solve_time if 'solve_time' in locals() else np.nan - ) - - # Diagnostic: print the table after each restart - logger.debug(results_df) + # check if the step input is a float + if not isinstance(step, float): + raise TypeError("Expected a float for the step, e.g., 1e-2") - # Add buffer to save the dataframe dynamically, if save_results is True - if save_results and (i + 1) % buffer == 0: - mode = 'w' if i + 1 == buffer else 'a' - header = i + 1 == buffer - results_df.to_csv(file_name, mode=mode, header=header, index=False) - logger.info(f"Intermediate results saved after {i + 1} iterations.") - - # Final save after all iterations - if save_results: - results_df.to_csv(file_name, mode='a', header=False, index=False) - logger.info("Final results saved.") + # number of unknown parameters + num_unknowns = max( + [ + len(experiment.get_labeled_model().unknown_parameters) + for experiment in self.exp_list + ] + ) + assert self.number_exp > num_unknowns, ( + "The number of datapoints must be greater than the " + "number of parameters to estimate." + ) - return results_df, best_theta, best_objectiveval + return self._cov_at_theta(method=method, solver=solver, step=step) def theta_est_bootstrap( self, @@ -1819,7 +2236,7 @@ def group_data(data, groupby_column_name, use_mean=None): return grouped_data -class _DeprecatedSecondStageCostExpr(object): +class _DeprecatedSecondStageCostExpr: """ Class to pass objective expression into the Pyomo model """ @@ -1832,7 +2249,7 @@ def __call__(self, model): return self._ssc_function(model, self._data) -class _DeprecatedEstimator(object): +class _DeprecatedEstimator: """ Parameter estimation class @@ -2072,7 +2489,7 @@ def _Q_opt( for ndname, Var, solval in ef_nonants(ef): ind_vars.append(Var) # calculate the reduced hessian - (solve_result, inv_red_hes) = ( + solve_result, inv_red_hes = ( inverse_reduced_hessian.inv_reduced_hessian_barrier( self.ef_instance, independent_variables=ind_vars, @@ -2268,7 +2685,7 @@ def _Q_at_theta(self, thetavals, initialize_parmest_model=False): if self.diagnostic_mode: print(' Experiment = ', snum) print(' First solve with special diagnostics wrapper') - (status_obj, solved, iters, time, regu) = ( + status_obj, solved, iters, time, regu = ( utils.ipopt_solve_with_stats( instance, optimizer, max_iter=500, max_cpu_time=120 ) @@ -2386,11 +2803,9 @@ def _get_sample_list(self, samplesize, num_samples, replacement=True): attempts += 1 if attempts > num_samples: # arbitrary timeout limit - raise RuntimeError( - """Internal error: timeout constructing + raise RuntimeError("""Internal error: timeout constructing a sample, the dim of theta may be too - close to the samplesize""" - ) + close to the samplesize""") samplelist.append((i, sample)) @@ -2427,7 +2842,7 @@ def theta_est( """ assert isinstance(solver, str) assert isinstance(return_values, list) - assert isinstance(calc_cov, bool) + assert (calc_cov is NOTSET) or isinstance(calc_cov, bool) if calc_cov: assert isinstance( cov_n, int From 3c87d7ad40e706eee6489f2306b9583136ed2482 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 19 Feb 2026 00:25:04 -0500 Subject: [PATCH 25/32] Added old files in temporarily for reference --- .../reactor_design/multistart_example_old.py | 48 + pyomo/contrib/parmest/parmest_old.py | 2885 +++++++++++++++++ 2 files changed, 2933 insertions(+) create mode 100644 pyomo/contrib/parmest/examples/reactor_design/multistart_example_old.py create mode 100644 pyomo/contrib/parmest/parmest_old.py diff --git a/pyomo/contrib/parmest/examples/reactor_design/multistart_example_old.py b/pyomo/contrib/parmest/examples/reactor_design/multistart_example_old.py new file mode 100644 index 00000000000..033c0ddcdc5 --- /dev/null +++ b/pyomo/contrib/parmest/examples/reactor_design/multistart_example_old.py @@ -0,0 +1,48 @@ +# ___________________________________________________________________________ +# +# Pyomo: Python Optimization Modeling Objects +# Copyright (c) 2008-2025 +# 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 +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 = [] + for i in range(data.shape[0]): + exp_list.append(ReactorDesignExperiment(data, i)) + + # View one model + # exp0_model = exp_list[0].get_labeled_model() + # exp0_model.pprint() + + pest = parmest.Estimator(exp_list, obj_function='SSE') + + # Parameter estimation + obj, theta = pest.theta_est() + + # Parameter estimation with multistart to avoid local minima + obj, theta = pest.theta_est_multistart( + num_starts=10, start_method='random', random_seed=42, max_iter=1000, tol=1e-6 + ) + + +if __name__ == "__main__": + main() diff --git a/pyomo/contrib/parmest/parmest_old.py b/pyomo/contrib/parmest/parmest_old.py new file mode 100644 index 00000000000..0ee63e8cb8e --- /dev/null +++ b/pyomo/contrib/parmest/parmest_old.py @@ -0,0 +1,2885 @@ +# ___________________________________________________________________________ +# +# Pyomo: Python Optimization Modeling Objects +# Copyright (c) 2008-2025 +# 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. +# ___________________________________________________________________________ +#### Using mpi-sppy instead of PySP; May 2020 +#### Adding option for "local" EF starting Sept 2020 +#### Wrapping mpi-sppy functionality and local option Jan 2021, Feb 2021 +#### Redesign with Experiment class Dec 2023 + +# TODO: move use_mpisppy to a Pyomo configuration option +# False implies always use the EF that is local to parmest +use_mpisppy = True # Use it if we can but use local if not. +if use_mpisppy: + try: + # MPI-SPPY has an unfortunate side effect of outputting + # "[ 0.00] Initializing mpi-sppy" when it is imported. This can + # cause things like doctests to fail. We will suppress that + # information here. + from pyomo.common.tee import capture_output + + with capture_output(): + import mpisppy.utils.sputils as sputils + except ImportError: + use_mpisppy = False # we can't use it +if use_mpisppy: + # These things should be outside the try block. + sputils.disable_tictoc_output() + import mpisppy.opt.ef as st + import mpisppy.scenario_tree as scenario_tree +else: + import pyomo.contrib.parmest.utils.create_ef as local_ef + import pyomo.contrib.parmest.utils.scenario_tree as scenario_tree + +import re +import importlib as im +import logging +import types +import json +from collections.abc import Callable +from itertools import combinations +from functools import singledispatchmethod + +from pyomo.common.dependencies import ( + attempt_import, + numpy as np, + numpy_available, + pandas as pd, + pandas_available, + scipy, + scipy_available, +) + +import pyomo.environ as pyo + +from pyomo.opt import SolverFactory +from pyomo.environ import Block, ComponentUID + +import pyomo.contrib.parmest.utils as utils +import pyomo.contrib.parmest.graphics as graphics +from pyomo.dae import ContinuousSet + +# Add imports for HierchicalTimer +import time +from pyomo.common.timing import TicTocTimer +from enum import Enum + +from pyomo.common.deprecation import deprecated +from pyomo.common.deprecation import deprecation_warning + +parmest_available = numpy_available & pandas_available & scipy_available + +inverse_reduced_hessian, inverse_reduced_hessian_available = attempt_import( + 'pyomo.contrib.interior_point.inverse_reduced_hessian' +) + +logger = logging.getLogger(__name__) + + +def ef_nonants(ef): + # Wrapper to call someone's ef_nonants + # (the function being called is very short, but it might be changed) + if use_mpisppy: + return sputils.ef_nonants(ef) + else: + return local_ef.ef_nonants(ef) + + +def _experiment_instance_creation_callback( + scenario_name, node_names=None, cb_data=None, fix_vars=False +): + """ + This is going to be called by mpi-sppy or the local EF and it will call into + the user's model's callback. + + Parameters: + ----------- + scenario_name: `str` Scenario name should end with a number + node_names: `None` ( Not used here ) + cb_data : dict with ["callback"], ["BootList"], + ["theta_names"], ["cb_data"], etc. + "cb_data" is passed through to user's callback function + that is the "callback" value. + "BootList" is None or bootstrap experiment number list. + (called cb_data by mpisppy) + fix_vars: `bool` If True, the theta variables are fixed to the values + provided in the cb_data["ThetaVals"] dictionary. + + + Returns: + -------- + instance: `ConcreteModel` + instantiated scenario + + Note: + ---- + There is flexibility both in how the function is passed and its signature. + """ + assert cb_data is not None + outer_cb_data = cb_data + scen_num_str = re.compile(r'(\d+)$').search(scenario_name).group(1) + scen_num = int(scen_num_str) + basename = scenario_name[: -len(scen_num_str)] # to reconstruct name + + CallbackFunction = outer_cb_data["callback"] + + if callable(CallbackFunction): + callback = CallbackFunction + else: + cb_name = CallbackFunction + + if "CallbackModule" not in outer_cb_data: + raise RuntimeError( + "Internal Error: need CallbackModule in parmest callback" + ) + else: + modname = outer_cb_data["CallbackModule"] + + if isinstance(modname, str): + cb_module = im.import_module(modname, package=None) + elif isinstance(modname, types.ModuleType): + cb_module = modname + else: + print("Internal Error: bad CallbackModule") + raise + + try: + callback = getattr(cb_module, cb_name) + except: + print("Error getting function=" + cb_name + " from module=" + str(modname)) + raise + + if "BootList" in outer_cb_data: + bootlist = outer_cb_data["BootList"] + # print("debug in callback: using bootlist=",str(bootlist)) + # assuming bootlist itself is zero based + exp_num = bootlist[scen_num] + else: + exp_num = scen_num + + scen_name = basename + str(exp_num) + + cb_data = outer_cb_data["cb_data"] # cb_data might be None. + + # at least three signatures are supported. The first is preferred + try: + instance = callback(experiment_number=exp_num, cb_data=cb_data) + except TypeError: + raise RuntimeError( + "Only one callback signature is supported: " + "callback(experiment_number, cb_data) " + ) + """ + try: + instance = callback(scenario_tree_model, scen_name, node_names) + except TypeError: # deprecated signature? + try: + instance = callback(scen_name, node_names) + except: + print("Failed to create instance using callback; TypeError+") + raise + except: + print("Failed to create instance using callback.") + raise + """ + if hasattr(instance, "_mpisppy_node_list"): + raise RuntimeError(f"scenario for experiment {exp_num} has _mpisppy_node_list") + nonant_list = [ + instance.find_component(vstr) for vstr in outer_cb_data["theta_names"] + ] + if use_mpisppy: + instance._mpisppy_node_list = [ + scenario_tree.ScenarioNode( + name="ROOT", + cond_prob=1.0, + stage=1, + cost_expression=instance.FirstStageCost, + nonant_list=nonant_list, + scen_model=instance, + ) + ] + else: + instance._mpisppy_node_list = [ + scenario_tree.ScenarioNode( + name="ROOT", + cond_prob=1.0, + stage=1, + cost_expression=instance.FirstStageCost, + scen_name_list=None, + nonant_list=nonant_list, + scen_model=instance, + ) + ] + # @Reviewers, here is where the parmest model is made for each run + # This is the only way I see to pass the theta values to the model + # Can we add an optional argument to fix them or not? + # Curently, thetavals provided are fixed if not None + # Suggested fix in this function and _Q_at_theta + if "ThetaVals" in outer_cb_data: + thetavals = outer_cb_data["ThetaVals"] + + # dlw august 2018: see mea code for more general theta + for name, val in thetavals.items(): + theta_cuid = ComponentUID(name) + theta_object = theta_cuid.find_component_on(instance) + if val is not None and fix_vars is True: + # print("Fixing",vstr,"at",str(thetavals[vstr])) + theta_object.fix(val) + # ADDED OPTION: Set initial value, but do not fix + elif val is not None and fix_vars is False: + # print("Setting",vstr,"to",str(thetavals[vstr])) + theta_object.set_value(val) + theta_object.unfix() + else: + # print("Freeing",vstr) + theta_object.unfix() + + return instance + + +def SSE(model): + """ + Sum of squared error between `experiment_output` model and data values + """ + expr = sum((y - y_hat) ** 2 for y, y_hat in model.experiment_outputs.items()) + return expr + + +class MultistartSamplingMethodLib(Enum): + """ + Enum class for multistart sampling methods. + """ + + uniform_random = "uniform_random" + latin_hypercube = "latin_hypercube" + sobol_sampling = "sobol_sampling" + user_provided_values = "user_provided_values" + + +class Estimator(object): + """ + Parameter estimation class + + Parameters + ---------- + experiment_list: list of Experiments + A list of experiment objects which creates one labeled model for + each experiment + obj_function: string or function (optional) + Built in objective (currently only "SSE") or custom function used to + formulate parameter estimation objective. + If no function is specified, the model is used + "as is" and should be defined with a "FirstStageCost" and + "SecondStageCost" expression that are used to build an objective. + Default is None. + tee: bool, optional + If True, print the solver output to the screen. Default is False. + diagnostic_mode: bool, optional + If True, print diagnostics from the solver. Default is False. + solver_options: dict, optional + Provides options to the solver (also the name of an attribute). + Default is None. + """ + + # The singledispatchmethod decorator is used here as a deprecation + # shim to be able to support the now deprecated Estimator interface + # which had a different number of arguments. When the deprecated API + # is removed this decorator and the _deprecated_init method below + # can be removed + @singledispatchmethod + def __init__( + self, + experiment_list, + obj_function=None, + tee=False, + diagnostic_mode=False, + solver_options=None, + ): + '''first theta would be provided by the user in the initialization of + the Estimator class through the unknown parameter variables. Additional + would need to be generated using the sampling method provided by the user. + ''' + + # check that we have a (non-empty) list of experiments + assert isinstance(experiment_list, list) + self.exp_list = experiment_list + + # check that an experiment has experiment_outputs and unknown_parameters + model = self.exp_list[0].get_labeled_model() + try: + outputs = [k.name for k, v in model.experiment_outputs.items()] + except: + raise RuntimeError( + 'Experiment list model does not have suffix ' + '"experiment_outputs".' + ) + try: + params = [k.name for k, v in model.unknown_parameters.items()] + except: + raise RuntimeError( + 'Experiment list model does not have suffix ' + '"unknown_parameters".' + ) + + # populate keyword argument options + self.obj_function = obj_function + self.tee = tee + self.diagnostic_mode = diagnostic_mode + self.solver_options = solver_options + + # TODO: delete this when the deprecated interface is removed + self.pest_deprecated = None + + # TODO This might not be needed here. + # We could collect the union (or intersect?) of thetas when the models are built + theta_names = [] + for experiment in self.exp_list: + model = experiment.get_labeled_model() + theta_names.extend([k.name for k, v in model.unknown_parameters.items()]) + # Utilize list(dict.fromkeys(theta_names)) to preserve parameter + # order compared with list(set(theta_names)), which had + # nondeterministic ordering of parameters + self.estimator_theta_names = list(dict.fromkeys(theta_names)) + + self._second_stage_cost_exp = "SecondStageCost" + # boolean to indicate if model is initialized using a square solve + self.model_initialized = False + + # The deprecated Estimator constructor + # This works by checking the type of the first argument passed to + # the class constructor. If it matches the old interface (i.e. is + # callable) then this _deprecated_init method is called and the + # deprecation warning is displayed. + @__init__.register(Callable) + def _deprecated_init( + self, + model_function, + data, + theta_names, + obj_function=None, + tee=False, + diagnostic_mode=False, + solver_options=None, + ): + + deprecation_warning( + "You're using the deprecated parmest interface (model_function, " + "data, theta_names). This interface will be removed in a future release, " + "please update to the new parmest interface using experiment lists.", + version='6.7.2', + ) + self.pest_deprecated = _DeprecatedEstimator( + model_function, + data, + theta_names, + obj_function, + tee, + diagnostic_mode, + solver_options, + ) + + def _return_theta_names(self): + """ + Return list of fitted model parameter names + """ + # check for deprecated inputs + if self.pest_deprecated: + + # if fitted model parameter names differ from theta_names + # created when Estimator object is created + if hasattr(self, 'theta_names_updated'): + return self.pest_deprecated.theta_names_updated + + else: + + # default theta_names, created when Estimator object is created + return self.pest_deprecated.theta_names + + else: + + # if fitted model parameter names differ from theta_names + # created when Estimator object is created + if hasattr(self, 'theta_names_updated'): + return self.theta_names_updated + + else: + + # default theta_names, created when Estimator object is created + return self.estimator_theta_names + + def _expand_indexed_unknowns(self, model_temp): + """ + Expand indexed variables to get full list of thetas + """ + + model_theta_list = [] + for c in model_temp.unknown_parameters.keys(): + if c.is_indexed(): + for _, ci in c.items(): + model_theta_list.append(ci.name) + else: + model_theta_list.append(c.name) + + return model_theta_list + + def _create_parmest_model(self, experiment_number): + """ + Modify the Pyomo model for parameter estimation + """ + + model = self.exp_list[experiment_number].get_labeled_model() + + if len(model.unknown_parameters) == 0: + model.parmest_dummy_var = pyo.Var(initialize=1.0) + + # Add objective function (optional) + if self.obj_function: + # Check for component naming conflicts + reserved_names = [ + 'Total_Cost_Objective', + 'FirstStageCost', + 'SecondStageCost', + ] + for n in reserved_names: + if model.component(n) or hasattr(model, n): + raise RuntimeError( + f"Parmest will not override the existing model component named {n}" + ) + + # Deactivate any existing objective functions + for obj in model.component_objects(pyo.Objective): + obj.deactivate() + + # 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 + else: + # A custom function uses model.experiment_outputs as data + second_stage_rule = self.obj_function + + model.FirstStageCost = pyo.Expression(expr=0) + model.SecondStageCost = pyo.Expression(rule=second_stage_rule) + + def TotalCost_rule(model): + return model.FirstStageCost + model.SecondStageCost + + model.Total_Cost_Objective = pyo.Objective( + rule=TotalCost_rule, sense=pyo.minimize + ) + + # Convert theta Params to Vars, and unfix theta Vars + theta_names = [k.name for k, v in model.unknown_parameters.items()] + parmest_model = utils.convert_params_to_vars(model, theta_names, fix_vars=False) + + return parmest_model + + # TODO: Make so this generates the initial DATAFRAME, not the entire list of values. + # Make new private method, _generate_initial_theta: + # This method will be used to generate the initial theta values for multistart + # optimization. It will take the theta names and the initial theta values + # and return a dictionary of theta names and their corresponding values. + def _generate_initial_theta( + self, + parmest_model=None, + seed=None, + n_restarts=None, + multistart_sampling_method=None, + user_provided_df=None, + ): + """ + Generate initial theta values for multistart optimization using selected sampling method. + """ + # Locate the unknown parameters in the model from the suffix + suffix_params = parmest_model.unknown_parameters + + # Get the VarData objects from the suffix + theta_vars = list(suffix_params.keys()) + + # Extract names, starting values, and bounds for the theta variables + theta_names = [v.name for v in theta_vars] + initial_theta = np.array([v.value for v in theta_vars]) + lower_bound = np.array([v.lb for v in theta_vars]) + upper_bound = np.array([v.ub for v in theta_vars]) + + # Check if the lower and upper bounds are defined + if any(bound is None for bound in lower_bound) or any( + bound is None for bound in upper_bound + ): + raise ValueError( + "The lower and upper bounds for the theta values must be defined." + ) + + if multistart_sampling_method == "uniform_random": + # Generate random theta values using uniform distribution, with set seed for reproducibility + np.random.seed(seed) + # Generate random theta values for each restart (n_restarts x len(theta_names)) + theta_vals_multistart = np.random.uniform( + low=lower_bound, high=upper_bound, size=(n_restarts, len(theta_names)) + ) + + elif multistart_sampling_method == "latin_hypercube": + # Generate theta values using Latin hypercube sampling or Sobol sampling + # Generate theta values using Latin hypercube sampling + # Create a Latin Hypercube sampler that uses the dimensions of the theta names + sampler = scipy.stats.qmc.LatinHypercube(d=len(theta_names), seed=seed) + # Generate random samples in the range of [0, 1] for number of restarts + samples = sampler.random(n=n_restarts) + # Resulting samples should be size (n_restarts, len(theta_names)) + + elif multistart_sampling_method == "sobol_sampling": + sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) + # Generate theta values using Sobol sampling + # The first value of the Sobol sequence is 0, so we skip it + samples = sampler.random(n=n_restarts + 1)[1:] + + elif multistart_sampling_method == "user_provided_values": + # Add user provided dataframe option + if user_provided_df is not None: + + if isinstance(user_provided_df, pd.DataFrame): + # Check if the user provided dataframe has the same number of rows as the number of restarts + if user_provided_df.shape[0] != n_restarts: + raise ValueError( + "The user provided dataframe must have the same number of rows as the number of restarts." + ) + # Check if the user provided dataframe has the same number of columns as the number of theta names + if user_provided_df.shape[1] != len(theta_names): + raise ValueError( + "The user provided dataframe must have the same number of columns as the number of theta names." + ) + # Check if the user provided dataframe has the same theta names as the model + # if not, raise an error + if not all(theta in theta_names for theta in user_provided_df.columns): + raise ValueError( + "The user provided dataframe must have the same theta names as the model." + ) + # If all checks pass, return the user provided dataframe + theta_vals_multistart = user_provided_df.iloc[ + 0 : len(initial_theta) + ].values + else: + raise ValueError( + "The user must provide a pandas dataframe to use the 'user_provided_values' method." + ) + + else: + raise ValueError( + "Invalid sampling method. Choose 'uniform_random', 'latin_hypercube', 'sobol_sampling' or 'user_provided_values'." + ) + + if ( + multistart_sampling_method == "sobol_sampling" + or multistart_sampling_method == "latin_hypercube" + ): + # Scale the samples to the range of the lower and upper bounds for each theta in theta_names + # The samples are in the range [0, 1], so we scale them to the range of the lower and upper bounds + theta_vals_multistart = np.array( + [lower_bound + (upper_bound - lower_bound) * theta for theta in samples] + ) + + # Create a DataFrame where each row is an initial theta vector for a restart, + # columns are theta_names, and values are the initial theta values for each restart + if multistart_sampling_method == "user_provided_values": + # If user_provided_values is a DataFrame, use its columns and values directly + if isinstance(user_provided_df, pd.DataFrame): + df_multistart = user_provided_df.copy() + df_multistart.columns = theta_names + else: + df_multistart = pd.DataFrame(theta_vals_multistart, columns=theta_names) + else: + # Ensure theta_vals_multistart is 2D (n_restarts, len(theta_names)) + arr = np.atleast_2d(theta_vals_multistart) + if arr.shape[0] == 1 and n_restarts > 1: + arr = np.tile(arr, (n_restarts, 1)) + df_multistart = pd.DataFrame(arr, columns=theta_names) + + # Add columns for output info, initialized as nan + for name in theta_names: + df_multistart[f'converged_{name}'] = np.nan + df_multistart["initial objective"] = np.nan + df_multistart["final objective"] = np.nan + df_multistart["solver termination"] = np.nan + df_multistart["solve_time"] = np.nan + + # Debugging output + # print(df_multistart) + + return df_multistart + + def _instance_creation_callback(self, experiment_number=None, cb_data=None): + model = self._create_parmest_model(experiment_number) + return model + + # TODO: Add a way to pass in a parmest_model to this function, currently cannot + # access the model within the build function. + + # I need to check, if I use the update model utility BEFORE calling _Q_opt, does it still + # work? If so, then I can remove the parmest_model argument. + def _Q_opt( + self, + ThetaVals=None, + solver="ef_ipopt", + return_values=[], + bootlist=None, + calc_cov=False, + multistart=False, + cov_n=None, + ): + """ + Set up all thetas as first stage Vars, return resulting theta + values as well as the objective function value. + + """ + if solver == "k_aug": + raise RuntimeError("k_aug no longer supported.") + + # (Bootstrap scenarios will use indirection through the bootlist) + if bootlist is None: + scenario_numbers = list(range(len(self.exp_list))) + scen_names = ["Scenario{}".format(i) for i in scenario_numbers] + else: + scen_names = ["Scenario{}".format(i) for i in range(len(bootlist))] + + # tree_model.CallbackModule = None + outer_cb_data = dict() + outer_cb_data["callback"] = self._instance_creation_callback + if ThetaVals is not None: + outer_cb_data["ThetaVals"] = ThetaVals + if bootlist is not None: + outer_cb_data["BootList"] = bootlist + outer_cb_data["cb_data"] = None # None is OK + outer_cb_data["theta_names"] = self.estimator_theta_names + + options = {"solver": "ipopt"} + scenario_creator_options = {"cb_data": outer_cb_data} + if use_mpisppy: + ef = sputils.create_EF( + scen_names, + _experiment_instance_creation_callback, + EF_name="_Q_opt", + suppress_warnings=True, + scenario_creator_kwargs=scenario_creator_options, + ) + else: + ef = local_ef.create_EF( + scen_names, + _experiment_instance_creation_callback, + EF_name="_Q_opt", + suppress_warnings=True, + scenario_creator_kwargs=scenario_creator_options, + ) + self.ef_instance = ef + + # Solve the extensive form with ipopt + if solver == "ef_ipopt": + if not calc_cov: + # Do not calculate the reduced hessian + + solver = SolverFactory('ipopt') + if self.solver_options is not None: + for key in self.solver_options: + solver.options[key] = self.solver_options[key] + + solve_result = solver.solve(self.ef_instance, tee=self.tee) + + # The import error will be raised when we attempt to use + # inv_reduced_hessian_barrier below. + # + # elif not asl_available: + # raise ImportError("parmest requires ASL to calculate the " + # "covariance matrix with solver 'ipopt'") + else: + # parmest makes the fitted parameters stage 1 variables + ind_vars = [] + for ndname, Var, solval in ef_nonants(ef): + ind_vars.append(Var) + # calculate the reduced hessian + (solve_result, inv_red_hes) = ( + inverse_reduced_hessian.inv_reduced_hessian_barrier( + self.ef_instance, + independent_variables=ind_vars, + solver_options=self.solver_options, + tee=self.tee, + ) + ) + + if self.diagnostic_mode: + print( + ' Solver termination condition = ', + str(solve_result.solver.termination_condition), + ) + + # assume all first stage are thetas... + thetavals = {} + for ndname, Var, solval in ef_nonants(ef): + # process the name + # the scenarios are blocks, so strip the scenario name + vname = Var.name[Var.name.find(".") + 1 :] + thetavals[vname] = solval + + objval = pyo.value(ef.EF_Obj) + + if calc_cov: + # Calculate the covariance matrix + + # Number of data points considered + n = cov_n + + # Extract number of fitted parameters + l = len(thetavals) + + # Assumption: Objective value is sum of squared errors + sse = objval + + '''Calculate covariance assuming experimental observation errors are + independent and follow a Gaussian + distribution with constant variance. + + The formula used in parmest was verified against equations (7-5-15) and + (7-5-16) in "Nonlinear Parameter Estimation", Y. Bard, 1974. + + This formula is also applicable if the objective is scaled by a constant; + the constant cancels out. (was scaled by 1/n because it computes an + expected value.) + ''' + cov = 2 * sse / (n - l) * inv_red_hes + cov = pd.DataFrame( + cov, index=thetavals.keys(), columns=thetavals.keys() + ) + + thetavals = pd.Series(thetavals) + + if len(return_values) > 0: + var_values = [] + if len(scen_names) > 1: # multiple scenarios + block_objects = self.ef_instance.component_objects( + Block, descend_into=False + ) + else: # single scenario + block_objects = [self.ef_instance] + for exp_i in block_objects: + vals = {} + for var in return_values: + exp_i_var = exp_i.find_component(str(var)) + if ( + exp_i_var is None + ): # we might have a block such as _mpisppy_data + continue + # if value to return is ContinuousSet + if type(exp_i_var) == ContinuousSet: + temp = list(exp_i_var) + else: + temp = [pyo.value(_) for _ in exp_i_var.values()] + if len(temp) == 1: + vals[var] = temp[0] + else: + vals[var] = temp + if len(vals) > 0: + var_values.append(vals) + var_values = pd.DataFrame(var_values) + if calc_cov: + return objval, thetavals, var_values, cov + else: + return objval, thetavals, var_values + + if calc_cov: + return objval, thetavals, cov + if multistart: + return objval, thetavals, solve_result + else: + return objval, thetavals + + else: + raise RuntimeError("Unknown solver in Q_Opt=" + solver) + + def _Q_at_theta(self, thetavals, initialize_parmest_model=False): + """ + Return the objective function value with fixed theta values. + + Parameters + ---------- + thetavals: dict + A dictionary of theta values. + + initialize_parmest_model: boolean + If True: Solve square problem instance, build extensive form of the model for + parameter estimation, and set flag model_initialized to True. Default is False. + + Returns + ------- + objectiveval: float + The objective function value. + thetavals: dict + A dictionary of all values for theta that were input. + solvertermination: Pyomo TerminationCondition + Tries to return the "worst" solver status across the scenarios. + pyo.TerminationCondition.optimal is the best and + pyo.TerminationCondition.infeasible is the worst. + """ + + optimizer = pyo.SolverFactory('ipopt') + + if len(thetavals) > 0: + dummy_cb = { + "callback": self._instance_creation_callback, + "ThetaVals": thetavals, + "theta_names": self._return_theta_names(), + "cb_data": None, + } + else: + dummy_cb = { + "callback": self._instance_creation_callback, + "theta_names": self._return_theta_names(), + "cb_data": None, + } + + if self.diagnostic_mode: + if len(thetavals) > 0: + print(' Compute objective at theta = ', str(thetavals)) + else: + print(' Compute objective at initial theta') + + # start block of code to deal with models with no constraints + # (ipopt will crash or complain on such problems without special care) + instance = _experiment_instance_creation_callback("FOO0", None, dummy_cb) + try: # deal with special problems so Ipopt will not crash + first = next(instance.component_objects(pyo.Constraint, active=True)) + active_constraints = True + except: + active_constraints = False + # end block of code to deal with models with no constraints + + WorstStatus = pyo.TerminationCondition.optimal + totobj = 0 + scenario_numbers = list(range(len(self.exp_list))) + if initialize_parmest_model: + # create dictionary to store pyomo model instances (scenarios) + scen_dict = dict() + + for snum in scenario_numbers: + sname = "scenario_NODE" + str(snum) + instance = _experiment_instance_creation_callback( + sname, None, dummy_cb, fix_vars=True + ) + model_theta_names = self._expand_indexed_unknowns(instance) + + if initialize_parmest_model: + # list to store fitted parameter names that will be unfixed + # after initialization + theta_init_vals = [] + # use appropriate theta_names member + theta_ref = model_theta_names + + for i, theta in enumerate(theta_ref): + # Use parser in ComponentUID to locate the component + var_cuid = ComponentUID(theta) + var_validate = var_cuid.find_component_on(instance) + if var_validate is None: + logger.warning( + "theta_name %s was not found on the model", (theta) + ) + else: + try: + if len(thetavals) == 0: + var_validate.fix() + else: + var_validate.fix(thetavals[theta]) + theta_init_vals.append(var_validate) + except: + logger.warning( + 'Unable to fix model parameter value for %s (not a Pyomo model Var)', + (theta), + ) + + if active_constraints: + if self.diagnostic_mode: + print(' Experiment = ', snum) + print(' First solve with special diagnostics wrapper') + (status_obj, solved, iters, time, regu) = ( + utils.ipopt_solve_with_stats( + instance, optimizer, max_iter=500, max_cpu_time=120 + ) + ) + print( + " status_obj, solved, iters, time, regularization_stat = ", + str(status_obj), + str(solved), + str(iters), + str(time), + str(regu), + ) + + results = optimizer.solve(instance) + if self.diagnostic_mode: + print( + 'standard solve solver termination condition=', + str(results.solver.termination_condition), + ) + + if ( + results.solver.termination_condition + != pyo.TerminationCondition.optimal + ): + # DLW: Aug2018: not distinguishing "middlish" conditions + if WorstStatus != pyo.TerminationCondition.infeasible: + WorstStatus = results.solver.termination_condition + if initialize_parmest_model: + if self.diagnostic_mode: + print( + "Scenario {:d} infeasible with initialized parameter values".format( + snum + ) + ) + else: + if initialize_parmest_model: + if self.diagnostic_mode: + print( + "Scenario {:d} initialization successful with initial parameter values".format( + snum + ) + ) + if initialize_parmest_model: + # unfix parameters after initialization + for theta in theta_init_vals: + theta.unfix() + scen_dict[sname] = instance + else: + if initialize_parmest_model: + # unfix parameters after initialization + for theta in theta_init_vals: + theta.unfix() + scen_dict[sname] = instance + + objobject = getattr(instance, self._second_stage_cost_exp) + objval = pyo.value(objobject) + totobj += objval + + retval = totobj / len(scenario_numbers) # -1?? + if initialize_parmest_model and not hasattr(self, 'ef_instance'): + # create extensive form of the model using scenario dictionary + if len(scen_dict) > 0: + for scen in scen_dict.values(): + scen._mpisppy_probability = 1 / len(scen_dict) + + if use_mpisppy: + EF_instance = sputils._create_EF_from_scen_dict( + scen_dict, + EF_name="_Q_at_theta", + # suppress_warnings=True + ) + else: + EF_instance = local_ef._create_EF_from_scen_dict( + scen_dict, EF_name="_Q_at_theta", nonant_for_fixed_vars=True + ) + + self.ef_instance = EF_instance + # set self.model_initialized flag to True to skip extensive form model + # creation using theta_est() + self.model_initialized = True + + # return initialized theta values + if len(thetavals) == 0: + # use appropriate theta_names member + theta_ref = self._return_theta_names() + for i, theta in enumerate(theta_ref): + thetavals[theta] = theta_init_vals[i]() + + return retval, thetavals, WorstStatus + + def _get_sample_list(self, samplesize, num_samples, replacement=True): + samplelist = list() + + scenario_numbers = list(range(len(self.exp_list))) + + if num_samples is None: + # This could get very large + for i, l in enumerate(combinations(scenario_numbers, samplesize)): + samplelist.append((i, np.sort(l))) + else: + for i in range(num_samples): + attempts = 0 + unique_samples = 0 # check for duplicates in each sample + duplicate = False # check for duplicates between samples + while (unique_samples <= len(self._return_theta_names())) and ( + not duplicate + ): + sample = np.random.choice( + scenario_numbers, samplesize, replace=replacement + ) + sample = np.sort(sample).tolist() + unique_samples = len(np.unique(sample)) + if sample in samplelist: + duplicate = True + + attempts += 1 + if attempts > num_samples: # arbitrary timeout limit + raise RuntimeError( + """Internal error: timeout constructing + a sample, the dim of theta may be too + close to the samplesize""" + ) + + samplelist.append((i, sample)) + + return samplelist + + def theta_est( + self, solver="ef_ipopt", return_values=[], calc_cov=False, cov_n=None + ): + """ + Parameter estimation using all scenarios in the data + + Parameters + ---------- + solver: string, optional + Currently only "ef_ipopt" is supported. Default is "ef_ipopt". + return_values: list, optional + List of Variable names, used to return values from the model for data reconciliation + calc_cov: boolean, optional + If True, calculate and return the covariance matrix (only for "ef_ipopt" solver). + Default is False. + cov_n: int, optional + If calc_cov=True, then the user needs to supply the number of datapoints + that are used in the objective function. + + Returns + ------- + objectiveval: float + The objective function value + thetavals: pd.Series + Estimated values for theta + variable values: pd.DataFrame + Variable values for each variable name in return_values (only for solver='ef_ipopt') + cov: pd.DataFrame + Covariance matrix of the fitted parameters (only for solver='ef_ipopt') + """ + + # check if we are using deprecated parmest + if self.pest_deprecated is not None: + return self.pest_deprecated.theta_est( + solver=solver, + return_values=return_values, + calc_cov=calc_cov, + cov_n=cov_n, + ) + + assert isinstance(solver, str) + assert isinstance(return_values, list) + assert isinstance(calc_cov, bool) + if calc_cov: + num_unknowns = max( + [ + len(experiment.get_labeled_model().unknown_parameters) + for experiment in self.exp_list + ] + ) + assert isinstance(cov_n, int), ( + "The number of datapoints that are used in the objective function is " + "required to calculate the covariance matrix" + ) + assert ( + cov_n > num_unknowns + ), "The number of datapoints must be greater than the number of parameters to estimate" + + return self._Q_opt( + solver=solver, + return_values=return_values, + bootlist=None, + calc_cov=calc_cov, + cov_n=cov_n, + ) + + # TODO: Make the user provide a list of values, not the whole data frame + # TODO: Add a way to print the empty data_frame before solve so it can be previewed beforehand + # TODO: Fix so the theta values are generated at each iteration, not all beforehand in _generate_initial_theta + # Fix _generate_initial_theta to return an empty DataFrame first + # TODO: Add save model option to save the model after each iteration or at the end of the multistart + def theta_est_multistart( + self, + n_restarts=20, + multistart_sampling_method="uniform_random", + user_provided_list=None, + seed=None, + save_results=False, + theta_vals=None, + solver="ef_ipopt", + file_name="multistart_results.csv", + return_values=[], + ): + """ + Parameter estimation using multistart optimization + + Parameters + ---------- + n_restarts: int, optional + Number of restarts for multistart. Default is 1. + multistart_sampling_method: string, optional + Method used to sample theta values. Options are "uniform_random", "latin_hypercube", "sobol_sampling", or "user_provided_values". + Default is "uniform_random". + buffer: int, optional + Number of iterations to save results dynamically if save_results=True. Default is 10. + user_provided_df: pd.DataFrame, optional + User provided array or dataframe of theta values for multistart optimization. + seed: int, optional + Random seed for reproducibility. + save_results: bool, optional + If True, intermediate and final results are saved to file_name. + theta_vals: pd.DataFrame, optional + Initial theta values for restarts (overrides sampling). + solver: string, optional + Currently only "ef_ipopt" is supported. Default is "ef_ipopt". + file_name: str, optional + File name for saving results if save_results is True. + return_values: list, optional + List of Variable names, used to return values from the model for data reconciliation. + + Returns + ------- + results_df: pd.DataFrame + DataFrame containing initial and converged theta values, objectives, and solver info for each restart. + best_theta: dict + Dictionary of theta values corresponding to the best (lowest) objective value found. + best_objectiveval: float + The best (lowest) objective function value found across all restarts. + """ + + # check if we are using deprecated parmest + if self.pest_deprecated is not None: + return print( + "Multistart is not supported in the deprecated parmest interface" + ) + + # Validate input types + if not isinstance(n_restarts, int): + raise TypeError("n_restarts must be an integer") + if not isinstance(multistart_sampling_method, str): + raise TypeError("multistart_sampling_method must be a string") + if not isinstance(solver, str): + raise TypeError("solver must be a string") + if not isinstance(return_values, list): + raise TypeError("return_values must be a list") + + if n_restarts <= 1: + # If n_restarts is 1 or less, no multistart optimization is needed + logger.warning( + "No multistart optimization needed. Please use normal theta_est()." + ) + return self.theta_est( + solver=solver, return_values=return_values, calc_cov=False, cov_n=None + ) + + if n_restarts > 1 and multistart_sampling_method is not None: + + # Find the initialized values of theta from the labeled parmest model + # and the theta names from the estimator object + + # logger statement to indicate multistart optimization is starting + logger.info( + f"Starting multistart optimization with {n_restarts} restarts using {multistart_sampling_method} sampling method." + ) + + # @Reviewers, pyomo team: Use this or use instance creation callback? + theta_names = self._return_theta_names() + # Generate theta values using the sampling method + parmest_model_for_bounds = self._create_parmest_model(experiment_number=0) + results_df = self._generate_initial_theta( + parmest_model_for_bounds, + seed=seed, + n_restarts=n_restarts, + multistart_sampling_method=multistart_sampling_method, + user_provided_df=user_provided_df, + ) + results_df = pd.DataFrame(results_df) + # Extract theta_vals from the dataframe + theta_vals = results_df.iloc[:, : len(theta_names)] + converged_theta_vals = np.zeros((n_restarts, len(theta_names))) + + timer = TicTocTimer() + + # Each restart uses a fresh model instance + for i in range(n_restarts): + + # Add a timer for each restart + timer.tic(f"Restart {i+1}/{n_restarts}") + + # No longer needed, keeping until confirming update works as expected + # # Create a fresh model for each restart + # parmest_model = self._create_parmest_model(experiment_number=0) + theta_vals_current = theta_vals.iloc[i, :].to_dict() + # If theta_vals is provided, use it to set the current theta values + # # Convert values to a list + # theta_vals_current = list(theta_vals.iloc[i, :]) + + # # Update the model with the current theta values + # update_model_from_suffix(parmest_model, 'experiment_inputs', theta_vals_current) + + # # Set current theta values in the model + # for name, value in theta_vals_current.items(): + # parmest_model.find_component(name).set_value(value) + + # # Optional: Print the current theta values being set + # print(f"Setting {name} to {value}") + # for name in theta_names: + # current_value = parmest_model.find_component(name)() + # print(f"Current value of {name} is {current_value}") + + # Call the _Q_opt method with the generated theta values + qopt_result = self._Q_opt( + ThetaVals=theta_vals_current, + bootlist=None, + solver=solver, + return_values=return_values, + multistart=True, + ) + + # Unpack results + objectiveval, converged_theta, solver_info = qopt_result + + # Added an extra option to Q_opt to return the full solver result if multistart=True + solver_termination = solver_info.solver.termination_condition + if solver_termination != pyo.TerminationCondition.optimal: + # If the solver did not converge, set the converged theta to NaN + solve_time = np.nan + final_objectiveval = np.nan + init_objectiveval = np.nan + else: + converged_theta_vals[i, :] = converged_theta.values + # Calculate the initial objective value using the current theta values + # Use the _Q_at_theta method to evaluate the objective at these theta values + init_objectiveval, _, _ = self._Q_at_theta(theta_vals_current) + final_objectiveval = objectiveval + + # # Check if the objective value is better than the best objective value + # # Set a very high initial best objective value + if i == 0: + # Initialize best objective value and theta + best_objectiveval = np.inf + best_theta = np.inf + # Check if the final objective value is better than the best found so far + if final_objectiveval < best_objectiveval: + best_objectiveval = objectiveval + best_theta = converged_theta.values + + logger.info( + f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}" + ) + + # Stop the timer for this restart + solve_time = timer.toc(f"Restart {i+1}/{n_restarts}") + + # Store the results in the DataFrame for this restart + # Fill converged theta values + for j, name in enumerate(theta_names): + results_df.at[i, f'converged_{name}'] = ( + converged_theta.iloc[j] + if not np.isnan(converged_theta_vals[i, j]) + else np.nan + ) + # Fill initial and final objective values, solver termination, and solve time + results_df.at[i, "initial objective"] = ( + init_objectiveval if 'init_objectiveval' in locals() else np.nan + ) + results_df.at[i, "final objective"] = ( + objectiveval if 'objectiveval' in locals() else np.nan + ) + results_df.at[i, "solver termination"] = ( + solver_termination if 'solver_termination' in locals() else np.nan + ) + results_df.at[i, "solve_time"] = ( + solve_time if 'solve_time' in locals() else np.nan + ) + + # Diagnostic: print the table after each restart + logger.debug(results_df) + + # Add buffer to save the dataframe dynamically, if save_results is True + if save_results and (i + 1) % buffer == 0: + mode = 'w' if i + 1 == buffer else 'a' + header = i + 1 == buffer + results_df.to_csv(file_name, mode=mode, header=header, index=False) + logger.info(f"Intermediate results saved after {i + 1} iterations.") + + # Final save after all iterations + if save_results: + results_df.to_csv(file_name, mode='a', header=False, index=False) + logger.info("Final results saved.") + + return results_df, best_theta, best_objectiveval + + def theta_est_bootstrap( + self, + bootstrap_samples, + samplesize=None, + replacement=True, + seed=None, + return_samples=False, + ): + """ + Parameter estimation using bootstrap resampling of the data + + Parameters + ---------- + bootstrap_samples: int + Number of bootstrap samples to draw from the data + samplesize: int or None, optional + Size of each bootstrap sample. If samplesize=None, samplesize will be + set to the number of samples in the data + replacement: bool, optional + Sample with or without replacement. Default is True. + seed: int or None, optional + Random seed + return_samples: bool, optional + Return a list of sample numbers used in each bootstrap estimation. + Default is False. + + Returns + ------- + bootstrap_theta: pd.DataFrame + Theta values for each sample and (if return_samples = True) + the sample numbers used in each estimation + """ + + # check if we are using deprecated parmest + if self.pest_deprecated is not None: + return self.pest_deprecated.theta_est_bootstrap( + bootstrap_samples, + samplesize=samplesize, + replacement=replacement, + seed=seed, + return_samples=return_samples, + ) + + assert isinstance(bootstrap_samples, int) + assert isinstance(samplesize, (type(None), int)) + assert isinstance(replacement, bool) + assert isinstance(seed, (type(None), int)) + assert isinstance(return_samples, bool) + + if samplesize is None: + samplesize = len(self.exp_list) + + if seed is not None: + np.random.seed(seed) + + global_list = self._get_sample_list(samplesize, bootstrap_samples, replacement) + + task_mgr = utils.ParallelTaskManager(bootstrap_samples) + local_list = task_mgr.global_to_local_data(global_list) + + bootstrap_theta = list() + for idx, sample in local_list: + objval, thetavals = self._Q_opt(bootlist=list(sample)) + thetavals['samples'] = sample + bootstrap_theta.append(thetavals) + + global_bootstrap_theta = task_mgr.allgather_global_data(bootstrap_theta) + bootstrap_theta = pd.DataFrame(global_bootstrap_theta) + + if not return_samples: + del bootstrap_theta['samples'] + + return bootstrap_theta + + def theta_est_leaveNout( + self, lNo, lNo_samples=None, seed=None, return_samples=False + ): + """ + Parameter estimation where N data points are left out of each sample + + Parameters + ---------- + lNo: int + Number of data points to leave out for parameter estimation + lNo_samples: int + Number of leave-N-out samples. If lNo_samples=None, the maximum + number of combinations will be used + seed: int or None, optional + Random seed + return_samples: bool, optional + Return a list of sample numbers that were left out. Default is False. + + Returns + ------- + lNo_theta: pd.DataFrame + Theta values for each sample and (if return_samples = True) + the sample numbers left out of each estimation + """ + + # check if we are using deprecated parmest + if self.pest_deprecated is not None: + return self.pest_deprecated.theta_est_leaveNout( + lNo, lNo_samples=lNo_samples, seed=seed, return_samples=return_samples + ) + + assert isinstance(lNo, int) + assert isinstance(lNo_samples, (type(None), int)) + assert isinstance(seed, (type(None), int)) + assert isinstance(return_samples, bool) + + samplesize = len(self.exp_list) - lNo + + if seed is not None: + np.random.seed(seed) + + global_list = self._get_sample_list(samplesize, lNo_samples, replacement=False) + + task_mgr = utils.ParallelTaskManager(len(global_list)) + local_list = task_mgr.global_to_local_data(global_list) + + lNo_theta = list() + for idx, sample in local_list: + objval, thetavals = self._Q_opt(bootlist=list(sample)) + lNo_s = list(set(range(len(self.exp_list))) - set(sample)) + thetavals['lNo'] = np.sort(lNo_s) + lNo_theta.append(thetavals) + + global_bootstrap_theta = task_mgr.allgather_global_data(lNo_theta) + lNo_theta = pd.DataFrame(global_bootstrap_theta) + + if not return_samples: + del lNo_theta['lNo'] + + return lNo_theta + + def leaveNout_bootstrap_test( + self, lNo, lNo_samples, bootstrap_samples, distribution, alphas, seed=None + ): + """ + Leave-N-out bootstrap test to compare theta values where N data points are + left out to a bootstrap analysis using the remaining data, + results indicate if theta is within a confidence region + determined by the bootstrap analysis + + Parameters + ---------- + lNo: int + Number of data points to leave out for parameter estimation + lNo_samples: int + Leave-N-out sample size. If lNo_samples=None, the maximum number + of combinations will be used + bootstrap_samples: int: + Bootstrap sample size + distribution: string + Statistical distribution used to define a confidence region, + options = 'MVN' for multivariate_normal, 'KDE' for gaussian_kde, + and 'Rect' for rectangular. + alphas: list + List of alpha values used to determine if theta values are inside + or outside the region. + seed: int or None, optional + Random seed + + Returns + ------- + List of tuples with one entry per lNo_sample: + + * The first item in each tuple is the list of N samples that are left + out. + * The second item in each tuple is a DataFrame of theta estimated using + the N samples. + * The third item in each tuple is a DataFrame containing results from + the bootstrap analysis using the remaining samples. + + For each DataFrame a column is added for each value of alpha which + indicates if the theta estimate is in (True) or out (False) of the + alpha region for a given distribution (based on the bootstrap results) + """ + + # check if we are using deprecated parmest + if self.pest_deprecated is not None: + return self.pest_deprecated.leaveNout_bootstrap_test( + lNo, lNo_samples, bootstrap_samples, distribution, alphas, seed=seed + ) + + assert isinstance(lNo, int) + assert isinstance(lNo_samples, (type(None), int)) + assert isinstance(bootstrap_samples, int) + assert distribution in ['Rect', 'MVN', 'KDE'] + assert isinstance(alphas, list) + assert isinstance(seed, (type(None), int)) + + if seed is not None: + np.random.seed(seed) + + global_list = self._get_sample_list(lNo, lNo_samples, replacement=False) + + results = [] + for idx, sample in global_list: + + obj, theta = self.theta_est() + + bootstrap_theta = self.theta_est_bootstrap(bootstrap_samples, seed=seed) + + training, test = self.confidence_region_test( + bootstrap_theta, + distribution=distribution, + alphas=alphas, + test_theta_values=theta, + seed=seed, + ) + + results.append((sample, test, training)) + + return results + + def objective_at_theta(self, theta_values=None, initialize_parmest_model=False): + """ + Objective value for each theta + + Parameters + ---------- + theta_values: pd.DataFrame, columns=theta_names + Values of theta used to compute the objective + + initialize_parmest_model: boolean + If True: Solve square problem instance, build extensive form + of the model for parameter estimation, and set flag + model_initialized to True. Default is False. + + + Returns + ------- + obj_at_theta: pd.DataFrame + Objective value for each theta (infeasible solutions are + omitted). + """ + + # check if we are using deprecated parmest + if self.pest_deprecated is not None: + return self.pest_deprecated.objective_at_theta( + theta_values=theta_values, + initialize_parmest_model=initialize_parmest_model, + ) + + if len(self.estimator_theta_names) == 0: + pass # skip assertion if model has no fitted parameters + else: + # create a local instance of the pyomo model to access model variables and parameters + model_temp = self._create_parmest_model(0) + model_theta_list = self._expand_indexed_unknowns(model_temp) + + # if self.estimator_theta_names is not the same as temp model_theta_list, + # create self.theta_names_updated + if set(self.estimator_theta_names) == set(model_theta_list) and len( + self.estimator_theta_names + ) == len(set(model_theta_list)): + pass + else: + self.theta_names_updated = model_theta_list + + if theta_values is None: + all_thetas = {} # dictionary to store fitted variables + # use appropriate theta names member + theta_names = model_theta_list + else: + assert isinstance(theta_values, pd.DataFrame) + # for parallel code we need to use lists and dicts in the loop + theta_names = theta_values.columns + # # check if theta_names are in model + for theta in list(theta_names): + theta_temp = theta.replace("'", "") # cleaning quotes from theta_names + assert theta_temp in [ + t.replace("'", "") for t in model_theta_list + ], "Theta name {} in 'theta_values' not in 'theta_names' {}".format( + theta_temp, model_theta_list + ) + + assert len(list(theta_names)) == len(model_theta_list) + + all_thetas = theta_values.to_dict('records') + + if all_thetas: + task_mgr = utils.ParallelTaskManager(len(all_thetas)) + local_thetas = task_mgr.global_to_local_data(all_thetas) + else: + if initialize_parmest_model: + task_mgr = utils.ParallelTaskManager( + 1 + ) # initialization performed using just 1 set of theta values + # walk over the mesh, return objective function + all_obj = list() + if len(all_thetas) > 0: + for Theta in local_thetas: + obj, thetvals, worststatus = self._Q_at_theta( + Theta, initialize_parmest_model=initialize_parmest_model + ) + if worststatus != pyo.TerminationCondition.infeasible: + all_obj.append(list(Theta.values()) + [obj]) + # DLW, Aug2018: should we also store the worst solver status? + else: + obj, thetvals, worststatus = self._Q_at_theta( + thetavals={}, initialize_parmest_model=initialize_parmest_model + ) + if worststatus != pyo.TerminationCondition.infeasible: + all_obj.append(list(thetvals.values()) + [obj]) + + global_all_obj = task_mgr.allgather_global_data(all_obj) + dfcols = list(theta_names) + ['obj'] + obj_at_theta = pd.DataFrame(data=global_all_obj, columns=dfcols) + return obj_at_theta + + def likelihood_ratio_test( + self, obj_at_theta, obj_value, alphas, return_thresholds=False + ): + r""" + Likelihood ratio test to identify theta values within a confidence + region using the :math:`\chi^2` distribution + + Parameters + ---------- + obj_at_theta: pd.DataFrame, columns = theta_names + 'obj' + Objective values for each theta value (returned by + objective_at_theta) + obj_value: int or float + Objective value from parameter estimation using all data + alphas: list + List of alpha values to use in the chi2 test + return_thresholds: bool, optional + Return the threshold value for each alpha. Default is False. + + Returns + ------- + LR: pd.DataFrame + Objective values for each theta value along with True or False for + each alpha + thresholds: pd.Series + If return_threshold = True, the thresholds are also returned. + """ + + # check if we are using deprecated parmest + if self.pest_deprecated is not None: + return self.pest_deprecated.likelihood_ratio_test( + obj_at_theta, obj_value, alphas, return_thresholds=return_thresholds + ) + + assert isinstance(obj_at_theta, pd.DataFrame) + assert isinstance(obj_value, (int, float)) + assert isinstance(alphas, list) + assert isinstance(return_thresholds, bool) + + LR = obj_at_theta.copy() + S = len(self.exp_list) + thresholds = {} + for a in alphas: + chi2_val = scipy.stats.chi2.ppf(a, 2) + thresholds[a] = obj_value * ((chi2_val / (S - 2)) + 1) + LR[a] = LR['obj'] < thresholds[a] + + thresholds = pd.Series(thresholds) + + if return_thresholds: + return LR, thresholds + else: + return LR + + def confidence_region_test( + self, theta_values, distribution, alphas, test_theta_values=None, seed=None + ): + """ + Confidence region test to determine if theta values are within a + rectangular, multivariate normal, or Gaussian kernel density distribution + for a range of alpha values + + Parameters + ---------- + theta_values: pd.DataFrame, columns = theta_names + Theta values used to generate a confidence region + (generally returned by theta_est_bootstrap) + distribution: string + Statistical distribution used to define a confidence region, + options = 'MVN' for multivariate_normal, 'KDE' for gaussian_kde, + and 'Rect' for rectangular. + alphas: list + List of alpha values used to determine if theta values are inside + or outside the region. + test_theta_values: pd.Series or pd.DataFrame, keys/columns = theta_names, optional + Additional theta values that are compared to the confidence region + to determine if they are inside or outside. + + Returns + ------- + training_results: pd.DataFrame + Theta value used to generate the confidence region along with True + (inside) or False (outside) for each alpha + test_results: pd.DataFrame + If test_theta_values is not None, returns test theta value along + with True (inside) or False (outside) for each alpha + """ + + # check if we are using deprecated parmest + if self.pest_deprecated is not None: + return self.pest_deprecated.confidence_region_test( + theta_values, distribution, alphas, test_theta_values=test_theta_values + ) + + assert isinstance(theta_values, pd.DataFrame) + assert distribution in ['Rect', 'MVN', 'KDE'] + assert isinstance(alphas, list) + assert isinstance( + test_theta_values, (type(None), dict, pd.Series, pd.DataFrame) + ) + + if isinstance(test_theta_values, (dict, pd.Series)): + test_theta_values = pd.Series(test_theta_values).to_frame().transpose() + + training_results = theta_values.copy() + + if test_theta_values is not None: + test_result = test_theta_values.copy() + + if seed is not None: + np.random.seed(seed) + + for a in alphas: + if distribution == 'Rect': + lb, ub = graphics.fit_rect_dist(theta_values, a) + training_results[a] = (theta_values > lb).all(axis=1) & ( + theta_values < ub + ).all(axis=1) + + if test_theta_values is not None: + # use upper and lower bound from the training set + test_result[a] = (test_theta_values > lb).all(axis=1) & ( + test_theta_values < ub + ).all(axis=1) + + elif distribution == 'MVN': + dist = graphics.fit_mvn_dist(theta_values, seed=seed) + Z = dist.pdf(theta_values) + score = scipy.stats.scoreatpercentile(Z, (1 - a) * 100) + training_results[a] = Z >= score + + if test_theta_values is not None: + # use score from the training set + Z = dist.pdf(test_theta_values) + test_result[a] = Z >= score + + elif distribution == 'KDE': + dist = graphics.fit_kde_dist(theta_values, seed=seed) + Z = dist.pdf(theta_values.transpose()) + score = scipy.stats.scoreatpercentile(Z, (1 - a) * 100) + training_results[a] = Z >= score + + if test_theta_values is not None: + # use score from the training set + Z = dist.pdf(test_theta_values.transpose()) + test_result[a] = Z >= score + + if test_theta_values is not None: + return training_results, test_result + else: + return training_results + + +################################ +# deprecated functions/classes # +################################ + + +@deprecated(version='6.7.2') +def group_data(data, groupby_column_name, use_mean=None): + """ + Group data by scenario + + Parameters + ---------- + data: DataFrame + Data + groupby_column_name: strings + Name of data column which contains scenario numbers + use_mean: list of column names or None, optional + Name of data columns which should be reduced to a single value per + scenario by taking the mean + + Returns + ---------- + grouped_data: list of dictionaries + Grouped data + """ + if use_mean is None: + use_mean_list = [] + else: + use_mean_list = use_mean + + grouped_data = [] + for exp_num, group in data.groupby(data[groupby_column_name]): + d = {} + for col in group.columns: + if col in use_mean_list: + d[col] = group[col].mean() + else: + d[col] = list(group[col]) + grouped_data.append(d) + + return grouped_data + + +class _DeprecatedSecondStageCostExpr(object): + """ + Class to pass objective expression into the Pyomo model + """ + + def __init__(self, ssc_function, data): + self._ssc_function = ssc_function + self._data = data + + def __call__(self, model): + return self._ssc_function(model, self._data) + + +class _DeprecatedEstimator(object): + """ + Parameter estimation class + + Parameters + ---------- + model_function: function + Function that generates an instance of the Pyomo model using 'data' + as the input argument + data: pd.DataFrame, list of dictionaries, list of dataframes, or list of json file names + Data that is used to build an instance of the Pyomo model and build + the objective function + theta_names: list of strings + List of Var names to estimate + obj_function: function, optional + Function used to formulate parameter estimation objective, generally + sum of squared error between measurements and model variables. + If no function is specified, the model is used + "as is" and should be defined with a "FirstStageCost" and + "SecondStageCost" expression that are used to build an objective. + tee: bool, optional + Indicates that ef solver output should be teed + diagnostic_mode: bool, optional + If True, print diagnostics from the solver + solver_options: dict, optional + Provides options to the solver (also the name of an attribute) + """ + + def __init__( + self, + model_function, + data, + theta_names, + obj_function=None, + tee=False, + diagnostic_mode=False, + solver_options=None, + ): + self.model_function = model_function + + assert isinstance( + data, (list, pd.DataFrame) + ), "Data must be a list or DataFrame" + # convert dataframe into a list of dataframes, each row = one scenario + if isinstance(data, pd.DataFrame): + self.callback_data = [ + data.loc[i, :].to_frame().transpose() for i in data.index + ] + else: + self.callback_data = data + assert isinstance( + self.callback_data[0], (dict, pd.DataFrame, str) + ), "The scenarios in data must be a dictionary, DataFrame or filename" + + if len(theta_names) == 0: + self.theta_names = ['parmest_dummy_var'] + else: + self.theta_names = theta_names + + self.obj_function = obj_function + self.tee = tee + self.diagnostic_mode = diagnostic_mode + self.solver_options = solver_options + + self._second_stage_cost_exp = "SecondStageCost" + # boolean to indicate if model is initialized using a square solve + self.model_initialized = False + + def _return_theta_names(self): + """ + Return list of fitted model parameter names + """ + # if fitted model parameter names differ from theta_names created when Estimator object is created + if hasattr(self, 'theta_names_updated'): + return self.theta_names_updated + + else: + return ( + self.theta_names + ) # default theta_names, created when Estimator object is created + + def _create_parmest_model(self, data): + """ + Modify the Pyomo model for parameter estimation + """ + model = self.model_function(data) + + if (len(self.theta_names) == 1) and ( + self.theta_names[0] == 'parmest_dummy_var' + ): + model.parmest_dummy_var = pyo.Var(initialize=1.0) + + # Add objective function (optional) + if self.obj_function: + for obj in model.component_objects(pyo.Objective): + if obj.name in ["Total_Cost_Objective"]: + raise RuntimeError( + "Parmest will not override the existing model Objective named " + + obj.name + ) + obj.deactivate() + + for expr in model.component_data_objects(pyo.Expression): + if expr.name in ["FirstStageCost", "SecondStageCost"]: + raise RuntimeError( + "Parmest will not override the existing model Expression named " + + expr.name + ) + model.FirstStageCost = pyo.Expression(expr=0) + model.SecondStageCost = pyo.Expression( + rule=_DeprecatedSecondStageCostExpr(self.obj_function, data) + ) + + def TotalCost_rule(model): + return model.FirstStageCost + model.SecondStageCost + + model.Total_Cost_Objective = pyo.Objective( + rule=TotalCost_rule, sense=pyo.minimize + ) + + # Convert theta Params to Vars, and unfix theta Vars + model = utils.convert_params_to_vars(model, self.theta_names) + + # Update theta names list to use CUID string representation + for i, theta in enumerate(self.theta_names): + var_cuid = ComponentUID(theta) + var_validate = var_cuid.find_component_on(model) + if var_validate is None: + logger.warning( + "theta_name[%s] (%s) was not found on the model", (i, theta) + ) + else: + try: + # If the component is not a variable, + # this will generate an exception (and the warning + # in the 'except') + var_validate.unfix() + self.theta_names[i] = repr(var_cuid) + except: + logger.warning(theta + ' is not a variable') + + self.parmest_model = model + + return model + + def _instance_creation_callback(self, experiment_number=None, cb_data=None): + # cb_data is a list of dictionaries, list of dataframes, OR list of json file names + exp_data = cb_data[experiment_number] + if isinstance(exp_data, (dict, pd.DataFrame)): + pass + elif isinstance(exp_data, str): + try: + with open(exp_data, 'r') as infile: + exp_data = json.load(infile) + except: + raise RuntimeError(f'Could not read {exp_data} as json') + else: + raise RuntimeError(f'Unexpected data format for cb_data={cb_data}') + model = self._create_parmest_model(exp_data) + + return model + + def _Q_opt( + self, + ThetaVals=None, + solver="ef_ipopt", + return_values=[], + bootlist=None, + calc_cov=False, + cov_n=None, + ): + """ + Set up all thetas as first stage Vars, return resulting theta + values as well as the objective function value. + + """ + if solver == "k_aug": + raise RuntimeError("k_aug no longer supported.") + + # (Bootstrap scenarios will use indirection through the bootlist) + if bootlist is None: + scenario_numbers = list(range(len(self.callback_data))) + scen_names = ["Scenario{}".format(i) for i in scenario_numbers] + else: + scen_names = ["Scenario{}".format(i) for i in range(len(bootlist))] + + # tree_model.CallbackModule = None + outer_cb_data = dict() + outer_cb_data["callback"] = self._instance_creation_callback + if ThetaVals is not None: + outer_cb_data["ThetaVals"] = ThetaVals + if bootlist is not None: + outer_cb_data["BootList"] = bootlist + outer_cb_data["cb_data"] = self.callback_data # None is OK + outer_cb_data["theta_names"] = self.theta_names + + options = {"solver": "ipopt"} + scenario_creator_options = {"cb_data": outer_cb_data} + if use_mpisppy: + ef = sputils.create_EF( + scen_names, + _experiment_instance_creation_callback, + EF_name="_Q_opt", + suppress_warnings=True, + scenario_creator_kwargs=scenario_creator_options, + ) + else: + ef = local_ef.create_EF( + scen_names, + _experiment_instance_creation_callback, + EF_name="_Q_opt", + suppress_warnings=True, + scenario_creator_kwargs=scenario_creator_options, + ) + self.ef_instance = ef + + # Solve the extensive form with ipopt + if solver == "ef_ipopt": + if not calc_cov: + # Do not calculate the reduced hessian + + solver = SolverFactory('ipopt') + if self.solver_options is not None: + for key in self.solver_options: + solver.options[key] = self.solver_options[key] + + solve_result = solver.solve(self.ef_instance, tee=self.tee) + + # The import error will be raised when we attempt to use + # inv_reduced_hessian_barrier below. + # + # elif not asl_available: + # raise ImportError("parmest requires ASL to calculate the " + # "covariance matrix with solver 'ipopt'") + else: + # parmest makes the fitted parameters stage 1 variables + ind_vars = [] + for ndname, Var, solval in ef_nonants(ef): + ind_vars.append(Var) + # calculate the reduced hessian + (solve_result, inv_red_hes) = ( + inverse_reduced_hessian.inv_reduced_hessian_barrier( + self.ef_instance, + independent_variables=ind_vars, + solver_options=self.solver_options, + tee=self.tee, + ) + ) + + if self.diagnostic_mode: + print( + ' Solver termination condition = ', + str(solve_result.solver.termination_condition), + ) + + # assume all first stage are thetas... + thetavals = {} + for ndname, Var, solval in ef_nonants(ef): + # process the name + # the scenarios are blocks, so strip the scenario name + vname = Var.name[Var.name.find(".") + 1 :] + thetavals[vname] = solval + + objval = pyo.value(ef.EF_Obj) + + if calc_cov: + # Calculate the covariance matrix + + # Number of data points considered + n = cov_n + + # Extract number of fitted parameters + l = len(thetavals) + + # Assumption: Objective value is sum of squared errors + sse = objval + + '''Calculate covariance assuming experimental observation errors are + independent and follow a Gaussian + distribution with constant variance. + + The formula used in parmest was verified against equations (7-5-15) and + (7-5-16) in "Nonlinear Parameter Estimation", Y. Bard, 1974. + + This formula is also applicable if the objective is scaled by a constant; + the constant cancels out. (was scaled by 1/n because it computes an + expected value.) + ''' + cov = 2 * sse / (n - l) * inv_red_hes + cov = pd.DataFrame( + cov, index=thetavals.keys(), columns=thetavals.keys() + ) + + thetavals = pd.Series(thetavals) + + if len(return_values) > 0: + var_values = [] + if len(scen_names) > 1: # multiple scenarios + block_objects = self.ef_instance.component_objects( + Block, descend_into=False + ) + else: # single scenario + block_objects = [self.ef_instance] + for exp_i in block_objects: + vals = {} + for var in return_values: + exp_i_var = exp_i.find_component(str(var)) + if ( + exp_i_var is None + ): # we might have a block such as _mpisppy_data + continue + # if value to return is ContinuousSet + if type(exp_i_var) == ContinuousSet: + temp = list(exp_i_var) + else: + temp = [pyo.value(_) for _ in exp_i_var.values()] + if len(temp) == 1: + vals[var] = temp[0] + else: + vals[var] = temp + if len(vals) > 0: + var_values.append(vals) + var_values = pd.DataFrame(var_values) + if calc_cov: + return objval, thetavals, var_values, cov + else: + return objval, thetavals, var_values + + if calc_cov: + return objval, thetavals, cov + else: + return objval, thetavals + + else: + raise RuntimeError("Unknown solver in Q_Opt=" + solver) + + def _Q_at_theta(self, thetavals, initialize_parmest_model=False): + """ + Return the objective function value with fixed theta values. + + Parameters + ---------- + thetavals: dict + A dictionary of theta values. + + initialize_parmest_model: boolean + If True: Solve square problem instance, build extensive form of the model for + parameter estimation, and set flag model_initialized to True + + Returns + ------- + objectiveval: float + The objective function value. + thetavals: dict + A dictionary of all values for theta that were input. + solvertermination: Pyomo TerminationCondition + Tries to return the "worst" solver status across the scenarios. + pyo.TerminationCondition.optimal is the best and + pyo.TerminationCondition.infeasible is the worst. + """ + + optimizer = pyo.SolverFactory('ipopt') + + if len(thetavals) > 0: + dummy_cb = { + "callback": self._instance_creation_callback, + "ThetaVals": thetavals, + "theta_names": self._return_theta_names(), + "cb_data": self.callback_data, + } + else: + dummy_cb = { + "callback": self._instance_creation_callback, + "theta_names": self._return_theta_names(), + "cb_data": self.callback_data, + } + + if self.diagnostic_mode: + if len(thetavals) > 0: + print(' Compute objective at theta = ', str(thetavals)) + else: + print(' Compute objective at initial theta') + + # start block of code to deal with models with no constraints + # (ipopt will crash or complain on such problems without special care) + instance = _experiment_instance_creation_callback("FOO0", None, dummy_cb) + try: # deal with special problems so Ipopt will not crash + first = next(instance.component_objects(pyo.Constraint, active=True)) + active_constraints = True + except: + active_constraints = False + # end block of code to deal with models with no constraints + + WorstStatus = pyo.TerminationCondition.optimal + totobj = 0 + scenario_numbers = list(range(len(self.callback_data))) + if initialize_parmest_model: + # create dictionary to store pyomo model instances (scenarios) + scen_dict = dict() + + for snum in scenario_numbers: + sname = "scenario_NODE" + str(snum) + instance = _experiment_instance_creation_callback(sname, None, dummy_cb) + + if initialize_parmest_model: + # list to store fitted parameter names that will be unfixed + # after initialization + theta_init_vals = [] + # use appropriate theta_names member + theta_ref = self._return_theta_names() + + for i, theta in enumerate(theta_ref): + # Use parser in ComponentUID to locate the component + var_cuid = ComponentUID(theta) + var_validate = var_cuid.find_component_on(instance) + if var_validate is None: + logger.warning( + "theta_name %s was not found on the model", (theta) + ) + else: + try: + if len(thetavals) == 0: + var_validate.fix() + else: + var_validate.fix(thetavals[theta]) + theta_init_vals.append(var_validate) + except: + logger.warning( + 'Unable to fix model parameter value for %s (not a Pyomo model Var)', + (theta), + ) + + if active_constraints: + if self.diagnostic_mode: + print(' Experiment = ', snum) + print(' First solve with special diagnostics wrapper') + (status_obj, solved, iters, time, regu) = ( + utils.ipopt_solve_with_stats( + instance, optimizer, max_iter=500, max_cpu_time=120 + ) + ) + print( + " status_obj, solved, iters, time, regularization_stat = ", + str(status_obj), + str(solved), + str(iters), + str(time), + str(regu), + ) + + results = optimizer.solve(instance) + if self.diagnostic_mode: + print( + 'standard solve solver termination condition=', + str(results.solver.termination_condition), + ) + + if ( + results.solver.termination_condition + != pyo.TerminationCondition.optimal + ): + # DLW: Aug2018: not distinguishing "middlish" conditions + if WorstStatus != pyo.TerminationCondition.infeasible: + WorstStatus = results.solver.termination_condition + if initialize_parmest_model: + if self.diagnostic_mode: + print( + "Scenario {:d} infeasible with initialized parameter values".format( + snum + ) + ) + else: + if initialize_parmest_model: + if self.diagnostic_mode: + print( + "Scenario {:d} initialization successful with initial parameter values".format( + snum + ) + ) + if initialize_parmest_model: + # unfix parameters after initialization + for theta in theta_init_vals: + theta.unfix() + scen_dict[sname] = instance + else: + if initialize_parmest_model: + # unfix parameters after initialization + for theta in theta_init_vals: + theta.unfix() + scen_dict[sname] = instance + + objobject = getattr(instance, self._second_stage_cost_exp) + objval = pyo.value(objobject) + totobj += objval + + retval = totobj / len(scenario_numbers) # -1?? + if initialize_parmest_model and not hasattr(self, 'ef_instance'): + # create extensive form of the model using scenario dictionary + if len(scen_dict) > 0: + for scen in scen_dict.values(): + scen._mpisppy_probability = 1 / len(scen_dict) + + if use_mpisppy: + EF_instance = sputils._create_EF_from_scen_dict( + scen_dict, + EF_name="_Q_at_theta", + # suppress_warnings=True + ) + else: + EF_instance = local_ef._create_EF_from_scen_dict( + scen_dict, EF_name="_Q_at_theta", nonant_for_fixed_vars=True + ) + + self.ef_instance = EF_instance + # set self.model_initialized flag to True to skip extensive form model + # creation using theta_est() + self.model_initialized = True + + # return initialized theta values + if len(thetavals) == 0: + # use appropriate theta_names member + theta_ref = self._return_theta_names() + for i, theta in enumerate(theta_ref): + thetavals[theta] = theta_init_vals[i]() + + return retval, thetavals, WorstStatus + + def _get_sample_list(self, samplesize, num_samples, replacement=True): + samplelist = list() + + scenario_numbers = list(range(len(self.callback_data))) + + if num_samples is None: + # This could get very large + for i, l in enumerate(combinations(scenario_numbers, samplesize)): + samplelist.append((i, np.sort(l))) + else: + for i in range(num_samples): + attempts = 0 + unique_samples = 0 # check for duplicates in each sample + duplicate = False # check for duplicates between samples + while (unique_samples <= len(self._return_theta_names())) and ( + not duplicate + ): + sample = np.random.choice( + scenario_numbers, samplesize, replace=replacement + ) + sample = np.sort(sample).tolist() + unique_samples = len(np.unique(sample)) + if sample in samplelist: + duplicate = True + + attempts += 1 + if attempts > num_samples: # arbitrary timeout limit + raise RuntimeError( + """Internal error: timeout constructing + a sample, the dim of theta may be too + close to the samplesize""" + ) + + samplelist.append((i, sample)) + + return samplelist + + def theta_est( + self, solver="ef_ipopt", return_values=[], calc_cov=False, cov_n=None + ): + """ + Parameter estimation using all scenarios in the data + + Parameters + ---------- + solver: string, optional + Currently only "ef_ipopt" is supported. Default is "ef_ipopt". + return_values: list, optional + List of Variable names, used to return values from the model for data reconciliation + calc_cov: boolean, optional + If True, calculate and return the covariance matrix (only for "ef_ipopt" solver) + cov_n: int, optional + If calc_cov=True, then the user needs to supply the number of datapoints + that are used in the objective function + + Returns + ------- + objectiveval: float + The objective function value + thetavals: pd.Series + Estimated values for theta + variable values: pd.DataFrame + Variable values for each variable name in return_values (only for solver='ef_ipopt') + cov: pd.DataFrame + Covariance matrix of the fitted parameters (only for solver='ef_ipopt') + """ + assert isinstance(solver, str) + assert isinstance(return_values, list) + assert isinstance(calc_cov, bool) + if calc_cov: + assert isinstance( + cov_n, int + ), "The number of datapoints that are used in the objective function is required to calculate the covariance matrix" + assert cov_n > len( + self._return_theta_names() + ), "The number of datapoints must be greater than the number of parameters to estimate" + + return self._Q_opt( + solver=solver, + return_values=return_values, + bootlist=None, + calc_cov=calc_cov, + cov_n=cov_n, + ) + + def theta_est_bootstrap( + self, + bootstrap_samples, + samplesize=None, + replacement=True, + seed=None, + return_samples=False, + ): + """ + Parameter estimation using bootstrap resampling of the data + + Parameters + ---------- + bootstrap_samples: int + Number of bootstrap samples to draw from the data + samplesize: int or None, optional + Size of each bootstrap sample. If samplesize=None, samplesize will be + set to the number of samples in the data + replacement: bool, optional + Sample with or without replacement + seed: int or None, optional + Random seed + return_samples: bool, optional + Return a list of sample numbers used in each bootstrap estimation + + Returns + ------- + bootstrap_theta: pd.DataFrame + Theta values for each sample and (if return_samples = True) + the sample numbers used in each estimation + """ + assert isinstance(bootstrap_samples, int) + assert isinstance(samplesize, (type(None), int)) + assert isinstance(replacement, bool) + assert isinstance(seed, (type(None), int)) + assert isinstance(return_samples, bool) + + if samplesize is None: + samplesize = len(self.callback_data) + + if seed is not None: + np.random.seed(seed) + + global_list = self._get_sample_list(samplesize, bootstrap_samples, replacement) + + task_mgr = utils.ParallelTaskManager(bootstrap_samples) + local_list = task_mgr.global_to_local_data(global_list) + + bootstrap_theta = list() + for idx, sample in local_list: + objval, thetavals = self._Q_opt(bootlist=list(sample)) + thetavals['samples'] = sample + bootstrap_theta.append(thetavals) + + global_bootstrap_theta = task_mgr.allgather_global_data(bootstrap_theta) + bootstrap_theta = pd.DataFrame(global_bootstrap_theta) + + if not return_samples: + del bootstrap_theta['samples'] + + return bootstrap_theta + + def theta_est_leaveNout( + self, lNo, lNo_samples=None, seed=None, return_samples=False + ): + """ + Parameter estimation where N data points are left out of each sample + + Parameters + ---------- + lNo: int + Number of data points to leave out for parameter estimation + lNo_samples: int + Number of leave-N-out samples. If lNo_samples=None, the maximum + number of combinations will be used + seed: int or None, optional + Random seed + return_samples: bool, optional + Return a list of sample numbers that were left out + + Returns + ------- + lNo_theta: pd.DataFrame + Theta values for each sample and (if return_samples = True) + the sample numbers left out of each estimation + """ + assert isinstance(lNo, int) + assert isinstance(lNo_samples, (type(None), int)) + assert isinstance(seed, (type(None), int)) + assert isinstance(return_samples, bool) + + samplesize = len(self.callback_data) - lNo + + if seed is not None: + np.random.seed(seed) + + global_list = self._get_sample_list(samplesize, lNo_samples, replacement=False) + + task_mgr = utils.ParallelTaskManager(len(global_list)) + local_list = task_mgr.global_to_local_data(global_list) + + lNo_theta = list() + for idx, sample in local_list: + objval, thetavals = self._Q_opt(bootlist=list(sample)) + lNo_s = list(set(range(len(self.callback_data))) - set(sample)) + thetavals['lNo'] = np.sort(lNo_s) + lNo_theta.append(thetavals) + + global_bootstrap_theta = task_mgr.allgather_global_data(lNo_theta) + lNo_theta = pd.DataFrame(global_bootstrap_theta) + + if not return_samples: + del lNo_theta['lNo'] + + return lNo_theta + + def leaveNout_bootstrap_test( + self, lNo, lNo_samples, bootstrap_samples, distribution, alphas, seed=None + ): + """ + Leave-N-out bootstrap test to compare theta values where N data points are + left out to a bootstrap analysis using the remaining data, + results indicate if theta is within a confidence region + determined by the bootstrap analysis + + Parameters + ---------- + lNo: int + Number of data points to leave out for parameter estimation + lNo_samples: int + Leave-N-out sample size. If lNo_samples=None, the maximum number + of combinations will be used + bootstrap_samples: int: + Bootstrap sample size + distribution: string + Statistical distribution used to define a confidence region, + options = 'MVN' for multivariate_normal, 'KDE' for gaussian_kde, + and 'Rect' for rectangular. + alphas: list + List of alpha values used to determine if theta values are inside + or outside the region. + seed: int or None, optional + Random seed + + Returns + ---------- + List of tuples with one entry per lNo_sample: + + * The first item in each tuple is the list of N samples that are left + out. + * The second item in each tuple is a DataFrame of theta estimated using + the N samples. + * The third item in each tuple is a DataFrame containing results from + the bootstrap analysis using the remaining samples. + + For each DataFrame a column is added for each value of alpha which + indicates if the theta estimate is in (True) or out (False) of the + alpha region for a given distribution (based on the bootstrap results) + """ + assert isinstance(lNo, int) + assert isinstance(lNo_samples, (type(None), int)) + assert isinstance(bootstrap_samples, int) + assert distribution in ['Rect', 'MVN', 'KDE'] + assert isinstance(alphas, list) + assert isinstance(seed, (type(None), int)) + + if seed is not None: + np.random.seed(seed) + + data = self.callback_data.copy() + + global_list = self._get_sample_list(lNo, lNo_samples, replacement=False) + + results = [] + for idx, sample in global_list: + # Reset callback_data to only include the sample + self.callback_data = [data[i] for i in sample] + + obj, theta = self.theta_est() + + # Reset callback_data to include all scenarios except the sample + self.callback_data = [data[i] for i in range(len(data)) if i not in sample] + + bootstrap_theta = self.theta_est_bootstrap(bootstrap_samples) + + training, test = self.confidence_region_test( + bootstrap_theta, + distribution=distribution, + alphas=alphas, + test_theta_values=theta, + ) + + results.append((sample, test, training)) + + # Reset callback_data (back to full data set) + self.callback_data = data + + return results + + def objective_at_theta(self, theta_values=None, initialize_parmest_model=False): + """ + Objective value for each theta + + Parameters + ---------- + theta_values: pd.DataFrame, columns=theta_names + Values of theta used to compute the objective + + initialize_parmest_model: boolean + If True: Solve square problem instance, build extensive form of the model for + parameter estimation, and set flag model_initialized to True + + + Returns + ------- + obj_at_theta: pd.DataFrame + Objective value for each theta (infeasible solutions are + omitted). + """ + if len(self.theta_names) == 1 and self.theta_names[0] == 'parmest_dummy_var': + pass # skip assertion if model has no fitted parameters + else: + # create a local instance of the pyomo model to access model variables and parameters + model_temp = self._create_parmest_model(self.callback_data[0]) + model_theta_list = [] # list to store indexed and non-indexed parameters + # iterate over original theta_names + for theta_i in self.theta_names: + var_cuid = ComponentUID(theta_i) + var_validate = var_cuid.find_component_on(model_temp) + # check if theta in theta_names are indexed + try: + # get component UID of Set over which theta is defined + set_cuid = ComponentUID(var_validate.index_set()) + # access and iterate over the Set to generate theta names as they appear + # in the pyomo model + set_validate = set_cuid.find_component_on(model_temp) + for s in set_validate: + self_theta_temp = repr(var_cuid) + "[" + repr(s) + "]" + # generate list of theta names + model_theta_list.append(self_theta_temp) + # if theta is not indexed, copy theta name to list as-is + except AttributeError: + self_theta_temp = repr(var_cuid) + model_theta_list.append(self_theta_temp) + except: + raise + # if self.theta_names is not the same as temp model_theta_list, + # create self.theta_names_updated + if set(self.theta_names) == set(model_theta_list) and len( + self.theta_names + ) == set(model_theta_list): + pass + else: + self.theta_names_updated = model_theta_list + + if theta_values is None: + all_thetas = {} # dictionary to store fitted variables + # use appropriate theta names member + theta_names = self._return_theta_names() + else: + assert isinstance(theta_values, pd.DataFrame) + # for parallel code we need to use lists and dicts in the loop + theta_names = theta_values.columns + # # check if theta_names are in model + for theta in list(theta_names): + theta_temp = theta.replace("'", "") # cleaning quotes from theta_names + + assert theta_temp in [ + t.replace("'", "") for t in model_theta_list + ], "Theta name {} in 'theta_values' not in 'theta_names' {}".format( + theta_temp, model_theta_list + ) + assert len(list(theta_names)) == len(model_theta_list) + + all_thetas = theta_values.to_dict('records') + + if all_thetas: + task_mgr = utils.ParallelTaskManager(len(all_thetas)) + local_thetas = task_mgr.global_to_local_data(all_thetas) + else: + if initialize_parmest_model: + task_mgr = utils.ParallelTaskManager( + 1 + ) # initialization performed using just 1 set of theta values + # walk over the mesh, return objective function + all_obj = list() + if len(all_thetas) > 0: + for Theta in local_thetas: + obj, thetvals, worststatus = self._Q_at_theta( + Theta, initialize_parmest_model=initialize_parmest_model + ) + if worststatus != pyo.TerminationCondition.infeasible: + all_obj.append(list(Theta.values()) + [obj]) + # DLW, Aug2018: should we also store the worst solver status? + else: + obj, thetvals, worststatus = self._Q_at_theta( + thetavals={}, initialize_parmest_model=initialize_parmest_model + ) + if worststatus != pyo.TerminationCondition.infeasible: + all_obj.append(list(thetvals.values()) + [obj]) + + global_all_obj = task_mgr.allgather_global_data(all_obj) + dfcols = list(theta_names) + ['obj'] + obj_at_theta = pd.DataFrame(data=global_all_obj, columns=dfcols) + return obj_at_theta + + def likelihood_ratio_test( + self, obj_at_theta, obj_value, alphas, return_thresholds=False + ): + r""" + Likelihood ratio test to identify theta values within a confidence + region using the :math:`\chi^2` distribution + + Parameters + ---------- + obj_at_theta: pd.DataFrame, columns = theta_names + 'obj' + Objective values for each theta value (returned by + objective_at_theta) + obj_value: int or float + Objective value from parameter estimation using all data + alphas: list + List of alpha values to use in the chi2 test + return_thresholds: bool, optional + Return the threshold value for each alpha + + Returns + ------- + LR: pd.DataFrame + Objective values for each theta value along with True or False for + each alpha + thresholds: pd.Series + If return_threshold = True, the thresholds are also returned. + """ + assert isinstance(obj_at_theta, pd.DataFrame) + assert isinstance(obj_value, (int, float)) + assert isinstance(alphas, list) + assert isinstance(return_thresholds, bool) + + LR = obj_at_theta.copy() + S = len(self.callback_data) + thresholds = {} + for a in alphas: + chi2_val = scipy.stats.chi2.ppf(a, 2) + thresholds[a] = obj_value * ((chi2_val / (S - 2)) + 1) + LR[a] = LR['obj'] < thresholds[a] + + thresholds = pd.Series(thresholds) + + if return_thresholds: + return LR, thresholds + else: + return LR + + def confidence_region_test( + self, theta_values, distribution, alphas, test_theta_values=None + ): + """ + Confidence region test to determine if theta values are within a + rectangular, multivariate normal, or Gaussian kernel density distribution + for a range of alpha values + + Parameters + ---------- + theta_values: pd.DataFrame, columns = theta_names + Theta values used to generate a confidence region + (generally returned by theta_est_bootstrap) + distribution: string + Statistical distribution used to define a confidence region, + options = 'MVN' for multivariate_normal, 'KDE' for gaussian_kde, + and 'Rect' for rectangular. + alphas: list + List of alpha values used to determine if theta values are inside + or outside the region. + test_theta_values: pd.Series or pd.DataFrame, keys/columns = theta_names, optional + Additional theta values that are compared to the confidence region + to determine if they are inside or outside. + + Returns + training_results: pd.DataFrame + Theta value used to generate the confidence region along with True + (inside) or False (outside) for each alpha + test_results: pd.DataFrame + If test_theta_values is not None, returns test theta value along + with True (inside) or False (outside) for each alpha + """ + assert isinstance(theta_values, pd.DataFrame) + assert distribution in ['Rect', 'MVN', 'KDE'] + assert isinstance(alphas, list) + assert isinstance( + test_theta_values, (type(None), dict, pd.Series, pd.DataFrame) + ) + + if isinstance(test_theta_values, (dict, pd.Series)): + test_theta_values = pd.Series(test_theta_values).to_frame().transpose() + + training_results = theta_values.copy() + + if test_theta_values is not None: + test_result = test_theta_values.copy() + + for a in alphas: + if distribution == 'Rect': + lb, ub = graphics.fit_rect_dist(theta_values, a) + training_results[a] = (theta_values > lb).all(axis=1) & ( + theta_values < ub + ).all(axis=1) + + if test_theta_values is not None: + # use upper and lower bound from the training set + test_result[a] = (test_theta_values > lb).all(axis=1) & ( + test_theta_values < ub + ).all(axis=1) + + elif distribution == 'MVN': + dist = graphics.fit_mvn_dist(theta_values) + Z = dist.pdf(theta_values) + score = scipy.stats.scoreatpercentile(Z, (1 - a) * 100) + training_results[a] = Z >= score + + if test_theta_values is not None: + # use score from the training set + Z = dist.pdf(test_theta_values) + test_result[a] = Z >= score + + elif distribution == 'KDE': + dist = graphics.fit_kde_dist(theta_values) + Z = dist.pdf(theta_values.transpose()) + score = scipy.stats.scoreatpercentile(Z, (1 - a) * 100) + training_results[a] = Z >= score + + if test_theta_values is not None: + # use score from the training set + Z = dist.pdf(test_theta_values.transpose()) + test_result[a] = Z >= score + + if test_theta_values is not None: + return training_results, test_result + else: + return training_results From 4e09d33b4cab1f7445460e2fe82b7f1470839597 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 19 Feb 2026 00:26:06 -0500 Subject: [PATCH 26/32] Ran black --- pyomo/contrib/parmest/parmest_old.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/pyomo/contrib/parmest/parmest_old.py b/pyomo/contrib/parmest/parmest_old.py index 0ee63e8cb8e..2d5cab7c572 100644 --- a/pyomo/contrib/parmest/parmest_old.py +++ b/pyomo/contrib/parmest/parmest_old.py @@ -554,7 +554,9 @@ def _generate_initial_theta( ) # Check if the user provided dataframe has the same theta names as the model # if not, raise an error - if not all(theta in theta_names for theta in user_provided_df.columns): + if not all( + theta in theta_names for theta in user_provided_df.columns + ): raise ValueError( "The user provided dataframe must have the same theta names as the model." ) @@ -615,7 +617,7 @@ def _instance_creation_callback(self, experiment_number=None, cb_data=None): model = self._create_parmest_model(experiment_number) return model - # TODO: Add a way to pass in a parmest_model to this function, currently cannot + # TODO: Add a way to pass in a parmest_model to this function, currently cannot # access the model within the build function. # I need to check, if I use the update model utility BEFORE calling _Q_opt, does it still @@ -699,7 +701,7 @@ def _Q_opt( for ndname, Var, solval in ef_nonants(ef): ind_vars.append(Var) # calculate the reduced hessian - (solve_result, inv_red_hes) = ( + solve_result, inv_red_hes = ( inverse_reduced_hessian.inv_reduced_hessian_barrier( self.ef_instance, independent_variables=ind_vars, @@ -900,7 +902,7 @@ def _Q_at_theta(self, thetavals, initialize_parmest_model=False): if self.diagnostic_mode: print(' Experiment = ', snum) print(' First solve with special diagnostics wrapper') - (status_obj, solved, iters, time, regu) = ( + status_obj, solved, iters, time, regu = ( utils.ipopt_solve_with_stats( instance, optimizer, max_iter=500, max_cpu_time=120 ) @@ -1018,11 +1020,9 @@ def _get_sample_list(self, samplesize, num_samples, replacement=True): attempts += 1 if attempts > num_samples: # arbitrary timeout limit - raise RuntimeError( - """Internal error: timeout constructing + raise RuntimeError("""Internal error: timeout constructing a sample, the dim of theta may be too - close to the samplesize""" - ) + close to the samplesize""") samplelist.append((i, sample)) @@ -2072,7 +2072,7 @@ def _Q_opt( for ndname, Var, solval in ef_nonants(ef): ind_vars.append(Var) # calculate the reduced hessian - (solve_result, inv_red_hes) = ( + solve_result, inv_red_hes = ( inverse_reduced_hessian.inv_reduced_hessian_barrier( self.ef_instance, independent_variables=ind_vars, @@ -2268,7 +2268,7 @@ def _Q_at_theta(self, thetavals, initialize_parmest_model=False): if self.diagnostic_mode: print(' Experiment = ', snum) print(' First solve with special diagnostics wrapper') - (status_obj, solved, iters, time, regu) = ( + status_obj, solved, iters, time, regu = ( utils.ipopt_solve_with_stats( instance, optimizer, max_iter=500, max_cpu_time=120 ) @@ -2386,11 +2386,9 @@ def _get_sample_list(self, samplesize, num_samples, replacement=True): attempts += 1 if attempts > num_samples: # arbitrary timeout limit - raise RuntimeError( - """Internal error: timeout constructing + raise RuntimeError("""Internal error: timeout constructing a sample, the dim of theta may be too - close to the samplesize""" - ) + close to the samplesize""") samplelist.append((i, sample)) From 12d0af1edd87fe4f4bb6c27a8c0633317447f764 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Thu, 19 Feb 2026 01:01:35 -0500 Subject: [PATCH 27/32] Made quick working example, and small modification for multistart --- .../reactor_design/multistart_example.py | 51 +++++++++++ .../rooney_biegler/multistart_example.py | 57 ++++++++++++ pyomo/contrib/parmest/parmest.py | 87 ++++++++++++++++++- 3 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 pyomo/contrib/parmest/examples/reactor_design/multistart_example.py create mode 100644 pyomo/contrib/parmest/examples/rooney_biegler/multistart_example.py diff --git a/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py new file mode 100644 index 00000000000..9008cd650c4 --- /dev/null +++ b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py @@ -0,0 +1,51 @@ +# ____________________________________________________________________________________ +# +# 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 = [] + for i in range(data.shape[0]): + exp_list.append(ReactorDesignExperiment(data, i)) + + # View one model + # exp0_model = exp_list[0].get_labeled_model() + # exp0_model.pprint() + + pest = parmest.Estimator(exp_list, obj_function='SSE') + + # Parameter estimation + obj, theta = pest.theta_est() + + # Find the objective value at each theta estimate + k1 = [0.8, 1.6, 2.4] + k2 = [1.6, 2.4, 3.2] + k3 = [0.00016, 0.00032, 0.005] + theta_vals = pd.DataFrame(list(product(k1, k2, k3)), columns=["k1", "k2", "k3"]) + multistart_results = pest.theta_est_multistart(theta_vals) + + print(multistart_results) + + +if __name__ == "__main__": + main() diff --git a/pyomo/contrib/parmest/examples/rooney_biegler/multistart_example.py b/pyomo/contrib/parmest/examples/rooney_biegler/multistart_example.py new file mode 100644 index 00000000000..228feb7387b --- /dev/null +++ b/pyomo/contrib/parmest/examples/rooney_biegler/multistart_example.py @@ -0,0 +1,57 @@ +# ____________________________________________________________________________________ +# +# 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'], + ) + + # Sum of squared error function + def SSE(model): + expr = (model.experiment_outputs[model.y] - model.y) ** 2 + return expr + + # 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() + + # Create an instance of the parmest estimator + pest = parmest.Estimator(exp_list, obj_function=SSE, tee=True) + + # Parameter estimation + obj, theta = pest.theta_est() + + # Find the objective value at each theta estimate + asym = np.arange(10, 30, 2) + rate = np.arange(0, 1.5, 0.1) + theta_vals = pd.DataFrame( + list(product(asym, rate)), columns=['asymptote', 'rate_constant'] + ) + multistart_results = pest.theta_est_multistart(theta_vals) + print(multistart_results) + + +if __name__ == "__main__": + main() diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index c1292a8cfe1..6efaac70651 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -986,7 +986,9 @@ def _instance_creation_callback(self, experiment_number=None, cb_data=None): model = self._create_parmest_model(experiment_number) return model - def _create_scenario_blocks(self, bootlist=None, theta_vals=None, fix_theta=False): + def _create_scenario_blocks( + self, bootlist=None, theta_vals=None, fix_theta=False, multistart=False + ): # Create scenario block structure """ Create scenario blocks for parameter estimation @@ -1097,6 +1099,7 @@ def _Q_opt( calc_cov=NOTSET, cov_n=NOTSET, fix_theta=False, + multistart=False, ): ''' Making new version of _Q_opt that uses scenario blocks, similar to DoE. @@ -1176,7 +1179,7 @@ def _Q_opt( # Separate handling of termination conditions for _Q_at_theta vs _Q_opt # If not fixing theta, ensure optimal termination of the solve to return result - if not fix_theta: + if not fix_theta and not multistart: # Ensure optimal termination assert_optimal_termination(solve_result) # If fixing theta, capture termination condition if not optimal unless infeasible @@ -1210,7 +1213,7 @@ def _Q_opt( self.estimated_theta = theta_estimates # If fixing theta, return objective value, theta estimates, and worst status - if fix_theta: + if fix_theta or multistart: return obj_value, theta_estimates, worst_status # Return theta estimates as a pandas Series @@ -1891,6 +1894,84 @@ def leaveNout_bootstrap_test( return results + # Updated version that uses _Q_opt + def theta_est_multistart(self, theta_values=None): + """ + Objective value for each theta, solving parameter estimation problem for each theta value provided. + + Parameters + ---------- + theta_values: pd.DataFrame, columns=theta_names + Values of theta used to compute the objective + + Returns + ------- + obj_at_theta: pd.DataFrame + Objective value for each theta (infeasible solutions are + omitted). + """ + + if theta_values is None: + all_thetas = {} # dictionary to store fitted variables + # use appropriate theta names member + # Get theta names from fresh parmest model, assuming this can be called + # directly after creating Estimator. + theta_names = self._expand_indexed_unknowns(self._create_parmest_model(0)) + else: + assert isinstance(theta_values, pd.DataFrame) + # for parallel code we need to use lists and dicts in the loop + theta_names = theta_values.columns + # # check if theta_names are in model + # Clean names, ignore quotes, and compare sets + clean_provided = [t.replace("'", "") for t in theta_names] + clean_expected = [ + t.replace("'", "") + for t in self._expand_indexed_unknowns(self._create_parmest_model(0)) + ] + # If they do not match, raise error + if set(clean_provided) != set(clean_expected): + raise ValueError( + f"Provided theta values {clean_provided} do not match expected theta names {clean_expected}." + ) + # Rename columns using cleaned names + if set(clean_provided) != set(theta_names): + theta_values.columns = clean_provided + + # Convert to list of dicts for parallel processing + all_thetas = theta_values.to_dict('records') + + # Initialize task manager + num_tasks = len(all_thetas) if all_thetas else 1 + task_mgr = utils.ParallelTaskManager(num_tasks) + + # Use local theta values for each task if all_thetas is provided, else empty list + if all_thetas: + local_thetas = task_mgr.global_to_local_data(all_thetas) + + # walk over the mesh, return objective function + all_obj = list() + if len(all_thetas) > 0: + print("Running multistart parameter estimation...") + for Theta in local_thetas: + obj, thetvals, worststatus = self._Q_opt( + theta_vals=Theta, multistart=True + ) + if worststatus != pyo.TerminationCondition.infeasible: + # Make list out of + # Append original theta values, objective value, and estimated theta values to all_obj + all_obj.append( + list(Theta.values()) + [obj] + list(thetvals.values()) + ) + else: + obj, thetvals, worststatus = self._Q_opt(theta_vals=None, multistart=True) + if worststatus != pyo.TerminationCondition.infeasible: + all_obj.append(list(thetvals.values()) + [obj]) + + global_all_obj = task_mgr.allgather_global_data(all_obj) + dfcols = list(theta_names) + ['obj'] + list(thetvals.keys()) + obj_at_theta = pd.DataFrame(data=global_all_obj, columns=dfcols) + return obj_at_theta + # Updated version that uses _Q_opt def objective_at_theta(self, theta_values=None, initialize_parmest_model=False): """ From 9ccfba483ca12353d294f1423f5efa9c68f7b0e2 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Tue, 3 Mar 2026 00:33:04 -0500 Subject: [PATCH 28/32] Added theta generation and old multistart over --- pyomo/contrib/parmest/parmest.py | 354 ++++ pyomo/contrib/parmest/parmest_old.py | 2883 -------------------------- 2 files changed, 354 insertions(+), 2883 deletions(-) delete mode 100644 pyomo/contrib/parmest/parmest_old.py diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 6efaac70651..8358138764e 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -1087,6 +1087,141 @@ def total_obj(m): model.Obj = pyo.Objective(rule=total_obj, sense=pyo.minimize) return model + + # TODO: Make so this generates the initial DATAFRAME, not the entire list of values. + # Make new private method, _generate_initial_theta: + # This method will be used to generate the initial theta values for multistart + # optimization. It will take the theta names and the initial theta values + # and return a dictionary of theta names and their corresponding values. + def _generate_initial_theta( + self, + parmest_model=None, + seed=None, + n_restarts=None, + multistart_sampling_method=None, + user_provided_df=None, + ): + """ + Generate initial theta values for multistart optimization using selected sampling method. + """ + # Locate the unknown parameters in the model from the suffix + suffix_params = parmest_model.unknown_parameters + + # Get the VarData objects from the suffix + theta_vars = list(suffix_params.keys()) + + # Extract names, starting values, and bounds for the theta variables + theta_names = [v.name for v in theta_vars] + initial_theta = np.array([v.value for v in theta_vars]) + lower_bound = np.array([v.lb for v in theta_vars]) + upper_bound = np.array([v.ub for v in theta_vars]) + + # Check if the lower and upper bounds are defined + if any(bound is None for bound in lower_bound) or any( + bound is None for bound in upper_bound + ): + raise ValueError( + "The lower and upper bounds for the theta values must be defined." + ) + + if multistart_sampling_method == "uniform_random": + # Generate random theta values using uniform distribution, with set seed for reproducibility + np.random.seed(seed) + # Generate random theta values for each restart (n_restarts x len(theta_names)) + theta_vals_multistart = np.random.uniform( + low=lower_bound, high=upper_bound, size=(n_restarts, len(theta_names)) + ) + + elif multistart_sampling_method == "latin_hypercube": + # Generate theta values using Latin hypercube sampling or Sobol sampling + # Generate theta values using Latin hypercube sampling + # Create a Latin Hypercube sampler that uses the dimensions of the theta names + sampler = scipy.stats.qmc.LatinHypercube(d=len(theta_names), seed=seed) + # Generate random samples in the range of [0, 1] for number of restarts + samples = sampler.random(n=n_restarts) + # Resulting samples should be size (n_restarts, len(theta_names)) + + elif multistart_sampling_method == "sobol_sampling": + sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) + # Generate theta values using Sobol sampling + # The first value of the Sobol sequence is 0, so we skip it + samples = sampler.random(n=n_restarts + 1)[1:] + + elif multistart_sampling_method == "user_provided_values": + # Add user provided dataframe option + if user_provided_df is not None: + + if isinstance(user_provided_df, pd.DataFrame): + # Check if the user provided dataframe has the same number of rows as the number of restarts + if user_provided_df.shape[0] != n_restarts: + raise ValueError( + "The user provided dataframe must have the same number of rows as the number of restarts." + ) + # Check if the user provided dataframe has the same number of columns as the number of theta names + if user_provided_df.shape[1] != len(theta_names): + raise ValueError( + "The user provided dataframe must have the same number of columns as the number of theta names." + ) + # Check if the user provided dataframe has the same theta names as the model + # if not, raise an error + if not all( + theta in theta_names for theta in user_provided_df.columns + ): + raise ValueError( + "The user provided dataframe must have the same theta names as the model." + ) + # If all checks pass, return the user provided dataframe + theta_vals_multistart = user_provided_df.iloc[ + 0 : len(initial_theta) + ].values + else: + raise ValueError( + "The user must provide a pandas dataframe to use the 'user_provided_values' method." + ) + + else: + raise ValueError( + "Invalid sampling method. Choose 'uniform_random', 'latin_hypercube', 'sobol_sampling' or 'user_provided_values'." + ) + + if ( + multistart_sampling_method == "sobol_sampling" + or multistart_sampling_method == "latin_hypercube" + ): + # Scale the samples to the range of the lower and upper bounds for each theta in theta_names + # The samples are in the range [0, 1], so we scale them to the range of the lower and upper bounds + theta_vals_multistart = np.array( + [lower_bound + (upper_bound - lower_bound) * theta for theta in samples] + ) + + # Create a DataFrame where each row is an initial theta vector for a restart, + # columns are theta_names, and values are the initial theta values for each restart + if multistart_sampling_method == "user_provided_values": + # If user_provided_values is a DataFrame, use its columns and values directly + if isinstance(user_provided_df, pd.DataFrame): + df_multistart = user_provided_df.copy() + df_multistart.columns = theta_names + else: + df_multistart = pd.DataFrame(theta_vals_multistart, columns=theta_names) + else: + # Ensure theta_vals_multistart is 2D (n_restarts, len(theta_names)) + arr = np.atleast_2d(theta_vals_multistart) + if arr.shape[0] == 1 and n_restarts > 1: + arr = np.tile(arr, (n_restarts, 1)) + df_multistart = pd.DataFrame(arr, columns=theta_names) + + # Add columns for output info, initialized as nan + for name in theta_names: + df_multistart[f'converged_{name}'] = np.nan + df_multistart["initial objective"] = np.nan + df_multistart["final objective"] = np.nan + df_multistart["solver termination"] = np.nan + df_multistart["solve_time"] = np.nan + + # Debugging output + # print(df_multistart) + + return df_multistart # Redesigned _Q_opt method using scenario blocks, and combined with # _Q_at_theta structure. @@ -1894,6 +2029,225 @@ def leaveNout_bootstrap_test( return results + ''' + # TODO: Make the user provide a list of values, not the whole data frame + # TODO: Add a way to print the empty data_frame before solve so it can be previewed beforehand + # TODO: Fix so the theta values are generated at each iteration, not all beforehand in _generate_initial_theta + # Fix _generate_initial_theta to return an empty DataFrame first + # TODO: Add save model option to save the model after each iteration or at the end of the multistart + def theta_est_multistart( + self, + n_restarts=20, + multistart_sampling_method="uniform_random", + user_provided_list=None, + seed=None, + save_results=False, + theta_vals=None, + solver="ef_ipopt", + file_name="multistart_results.csv", + return_values=[], + ): + """ + Parameter estimation using multistart optimization + + Parameters + ---------- + n_restarts: int, optional + Number of restarts for multistart. Default is 1. + multistart_sampling_method: string, optional + Method used to sample theta values. Options are "uniform_random", "latin_hypercube", "sobol_sampling", or "user_provided_values". + Default is "uniform_random". + buffer: int, optional + Number of iterations to save results dynamically if save_results=True. Default is 10. + user_provided_df: pd.DataFrame, optional + User provided array or dataframe of theta values for multistart optimization. + seed: int, optional + Random seed for reproducibility. + save_results: bool, optional + If True, intermediate and final results are saved to file_name. + theta_vals: pd.DataFrame, optional + Initial theta values for restarts (overrides sampling). + solver: string, optional + Currently only "ef_ipopt" is supported. Default is "ef_ipopt". + file_name: str, optional + File name for saving results if save_results is True. + return_values: list, optional + List of Variable names, used to return values from the model for data reconciliation. + + Returns + ------- + results_df: pd.DataFrame + DataFrame containing initial and converged theta values, objectives, and solver info for each restart. + best_theta: dict + Dictionary of theta values corresponding to the best (lowest) objective value found. + best_objectiveval: float + The best (lowest) objective function value found across all restarts. + """ + + # check if we are using deprecated parmest + if self.pest_deprecated is not None: + return print( + "Multistart is not supported in the deprecated parmest interface" + ) + + # Validate input types + if not isinstance(n_restarts, int): + raise TypeError("n_restarts must be an integer") + if not isinstance(multistart_sampling_method, str): + raise TypeError("multistart_sampling_method must be a string") + if not isinstance(solver, str): + raise TypeError("solver must be a string") + if not isinstance(return_values, list): + raise TypeError("return_values must be a list") + + if n_restarts <= 1: + # If n_restarts is 1 or less, no multistart optimization is needed + logger.warning( + "No multistart optimization needed. Please use normal theta_est()." + ) + return self.theta_est( + solver=solver, return_values=return_values, calc_cov=False, cov_n=None + ) + + if n_restarts > 1 and multistart_sampling_method is not None: + + # Find the initialized values of theta from the labeled parmest model + # and the theta names from the estimator object + + # logger statement to indicate multistart optimization is starting + logger.info( + f"Starting multistart optimization with {n_restarts} restarts using {multistart_sampling_method} sampling method." + ) + + # @Reviewers, pyomo team: Use this or use instance creation callback? + theta_names = self._return_theta_names() + # Generate theta values using the sampling method + parmest_model_for_bounds = self._create_parmest_model(experiment_number=0) + results_df = self._generate_initial_theta( + parmest_model_for_bounds, + seed=seed, + n_restarts=n_restarts, + multistart_sampling_method=multistart_sampling_method, + user_provided_df=user_provided_df, + ) + results_df = pd.DataFrame(results_df) + # Extract theta_vals from the dataframe + theta_vals = results_df.iloc[:, : len(theta_names)] + converged_theta_vals = np.zeros((n_restarts, len(theta_names))) + + timer = TicTocTimer() + + # Each restart uses a fresh model instance + for i in range(n_restarts): + + # Add a timer for each restart + timer.tic(f"Restart {i+1}/{n_restarts}") + + # No longer needed, keeping until confirming update works as expected + # # Create a fresh model for each restart + # parmest_model = self._create_parmest_model(experiment_number=0) + theta_vals_current = theta_vals.iloc[i, :].to_dict() + # If theta_vals is provided, use it to set the current theta values + # # Convert values to a list + # theta_vals_current = list(theta_vals.iloc[i, :]) + + # # Update the model with the current theta values + # update_model_from_suffix(parmest_model, 'experiment_inputs', theta_vals_current) + + # # Set current theta values in the model + # for name, value in theta_vals_current.items(): + # parmest_model.find_component(name).set_value(value) + + # # Optional: Print the current theta values being set + # print(f"Setting {name} to {value}") + # for name in theta_names: + # current_value = parmest_model.find_component(name)() + # print(f"Current value of {name} is {current_value}") + + # Call the _Q_opt method with the generated theta values + qopt_result = self._Q_opt( + ThetaVals=theta_vals_current, + bootlist=None, + solver=solver, + return_values=return_values, + multistart=True, + ) + + # Unpack results + objectiveval, converged_theta, solver_info = qopt_result + + # Added an extra option to Q_opt to return the full solver result if multistart=True + solver_termination = solver_info.solver.termination_condition + if solver_termination != pyo.TerminationCondition.optimal: + # If the solver did not converge, set the converged theta to NaN + solve_time = np.nan + final_objectiveval = np.nan + init_objectiveval = np.nan + else: + converged_theta_vals[i, :] = converged_theta.values + # Calculate the initial objective value using the current theta values + # Use the _Q_at_theta method to evaluate the objective at these theta values + init_objectiveval, _, _ = self._Q_at_theta(theta_vals_current) + final_objectiveval = objectiveval + + # # Check if the objective value is better than the best objective value + # # Set a very high initial best objective value + if i == 0: + # Initialize best objective value and theta + best_objectiveval = np.inf + best_theta = np.inf + # Check if the final objective value is better than the best found so far + if final_objectiveval < best_objectiveval: + best_objectiveval = objectiveval + best_theta = converged_theta.values + + logger.info( + f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}" + ) + + # Stop the timer for this restart + solve_time = timer.toc(f"Restart {i+1}/{n_restarts}") + + # Store the results in the DataFrame for this restart + # Fill converged theta values + for j, name in enumerate(theta_names): + results_df.at[i, f'converged_{name}'] = ( + converged_theta.iloc[j] + if not np.isnan(converged_theta_vals[i, j]) + else np.nan + ) + # Fill initial and final objective values, solver termination, and solve time + results_df.at[i, "initial objective"] = ( + init_objectiveval if 'init_objectiveval' in locals() else np.nan + ) + results_df.at[i, "final objective"] = ( + objectiveval if 'objectiveval' in locals() else np.nan + ) + results_df.at[i, "solver termination"] = ( + solver_termination if 'solver_termination' in locals() else np.nan + ) + results_df.at[i, "solve_time"] = ( + solve_time if 'solve_time' in locals() else np.nan + ) + + # Diagnostic: print the table after each restart + logger.debug(results_df) + + # Add buffer to save the dataframe dynamically, if save_results is True + if save_results and (i + 1) % buffer == 0: + mode = 'w' if i + 1 == buffer else 'a' + header = i + 1 == buffer + results_df.to_csv(file_name, mode=mode, header=header, index=False) + logger.info(f"Intermediate results saved after {i + 1} iterations.") + + # Final save after all iterations + if save_results: + results_df.to_csv(file_name, mode='a', header=False, index=False) + logger.info("Final results saved.") + + return results_df, best_theta, best_objectiveval + ''' + # Updated version that uses _Q_opt def theta_est_multistart(self, theta_values=None): """ diff --git a/pyomo/contrib/parmest/parmest_old.py b/pyomo/contrib/parmest/parmest_old.py deleted file mode 100644 index 2d5cab7c572..00000000000 --- a/pyomo/contrib/parmest/parmest_old.py +++ /dev/null @@ -1,2883 +0,0 @@ -# ___________________________________________________________________________ -# -# Pyomo: Python Optimization Modeling Objects -# Copyright (c) 2008-2025 -# 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. -# ___________________________________________________________________________ -#### Using mpi-sppy instead of PySP; May 2020 -#### Adding option for "local" EF starting Sept 2020 -#### Wrapping mpi-sppy functionality and local option Jan 2021, Feb 2021 -#### Redesign with Experiment class Dec 2023 - -# TODO: move use_mpisppy to a Pyomo configuration option -# False implies always use the EF that is local to parmest -use_mpisppy = True # Use it if we can but use local if not. -if use_mpisppy: - try: - # MPI-SPPY has an unfortunate side effect of outputting - # "[ 0.00] Initializing mpi-sppy" when it is imported. This can - # cause things like doctests to fail. We will suppress that - # information here. - from pyomo.common.tee import capture_output - - with capture_output(): - import mpisppy.utils.sputils as sputils - except ImportError: - use_mpisppy = False # we can't use it -if use_mpisppy: - # These things should be outside the try block. - sputils.disable_tictoc_output() - import mpisppy.opt.ef as st - import mpisppy.scenario_tree as scenario_tree -else: - import pyomo.contrib.parmest.utils.create_ef as local_ef - import pyomo.contrib.parmest.utils.scenario_tree as scenario_tree - -import re -import importlib as im -import logging -import types -import json -from collections.abc import Callable -from itertools import combinations -from functools import singledispatchmethod - -from pyomo.common.dependencies import ( - attempt_import, - numpy as np, - numpy_available, - pandas as pd, - pandas_available, - scipy, - scipy_available, -) - -import pyomo.environ as pyo - -from pyomo.opt import SolverFactory -from pyomo.environ import Block, ComponentUID - -import pyomo.contrib.parmest.utils as utils -import pyomo.contrib.parmest.graphics as graphics -from pyomo.dae import ContinuousSet - -# Add imports for HierchicalTimer -import time -from pyomo.common.timing import TicTocTimer -from enum import Enum - -from pyomo.common.deprecation import deprecated -from pyomo.common.deprecation import deprecation_warning - -parmest_available = numpy_available & pandas_available & scipy_available - -inverse_reduced_hessian, inverse_reduced_hessian_available = attempt_import( - 'pyomo.contrib.interior_point.inverse_reduced_hessian' -) - -logger = logging.getLogger(__name__) - - -def ef_nonants(ef): - # Wrapper to call someone's ef_nonants - # (the function being called is very short, but it might be changed) - if use_mpisppy: - return sputils.ef_nonants(ef) - else: - return local_ef.ef_nonants(ef) - - -def _experiment_instance_creation_callback( - scenario_name, node_names=None, cb_data=None, fix_vars=False -): - """ - This is going to be called by mpi-sppy or the local EF and it will call into - the user's model's callback. - - Parameters: - ----------- - scenario_name: `str` Scenario name should end with a number - node_names: `None` ( Not used here ) - cb_data : dict with ["callback"], ["BootList"], - ["theta_names"], ["cb_data"], etc. - "cb_data" is passed through to user's callback function - that is the "callback" value. - "BootList" is None or bootstrap experiment number list. - (called cb_data by mpisppy) - fix_vars: `bool` If True, the theta variables are fixed to the values - provided in the cb_data["ThetaVals"] dictionary. - - - Returns: - -------- - instance: `ConcreteModel` - instantiated scenario - - Note: - ---- - There is flexibility both in how the function is passed and its signature. - """ - assert cb_data is not None - outer_cb_data = cb_data - scen_num_str = re.compile(r'(\d+)$').search(scenario_name).group(1) - scen_num = int(scen_num_str) - basename = scenario_name[: -len(scen_num_str)] # to reconstruct name - - CallbackFunction = outer_cb_data["callback"] - - if callable(CallbackFunction): - callback = CallbackFunction - else: - cb_name = CallbackFunction - - if "CallbackModule" not in outer_cb_data: - raise RuntimeError( - "Internal Error: need CallbackModule in parmest callback" - ) - else: - modname = outer_cb_data["CallbackModule"] - - if isinstance(modname, str): - cb_module = im.import_module(modname, package=None) - elif isinstance(modname, types.ModuleType): - cb_module = modname - else: - print("Internal Error: bad CallbackModule") - raise - - try: - callback = getattr(cb_module, cb_name) - except: - print("Error getting function=" + cb_name + " from module=" + str(modname)) - raise - - if "BootList" in outer_cb_data: - bootlist = outer_cb_data["BootList"] - # print("debug in callback: using bootlist=",str(bootlist)) - # assuming bootlist itself is zero based - exp_num = bootlist[scen_num] - else: - exp_num = scen_num - - scen_name = basename + str(exp_num) - - cb_data = outer_cb_data["cb_data"] # cb_data might be None. - - # at least three signatures are supported. The first is preferred - try: - instance = callback(experiment_number=exp_num, cb_data=cb_data) - except TypeError: - raise RuntimeError( - "Only one callback signature is supported: " - "callback(experiment_number, cb_data) " - ) - """ - try: - instance = callback(scenario_tree_model, scen_name, node_names) - except TypeError: # deprecated signature? - try: - instance = callback(scen_name, node_names) - except: - print("Failed to create instance using callback; TypeError+") - raise - except: - print("Failed to create instance using callback.") - raise - """ - if hasattr(instance, "_mpisppy_node_list"): - raise RuntimeError(f"scenario for experiment {exp_num} has _mpisppy_node_list") - nonant_list = [ - instance.find_component(vstr) for vstr in outer_cb_data["theta_names"] - ] - if use_mpisppy: - instance._mpisppy_node_list = [ - scenario_tree.ScenarioNode( - name="ROOT", - cond_prob=1.0, - stage=1, - cost_expression=instance.FirstStageCost, - nonant_list=nonant_list, - scen_model=instance, - ) - ] - else: - instance._mpisppy_node_list = [ - scenario_tree.ScenarioNode( - name="ROOT", - cond_prob=1.0, - stage=1, - cost_expression=instance.FirstStageCost, - scen_name_list=None, - nonant_list=nonant_list, - scen_model=instance, - ) - ] - # @Reviewers, here is where the parmest model is made for each run - # This is the only way I see to pass the theta values to the model - # Can we add an optional argument to fix them or not? - # Curently, thetavals provided are fixed if not None - # Suggested fix in this function and _Q_at_theta - if "ThetaVals" in outer_cb_data: - thetavals = outer_cb_data["ThetaVals"] - - # dlw august 2018: see mea code for more general theta - for name, val in thetavals.items(): - theta_cuid = ComponentUID(name) - theta_object = theta_cuid.find_component_on(instance) - if val is not None and fix_vars is True: - # print("Fixing",vstr,"at",str(thetavals[vstr])) - theta_object.fix(val) - # ADDED OPTION: Set initial value, but do not fix - elif val is not None and fix_vars is False: - # print("Setting",vstr,"to",str(thetavals[vstr])) - theta_object.set_value(val) - theta_object.unfix() - else: - # print("Freeing",vstr) - theta_object.unfix() - - return instance - - -def SSE(model): - """ - Sum of squared error between `experiment_output` model and data values - """ - expr = sum((y - y_hat) ** 2 for y, y_hat in model.experiment_outputs.items()) - return expr - - -class MultistartSamplingMethodLib(Enum): - """ - Enum class for multistart sampling methods. - """ - - uniform_random = "uniform_random" - latin_hypercube = "latin_hypercube" - sobol_sampling = "sobol_sampling" - user_provided_values = "user_provided_values" - - -class Estimator(object): - """ - Parameter estimation class - - Parameters - ---------- - experiment_list: list of Experiments - A list of experiment objects which creates one labeled model for - each experiment - obj_function: string or function (optional) - Built in objective (currently only "SSE") or custom function used to - formulate parameter estimation objective. - If no function is specified, the model is used - "as is" and should be defined with a "FirstStageCost" and - "SecondStageCost" expression that are used to build an objective. - Default is None. - tee: bool, optional - If True, print the solver output to the screen. Default is False. - diagnostic_mode: bool, optional - If True, print diagnostics from the solver. Default is False. - solver_options: dict, optional - Provides options to the solver (also the name of an attribute). - Default is None. - """ - - # The singledispatchmethod decorator is used here as a deprecation - # shim to be able to support the now deprecated Estimator interface - # which had a different number of arguments. When the deprecated API - # is removed this decorator and the _deprecated_init method below - # can be removed - @singledispatchmethod - def __init__( - self, - experiment_list, - obj_function=None, - tee=False, - diagnostic_mode=False, - solver_options=None, - ): - '''first theta would be provided by the user in the initialization of - the Estimator class through the unknown parameter variables. Additional - would need to be generated using the sampling method provided by the user. - ''' - - # check that we have a (non-empty) list of experiments - assert isinstance(experiment_list, list) - self.exp_list = experiment_list - - # check that an experiment has experiment_outputs and unknown_parameters - model = self.exp_list[0].get_labeled_model() - try: - outputs = [k.name for k, v in model.experiment_outputs.items()] - except: - raise RuntimeError( - 'Experiment list model does not have suffix ' + '"experiment_outputs".' - ) - try: - params = [k.name for k, v in model.unknown_parameters.items()] - except: - raise RuntimeError( - 'Experiment list model does not have suffix ' + '"unknown_parameters".' - ) - - # populate keyword argument options - self.obj_function = obj_function - self.tee = tee - self.diagnostic_mode = diagnostic_mode - self.solver_options = solver_options - - # TODO: delete this when the deprecated interface is removed - self.pest_deprecated = None - - # TODO This might not be needed here. - # We could collect the union (or intersect?) of thetas when the models are built - theta_names = [] - for experiment in self.exp_list: - model = experiment.get_labeled_model() - theta_names.extend([k.name for k, v in model.unknown_parameters.items()]) - # Utilize list(dict.fromkeys(theta_names)) to preserve parameter - # order compared with list(set(theta_names)), which had - # nondeterministic ordering of parameters - self.estimator_theta_names = list(dict.fromkeys(theta_names)) - - self._second_stage_cost_exp = "SecondStageCost" - # boolean to indicate if model is initialized using a square solve - self.model_initialized = False - - # The deprecated Estimator constructor - # This works by checking the type of the first argument passed to - # the class constructor. If it matches the old interface (i.e. is - # callable) then this _deprecated_init method is called and the - # deprecation warning is displayed. - @__init__.register(Callable) - def _deprecated_init( - self, - model_function, - data, - theta_names, - obj_function=None, - tee=False, - diagnostic_mode=False, - solver_options=None, - ): - - deprecation_warning( - "You're using the deprecated parmest interface (model_function, " - "data, theta_names). This interface will be removed in a future release, " - "please update to the new parmest interface using experiment lists.", - version='6.7.2', - ) - self.pest_deprecated = _DeprecatedEstimator( - model_function, - data, - theta_names, - obj_function, - tee, - diagnostic_mode, - solver_options, - ) - - def _return_theta_names(self): - """ - Return list of fitted model parameter names - """ - # check for deprecated inputs - if self.pest_deprecated: - - # if fitted model parameter names differ from theta_names - # created when Estimator object is created - if hasattr(self, 'theta_names_updated'): - return self.pest_deprecated.theta_names_updated - - else: - - # default theta_names, created when Estimator object is created - return self.pest_deprecated.theta_names - - else: - - # if fitted model parameter names differ from theta_names - # created when Estimator object is created - if hasattr(self, 'theta_names_updated'): - return self.theta_names_updated - - else: - - # default theta_names, created when Estimator object is created - return self.estimator_theta_names - - def _expand_indexed_unknowns(self, model_temp): - """ - Expand indexed variables to get full list of thetas - """ - - model_theta_list = [] - for c in model_temp.unknown_parameters.keys(): - if c.is_indexed(): - for _, ci in c.items(): - model_theta_list.append(ci.name) - else: - model_theta_list.append(c.name) - - return model_theta_list - - def _create_parmest_model(self, experiment_number): - """ - Modify the Pyomo model for parameter estimation - """ - - model = self.exp_list[experiment_number].get_labeled_model() - - if len(model.unknown_parameters) == 0: - model.parmest_dummy_var = pyo.Var(initialize=1.0) - - # Add objective function (optional) - if self.obj_function: - # Check for component naming conflicts - reserved_names = [ - 'Total_Cost_Objective', - 'FirstStageCost', - 'SecondStageCost', - ] - for n in reserved_names: - if model.component(n) or hasattr(model, n): - raise RuntimeError( - f"Parmest will not override the existing model component named {n}" - ) - - # Deactivate any existing objective functions - for obj in model.component_objects(pyo.Objective): - obj.deactivate() - - # 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 - else: - # A custom function uses model.experiment_outputs as data - second_stage_rule = self.obj_function - - model.FirstStageCost = pyo.Expression(expr=0) - model.SecondStageCost = pyo.Expression(rule=second_stage_rule) - - def TotalCost_rule(model): - return model.FirstStageCost + model.SecondStageCost - - model.Total_Cost_Objective = pyo.Objective( - rule=TotalCost_rule, sense=pyo.minimize - ) - - # Convert theta Params to Vars, and unfix theta Vars - theta_names = [k.name for k, v in model.unknown_parameters.items()] - parmest_model = utils.convert_params_to_vars(model, theta_names, fix_vars=False) - - return parmest_model - - # TODO: Make so this generates the initial DATAFRAME, not the entire list of values. - # Make new private method, _generate_initial_theta: - # This method will be used to generate the initial theta values for multistart - # optimization. It will take the theta names and the initial theta values - # and return a dictionary of theta names and their corresponding values. - def _generate_initial_theta( - self, - parmest_model=None, - seed=None, - n_restarts=None, - multistart_sampling_method=None, - user_provided_df=None, - ): - """ - Generate initial theta values for multistart optimization using selected sampling method. - """ - # Locate the unknown parameters in the model from the suffix - suffix_params = parmest_model.unknown_parameters - - # Get the VarData objects from the suffix - theta_vars = list(suffix_params.keys()) - - # Extract names, starting values, and bounds for the theta variables - theta_names = [v.name for v in theta_vars] - initial_theta = np.array([v.value for v in theta_vars]) - lower_bound = np.array([v.lb for v in theta_vars]) - upper_bound = np.array([v.ub for v in theta_vars]) - - # Check if the lower and upper bounds are defined - if any(bound is None for bound in lower_bound) or any( - bound is None for bound in upper_bound - ): - raise ValueError( - "The lower and upper bounds for the theta values must be defined." - ) - - if multistart_sampling_method == "uniform_random": - # Generate random theta values using uniform distribution, with set seed for reproducibility - np.random.seed(seed) - # Generate random theta values for each restart (n_restarts x len(theta_names)) - theta_vals_multistart = np.random.uniform( - low=lower_bound, high=upper_bound, size=(n_restarts, len(theta_names)) - ) - - elif multistart_sampling_method == "latin_hypercube": - # Generate theta values using Latin hypercube sampling or Sobol sampling - # Generate theta values using Latin hypercube sampling - # Create a Latin Hypercube sampler that uses the dimensions of the theta names - sampler = scipy.stats.qmc.LatinHypercube(d=len(theta_names), seed=seed) - # Generate random samples in the range of [0, 1] for number of restarts - samples = sampler.random(n=n_restarts) - # Resulting samples should be size (n_restarts, len(theta_names)) - - elif multistart_sampling_method == "sobol_sampling": - sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) - # Generate theta values using Sobol sampling - # The first value of the Sobol sequence is 0, so we skip it - samples = sampler.random(n=n_restarts + 1)[1:] - - elif multistart_sampling_method == "user_provided_values": - # Add user provided dataframe option - if user_provided_df is not None: - - if isinstance(user_provided_df, pd.DataFrame): - # Check if the user provided dataframe has the same number of rows as the number of restarts - if user_provided_df.shape[0] != n_restarts: - raise ValueError( - "The user provided dataframe must have the same number of rows as the number of restarts." - ) - # Check if the user provided dataframe has the same number of columns as the number of theta names - if user_provided_df.shape[1] != len(theta_names): - raise ValueError( - "The user provided dataframe must have the same number of columns as the number of theta names." - ) - # Check if the user provided dataframe has the same theta names as the model - # if not, raise an error - if not all( - theta in theta_names for theta in user_provided_df.columns - ): - raise ValueError( - "The user provided dataframe must have the same theta names as the model." - ) - # If all checks pass, return the user provided dataframe - theta_vals_multistart = user_provided_df.iloc[ - 0 : len(initial_theta) - ].values - else: - raise ValueError( - "The user must provide a pandas dataframe to use the 'user_provided_values' method." - ) - - else: - raise ValueError( - "Invalid sampling method. Choose 'uniform_random', 'latin_hypercube', 'sobol_sampling' or 'user_provided_values'." - ) - - if ( - multistart_sampling_method == "sobol_sampling" - or multistart_sampling_method == "latin_hypercube" - ): - # Scale the samples to the range of the lower and upper bounds for each theta in theta_names - # The samples are in the range [0, 1], so we scale them to the range of the lower and upper bounds - theta_vals_multistart = np.array( - [lower_bound + (upper_bound - lower_bound) * theta for theta in samples] - ) - - # Create a DataFrame where each row is an initial theta vector for a restart, - # columns are theta_names, and values are the initial theta values for each restart - if multistart_sampling_method == "user_provided_values": - # If user_provided_values is a DataFrame, use its columns and values directly - if isinstance(user_provided_df, pd.DataFrame): - df_multistart = user_provided_df.copy() - df_multistart.columns = theta_names - else: - df_multistart = pd.DataFrame(theta_vals_multistart, columns=theta_names) - else: - # Ensure theta_vals_multistart is 2D (n_restarts, len(theta_names)) - arr = np.atleast_2d(theta_vals_multistart) - if arr.shape[0] == 1 and n_restarts > 1: - arr = np.tile(arr, (n_restarts, 1)) - df_multistart = pd.DataFrame(arr, columns=theta_names) - - # Add columns for output info, initialized as nan - for name in theta_names: - df_multistart[f'converged_{name}'] = np.nan - df_multistart["initial objective"] = np.nan - df_multistart["final objective"] = np.nan - df_multistart["solver termination"] = np.nan - df_multistart["solve_time"] = np.nan - - # Debugging output - # print(df_multistart) - - return df_multistart - - def _instance_creation_callback(self, experiment_number=None, cb_data=None): - model = self._create_parmest_model(experiment_number) - return model - - # TODO: Add a way to pass in a parmest_model to this function, currently cannot - # access the model within the build function. - - # I need to check, if I use the update model utility BEFORE calling _Q_opt, does it still - # work? If so, then I can remove the parmest_model argument. - def _Q_opt( - self, - ThetaVals=None, - solver="ef_ipopt", - return_values=[], - bootlist=None, - calc_cov=False, - multistart=False, - cov_n=None, - ): - """ - Set up all thetas as first stage Vars, return resulting theta - values as well as the objective function value. - - """ - if solver == "k_aug": - raise RuntimeError("k_aug no longer supported.") - - # (Bootstrap scenarios will use indirection through the bootlist) - if bootlist is None: - scenario_numbers = list(range(len(self.exp_list))) - scen_names = ["Scenario{}".format(i) for i in scenario_numbers] - else: - scen_names = ["Scenario{}".format(i) for i in range(len(bootlist))] - - # tree_model.CallbackModule = None - outer_cb_data = dict() - outer_cb_data["callback"] = self._instance_creation_callback - if ThetaVals is not None: - outer_cb_data["ThetaVals"] = ThetaVals - if bootlist is not None: - outer_cb_data["BootList"] = bootlist - outer_cb_data["cb_data"] = None # None is OK - outer_cb_data["theta_names"] = self.estimator_theta_names - - options = {"solver": "ipopt"} - scenario_creator_options = {"cb_data": outer_cb_data} - if use_mpisppy: - ef = sputils.create_EF( - scen_names, - _experiment_instance_creation_callback, - EF_name="_Q_opt", - suppress_warnings=True, - scenario_creator_kwargs=scenario_creator_options, - ) - else: - ef = local_ef.create_EF( - scen_names, - _experiment_instance_creation_callback, - EF_name="_Q_opt", - suppress_warnings=True, - scenario_creator_kwargs=scenario_creator_options, - ) - self.ef_instance = ef - - # Solve the extensive form with ipopt - if solver == "ef_ipopt": - if not calc_cov: - # Do not calculate the reduced hessian - - solver = SolverFactory('ipopt') - if self.solver_options is not None: - for key in self.solver_options: - solver.options[key] = self.solver_options[key] - - solve_result = solver.solve(self.ef_instance, tee=self.tee) - - # The import error will be raised when we attempt to use - # inv_reduced_hessian_barrier below. - # - # elif not asl_available: - # raise ImportError("parmest requires ASL to calculate the " - # "covariance matrix with solver 'ipopt'") - else: - # parmest makes the fitted parameters stage 1 variables - ind_vars = [] - for ndname, Var, solval in ef_nonants(ef): - ind_vars.append(Var) - # calculate the reduced hessian - solve_result, inv_red_hes = ( - inverse_reduced_hessian.inv_reduced_hessian_barrier( - self.ef_instance, - independent_variables=ind_vars, - solver_options=self.solver_options, - tee=self.tee, - ) - ) - - if self.diagnostic_mode: - print( - ' Solver termination condition = ', - str(solve_result.solver.termination_condition), - ) - - # assume all first stage are thetas... - thetavals = {} - for ndname, Var, solval in ef_nonants(ef): - # process the name - # the scenarios are blocks, so strip the scenario name - vname = Var.name[Var.name.find(".") + 1 :] - thetavals[vname] = solval - - objval = pyo.value(ef.EF_Obj) - - if calc_cov: - # Calculate the covariance matrix - - # Number of data points considered - n = cov_n - - # Extract number of fitted parameters - l = len(thetavals) - - # Assumption: Objective value is sum of squared errors - sse = objval - - '''Calculate covariance assuming experimental observation errors are - independent and follow a Gaussian - distribution with constant variance. - - The formula used in parmest was verified against equations (7-5-15) and - (7-5-16) in "Nonlinear Parameter Estimation", Y. Bard, 1974. - - This formula is also applicable if the objective is scaled by a constant; - the constant cancels out. (was scaled by 1/n because it computes an - expected value.) - ''' - cov = 2 * sse / (n - l) * inv_red_hes - cov = pd.DataFrame( - cov, index=thetavals.keys(), columns=thetavals.keys() - ) - - thetavals = pd.Series(thetavals) - - if len(return_values) > 0: - var_values = [] - if len(scen_names) > 1: # multiple scenarios - block_objects = self.ef_instance.component_objects( - Block, descend_into=False - ) - else: # single scenario - block_objects = [self.ef_instance] - for exp_i in block_objects: - vals = {} - for var in return_values: - exp_i_var = exp_i.find_component(str(var)) - if ( - exp_i_var is None - ): # we might have a block such as _mpisppy_data - continue - # if value to return is ContinuousSet - if type(exp_i_var) == ContinuousSet: - temp = list(exp_i_var) - else: - temp = [pyo.value(_) for _ in exp_i_var.values()] - if len(temp) == 1: - vals[var] = temp[0] - else: - vals[var] = temp - if len(vals) > 0: - var_values.append(vals) - var_values = pd.DataFrame(var_values) - if calc_cov: - return objval, thetavals, var_values, cov - else: - return objval, thetavals, var_values - - if calc_cov: - return objval, thetavals, cov - if multistart: - return objval, thetavals, solve_result - else: - return objval, thetavals - - else: - raise RuntimeError("Unknown solver in Q_Opt=" + solver) - - def _Q_at_theta(self, thetavals, initialize_parmest_model=False): - """ - Return the objective function value with fixed theta values. - - Parameters - ---------- - thetavals: dict - A dictionary of theta values. - - initialize_parmest_model: boolean - If True: Solve square problem instance, build extensive form of the model for - parameter estimation, and set flag model_initialized to True. Default is False. - - Returns - ------- - objectiveval: float - The objective function value. - thetavals: dict - A dictionary of all values for theta that were input. - solvertermination: Pyomo TerminationCondition - Tries to return the "worst" solver status across the scenarios. - pyo.TerminationCondition.optimal is the best and - pyo.TerminationCondition.infeasible is the worst. - """ - - optimizer = pyo.SolverFactory('ipopt') - - if len(thetavals) > 0: - dummy_cb = { - "callback": self._instance_creation_callback, - "ThetaVals": thetavals, - "theta_names": self._return_theta_names(), - "cb_data": None, - } - else: - dummy_cb = { - "callback": self._instance_creation_callback, - "theta_names": self._return_theta_names(), - "cb_data": None, - } - - if self.diagnostic_mode: - if len(thetavals) > 0: - print(' Compute objective at theta = ', str(thetavals)) - else: - print(' Compute objective at initial theta') - - # start block of code to deal with models with no constraints - # (ipopt will crash or complain on such problems without special care) - instance = _experiment_instance_creation_callback("FOO0", None, dummy_cb) - try: # deal with special problems so Ipopt will not crash - first = next(instance.component_objects(pyo.Constraint, active=True)) - active_constraints = True - except: - active_constraints = False - # end block of code to deal with models with no constraints - - WorstStatus = pyo.TerminationCondition.optimal - totobj = 0 - scenario_numbers = list(range(len(self.exp_list))) - if initialize_parmest_model: - # create dictionary to store pyomo model instances (scenarios) - scen_dict = dict() - - for snum in scenario_numbers: - sname = "scenario_NODE" + str(snum) - instance = _experiment_instance_creation_callback( - sname, None, dummy_cb, fix_vars=True - ) - model_theta_names = self._expand_indexed_unknowns(instance) - - if initialize_parmest_model: - # list to store fitted parameter names that will be unfixed - # after initialization - theta_init_vals = [] - # use appropriate theta_names member - theta_ref = model_theta_names - - for i, theta in enumerate(theta_ref): - # Use parser in ComponentUID to locate the component - var_cuid = ComponentUID(theta) - var_validate = var_cuid.find_component_on(instance) - if var_validate is None: - logger.warning( - "theta_name %s was not found on the model", (theta) - ) - else: - try: - if len(thetavals) == 0: - var_validate.fix() - else: - var_validate.fix(thetavals[theta]) - theta_init_vals.append(var_validate) - except: - logger.warning( - 'Unable to fix model parameter value for %s (not a Pyomo model Var)', - (theta), - ) - - if active_constraints: - if self.diagnostic_mode: - print(' Experiment = ', snum) - print(' First solve with special diagnostics wrapper') - status_obj, solved, iters, time, regu = ( - utils.ipopt_solve_with_stats( - instance, optimizer, max_iter=500, max_cpu_time=120 - ) - ) - print( - " status_obj, solved, iters, time, regularization_stat = ", - str(status_obj), - str(solved), - str(iters), - str(time), - str(regu), - ) - - results = optimizer.solve(instance) - if self.diagnostic_mode: - print( - 'standard solve solver termination condition=', - str(results.solver.termination_condition), - ) - - if ( - results.solver.termination_condition - != pyo.TerminationCondition.optimal - ): - # DLW: Aug2018: not distinguishing "middlish" conditions - if WorstStatus != pyo.TerminationCondition.infeasible: - WorstStatus = results.solver.termination_condition - if initialize_parmest_model: - if self.diagnostic_mode: - print( - "Scenario {:d} infeasible with initialized parameter values".format( - snum - ) - ) - else: - if initialize_parmest_model: - if self.diagnostic_mode: - print( - "Scenario {:d} initialization successful with initial parameter values".format( - snum - ) - ) - if initialize_parmest_model: - # unfix parameters after initialization - for theta in theta_init_vals: - theta.unfix() - scen_dict[sname] = instance - else: - if initialize_parmest_model: - # unfix parameters after initialization - for theta in theta_init_vals: - theta.unfix() - scen_dict[sname] = instance - - objobject = getattr(instance, self._second_stage_cost_exp) - objval = pyo.value(objobject) - totobj += objval - - retval = totobj / len(scenario_numbers) # -1?? - if initialize_parmest_model and not hasattr(self, 'ef_instance'): - # create extensive form of the model using scenario dictionary - if len(scen_dict) > 0: - for scen in scen_dict.values(): - scen._mpisppy_probability = 1 / len(scen_dict) - - if use_mpisppy: - EF_instance = sputils._create_EF_from_scen_dict( - scen_dict, - EF_name="_Q_at_theta", - # suppress_warnings=True - ) - else: - EF_instance = local_ef._create_EF_from_scen_dict( - scen_dict, EF_name="_Q_at_theta", nonant_for_fixed_vars=True - ) - - self.ef_instance = EF_instance - # set self.model_initialized flag to True to skip extensive form model - # creation using theta_est() - self.model_initialized = True - - # return initialized theta values - if len(thetavals) == 0: - # use appropriate theta_names member - theta_ref = self._return_theta_names() - for i, theta in enumerate(theta_ref): - thetavals[theta] = theta_init_vals[i]() - - return retval, thetavals, WorstStatus - - def _get_sample_list(self, samplesize, num_samples, replacement=True): - samplelist = list() - - scenario_numbers = list(range(len(self.exp_list))) - - if num_samples is None: - # This could get very large - for i, l in enumerate(combinations(scenario_numbers, samplesize)): - samplelist.append((i, np.sort(l))) - else: - for i in range(num_samples): - attempts = 0 - unique_samples = 0 # check for duplicates in each sample - duplicate = False # check for duplicates between samples - while (unique_samples <= len(self._return_theta_names())) and ( - not duplicate - ): - sample = np.random.choice( - scenario_numbers, samplesize, replace=replacement - ) - sample = np.sort(sample).tolist() - unique_samples = len(np.unique(sample)) - if sample in samplelist: - duplicate = True - - attempts += 1 - if attempts > num_samples: # arbitrary timeout limit - raise RuntimeError("""Internal error: timeout constructing - a sample, the dim of theta may be too - close to the samplesize""") - - samplelist.append((i, sample)) - - return samplelist - - def theta_est( - self, solver="ef_ipopt", return_values=[], calc_cov=False, cov_n=None - ): - """ - Parameter estimation using all scenarios in the data - - Parameters - ---------- - solver: string, optional - Currently only "ef_ipopt" is supported. Default is "ef_ipopt". - return_values: list, optional - List of Variable names, used to return values from the model for data reconciliation - calc_cov: boolean, optional - If True, calculate and return the covariance matrix (only for "ef_ipopt" solver). - Default is False. - cov_n: int, optional - If calc_cov=True, then the user needs to supply the number of datapoints - that are used in the objective function. - - Returns - ------- - objectiveval: float - The objective function value - thetavals: pd.Series - Estimated values for theta - variable values: pd.DataFrame - Variable values for each variable name in return_values (only for solver='ef_ipopt') - cov: pd.DataFrame - Covariance matrix of the fitted parameters (only for solver='ef_ipopt') - """ - - # check if we are using deprecated parmest - if self.pest_deprecated is not None: - return self.pest_deprecated.theta_est( - solver=solver, - return_values=return_values, - calc_cov=calc_cov, - cov_n=cov_n, - ) - - assert isinstance(solver, str) - assert isinstance(return_values, list) - assert isinstance(calc_cov, bool) - if calc_cov: - num_unknowns = max( - [ - len(experiment.get_labeled_model().unknown_parameters) - for experiment in self.exp_list - ] - ) - assert isinstance(cov_n, int), ( - "The number of datapoints that are used in the objective function is " - "required to calculate the covariance matrix" - ) - assert ( - cov_n > num_unknowns - ), "The number of datapoints must be greater than the number of parameters to estimate" - - return self._Q_opt( - solver=solver, - return_values=return_values, - bootlist=None, - calc_cov=calc_cov, - cov_n=cov_n, - ) - - # TODO: Make the user provide a list of values, not the whole data frame - # TODO: Add a way to print the empty data_frame before solve so it can be previewed beforehand - # TODO: Fix so the theta values are generated at each iteration, not all beforehand in _generate_initial_theta - # Fix _generate_initial_theta to return an empty DataFrame first - # TODO: Add save model option to save the model after each iteration or at the end of the multistart - def theta_est_multistart( - self, - n_restarts=20, - multistart_sampling_method="uniform_random", - user_provided_list=None, - seed=None, - save_results=False, - theta_vals=None, - solver="ef_ipopt", - file_name="multistart_results.csv", - return_values=[], - ): - """ - Parameter estimation using multistart optimization - - Parameters - ---------- - n_restarts: int, optional - Number of restarts for multistart. Default is 1. - multistart_sampling_method: string, optional - Method used to sample theta values. Options are "uniform_random", "latin_hypercube", "sobol_sampling", or "user_provided_values". - Default is "uniform_random". - buffer: int, optional - Number of iterations to save results dynamically if save_results=True. Default is 10. - user_provided_df: pd.DataFrame, optional - User provided array or dataframe of theta values for multistart optimization. - seed: int, optional - Random seed for reproducibility. - save_results: bool, optional - If True, intermediate and final results are saved to file_name. - theta_vals: pd.DataFrame, optional - Initial theta values for restarts (overrides sampling). - solver: string, optional - Currently only "ef_ipopt" is supported. Default is "ef_ipopt". - file_name: str, optional - File name for saving results if save_results is True. - return_values: list, optional - List of Variable names, used to return values from the model for data reconciliation. - - Returns - ------- - results_df: pd.DataFrame - DataFrame containing initial and converged theta values, objectives, and solver info for each restart. - best_theta: dict - Dictionary of theta values corresponding to the best (lowest) objective value found. - best_objectiveval: float - The best (lowest) objective function value found across all restarts. - """ - - # check if we are using deprecated parmest - if self.pest_deprecated is not None: - return print( - "Multistart is not supported in the deprecated parmest interface" - ) - - # Validate input types - if not isinstance(n_restarts, int): - raise TypeError("n_restarts must be an integer") - if not isinstance(multistart_sampling_method, str): - raise TypeError("multistart_sampling_method must be a string") - if not isinstance(solver, str): - raise TypeError("solver must be a string") - if not isinstance(return_values, list): - raise TypeError("return_values must be a list") - - if n_restarts <= 1: - # If n_restarts is 1 or less, no multistart optimization is needed - logger.warning( - "No multistart optimization needed. Please use normal theta_est()." - ) - return self.theta_est( - solver=solver, return_values=return_values, calc_cov=False, cov_n=None - ) - - if n_restarts > 1 and multistart_sampling_method is not None: - - # Find the initialized values of theta from the labeled parmest model - # and the theta names from the estimator object - - # logger statement to indicate multistart optimization is starting - logger.info( - f"Starting multistart optimization with {n_restarts} restarts using {multistart_sampling_method} sampling method." - ) - - # @Reviewers, pyomo team: Use this or use instance creation callback? - theta_names = self._return_theta_names() - # Generate theta values using the sampling method - parmest_model_for_bounds = self._create_parmest_model(experiment_number=0) - results_df = self._generate_initial_theta( - parmest_model_for_bounds, - seed=seed, - n_restarts=n_restarts, - multistart_sampling_method=multistart_sampling_method, - user_provided_df=user_provided_df, - ) - results_df = pd.DataFrame(results_df) - # Extract theta_vals from the dataframe - theta_vals = results_df.iloc[:, : len(theta_names)] - converged_theta_vals = np.zeros((n_restarts, len(theta_names))) - - timer = TicTocTimer() - - # Each restart uses a fresh model instance - for i in range(n_restarts): - - # Add a timer for each restart - timer.tic(f"Restart {i+1}/{n_restarts}") - - # No longer needed, keeping until confirming update works as expected - # # Create a fresh model for each restart - # parmest_model = self._create_parmest_model(experiment_number=0) - theta_vals_current = theta_vals.iloc[i, :].to_dict() - # If theta_vals is provided, use it to set the current theta values - # # Convert values to a list - # theta_vals_current = list(theta_vals.iloc[i, :]) - - # # Update the model with the current theta values - # update_model_from_suffix(parmest_model, 'experiment_inputs', theta_vals_current) - - # # Set current theta values in the model - # for name, value in theta_vals_current.items(): - # parmest_model.find_component(name).set_value(value) - - # # Optional: Print the current theta values being set - # print(f"Setting {name} to {value}") - # for name in theta_names: - # current_value = parmest_model.find_component(name)() - # print(f"Current value of {name} is {current_value}") - - # Call the _Q_opt method with the generated theta values - qopt_result = self._Q_opt( - ThetaVals=theta_vals_current, - bootlist=None, - solver=solver, - return_values=return_values, - multistart=True, - ) - - # Unpack results - objectiveval, converged_theta, solver_info = qopt_result - - # Added an extra option to Q_opt to return the full solver result if multistart=True - solver_termination = solver_info.solver.termination_condition - if solver_termination != pyo.TerminationCondition.optimal: - # If the solver did not converge, set the converged theta to NaN - solve_time = np.nan - final_objectiveval = np.nan - init_objectiveval = np.nan - else: - converged_theta_vals[i, :] = converged_theta.values - # Calculate the initial objective value using the current theta values - # Use the _Q_at_theta method to evaluate the objective at these theta values - init_objectiveval, _, _ = self._Q_at_theta(theta_vals_current) - final_objectiveval = objectiveval - - # # Check if the objective value is better than the best objective value - # # Set a very high initial best objective value - if i == 0: - # Initialize best objective value and theta - best_objectiveval = np.inf - best_theta = np.inf - # Check if the final objective value is better than the best found so far - if final_objectiveval < best_objectiveval: - best_objectiveval = objectiveval - best_theta = converged_theta.values - - logger.info( - f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}" - ) - - # Stop the timer for this restart - solve_time = timer.toc(f"Restart {i+1}/{n_restarts}") - - # Store the results in the DataFrame for this restart - # Fill converged theta values - for j, name in enumerate(theta_names): - results_df.at[i, f'converged_{name}'] = ( - converged_theta.iloc[j] - if not np.isnan(converged_theta_vals[i, j]) - else np.nan - ) - # Fill initial and final objective values, solver termination, and solve time - results_df.at[i, "initial objective"] = ( - init_objectiveval if 'init_objectiveval' in locals() else np.nan - ) - results_df.at[i, "final objective"] = ( - objectiveval if 'objectiveval' in locals() else np.nan - ) - results_df.at[i, "solver termination"] = ( - solver_termination if 'solver_termination' in locals() else np.nan - ) - results_df.at[i, "solve_time"] = ( - solve_time if 'solve_time' in locals() else np.nan - ) - - # Diagnostic: print the table after each restart - logger.debug(results_df) - - # Add buffer to save the dataframe dynamically, if save_results is True - if save_results and (i + 1) % buffer == 0: - mode = 'w' if i + 1 == buffer else 'a' - header = i + 1 == buffer - results_df.to_csv(file_name, mode=mode, header=header, index=False) - logger.info(f"Intermediate results saved after {i + 1} iterations.") - - # Final save after all iterations - if save_results: - results_df.to_csv(file_name, mode='a', header=False, index=False) - logger.info("Final results saved.") - - return results_df, best_theta, best_objectiveval - - def theta_est_bootstrap( - self, - bootstrap_samples, - samplesize=None, - replacement=True, - seed=None, - return_samples=False, - ): - """ - Parameter estimation using bootstrap resampling of the data - - Parameters - ---------- - bootstrap_samples: int - Number of bootstrap samples to draw from the data - samplesize: int or None, optional - Size of each bootstrap sample. If samplesize=None, samplesize will be - set to the number of samples in the data - replacement: bool, optional - Sample with or without replacement. Default is True. - seed: int or None, optional - Random seed - return_samples: bool, optional - Return a list of sample numbers used in each bootstrap estimation. - Default is False. - - Returns - ------- - bootstrap_theta: pd.DataFrame - Theta values for each sample and (if return_samples = True) - the sample numbers used in each estimation - """ - - # check if we are using deprecated parmest - if self.pest_deprecated is not None: - return self.pest_deprecated.theta_est_bootstrap( - bootstrap_samples, - samplesize=samplesize, - replacement=replacement, - seed=seed, - return_samples=return_samples, - ) - - assert isinstance(bootstrap_samples, int) - assert isinstance(samplesize, (type(None), int)) - assert isinstance(replacement, bool) - assert isinstance(seed, (type(None), int)) - assert isinstance(return_samples, bool) - - if samplesize is None: - samplesize = len(self.exp_list) - - if seed is not None: - np.random.seed(seed) - - global_list = self._get_sample_list(samplesize, bootstrap_samples, replacement) - - task_mgr = utils.ParallelTaskManager(bootstrap_samples) - local_list = task_mgr.global_to_local_data(global_list) - - bootstrap_theta = list() - for idx, sample in local_list: - objval, thetavals = self._Q_opt(bootlist=list(sample)) - thetavals['samples'] = sample - bootstrap_theta.append(thetavals) - - global_bootstrap_theta = task_mgr.allgather_global_data(bootstrap_theta) - bootstrap_theta = pd.DataFrame(global_bootstrap_theta) - - if not return_samples: - del bootstrap_theta['samples'] - - return bootstrap_theta - - def theta_est_leaveNout( - self, lNo, lNo_samples=None, seed=None, return_samples=False - ): - """ - Parameter estimation where N data points are left out of each sample - - Parameters - ---------- - lNo: int - Number of data points to leave out for parameter estimation - lNo_samples: int - Number of leave-N-out samples. If lNo_samples=None, the maximum - number of combinations will be used - seed: int or None, optional - Random seed - return_samples: bool, optional - Return a list of sample numbers that were left out. Default is False. - - Returns - ------- - lNo_theta: pd.DataFrame - Theta values for each sample and (if return_samples = True) - the sample numbers left out of each estimation - """ - - # check if we are using deprecated parmest - if self.pest_deprecated is not None: - return self.pest_deprecated.theta_est_leaveNout( - lNo, lNo_samples=lNo_samples, seed=seed, return_samples=return_samples - ) - - assert isinstance(lNo, int) - assert isinstance(lNo_samples, (type(None), int)) - assert isinstance(seed, (type(None), int)) - assert isinstance(return_samples, bool) - - samplesize = len(self.exp_list) - lNo - - if seed is not None: - np.random.seed(seed) - - global_list = self._get_sample_list(samplesize, lNo_samples, replacement=False) - - task_mgr = utils.ParallelTaskManager(len(global_list)) - local_list = task_mgr.global_to_local_data(global_list) - - lNo_theta = list() - for idx, sample in local_list: - objval, thetavals = self._Q_opt(bootlist=list(sample)) - lNo_s = list(set(range(len(self.exp_list))) - set(sample)) - thetavals['lNo'] = np.sort(lNo_s) - lNo_theta.append(thetavals) - - global_bootstrap_theta = task_mgr.allgather_global_data(lNo_theta) - lNo_theta = pd.DataFrame(global_bootstrap_theta) - - if not return_samples: - del lNo_theta['lNo'] - - return lNo_theta - - def leaveNout_bootstrap_test( - self, lNo, lNo_samples, bootstrap_samples, distribution, alphas, seed=None - ): - """ - Leave-N-out bootstrap test to compare theta values where N data points are - left out to a bootstrap analysis using the remaining data, - results indicate if theta is within a confidence region - determined by the bootstrap analysis - - Parameters - ---------- - lNo: int - Number of data points to leave out for parameter estimation - lNo_samples: int - Leave-N-out sample size. If lNo_samples=None, the maximum number - of combinations will be used - bootstrap_samples: int: - Bootstrap sample size - distribution: string - Statistical distribution used to define a confidence region, - options = 'MVN' for multivariate_normal, 'KDE' for gaussian_kde, - and 'Rect' for rectangular. - alphas: list - List of alpha values used to determine if theta values are inside - or outside the region. - seed: int or None, optional - Random seed - - Returns - ------- - List of tuples with one entry per lNo_sample: - - * The first item in each tuple is the list of N samples that are left - out. - * The second item in each tuple is a DataFrame of theta estimated using - the N samples. - * The third item in each tuple is a DataFrame containing results from - the bootstrap analysis using the remaining samples. - - For each DataFrame a column is added for each value of alpha which - indicates if the theta estimate is in (True) or out (False) of the - alpha region for a given distribution (based on the bootstrap results) - """ - - # check if we are using deprecated parmest - if self.pest_deprecated is not None: - return self.pest_deprecated.leaveNout_bootstrap_test( - lNo, lNo_samples, bootstrap_samples, distribution, alphas, seed=seed - ) - - assert isinstance(lNo, int) - assert isinstance(lNo_samples, (type(None), int)) - assert isinstance(bootstrap_samples, int) - assert distribution in ['Rect', 'MVN', 'KDE'] - assert isinstance(alphas, list) - assert isinstance(seed, (type(None), int)) - - if seed is not None: - np.random.seed(seed) - - global_list = self._get_sample_list(lNo, lNo_samples, replacement=False) - - results = [] - for idx, sample in global_list: - - obj, theta = self.theta_est() - - bootstrap_theta = self.theta_est_bootstrap(bootstrap_samples, seed=seed) - - training, test = self.confidence_region_test( - bootstrap_theta, - distribution=distribution, - alphas=alphas, - test_theta_values=theta, - seed=seed, - ) - - results.append((sample, test, training)) - - return results - - def objective_at_theta(self, theta_values=None, initialize_parmest_model=False): - """ - Objective value for each theta - - Parameters - ---------- - theta_values: pd.DataFrame, columns=theta_names - Values of theta used to compute the objective - - initialize_parmest_model: boolean - If True: Solve square problem instance, build extensive form - of the model for parameter estimation, and set flag - model_initialized to True. Default is False. - - - Returns - ------- - obj_at_theta: pd.DataFrame - Objective value for each theta (infeasible solutions are - omitted). - """ - - # check if we are using deprecated parmest - if self.pest_deprecated is not None: - return self.pest_deprecated.objective_at_theta( - theta_values=theta_values, - initialize_parmest_model=initialize_parmest_model, - ) - - if len(self.estimator_theta_names) == 0: - pass # skip assertion if model has no fitted parameters - else: - # create a local instance of the pyomo model to access model variables and parameters - model_temp = self._create_parmest_model(0) - model_theta_list = self._expand_indexed_unknowns(model_temp) - - # if self.estimator_theta_names is not the same as temp model_theta_list, - # create self.theta_names_updated - if set(self.estimator_theta_names) == set(model_theta_list) and len( - self.estimator_theta_names - ) == len(set(model_theta_list)): - pass - else: - self.theta_names_updated = model_theta_list - - if theta_values is None: - all_thetas = {} # dictionary to store fitted variables - # use appropriate theta names member - theta_names = model_theta_list - else: - assert isinstance(theta_values, pd.DataFrame) - # for parallel code we need to use lists and dicts in the loop - theta_names = theta_values.columns - # # check if theta_names are in model - for theta in list(theta_names): - theta_temp = theta.replace("'", "") # cleaning quotes from theta_names - assert theta_temp in [ - t.replace("'", "") for t in model_theta_list - ], "Theta name {} in 'theta_values' not in 'theta_names' {}".format( - theta_temp, model_theta_list - ) - - assert len(list(theta_names)) == len(model_theta_list) - - all_thetas = theta_values.to_dict('records') - - if all_thetas: - task_mgr = utils.ParallelTaskManager(len(all_thetas)) - local_thetas = task_mgr.global_to_local_data(all_thetas) - else: - if initialize_parmest_model: - task_mgr = utils.ParallelTaskManager( - 1 - ) # initialization performed using just 1 set of theta values - # walk over the mesh, return objective function - all_obj = list() - if len(all_thetas) > 0: - for Theta in local_thetas: - obj, thetvals, worststatus = self._Q_at_theta( - Theta, initialize_parmest_model=initialize_parmest_model - ) - if worststatus != pyo.TerminationCondition.infeasible: - all_obj.append(list(Theta.values()) + [obj]) - # DLW, Aug2018: should we also store the worst solver status? - else: - obj, thetvals, worststatus = self._Q_at_theta( - thetavals={}, initialize_parmest_model=initialize_parmest_model - ) - if worststatus != pyo.TerminationCondition.infeasible: - all_obj.append(list(thetvals.values()) + [obj]) - - global_all_obj = task_mgr.allgather_global_data(all_obj) - dfcols = list(theta_names) + ['obj'] - obj_at_theta = pd.DataFrame(data=global_all_obj, columns=dfcols) - return obj_at_theta - - def likelihood_ratio_test( - self, obj_at_theta, obj_value, alphas, return_thresholds=False - ): - r""" - Likelihood ratio test to identify theta values within a confidence - region using the :math:`\chi^2` distribution - - Parameters - ---------- - obj_at_theta: pd.DataFrame, columns = theta_names + 'obj' - Objective values for each theta value (returned by - objective_at_theta) - obj_value: int or float - Objective value from parameter estimation using all data - alphas: list - List of alpha values to use in the chi2 test - return_thresholds: bool, optional - Return the threshold value for each alpha. Default is False. - - Returns - ------- - LR: pd.DataFrame - Objective values for each theta value along with True or False for - each alpha - thresholds: pd.Series - If return_threshold = True, the thresholds are also returned. - """ - - # check if we are using deprecated parmest - if self.pest_deprecated is not None: - return self.pest_deprecated.likelihood_ratio_test( - obj_at_theta, obj_value, alphas, return_thresholds=return_thresholds - ) - - assert isinstance(obj_at_theta, pd.DataFrame) - assert isinstance(obj_value, (int, float)) - assert isinstance(alphas, list) - assert isinstance(return_thresholds, bool) - - LR = obj_at_theta.copy() - S = len(self.exp_list) - thresholds = {} - for a in alphas: - chi2_val = scipy.stats.chi2.ppf(a, 2) - thresholds[a] = obj_value * ((chi2_val / (S - 2)) + 1) - LR[a] = LR['obj'] < thresholds[a] - - thresholds = pd.Series(thresholds) - - if return_thresholds: - return LR, thresholds - else: - return LR - - def confidence_region_test( - self, theta_values, distribution, alphas, test_theta_values=None, seed=None - ): - """ - Confidence region test to determine if theta values are within a - rectangular, multivariate normal, or Gaussian kernel density distribution - for a range of alpha values - - Parameters - ---------- - theta_values: pd.DataFrame, columns = theta_names - Theta values used to generate a confidence region - (generally returned by theta_est_bootstrap) - distribution: string - Statistical distribution used to define a confidence region, - options = 'MVN' for multivariate_normal, 'KDE' for gaussian_kde, - and 'Rect' for rectangular. - alphas: list - List of alpha values used to determine if theta values are inside - or outside the region. - test_theta_values: pd.Series or pd.DataFrame, keys/columns = theta_names, optional - Additional theta values that are compared to the confidence region - to determine if they are inside or outside. - - Returns - ------- - training_results: pd.DataFrame - Theta value used to generate the confidence region along with True - (inside) or False (outside) for each alpha - test_results: pd.DataFrame - If test_theta_values is not None, returns test theta value along - with True (inside) or False (outside) for each alpha - """ - - # check if we are using deprecated parmest - if self.pest_deprecated is not None: - return self.pest_deprecated.confidence_region_test( - theta_values, distribution, alphas, test_theta_values=test_theta_values - ) - - assert isinstance(theta_values, pd.DataFrame) - assert distribution in ['Rect', 'MVN', 'KDE'] - assert isinstance(alphas, list) - assert isinstance( - test_theta_values, (type(None), dict, pd.Series, pd.DataFrame) - ) - - if isinstance(test_theta_values, (dict, pd.Series)): - test_theta_values = pd.Series(test_theta_values).to_frame().transpose() - - training_results = theta_values.copy() - - if test_theta_values is not None: - test_result = test_theta_values.copy() - - if seed is not None: - np.random.seed(seed) - - for a in alphas: - if distribution == 'Rect': - lb, ub = graphics.fit_rect_dist(theta_values, a) - training_results[a] = (theta_values > lb).all(axis=1) & ( - theta_values < ub - ).all(axis=1) - - if test_theta_values is not None: - # use upper and lower bound from the training set - test_result[a] = (test_theta_values > lb).all(axis=1) & ( - test_theta_values < ub - ).all(axis=1) - - elif distribution == 'MVN': - dist = graphics.fit_mvn_dist(theta_values, seed=seed) - Z = dist.pdf(theta_values) - score = scipy.stats.scoreatpercentile(Z, (1 - a) * 100) - training_results[a] = Z >= score - - if test_theta_values is not None: - # use score from the training set - Z = dist.pdf(test_theta_values) - test_result[a] = Z >= score - - elif distribution == 'KDE': - dist = graphics.fit_kde_dist(theta_values, seed=seed) - Z = dist.pdf(theta_values.transpose()) - score = scipy.stats.scoreatpercentile(Z, (1 - a) * 100) - training_results[a] = Z >= score - - if test_theta_values is not None: - # use score from the training set - Z = dist.pdf(test_theta_values.transpose()) - test_result[a] = Z >= score - - if test_theta_values is not None: - return training_results, test_result - else: - return training_results - - -################################ -# deprecated functions/classes # -################################ - - -@deprecated(version='6.7.2') -def group_data(data, groupby_column_name, use_mean=None): - """ - Group data by scenario - - Parameters - ---------- - data: DataFrame - Data - groupby_column_name: strings - Name of data column which contains scenario numbers - use_mean: list of column names or None, optional - Name of data columns which should be reduced to a single value per - scenario by taking the mean - - Returns - ---------- - grouped_data: list of dictionaries - Grouped data - """ - if use_mean is None: - use_mean_list = [] - else: - use_mean_list = use_mean - - grouped_data = [] - for exp_num, group in data.groupby(data[groupby_column_name]): - d = {} - for col in group.columns: - if col in use_mean_list: - d[col] = group[col].mean() - else: - d[col] = list(group[col]) - grouped_data.append(d) - - return grouped_data - - -class _DeprecatedSecondStageCostExpr(object): - """ - Class to pass objective expression into the Pyomo model - """ - - def __init__(self, ssc_function, data): - self._ssc_function = ssc_function - self._data = data - - def __call__(self, model): - return self._ssc_function(model, self._data) - - -class _DeprecatedEstimator(object): - """ - Parameter estimation class - - Parameters - ---------- - model_function: function - Function that generates an instance of the Pyomo model using 'data' - as the input argument - data: pd.DataFrame, list of dictionaries, list of dataframes, or list of json file names - Data that is used to build an instance of the Pyomo model and build - the objective function - theta_names: list of strings - List of Var names to estimate - obj_function: function, optional - Function used to formulate parameter estimation objective, generally - sum of squared error between measurements and model variables. - If no function is specified, the model is used - "as is" and should be defined with a "FirstStageCost" and - "SecondStageCost" expression that are used to build an objective. - tee: bool, optional - Indicates that ef solver output should be teed - diagnostic_mode: bool, optional - If True, print diagnostics from the solver - solver_options: dict, optional - Provides options to the solver (also the name of an attribute) - """ - - def __init__( - self, - model_function, - data, - theta_names, - obj_function=None, - tee=False, - diagnostic_mode=False, - solver_options=None, - ): - self.model_function = model_function - - assert isinstance( - data, (list, pd.DataFrame) - ), "Data must be a list or DataFrame" - # convert dataframe into a list of dataframes, each row = one scenario - if isinstance(data, pd.DataFrame): - self.callback_data = [ - data.loc[i, :].to_frame().transpose() for i in data.index - ] - else: - self.callback_data = data - assert isinstance( - self.callback_data[0], (dict, pd.DataFrame, str) - ), "The scenarios in data must be a dictionary, DataFrame or filename" - - if len(theta_names) == 0: - self.theta_names = ['parmest_dummy_var'] - else: - self.theta_names = theta_names - - self.obj_function = obj_function - self.tee = tee - self.diagnostic_mode = diagnostic_mode - self.solver_options = solver_options - - self._second_stage_cost_exp = "SecondStageCost" - # boolean to indicate if model is initialized using a square solve - self.model_initialized = False - - def _return_theta_names(self): - """ - Return list of fitted model parameter names - """ - # if fitted model parameter names differ from theta_names created when Estimator object is created - if hasattr(self, 'theta_names_updated'): - return self.theta_names_updated - - else: - return ( - self.theta_names - ) # default theta_names, created when Estimator object is created - - def _create_parmest_model(self, data): - """ - Modify the Pyomo model for parameter estimation - """ - model = self.model_function(data) - - if (len(self.theta_names) == 1) and ( - self.theta_names[0] == 'parmest_dummy_var' - ): - model.parmest_dummy_var = pyo.Var(initialize=1.0) - - # Add objective function (optional) - if self.obj_function: - for obj in model.component_objects(pyo.Objective): - if obj.name in ["Total_Cost_Objective"]: - raise RuntimeError( - "Parmest will not override the existing model Objective named " - + obj.name - ) - obj.deactivate() - - for expr in model.component_data_objects(pyo.Expression): - if expr.name in ["FirstStageCost", "SecondStageCost"]: - raise RuntimeError( - "Parmest will not override the existing model Expression named " - + expr.name - ) - model.FirstStageCost = pyo.Expression(expr=0) - model.SecondStageCost = pyo.Expression( - rule=_DeprecatedSecondStageCostExpr(self.obj_function, data) - ) - - def TotalCost_rule(model): - return model.FirstStageCost + model.SecondStageCost - - model.Total_Cost_Objective = pyo.Objective( - rule=TotalCost_rule, sense=pyo.minimize - ) - - # Convert theta Params to Vars, and unfix theta Vars - model = utils.convert_params_to_vars(model, self.theta_names) - - # Update theta names list to use CUID string representation - for i, theta in enumerate(self.theta_names): - var_cuid = ComponentUID(theta) - var_validate = var_cuid.find_component_on(model) - if var_validate is None: - logger.warning( - "theta_name[%s] (%s) was not found on the model", (i, theta) - ) - else: - try: - # If the component is not a variable, - # this will generate an exception (and the warning - # in the 'except') - var_validate.unfix() - self.theta_names[i] = repr(var_cuid) - except: - logger.warning(theta + ' is not a variable') - - self.parmest_model = model - - return model - - def _instance_creation_callback(self, experiment_number=None, cb_data=None): - # cb_data is a list of dictionaries, list of dataframes, OR list of json file names - exp_data = cb_data[experiment_number] - if isinstance(exp_data, (dict, pd.DataFrame)): - pass - elif isinstance(exp_data, str): - try: - with open(exp_data, 'r') as infile: - exp_data = json.load(infile) - except: - raise RuntimeError(f'Could not read {exp_data} as json') - else: - raise RuntimeError(f'Unexpected data format for cb_data={cb_data}') - model = self._create_parmest_model(exp_data) - - return model - - def _Q_opt( - self, - ThetaVals=None, - solver="ef_ipopt", - return_values=[], - bootlist=None, - calc_cov=False, - cov_n=None, - ): - """ - Set up all thetas as first stage Vars, return resulting theta - values as well as the objective function value. - - """ - if solver == "k_aug": - raise RuntimeError("k_aug no longer supported.") - - # (Bootstrap scenarios will use indirection through the bootlist) - if bootlist is None: - scenario_numbers = list(range(len(self.callback_data))) - scen_names = ["Scenario{}".format(i) for i in scenario_numbers] - else: - scen_names = ["Scenario{}".format(i) for i in range(len(bootlist))] - - # tree_model.CallbackModule = None - outer_cb_data = dict() - outer_cb_data["callback"] = self._instance_creation_callback - if ThetaVals is not None: - outer_cb_data["ThetaVals"] = ThetaVals - if bootlist is not None: - outer_cb_data["BootList"] = bootlist - outer_cb_data["cb_data"] = self.callback_data # None is OK - outer_cb_data["theta_names"] = self.theta_names - - options = {"solver": "ipopt"} - scenario_creator_options = {"cb_data": outer_cb_data} - if use_mpisppy: - ef = sputils.create_EF( - scen_names, - _experiment_instance_creation_callback, - EF_name="_Q_opt", - suppress_warnings=True, - scenario_creator_kwargs=scenario_creator_options, - ) - else: - ef = local_ef.create_EF( - scen_names, - _experiment_instance_creation_callback, - EF_name="_Q_opt", - suppress_warnings=True, - scenario_creator_kwargs=scenario_creator_options, - ) - self.ef_instance = ef - - # Solve the extensive form with ipopt - if solver == "ef_ipopt": - if not calc_cov: - # Do not calculate the reduced hessian - - solver = SolverFactory('ipopt') - if self.solver_options is not None: - for key in self.solver_options: - solver.options[key] = self.solver_options[key] - - solve_result = solver.solve(self.ef_instance, tee=self.tee) - - # The import error will be raised when we attempt to use - # inv_reduced_hessian_barrier below. - # - # elif not asl_available: - # raise ImportError("parmest requires ASL to calculate the " - # "covariance matrix with solver 'ipopt'") - else: - # parmest makes the fitted parameters stage 1 variables - ind_vars = [] - for ndname, Var, solval in ef_nonants(ef): - ind_vars.append(Var) - # calculate the reduced hessian - solve_result, inv_red_hes = ( - inverse_reduced_hessian.inv_reduced_hessian_barrier( - self.ef_instance, - independent_variables=ind_vars, - solver_options=self.solver_options, - tee=self.tee, - ) - ) - - if self.diagnostic_mode: - print( - ' Solver termination condition = ', - str(solve_result.solver.termination_condition), - ) - - # assume all first stage are thetas... - thetavals = {} - for ndname, Var, solval in ef_nonants(ef): - # process the name - # the scenarios are blocks, so strip the scenario name - vname = Var.name[Var.name.find(".") + 1 :] - thetavals[vname] = solval - - objval = pyo.value(ef.EF_Obj) - - if calc_cov: - # Calculate the covariance matrix - - # Number of data points considered - n = cov_n - - # Extract number of fitted parameters - l = len(thetavals) - - # Assumption: Objective value is sum of squared errors - sse = objval - - '''Calculate covariance assuming experimental observation errors are - independent and follow a Gaussian - distribution with constant variance. - - The formula used in parmest was verified against equations (7-5-15) and - (7-5-16) in "Nonlinear Parameter Estimation", Y. Bard, 1974. - - This formula is also applicable if the objective is scaled by a constant; - the constant cancels out. (was scaled by 1/n because it computes an - expected value.) - ''' - cov = 2 * sse / (n - l) * inv_red_hes - cov = pd.DataFrame( - cov, index=thetavals.keys(), columns=thetavals.keys() - ) - - thetavals = pd.Series(thetavals) - - if len(return_values) > 0: - var_values = [] - if len(scen_names) > 1: # multiple scenarios - block_objects = self.ef_instance.component_objects( - Block, descend_into=False - ) - else: # single scenario - block_objects = [self.ef_instance] - for exp_i in block_objects: - vals = {} - for var in return_values: - exp_i_var = exp_i.find_component(str(var)) - if ( - exp_i_var is None - ): # we might have a block such as _mpisppy_data - continue - # if value to return is ContinuousSet - if type(exp_i_var) == ContinuousSet: - temp = list(exp_i_var) - else: - temp = [pyo.value(_) for _ in exp_i_var.values()] - if len(temp) == 1: - vals[var] = temp[0] - else: - vals[var] = temp - if len(vals) > 0: - var_values.append(vals) - var_values = pd.DataFrame(var_values) - if calc_cov: - return objval, thetavals, var_values, cov - else: - return objval, thetavals, var_values - - if calc_cov: - return objval, thetavals, cov - else: - return objval, thetavals - - else: - raise RuntimeError("Unknown solver in Q_Opt=" + solver) - - def _Q_at_theta(self, thetavals, initialize_parmest_model=False): - """ - Return the objective function value with fixed theta values. - - Parameters - ---------- - thetavals: dict - A dictionary of theta values. - - initialize_parmest_model: boolean - If True: Solve square problem instance, build extensive form of the model for - parameter estimation, and set flag model_initialized to True - - Returns - ------- - objectiveval: float - The objective function value. - thetavals: dict - A dictionary of all values for theta that were input. - solvertermination: Pyomo TerminationCondition - Tries to return the "worst" solver status across the scenarios. - pyo.TerminationCondition.optimal is the best and - pyo.TerminationCondition.infeasible is the worst. - """ - - optimizer = pyo.SolverFactory('ipopt') - - if len(thetavals) > 0: - dummy_cb = { - "callback": self._instance_creation_callback, - "ThetaVals": thetavals, - "theta_names": self._return_theta_names(), - "cb_data": self.callback_data, - } - else: - dummy_cb = { - "callback": self._instance_creation_callback, - "theta_names": self._return_theta_names(), - "cb_data": self.callback_data, - } - - if self.diagnostic_mode: - if len(thetavals) > 0: - print(' Compute objective at theta = ', str(thetavals)) - else: - print(' Compute objective at initial theta') - - # start block of code to deal with models with no constraints - # (ipopt will crash or complain on such problems without special care) - instance = _experiment_instance_creation_callback("FOO0", None, dummy_cb) - try: # deal with special problems so Ipopt will not crash - first = next(instance.component_objects(pyo.Constraint, active=True)) - active_constraints = True - except: - active_constraints = False - # end block of code to deal with models with no constraints - - WorstStatus = pyo.TerminationCondition.optimal - totobj = 0 - scenario_numbers = list(range(len(self.callback_data))) - if initialize_parmest_model: - # create dictionary to store pyomo model instances (scenarios) - scen_dict = dict() - - for snum in scenario_numbers: - sname = "scenario_NODE" + str(snum) - instance = _experiment_instance_creation_callback(sname, None, dummy_cb) - - if initialize_parmest_model: - # list to store fitted parameter names that will be unfixed - # after initialization - theta_init_vals = [] - # use appropriate theta_names member - theta_ref = self._return_theta_names() - - for i, theta in enumerate(theta_ref): - # Use parser in ComponentUID to locate the component - var_cuid = ComponentUID(theta) - var_validate = var_cuid.find_component_on(instance) - if var_validate is None: - logger.warning( - "theta_name %s was not found on the model", (theta) - ) - else: - try: - if len(thetavals) == 0: - var_validate.fix() - else: - var_validate.fix(thetavals[theta]) - theta_init_vals.append(var_validate) - except: - logger.warning( - 'Unable to fix model parameter value for %s (not a Pyomo model Var)', - (theta), - ) - - if active_constraints: - if self.diagnostic_mode: - print(' Experiment = ', snum) - print(' First solve with special diagnostics wrapper') - status_obj, solved, iters, time, regu = ( - utils.ipopt_solve_with_stats( - instance, optimizer, max_iter=500, max_cpu_time=120 - ) - ) - print( - " status_obj, solved, iters, time, regularization_stat = ", - str(status_obj), - str(solved), - str(iters), - str(time), - str(regu), - ) - - results = optimizer.solve(instance) - if self.diagnostic_mode: - print( - 'standard solve solver termination condition=', - str(results.solver.termination_condition), - ) - - if ( - results.solver.termination_condition - != pyo.TerminationCondition.optimal - ): - # DLW: Aug2018: not distinguishing "middlish" conditions - if WorstStatus != pyo.TerminationCondition.infeasible: - WorstStatus = results.solver.termination_condition - if initialize_parmest_model: - if self.diagnostic_mode: - print( - "Scenario {:d} infeasible with initialized parameter values".format( - snum - ) - ) - else: - if initialize_parmest_model: - if self.diagnostic_mode: - print( - "Scenario {:d} initialization successful with initial parameter values".format( - snum - ) - ) - if initialize_parmest_model: - # unfix parameters after initialization - for theta in theta_init_vals: - theta.unfix() - scen_dict[sname] = instance - else: - if initialize_parmest_model: - # unfix parameters after initialization - for theta in theta_init_vals: - theta.unfix() - scen_dict[sname] = instance - - objobject = getattr(instance, self._second_stage_cost_exp) - objval = pyo.value(objobject) - totobj += objval - - retval = totobj / len(scenario_numbers) # -1?? - if initialize_parmest_model and not hasattr(self, 'ef_instance'): - # create extensive form of the model using scenario dictionary - if len(scen_dict) > 0: - for scen in scen_dict.values(): - scen._mpisppy_probability = 1 / len(scen_dict) - - if use_mpisppy: - EF_instance = sputils._create_EF_from_scen_dict( - scen_dict, - EF_name="_Q_at_theta", - # suppress_warnings=True - ) - else: - EF_instance = local_ef._create_EF_from_scen_dict( - scen_dict, EF_name="_Q_at_theta", nonant_for_fixed_vars=True - ) - - self.ef_instance = EF_instance - # set self.model_initialized flag to True to skip extensive form model - # creation using theta_est() - self.model_initialized = True - - # return initialized theta values - if len(thetavals) == 0: - # use appropriate theta_names member - theta_ref = self._return_theta_names() - for i, theta in enumerate(theta_ref): - thetavals[theta] = theta_init_vals[i]() - - return retval, thetavals, WorstStatus - - def _get_sample_list(self, samplesize, num_samples, replacement=True): - samplelist = list() - - scenario_numbers = list(range(len(self.callback_data))) - - if num_samples is None: - # This could get very large - for i, l in enumerate(combinations(scenario_numbers, samplesize)): - samplelist.append((i, np.sort(l))) - else: - for i in range(num_samples): - attempts = 0 - unique_samples = 0 # check for duplicates in each sample - duplicate = False # check for duplicates between samples - while (unique_samples <= len(self._return_theta_names())) and ( - not duplicate - ): - sample = np.random.choice( - scenario_numbers, samplesize, replace=replacement - ) - sample = np.sort(sample).tolist() - unique_samples = len(np.unique(sample)) - if sample in samplelist: - duplicate = True - - attempts += 1 - if attempts > num_samples: # arbitrary timeout limit - raise RuntimeError("""Internal error: timeout constructing - a sample, the dim of theta may be too - close to the samplesize""") - - samplelist.append((i, sample)) - - return samplelist - - def theta_est( - self, solver="ef_ipopt", return_values=[], calc_cov=False, cov_n=None - ): - """ - Parameter estimation using all scenarios in the data - - Parameters - ---------- - solver: string, optional - Currently only "ef_ipopt" is supported. Default is "ef_ipopt". - return_values: list, optional - List of Variable names, used to return values from the model for data reconciliation - calc_cov: boolean, optional - If True, calculate and return the covariance matrix (only for "ef_ipopt" solver) - cov_n: int, optional - If calc_cov=True, then the user needs to supply the number of datapoints - that are used in the objective function - - Returns - ------- - objectiveval: float - The objective function value - thetavals: pd.Series - Estimated values for theta - variable values: pd.DataFrame - Variable values for each variable name in return_values (only for solver='ef_ipopt') - cov: pd.DataFrame - Covariance matrix of the fitted parameters (only for solver='ef_ipopt') - """ - assert isinstance(solver, str) - assert isinstance(return_values, list) - assert isinstance(calc_cov, bool) - if calc_cov: - assert isinstance( - cov_n, int - ), "The number of datapoints that are used in the objective function is required to calculate the covariance matrix" - assert cov_n > len( - self._return_theta_names() - ), "The number of datapoints must be greater than the number of parameters to estimate" - - return self._Q_opt( - solver=solver, - return_values=return_values, - bootlist=None, - calc_cov=calc_cov, - cov_n=cov_n, - ) - - def theta_est_bootstrap( - self, - bootstrap_samples, - samplesize=None, - replacement=True, - seed=None, - return_samples=False, - ): - """ - Parameter estimation using bootstrap resampling of the data - - Parameters - ---------- - bootstrap_samples: int - Number of bootstrap samples to draw from the data - samplesize: int or None, optional - Size of each bootstrap sample. If samplesize=None, samplesize will be - set to the number of samples in the data - replacement: bool, optional - Sample with or without replacement - seed: int or None, optional - Random seed - return_samples: bool, optional - Return a list of sample numbers used in each bootstrap estimation - - Returns - ------- - bootstrap_theta: pd.DataFrame - Theta values for each sample and (if return_samples = True) - the sample numbers used in each estimation - """ - assert isinstance(bootstrap_samples, int) - assert isinstance(samplesize, (type(None), int)) - assert isinstance(replacement, bool) - assert isinstance(seed, (type(None), int)) - assert isinstance(return_samples, bool) - - if samplesize is None: - samplesize = len(self.callback_data) - - if seed is not None: - np.random.seed(seed) - - global_list = self._get_sample_list(samplesize, bootstrap_samples, replacement) - - task_mgr = utils.ParallelTaskManager(bootstrap_samples) - local_list = task_mgr.global_to_local_data(global_list) - - bootstrap_theta = list() - for idx, sample in local_list: - objval, thetavals = self._Q_opt(bootlist=list(sample)) - thetavals['samples'] = sample - bootstrap_theta.append(thetavals) - - global_bootstrap_theta = task_mgr.allgather_global_data(bootstrap_theta) - bootstrap_theta = pd.DataFrame(global_bootstrap_theta) - - if not return_samples: - del bootstrap_theta['samples'] - - return bootstrap_theta - - def theta_est_leaveNout( - self, lNo, lNo_samples=None, seed=None, return_samples=False - ): - """ - Parameter estimation where N data points are left out of each sample - - Parameters - ---------- - lNo: int - Number of data points to leave out for parameter estimation - lNo_samples: int - Number of leave-N-out samples. If lNo_samples=None, the maximum - number of combinations will be used - seed: int or None, optional - Random seed - return_samples: bool, optional - Return a list of sample numbers that were left out - - Returns - ------- - lNo_theta: pd.DataFrame - Theta values for each sample and (if return_samples = True) - the sample numbers left out of each estimation - """ - assert isinstance(lNo, int) - assert isinstance(lNo_samples, (type(None), int)) - assert isinstance(seed, (type(None), int)) - assert isinstance(return_samples, bool) - - samplesize = len(self.callback_data) - lNo - - if seed is not None: - np.random.seed(seed) - - global_list = self._get_sample_list(samplesize, lNo_samples, replacement=False) - - task_mgr = utils.ParallelTaskManager(len(global_list)) - local_list = task_mgr.global_to_local_data(global_list) - - lNo_theta = list() - for idx, sample in local_list: - objval, thetavals = self._Q_opt(bootlist=list(sample)) - lNo_s = list(set(range(len(self.callback_data))) - set(sample)) - thetavals['lNo'] = np.sort(lNo_s) - lNo_theta.append(thetavals) - - global_bootstrap_theta = task_mgr.allgather_global_data(lNo_theta) - lNo_theta = pd.DataFrame(global_bootstrap_theta) - - if not return_samples: - del lNo_theta['lNo'] - - return lNo_theta - - def leaveNout_bootstrap_test( - self, lNo, lNo_samples, bootstrap_samples, distribution, alphas, seed=None - ): - """ - Leave-N-out bootstrap test to compare theta values where N data points are - left out to a bootstrap analysis using the remaining data, - results indicate if theta is within a confidence region - determined by the bootstrap analysis - - Parameters - ---------- - lNo: int - Number of data points to leave out for parameter estimation - lNo_samples: int - Leave-N-out sample size. If lNo_samples=None, the maximum number - of combinations will be used - bootstrap_samples: int: - Bootstrap sample size - distribution: string - Statistical distribution used to define a confidence region, - options = 'MVN' for multivariate_normal, 'KDE' for gaussian_kde, - and 'Rect' for rectangular. - alphas: list - List of alpha values used to determine if theta values are inside - or outside the region. - seed: int or None, optional - Random seed - - Returns - ---------- - List of tuples with one entry per lNo_sample: - - * The first item in each tuple is the list of N samples that are left - out. - * The second item in each tuple is a DataFrame of theta estimated using - the N samples. - * The third item in each tuple is a DataFrame containing results from - the bootstrap analysis using the remaining samples. - - For each DataFrame a column is added for each value of alpha which - indicates if the theta estimate is in (True) or out (False) of the - alpha region for a given distribution (based on the bootstrap results) - """ - assert isinstance(lNo, int) - assert isinstance(lNo_samples, (type(None), int)) - assert isinstance(bootstrap_samples, int) - assert distribution in ['Rect', 'MVN', 'KDE'] - assert isinstance(alphas, list) - assert isinstance(seed, (type(None), int)) - - if seed is not None: - np.random.seed(seed) - - data = self.callback_data.copy() - - global_list = self._get_sample_list(lNo, lNo_samples, replacement=False) - - results = [] - for idx, sample in global_list: - # Reset callback_data to only include the sample - self.callback_data = [data[i] for i in sample] - - obj, theta = self.theta_est() - - # Reset callback_data to include all scenarios except the sample - self.callback_data = [data[i] for i in range(len(data)) if i not in sample] - - bootstrap_theta = self.theta_est_bootstrap(bootstrap_samples) - - training, test = self.confidence_region_test( - bootstrap_theta, - distribution=distribution, - alphas=alphas, - test_theta_values=theta, - ) - - results.append((sample, test, training)) - - # Reset callback_data (back to full data set) - self.callback_data = data - - return results - - def objective_at_theta(self, theta_values=None, initialize_parmest_model=False): - """ - Objective value for each theta - - Parameters - ---------- - theta_values: pd.DataFrame, columns=theta_names - Values of theta used to compute the objective - - initialize_parmest_model: boolean - If True: Solve square problem instance, build extensive form of the model for - parameter estimation, and set flag model_initialized to True - - - Returns - ------- - obj_at_theta: pd.DataFrame - Objective value for each theta (infeasible solutions are - omitted). - """ - if len(self.theta_names) == 1 and self.theta_names[0] == 'parmest_dummy_var': - pass # skip assertion if model has no fitted parameters - else: - # create a local instance of the pyomo model to access model variables and parameters - model_temp = self._create_parmest_model(self.callback_data[0]) - model_theta_list = [] # list to store indexed and non-indexed parameters - # iterate over original theta_names - for theta_i in self.theta_names: - var_cuid = ComponentUID(theta_i) - var_validate = var_cuid.find_component_on(model_temp) - # check if theta in theta_names are indexed - try: - # get component UID of Set over which theta is defined - set_cuid = ComponentUID(var_validate.index_set()) - # access and iterate over the Set to generate theta names as they appear - # in the pyomo model - set_validate = set_cuid.find_component_on(model_temp) - for s in set_validate: - self_theta_temp = repr(var_cuid) + "[" + repr(s) + "]" - # generate list of theta names - model_theta_list.append(self_theta_temp) - # if theta is not indexed, copy theta name to list as-is - except AttributeError: - self_theta_temp = repr(var_cuid) - model_theta_list.append(self_theta_temp) - except: - raise - # if self.theta_names is not the same as temp model_theta_list, - # create self.theta_names_updated - if set(self.theta_names) == set(model_theta_list) and len( - self.theta_names - ) == set(model_theta_list): - pass - else: - self.theta_names_updated = model_theta_list - - if theta_values is None: - all_thetas = {} # dictionary to store fitted variables - # use appropriate theta names member - theta_names = self._return_theta_names() - else: - assert isinstance(theta_values, pd.DataFrame) - # for parallel code we need to use lists and dicts in the loop - theta_names = theta_values.columns - # # check if theta_names are in model - for theta in list(theta_names): - theta_temp = theta.replace("'", "") # cleaning quotes from theta_names - - assert theta_temp in [ - t.replace("'", "") for t in model_theta_list - ], "Theta name {} in 'theta_values' not in 'theta_names' {}".format( - theta_temp, model_theta_list - ) - assert len(list(theta_names)) == len(model_theta_list) - - all_thetas = theta_values.to_dict('records') - - if all_thetas: - task_mgr = utils.ParallelTaskManager(len(all_thetas)) - local_thetas = task_mgr.global_to_local_data(all_thetas) - else: - if initialize_parmest_model: - task_mgr = utils.ParallelTaskManager( - 1 - ) # initialization performed using just 1 set of theta values - # walk over the mesh, return objective function - all_obj = list() - if len(all_thetas) > 0: - for Theta in local_thetas: - obj, thetvals, worststatus = self._Q_at_theta( - Theta, initialize_parmest_model=initialize_parmest_model - ) - if worststatus != pyo.TerminationCondition.infeasible: - all_obj.append(list(Theta.values()) + [obj]) - # DLW, Aug2018: should we also store the worst solver status? - else: - obj, thetvals, worststatus = self._Q_at_theta( - thetavals={}, initialize_parmest_model=initialize_parmest_model - ) - if worststatus != pyo.TerminationCondition.infeasible: - all_obj.append(list(thetvals.values()) + [obj]) - - global_all_obj = task_mgr.allgather_global_data(all_obj) - dfcols = list(theta_names) + ['obj'] - obj_at_theta = pd.DataFrame(data=global_all_obj, columns=dfcols) - return obj_at_theta - - def likelihood_ratio_test( - self, obj_at_theta, obj_value, alphas, return_thresholds=False - ): - r""" - Likelihood ratio test to identify theta values within a confidence - region using the :math:`\chi^2` distribution - - Parameters - ---------- - obj_at_theta: pd.DataFrame, columns = theta_names + 'obj' - Objective values for each theta value (returned by - objective_at_theta) - obj_value: int or float - Objective value from parameter estimation using all data - alphas: list - List of alpha values to use in the chi2 test - return_thresholds: bool, optional - Return the threshold value for each alpha - - Returns - ------- - LR: pd.DataFrame - Objective values for each theta value along with True or False for - each alpha - thresholds: pd.Series - If return_threshold = True, the thresholds are also returned. - """ - assert isinstance(obj_at_theta, pd.DataFrame) - assert isinstance(obj_value, (int, float)) - assert isinstance(alphas, list) - assert isinstance(return_thresholds, bool) - - LR = obj_at_theta.copy() - S = len(self.callback_data) - thresholds = {} - for a in alphas: - chi2_val = scipy.stats.chi2.ppf(a, 2) - thresholds[a] = obj_value * ((chi2_val / (S - 2)) + 1) - LR[a] = LR['obj'] < thresholds[a] - - thresholds = pd.Series(thresholds) - - if return_thresholds: - return LR, thresholds - else: - return LR - - def confidence_region_test( - self, theta_values, distribution, alphas, test_theta_values=None - ): - """ - Confidence region test to determine if theta values are within a - rectangular, multivariate normal, or Gaussian kernel density distribution - for a range of alpha values - - Parameters - ---------- - theta_values: pd.DataFrame, columns = theta_names - Theta values used to generate a confidence region - (generally returned by theta_est_bootstrap) - distribution: string - Statistical distribution used to define a confidence region, - options = 'MVN' for multivariate_normal, 'KDE' for gaussian_kde, - and 'Rect' for rectangular. - alphas: list - List of alpha values used to determine if theta values are inside - or outside the region. - test_theta_values: pd.Series or pd.DataFrame, keys/columns = theta_names, optional - Additional theta values that are compared to the confidence region - to determine if they are inside or outside. - - Returns - training_results: pd.DataFrame - Theta value used to generate the confidence region along with True - (inside) or False (outside) for each alpha - test_results: pd.DataFrame - If test_theta_values is not None, returns test theta value along - with True (inside) or False (outside) for each alpha - """ - assert isinstance(theta_values, pd.DataFrame) - assert distribution in ['Rect', 'MVN', 'KDE'] - assert isinstance(alphas, list) - assert isinstance( - test_theta_values, (type(None), dict, pd.Series, pd.DataFrame) - ) - - if isinstance(test_theta_values, (dict, pd.Series)): - test_theta_values = pd.Series(test_theta_values).to_frame().transpose() - - training_results = theta_values.copy() - - if test_theta_values is not None: - test_result = test_theta_values.copy() - - for a in alphas: - if distribution == 'Rect': - lb, ub = graphics.fit_rect_dist(theta_values, a) - training_results[a] = (theta_values > lb).all(axis=1) & ( - theta_values < ub - ).all(axis=1) - - if test_theta_values is not None: - # use upper and lower bound from the training set - test_result[a] = (test_theta_values > lb).all(axis=1) & ( - test_theta_values < ub - ).all(axis=1) - - elif distribution == 'MVN': - dist = graphics.fit_mvn_dist(theta_values) - Z = dist.pdf(theta_values) - score = scipy.stats.scoreatpercentile(Z, (1 - a) * 100) - training_results[a] = Z >= score - - if test_theta_values is not None: - # use score from the training set - Z = dist.pdf(test_theta_values) - test_result[a] = Z >= score - - elif distribution == 'KDE': - dist = graphics.fit_kde_dist(theta_values) - Z = dist.pdf(theta_values.transpose()) - score = scipy.stats.scoreatpercentile(Z, (1 - a) * 100) - training_results[a] = Z >= score - - if test_theta_values is not None: - # use score from the training set - Z = dist.pdf(test_theta_values.transpose()) - test_result[a] = Z >= score - - if test_theta_values is not None: - return training_results, test_result - else: - return training_results From 78f65f38ff6cd99f5a2be01b5f88dde61cdb5d18 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Tue, 3 Mar 2026 00:51:38 -0500 Subject: [PATCH 29/32] Updated multistart example and code --- .../reactor_design/multistart_example.py | 40 +- .../reactor_design/multistart_example_old.py | 48 --- pyomo/contrib/parmest/parmest.py | 358 +++++------------- 3 files changed, 111 insertions(+), 335 deletions(-) delete mode 100644 pyomo/contrib/parmest/examples/reactor_design/multistart_example_old.py diff --git a/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py index 9008cd650c4..7f976335522 100644 --- a/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py +++ b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py @@ -24,27 +24,33 @@ def main(): data = pd.read_csv(file_name) # Create an experiment list - exp_list = [] - for i in range(data.shape[0]): - exp_list.append(ReactorDesignExperiment(data, i)) + exp_list = [ReactorDesignExperiment(data, i) for i in range(data.shape[0])] - # 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') + pest = parmest.Estimator(exp_list, obj_function="SSE", solver_options=solver_options) - # Parameter estimation + # Single-start estimation obj, theta = pest.theta_est() - - # Find the objective value at each theta estimate - k1 = [0.8, 1.6, 2.4] - k2 = [1.6, 2.4, 3.2] - k3 = [0.00016, 0.00032, 0.005] - theta_vals = pd.DataFrame(list(product(k1, k2, k3)), columns=["k1", "k2", "k3"]) - multistart_results = pest.theta_est_multistart(theta_vals) - - print(multistart_results) + 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__": diff --git a/pyomo/contrib/parmest/examples/reactor_design/multistart_example_old.py b/pyomo/contrib/parmest/examples/reactor_design/multistart_example_old.py deleted file mode 100644 index 033c0ddcdc5..00000000000 --- a/pyomo/contrib/parmest/examples/reactor_design/multistart_example_old.py +++ /dev/null @@ -1,48 +0,0 @@ -# ___________________________________________________________________________ -# -# Pyomo: Python Optimization Modeling Objects -# Copyright (c) 2008-2025 -# 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 -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 = [] - for i in range(data.shape[0]): - exp_list.append(ReactorDesignExperiment(data, i)) - - # View one model - # exp0_model = exp_list[0].get_labeled_model() - # exp0_model.pprint() - - pest = parmest.Estimator(exp_list, obj_function='SSE') - - # Parameter estimation - obj, theta = pest.theta_est() - - # Parameter estimation with multistart to avoid local minima - obj, theta = pest.theta_est_multistart( - num_starts=10, start_method='random', random_seed=42, max_iter=1000, tol=1e-6 - ) - - -if __name__ == "__main__": - main() diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 8358138764e..091592366de 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -1213,7 +1213,6 @@ def _generate_initial_theta( # Add columns for output info, initialized as nan for name in theta_names: df_multistart[f'converged_{name}'] = np.nan - df_multistart["initial objective"] = np.nan df_multistart["final objective"] = np.nan df_multistart["solver termination"] = np.nan df_multistart["solve_time"] = np.nan @@ -2029,302 +2028,121 @@ def leaveNout_bootstrap_test( return results - ''' - # TODO: Make the user provide a list of values, not the whole data frame - # TODO: Add a way to print the empty data_frame before solve so it can be previewed beforehand - # TODO: Fix so the theta values are generated at each iteration, not all beforehand in _generate_initial_theta - # Fix _generate_initial_theta to return an empty DataFrame first - # TODO: Add save model option to save the model after each iteration or at the end of the multistart + def theta_est_multistart( self, n_restarts=20, multistart_sampling_method="uniform_random", - user_provided_list=None, + user_provided_df=None, seed=None, - save_results=False, - theta_vals=None, + theta_values=None, # optional override: DataFrame of initial thetas solver="ef_ipopt", + save_results=False, file_name="multistart_results.csv", - return_values=[], ): - """ - Parameter estimation using multistart optimization - - Parameters - ---------- - n_restarts: int, optional - Number of restarts for multistart. Default is 1. - multistart_sampling_method: string, optional - Method used to sample theta values. Options are "uniform_random", "latin_hypercube", "sobol_sampling", or "user_provided_values". - Default is "uniform_random". - buffer: int, optional - Number of iterations to save results dynamically if save_results=True. Default is 10. - user_provided_df: pd.DataFrame, optional - User provided array or dataframe of theta values for multistart optimization. - seed: int, optional - Random seed for reproducibility. - save_results: bool, optional - If True, intermediate and final results are saved to file_name. - theta_vals: pd.DataFrame, optional - Initial theta values for restarts (overrides sampling). - solver: string, optional - Currently only "ef_ipopt" is supported. Default is "ef_ipopt". - file_name: str, optional - File name for saving results if save_results is True. - return_values: list, optional - List of Variable names, used to return values from the model for data reconciliation. - - Returns - ------- - results_df: pd.DataFrame - DataFrame containing initial and converged theta values, objectives, and solver info for each restart. - best_theta: dict - Dictionary of theta values corresponding to the best (lowest) objective value found. - best_objectiveval: float - The best (lowest) objective function value found across all restarts. - """ - - # check if we are using deprecated parmest if self.pest_deprecated is not None: - return print( - "Multistart is not supported in the deprecated parmest interface" - ) + raise RuntimeError("Multistart is not supported in the deprecated parmest interface.") - # Validate input types - if not isinstance(n_restarts, int): - raise TypeError("n_restarts must be an integer") - if not isinstance(multistart_sampling_method, str): - raise TypeError("multistart_sampling_method must be a string") - if not isinstance(solver, str): - raise TypeError("solver must be a string") - if not isinstance(return_values, list): - raise TypeError("return_values must be a list") - - if n_restarts <= 1: - # If n_restarts is 1 or less, no multistart optimization is needed - logger.warning( - "No multistart optimization needed. Please use normal theta_est()." - ) - return self.theta_est( - solver=solver, return_values=return_values, calc_cov=False, cov_n=None - ) + # ---- Build results_df in the canonical schema (theta cols + output cols) ---- + if theta_values is not None: + if not isinstance(theta_values, pd.DataFrame): + raise TypeError("theta_values must be a pandas DataFrame (columns = theta names).") - if n_restarts > 1 and multistart_sampling_method is not None: + init_df = theta_values.copy() - # Find the initialized values of theta from the labeled parmest model - # and the theta names from the estimator object + # Normalize/validate names (same idea as your existing code) + clean_provided = [c.replace("'", "") for c in init_df.columns] + expected = [ + t.replace("'", "") + for t in self._expand_indexed_unknowns(self._create_parmest_model(0)) + ] + if set(clean_provided) != set(expected): + raise ValueError( + f"Provided theta_values columns {clean_provided} do not match expected {expected}." + ) + init_df.columns = clean_provided + theta_names = list(init_df.columns) - # logger statement to indicate multistart optimization is starting - logger.info( - f"Starting multistart optimization with {n_restarts} restarts using {multistart_sampling_method} sampling method." - ) + results_df = init_df.copy() + for name in theta_names: + results_df[f"converged_{name}"] = np.nan + results_df["final objective"] = np.nan + results_df["solver termination"] = np.nan + results_df["solve_time"] = np.nan - # @Reviewers, pyomo team: Use this or use instance creation callback? - theta_names = self._return_theta_names() - # Generate theta values using the sampling method + else: + # Use your canonical initializer parmest_model_for_bounds = self._create_parmest_model(experiment_number=0) results_df = self._generate_initial_theta( - parmest_model_for_bounds, + parmest_model=parmest_model_for_bounds, seed=seed, n_restarts=n_restarts, multistart_sampling_method=multistart_sampling_method, user_provided_df=user_provided_df, ) - results_df = pd.DataFrame(results_df) - # Extract theta_vals from the dataframe - theta_vals = results_df.iloc[:, : len(theta_names)] - converged_theta_vals = np.zeros((n_restarts, len(theta_names))) - - timer = TicTocTimer() - - # Each restart uses a fresh model instance - for i in range(n_restarts): - - # Add a timer for each restart - timer.tic(f"Restart {i+1}/{n_restarts}") - - # No longer needed, keeping until confirming update works as expected - # # Create a fresh model for each restart - # parmest_model = self._create_parmest_model(experiment_number=0) - theta_vals_current = theta_vals.iloc[i, :].to_dict() - # If theta_vals is provided, use it to set the current theta values - # # Convert values to a list - # theta_vals_current = list(theta_vals.iloc[i, :]) - - # # Update the model with the current theta values - # update_model_from_suffix(parmest_model, 'experiment_inputs', theta_vals_current) - - # # Set current theta values in the model - # for name, value in theta_vals_current.items(): - # parmest_model.find_component(name).set_value(value) - - # # Optional: Print the current theta values being set - # print(f"Setting {name} to {value}") - # for name in theta_names: - # current_value = parmest_model.find_component(name)() - # print(f"Current value of {name} is {current_value}") - - # Call the _Q_opt method with the generated theta values - qopt_result = self._Q_opt( - ThetaVals=theta_vals_current, - bootlist=None, + + # theta columns are the first |theta_names| columns (by construction) + # safest: infer from expected model names + theta_names = self._expand_indexed_unknowns(self._create_parmest_model(0)) + # also normalize in case of quotes: + theta_names = [t.replace("'", "") for t in theta_names] + + # Convert each row to (row_index, theta_dict) + tasks = [] + for i in range(results_df.shape[0]): + Theta = {name: float(results_df.loc[i, name]) for name in theta_names} + tasks.append((i, Theta)) + + task_mgr = utils.ParallelTaskManager(len(tasks)) + local_tasks = task_mgr.global_to_local_data(tasks) + + # Solve in parallel + local_results = [] + for i, Theta in local_tasks: + import time + t0 = time.time() + try: + final_obj, theta_hat, worst = self._Q_opt( + theta_vals=Theta, solver=solver, - return_values=return_values, multistart=True, ) - - # Unpack results - objectiveval, converged_theta, solver_info = qopt_result - - # Added an extra option to Q_opt to return the full solver result if multistart=True - solver_termination = solver_info.solver.termination_condition - if solver_termination != pyo.TerminationCondition.optimal: - # If the solver did not converge, set the converged theta to NaN - solve_time = np.nan - final_objectiveval = np.nan - init_objectiveval = np.nan - else: - converged_theta_vals[i, :] = converged_theta.values - # Calculate the initial objective value using the current theta values - # Use the _Q_at_theta method to evaluate the objective at these theta values - init_objectiveval, _, _ = self._Q_at_theta(theta_vals_current) - final_objectiveval = objectiveval - - # # Check if the objective value is better than the best objective value - # # Set a very high initial best objective value - if i == 0: - # Initialize best objective value and theta - best_objectiveval = np.inf - best_theta = np.inf - # Check if the final objective value is better than the best found so far - if final_objectiveval < best_objectiveval: - best_objectiveval = objectiveval - best_theta = converged_theta.values - - logger.info( - f"Restart {i+1}/{n_restarts}: Objective Value = {final_objectiveval}, Theta = {converged_theta}" - ) - - # Stop the timer for this restart - solve_time = timer.toc(f"Restart {i+1}/{n_restarts}") - - # Store the results in the DataFrame for this restart - # Fill converged theta values - for j, name in enumerate(theta_names): - results_df.at[i, f'converged_{name}'] = ( - converged_theta.iloc[j] - if not np.isnan(converged_theta_vals[i, j]) - else np.nan - ) - # Fill initial and final objective values, solver termination, and solve time - results_df.at[i, "initial objective"] = ( - init_objectiveval if 'init_objectiveval' in locals() else np.nan - ) - results_df.at[i, "final objective"] = ( - objectiveval if 'objectiveval' in locals() else np.nan - ) - results_df.at[i, "solver termination"] = ( - solver_termination if 'solver_termination' in locals() else np.nan - ) - results_df.at[i, "solve_time"] = ( - solve_time if 'solve_time' in locals() else np.nan - ) - - # Diagnostic: print the table after each restart - logger.debug(results_df) - - # Add buffer to save the dataframe dynamically, if save_results is True - if save_results and (i + 1) % buffer == 0: - mode = 'w' if i + 1 == buffer else 'a' - header = i + 1 == buffer - results_df.to_csv(file_name, mode=mode, header=header, index=False) - logger.info(f"Intermediate results saved after {i + 1} iterations.") - - # Final save after all iterations - if save_results: - results_df.to_csv(file_name, mode='a', header=False, index=False) - logger.info("Final results saved.") - - return results_df, best_theta, best_objectiveval - ''' - - # Updated version that uses _Q_opt - def theta_est_multistart(self, theta_values=None): - """ - Objective value for each theta, solving parameter estimation problem for each theta value provided. - - Parameters - ---------- - theta_values: pd.DataFrame, columns=theta_names - Values of theta used to compute the objective - - Returns - ------- - obj_at_theta: pd.DataFrame - Objective value for each theta (infeasible solutions are - omitted). - """ - - if theta_values is None: - all_thetas = {} # dictionary to store fitted variables - # use appropriate theta names member - # Get theta names from fresh parmest model, assuming this can be called - # directly after creating Estimator. - theta_names = self._expand_indexed_unknowns(self._create_parmest_model(0)) + solve_time = time.time() - t0 + local_results.append((i, final_obj, str(worst), solve_time, theta_hat)) + except Exception as exc: + solve_time = time.time() - t0 + local_results.append((i, np.nan, f"exception: {exc}", solve_time, None)) + + global_results = task_mgr.allgather_global_data(local_results) + + # Fill results_df + for i, final_obj, term, solve_time, theta_hat in global_results: + results_df.at[i, "final objective"] = final_obj + results_df.at[i, "solver termination"] = term + results_df.at[i, "solve_time"] = solve_time + + if theta_hat is not None: + for name in theta_names: + if name in theta_hat: + results_df.at[i, f"converged_{name}"] = float(theta_hat[name]) + + # Best solution (ignore NaNs) + feasible = results_df["final objective"].replace([np.inf, -np.inf], np.nan).dropna() + if len(feasible) == 0: + best_theta = None + best_obj = np.nan else: - assert isinstance(theta_values, pd.DataFrame) - # for parallel code we need to use lists and dicts in the loop - theta_names = theta_values.columns - # # check if theta_names are in model - # Clean names, ignore quotes, and compare sets - clean_provided = [t.replace("'", "") for t in theta_names] - clean_expected = [ - t.replace("'", "") - for t in self._expand_indexed_unknowns(self._create_parmest_model(0)) - ] - # If they do not match, raise error - if set(clean_provided) != set(clean_expected): - raise ValueError( - f"Provided theta values {clean_provided} do not match expected theta names {clean_expected}." - ) - # Rename columns using cleaned names - if set(clean_provided) != set(theta_names): - theta_values.columns = clean_provided - - # Convert to list of dicts for parallel processing - all_thetas = theta_values.to_dict('records') - - # Initialize task manager - num_tasks = len(all_thetas) if all_thetas else 1 - task_mgr = utils.ParallelTaskManager(num_tasks) + best_idx = feasible.idxmin() + best_obj = float(results_df.loc[best_idx, "final objective"]) + best_theta = { + name: float(results_df.loc[best_idx, f"converged_{name}"]) + for name in theta_names + } - # Use local theta values for each task if all_thetas is provided, else empty list - if all_thetas: - local_thetas = task_mgr.global_to_local_data(all_thetas) + if save_results: + results_df.to_csv(file_name, index=False) - # walk over the mesh, return objective function - all_obj = list() - if len(all_thetas) > 0: - print("Running multistart parameter estimation...") - for Theta in local_thetas: - obj, thetvals, worststatus = self._Q_opt( - theta_vals=Theta, multistart=True - ) - if worststatus != pyo.TerminationCondition.infeasible: - # Make list out of - # Append original theta values, objective value, and estimated theta values to all_obj - all_obj.append( - list(Theta.values()) + [obj] + list(thetvals.values()) - ) - else: - obj, thetvals, worststatus = self._Q_opt(theta_vals=None, multistart=True) - if worststatus != pyo.TerminationCondition.infeasible: - all_obj.append(list(thetvals.values()) + [obj]) - - global_all_obj = task_mgr.allgather_global_data(all_obj) - dfcols = list(theta_names) + ['obj'] + list(thetvals.keys()) - obj_at_theta = pd.DataFrame(data=global_all_obj, columns=dfcols) - return obj_at_theta + return results_df, best_theta, best_obj # Updated version that uses _Q_opt def objective_at_theta(self, theta_values=None, initialize_parmest_model=False): From 43a67ab46ace6dafa753a74a255fc31be80ea27c Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Tue, 3 Mar 2026 01:10:02 -0500 Subject: [PATCH 30/32] Added bounds to models, ran black --- .../reactor_design/multistart_example.py | 9 ++--- .../examples/reactor_design/reactor_design.py | 10 +++-- .../rooney_biegler/multistart_example.py | 37 +++++++++++-------- .../examples/rooney_biegler/rooney_biegler.py | 4 +- pyomo/contrib/parmest/parmest.py | 22 ++++++----- 5 files changed, 47 insertions(+), 35 deletions(-) diff --git a/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py index 7f976335522..cfb9eea9798 100644 --- a/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py +++ b/pyomo/contrib/parmest/examples/reactor_design/multistart_example.py @@ -27,12 +27,11 @@ def main(): 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, - } + solver_options = {"max_iter": 1000, "tol": 1e-6} - pest = parmest.Estimator(exp_list, obj_function="SSE", solver_options=solver_options) + pest = parmest.Estimator( + exp_list, obj_function="SSE", solver_options=solver_options + ) # Single-start estimation obj, theta = pest.theta_est() diff --git a/pyomo/contrib/parmest/examples/reactor_design/reactor_design.py b/pyomo/contrib/parmest/examples/reactor_design/reactor_design.py index 6172096e1ad..6a065d20a63 100644 --- a/pyomo/contrib/parmest/examples/reactor_design/reactor_design.py +++ b/pyomo/contrib/parmest/examples/reactor_design/reactor_design.py @@ -23,10 +23,14 @@ def reactor_design_model(): model = pyo.ConcreteModel() # Rate constants, make unknown parameters variables - model.k1 = pyo.Var(initialize=5.0 / 6.0, within=pyo.PositiveReals) # min^-1 - model.k2 = pyo.Var(initialize=5.0 / 3.0, within=pyo.PositiveReals) # min^-1 + model.k1 = pyo.Var( + initialize=5.0 / 6.0, within=pyo.PositiveReals, bounds=(0.1, 10.0) + ) # min^-1 + model.k2 = pyo.Var( + initialize=5.0 / 3.0, within=pyo.PositiveReals, bounds=(0.1, 10.0) + ) # min^-1 model.k3 = pyo.Var( - initialize=1.0 / 6000.0, within=pyo.PositiveReals + initialize=1.0 / 6000.0, within=pyo.PositiveReals, bounds=(1e-5, 1e-3) ) # m^3/(gmol min) # Inlet concentration of A, gmol/m^3 diff --git a/pyomo/contrib/parmest/examples/rooney_biegler/multistart_example.py b/pyomo/contrib/parmest/examples/rooney_biegler/multistart_example.py index 228feb7387b..7ff8f55ad4b 100644 --- a/pyomo/contrib/parmest/examples/rooney_biegler/multistart_example.py +++ b/pyomo/contrib/parmest/examples/rooney_biegler/multistart_example.py @@ -23,11 +23,6 @@ def main(): columns=['hour', 'y'], ) - # Sum of squared error function - def SSE(model): - expr = (model.experiment_outputs[model.y] - model.y) ** 2 - return expr - # Create an experiment list exp_list = [] for i in range(data.shape[0]): @@ -37,20 +32,30 @@ def SSE(model): # exp0_model = exp_list[0].get_labeled_model() # exp0_model.pprint() - # Create an instance of the parmest estimator - pest = parmest.Estimator(exp_list, obj_function=SSE, tee=True) + # Solver options belong here (Ipopt options shown as example) + solver_options = {"max_iter": 1000, "tol": 1e-6} - # Parameter estimation - obj, theta = pest.theta_est() + pest = parmest.Estimator( + exp_list, obj_function="SSE", solver_options=solver_options + ) - # Find the objective value at each theta estimate - asym = np.arange(10, 30, 2) - rate = np.arange(0, 1.5, 0.1) - theta_vals = pd.DataFrame( - list(product(asym, rate)), columns=['asymptote', 'rate_constant'] + # 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= ) - multistart_results = pest.theta_est_multistart(theta_vals) - print(multistart_results) + + print("\nMultistart best objective:", best_obj) + print("Multistart best theta:", best_theta) + print("\nAll multistart results:") + print(results_df) if __name__ == "__main__": diff --git a/pyomo/contrib/parmest/examples/rooney_biegler/rooney_biegler.py b/pyomo/contrib/parmest/examples/rooney_biegler/rooney_biegler.py index bdb494bca03..4ed4e8fc947 100644 --- a/pyomo/contrib/parmest/examples/rooney_biegler/rooney_biegler.py +++ b/pyomo/contrib/parmest/examples/rooney_biegler/rooney_biegler.py @@ -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() diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 091592366de..4c5f8eaab70 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -1087,7 +1087,7 @@ def total_obj(m): model.Obj = pyo.Objective(rule=total_obj, sense=pyo.minimize) return model - + # TODO: Make so this generates the initial DATAFRAME, not the entire list of values. # Make new private method, _generate_initial_theta: # This method will be used to generate the initial theta values for multistart @@ -2028,25 +2028,28 @@ def leaveNout_bootstrap_test( return results - def theta_est_multistart( self, n_restarts=20, multistart_sampling_method="uniform_random", user_provided_df=None, seed=None, - theta_values=None, # optional override: DataFrame of initial thetas + theta_values=None, # optional override: DataFrame of initial thetas solver="ef_ipopt", save_results=False, file_name="multistart_results.csv", ): if self.pest_deprecated is not None: - raise RuntimeError("Multistart is not supported in the deprecated parmest interface.") + raise RuntimeError( + "Multistart is not supported in the deprecated parmest interface." + ) # ---- Build results_df in the canonical schema (theta cols + output cols) ---- if theta_values is not None: if not isinstance(theta_values, pd.DataFrame): - raise TypeError("theta_values must be a pandas DataFrame (columns = theta names).") + raise TypeError( + "theta_values must be a pandas DataFrame (columns = theta names)." + ) init_df = theta_values.copy() @@ -2100,12 +2103,11 @@ def theta_est_multistart( local_results = [] for i, Theta in local_tasks: import time + t0 = time.time() try: final_obj, theta_hat, worst = self._Q_opt( - theta_vals=Theta, - solver=solver, - multistart=True, + theta_vals=Theta, solver=solver, multistart=True ) solve_time = time.time() - t0 local_results.append((i, final_obj, str(worst), solve_time, theta_hat)) @@ -2127,7 +2129,9 @@ def theta_est_multistart( results_df.at[i, f"converged_{name}"] = float(theta_hat[name]) # Best solution (ignore NaNs) - feasible = results_df["final objective"].replace([np.inf, -np.inf], np.nan).dropna() + feasible = ( + results_df["final objective"].replace([np.inf, -np.inf], np.nan).dropna() + ) if len(feasible) == 0: best_theta = None best_obj = np.nan From 813a981d7978fd4b9c63c3753ca8a92efa68ae54 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Fri, 6 Mar 2026 00:38:07 -0500 Subject: [PATCH 31/32] Adjusted implementation, added new tests in separate file --- pyomo/contrib/parmest/parmest.py | 154 ++++--- .../parmest/tests/test_parmest_multistart.py | 395 ++++++++++++++++++ 2 files changed, 489 insertions(+), 60 deletions(-) create mode 100644 pyomo/contrib/parmest/tests/test_parmest_multistart.py diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 3b3eaa4cbdb..63dc73ec26b 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -1093,31 +1093,36 @@ def _generate_initial_theta( """ Generate initial theta values for multistart optimization using selected sampling method. """ - # Locate the unknown parameters in the model from the suffix - suffix_params = parmest_model.unknown_parameters - - # Get the VarData objects from the suffix - theta_vars = list(suffix_params.keys()) + if parmest_model is None: + raise ValueError("A labeled parmest model must be provided.") + if not isinstance(n_restarts, int): + raise TypeError("n_restarts must be an integer.") + if n_restarts <= 0: + raise ValueError("n_restarts must be greater than zero.") + + theta_names = self._expand_indexed_unknowns(parmest_model) + theta_vars = [parmest_model.find_component(name) for name in theta_names] + if any(v is None for v in theta_vars): + raise RuntimeError( + "Failed to locate one or more theta components on model." + ) - # Extract names, starting values, and bounds for the theta variables - theta_names = [v.name for v in theta_vars] - initial_theta = np.array([v.value for v in theta_vars]) - lower_bound = np.array([v.lb for v in theta_vars]) - upper_bound = np.array([v.ub for v in theta_vars]) + lower_bound = np.array([v.lb for v in theta_vars], dtype=float) + upper_bound = np.array([v.ub for v in theta_vars], dtype=float) - # Check if the lower and upper bounds are defined - if any(bound is None for bound in lower_bound) or any( - bound is None for bound in upper_bound - ): + if np.any(np.isnan(lower_bound)) or np.any(np.isnan(upper_bound)): raise ValueError( "The lower and upper bounds for the theta values must be defined." ) + if np.any(lower_bound > upper_bound): + raise ValueError( + "Each lower bound must be less than or equal to the corresponding upper bound." + ) if multistart_sampling_method == "uniform_random": - # Generate random theta values using uniform distribution, with set seed for reproducibility - np.random.seed(seed) - # Generate random theta values for each restart (n_restarts x len(theta_names)) - theta_vals_multistart = np.random.uniform( + # Use a local RNG to avoid mutating global random state. + rng = np.random.default_rng(seed) + theta_vals_multistart = rng.uniform( low=lower_bound, high=upper_bound, size=(n_restarts, len(theta_names)) ) @@ -1137,36 +1142,33 @@ def _generate_initial_theta( samples = sampler.random(n=n_restarts + 1)[1:] elif multistart_sampling_method == "user_provided_values": - # Add user provided dataframe option - if user_provided_df is not None: - - if isinstance(user_provided_df, pd.DataFrame): - # Check if the user provided dataframe has the same number of rows as the number of restarts - if user_provided_df.shape[0] != n_restarts: - raise ValueError( - "The user provided dataframe must have the same number of rows as the number of restarts." - ) - # Check if the user provided dataframe has the same number of columns as the number of theta names - if user_provided_df.shape[1] != len(theta_names): - raise ValueError( - "The user provided dataframe must have the same number of columns as the number of theta names." - ) - # Check if the user provided dataframe has the same theta names as the model - # if not, raise an error - if not all( - theta in theta_names for theta in user_provided_df.columns - ): - raise ValueError( - "The user provided dataframe must have the same theta names as the model." - ) - # If all checks pass, return the user provided dataframe - theta_vals_multistart = user_provided_df.iloc[ - 0 : len(initial_theta) - ].values - else: + if user_provided_df is None: raise ValueError( "The user must provide a pandas dataframe to use the 'user_provided_values' method." ) + if not isinstance(user_provided_df, pd.DataFrame): + raise TypeError("user_provided_df must be a pandas DataFrame.") + if user_provided_df.shape[0] != n_restarts: + raise ValueError( + "The user provided dataframe must have the same number of rows as the number of restarts." + ) + if user_provided_df.shape[1] != len(theta_names): + raise ValueError( + "The user provided dataframe must have the same number of columns as the number of theta names." + ) + clean_cols = [str(c).replace("'", "") for c in user_provided_df.columns] + if len(clean_cols) != len(set(clean_cols)): + raise ValueError("Duplicate theta columns are not allowed.") + expected_clean = [t.replace("'", "") for t in theta_names] + if set(clean_cols) != set(expected_clean): + raise ValueError( + "The user provided dataframe must have the same theta names as the model." + ) + df_clean = user_provided_df.copy() + df_clean.columns = clean_cols + # Reindex by name to avoid column-order based value remapping. + df_clean = df_clean.reindex(columns=expected_clean) + theta_vals_multistart = df_clean.values else: raise ValueError( @@ -1186,12 +1188,7 @@ def _generate_initial_theta( # Create a DataFrame where each row is an initial theta vector for a restart, # columns are theta_names, and values are the initial theta values for each restart if multistart_sampling_method == "user_provided_values": - # If user_provided_values is a DataFrame, use its columns and values directly - if isinstance(user_provided_df, pd.DataFrame): - df_multistart = user_provided_df.copy() - df_multistart.columns = theta_names - else: - df_multistart = pd.DataFrame(theta_vals_multistart, columns=theta_names) + df_multistart = pd.DataFrame(theta_vals_multistart, columns=theta_names) else: # Ensure theta_vals_multistart is 2D (n_restarts, len(theta_names)) arr = np.atleast_2d(theta_vals_multistart) @@ -1199,11 +1196,17 @@ def _generate_initial_theta( arr = np.tile(arr, (n_restarts, 1)) df_multistart = pd.DataFrame(arr, columns=theta_names) + theta_arr = df_multistart[theta_names].to_numpy(dtype=float) + if not np.isfinite(theta_arr).all(): + raise ValueError("Initial theta values must be finite.") + if np.any(theta_arr < lower_bound) or np.any(theta_arr > upper_bound): + raise ValueError("Initial theta values must be within model bounds.") + # Add columns for output info, initialized as nan for name in theta_names: df_multistart[f'converged_{name}'] = np.nan df_multistart["final objective"] = np.nan - df_multistart["solver termination"] = np.nan + df_multistart["solver termination"] = "" df_multistart["solve_time"] = np.nan # Debugging output @@ -2032,6 +2035,10 @@ def theta_est_multistart( raise RuntimeError( "Multistart is not supported in the deprecated parmest interface." ) + if not isinstance(n_restarts, int): + raise TypeError("n_restarts must be an integer.") + if n_restarts <= 0: + raise ValueError("n_restarts must be greater than zero.") # ---- Build results_df in the canonical schema (theta cols + output cols) ---- if theta_values is not None: @@ -2048,18 +2055,26 @@ def theta_est_multistart( t.replace("'", "") for t in self._expand_indexed_unknowns(self._create_parmest_model(0)) ] + if len(clean_provided) != len(set(clean_provided)): + raise ValueError("Duplicate theta names are not allowed.") if set(clean_provided) != set(expected): raise ValueError( f"Provided theta_values columns {clean_provided} do not match expected {expected}." ) init_df.columns = clean_provided - theta_names = list(init_df.columns) + theta_names = list(expected) + init_df = init_df.reindex(columns=theta_names) + if init_df.shape[0] == 0: + raise ValueError("theta_values must contain at least one row.") + n_restarts = init_df.shape[0] + if not np.isfinite(init_df.to_numpy(dtype=float)).all(): + raise ValueError("theta_values must contain only finite values.") results_df = init_df.copy() for name in theta_names: results_df[f"converged_{name}"] = np.nan results_df["final objective"] = np.nan - results_df["solver termination"] = np.nan + results_df["solver termination"] = "" results_df["solve_time"] = np.nan else: @@ -2102,7 +2117,15 @@ def theta_est_multistart( local_results.append((i, final_obj, str(worst), solve_time, theta_hat)) except Exception as exc: solve_time = time.time() - t0 - local_results.append((i, np.nan, f"exception: {exc}", solve_time, None)) + local_results.append( + ( + i, + np.nan, + f"exception(start={i}, sampler={multistart_sampling_method}): {exc}", + solve_time, + None, + ) + ) global_results = task_mgr.allgather_global_data(local_results) @@ -2117,15 +2140,26 @@ def theta_est_multistart( if name in theta_hat: results_df.at[i, f"converged_{name}"] = float(theta_hat[name]) - # Best solution (ignore NaNs) - feasible = ( - results_df["final objective"].replace([np.inf, -np.inf], np.nan).dropna() + # Best solution: + # prioritize starts with acceptable solver terminations, then minimum objective. + acceptable_terms = { + str(pyo.TerminationCondition.optimal), + str(pyo.TerminationCondition.locallyOptimal), + str(pyo.TerminationCondition.globallyOptimal), + } + finite_obj_mask = np.isfinite( + results_df["final objective"].to_numpy(dtype=float) ) - if len(feasible) == 0: + acceptable_mask = results_df["solver termination"].isin(acceptable_terms) + ranked = results_df[finite_obj_mask & acceptable_mask] + if ranked.empty: + ranked = results_df[finite_obj_mask] + + if ranked.empty: best_theta = None best_obj = np.nan else: - best_idx = feasible.idxmin() + best_idx = ranked["final objective"].astype(float).idxmin() best_obj = float(results_df.loc[best_idx, "final objective"]) best_theta = { name: float(results_df.loc[best_idx, f"converged_{name}"]) diff --git a/pyomo/contrib/parmest/tests/test_parmest_multistart.py b/pyomo/contrib/parmest/tests/test_parmest_multistart.py new file mode 100644 index 00000000000..b8d330603ae --- /dev/null +++ b/pyomo/contrib/parmest/tests/test_parmest_multistart.py @@ -0,0 +1,395 @@ +# ___________________________________________________________________________ +# +# 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. +# ___________________________________________________________________________ + +import math + +import pyomo.common.unittest as unittest +import pyomo.environ as pyo +from pyomo.common.dependencies import numpy as np, pandas as pd +from unittest.mock import patch + +import pyomo.contrib.parmest.parmest as parmest +from pyomo.contrib.parmest.experiment import Experiment + +ipopt_available = pyo.SolverFactory("ipopt").available() + + +class LinearThetaExperiment(Experiment): + def __init__(self, x, y): + self.x_data = x + self.y_data = y + self.model = None + + def create_model(self): + m = pyo.ConcreteModel() + m.theta = pyo.Var(initialize=0.0, bounds=(-10.0, 10.0)) + m.x = pyo.Param(initialize=float(self.x_data), mutable=False) + m.y = pyo.Var(initialize=float(self.y_data)) + m.eq = pyo.Constraint(expr=m.y == m.theta + m.x) + self.model = m + + def label_model(self): + m = self.model + m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.experiment_outputs.update([(m.y, float(self.y_data))]) + m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.unknown_parameters.update([(m.theta, pyo.ComponentUID(m.theta))]) + m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.measurement_error.update([(m.y, None)]) + + def get_labeled_model(self): + self.create_model() + self.label_model() + return self.model + + +class IndexedThetaExperiment(Experiment): + def __init__(self): + self.model = None + + def create_model(self): + m = pyo.ConcreteModel() + m.I = pyo.Set(initialize=["a", "b"]) + m.theta = pyo.Var(m.I, initialize={"a": 1.0, "b": 2.0}) + m.theta["a"].setlb(0.0) + m.theta["a"].setub(5.0) + m.theta["b"].setlb(0.0) + m.theta["b"].setub(5.0) + m.theta["a"].fix() + m.theta["b"].fix() + m.y = pyo.Var(initialize=3.0) + m.eq = pyo.Constraint(expr=m.y == m.theta["a"] + m.theta["b"]) + self.model = m + + def label_model(self): + m = self.model + m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.experiment_outputs.update([(m.y, 3.0)]) + m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.unknown_parameters.update([(m.theta, pyo.ComponentUID(m.theta))]) + m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.measurement_error.update([(m.y, None)]) + + def get_labeled_model(self): + self.create_model() + self.label_model() + return self.model + + +class NoBoundsExperiment(Experiment): + def __init__(self): + self.model = None + + def create_model(self): + m = pyo.ConcreteModel() + m.theta = pyo.Var(initialize=1.0) + m.y = pyo.Var(initialize=2.0) + m.eq = pyo.Constraint(expr=m.y == m.theta + 1.0) + self.model = m + + def label_model(self): + m = self.model + m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.experiment_outputs.update([(m.y, 2.0)]) + m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.unknown_parameters.update([(m.theta, pyo.ComponentUID(m.theta))]) + m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.measurement_error.update([(m.y, None)]) + + def get_labeled_model(self): + self.create_model() + self.label_model() + return self.model + + +def _build_linear_estimator(): + exp_list = [LinearThetaExperiment(1.0, 2.0), LinearThetaExperiment(2.0, 3.0)] + return parmest.Estimator(exp_list, obj_function="SSE") + + +@unittest.skipIf( + not parmest.parmest_available, + "Cannot test parmest: required dependencies are missing", +) +class TestParmestMultistart(unittest.TestCase): + @unittest.skipIf(not ipopt_available, "The 'ipopt' solver is not available") + def test_multistart_baseline_equivalence_n1(self): + pest = _build_linear_estimator() + obj1, theta1 = pest.theta_est() + _, best_theta, best_obj = pest.theta_est_multistart( + n_restarts=1, multistart_sampling_method="uniform_random", seed=7 + ) + self.assertAlmostEqual(obj1, best_obj, places=7) + self.assertAlmostEqual(theta1["theta"], best_theta["theta"], places=7) + + def test_uniform_sampling_is_deterministic_with_seed(self): + pest = _build_linear_estimator() + model = pest._create_parmest_model(0) + df1 = pest._generate_initial_theta( + parmest_model=model, + seed=4, + n_restarts=5, + multistart_sampling_method="uniform_random", + ) + df2 = pest._generate_initial_theta( + parmest_model=model, + seed=4, + n_restarts=5, + multistart_sampling_method="uniform_random", + ) + self.assertTrue(df1[["theta"]].equals(df2[["theta"]])) + + def test_uniform_sampling_changes_with_different_seed(self): + pest = _build_linear_estimator() + model = pest._create_parmest_model(0) + df1 = pest._generate_initial_theta( + parmest_model=model, + seed=4, + n_restarts=5, + multistart_sampling_method="uniform_random", + ) + df2 = pest._generate_initial_theta( + parmest_model=model, + seed=5, + n_restarts=5, + multistart_sampling_method="uniform_random", + ) + self.assertFalse(df1[["theta"]].equals(df2[["theta"]])) + + def test_latin_hypercube_sampling_is_deterministic(self): + pest = _build_linear_estimator() + model = pest._create_parmest_model(0) + df1 = pest._generate_initial_theta( + parmest_model=model, + seed=11, + n_restarts=4, + multistart_sampling_method="latin_hypercube", + ) + df2 = pest._generate_initial_theta( + parmest_model=model, + seed=11, + n_restarts=4, + multistart_sampling_method="latin_hypercube", + ) + self.assertTrue(df1[["theta"]].equals(df2[["theta"]])) + + def test_sobol_sampling_is_deterministic(self): + pest = _build_linear_estimator() + model = pest._create_parmest_model(0) + df1 = pest._generate_initial_theta( + parmest_model=model, + seed=12, + n_restarts=4, + multistart_sampling_method="sobol_sampling", + ) + df2 = pest._generate_initial_theta( + parmest_model=model, + seed=12, + n_restarts=4, + multistart_sampling_method="sobol_sampling", + ) + self.assertTrue(df1[["theta"]].equals(df2[["theta"]])) + + def test_generated_starts_are_within_bounds(self): + pest = _build_linear_estimator() + model = pest._create_parmest_model(0) + for method in ("uniform_random", "latin_hypercube", "sobol_sampling"): + df = pest._generate_initial_theta( + parmest_model=model, + seed=1, + n_restarts=8, + multistart_sampling_method=method, + ) + self.assertTrue(((df["theta"] >= -10.0) & (df["theta"] <= 10.0)).all()) + + def test_missing_bounds_raise_error(self): + pest = parmest.Estimator([NoBoundsExperiment()], obj_function="SSE") + model = pest._create_parmest_model(0) + with self.assertRaisesRegex( + ValueError, "lower and upper bounds for the theta values must be defined" + ): + pest._generate_initial_theta( + parmest_model=model, + seed=1, + n_restarts=2, + multistart_sampling_method="uniform_random", + ) + + def test_invalid_bounds_raise_error(self): + pest = _build_linear_estimator() + model = pest._create_parmest_model(0) + model.theta.setlb(2.0) + model.theta.setub(1.0) + with self.assertRaisesRegex(ValueError, "lower bound must be less than"): + pest._generate_initial_theta( + parmest_model=model, + seed=1, + n_restarts=2, + multistart_sampling_method="uniform_random", + ) + + def test_user_provided_values_dimension_mismatch_raises(self): + pest = _build_linear_estimator() + user_df = pd.DataFrame([[1.0, 2.0]], columns=["theta", "extra"]) + with self.assertRaisesRegex( + ValueError, "same number of columns as the number of theta names" + ): + pest.theta_est_multistart( + n_restarts=1, + multistart_sampling_method="user_provided_values", + user_provided_df=user_df, + ) + + def test_user_provided_values_column_order_maps_by_name(self): + pest = parmest.Estimator([IndexedThetaExperiment()], obj_function="SSE") + user_df = pd.DataFrame( + [[0.3, 4.2], [0.4, 4.1]], columns=["theta[b]", "theta[a]"] + ) + results_df, _, _ = pest.theta_est_multistart( + n_restarts=2, + multistart_sampling_method="user_provided_values", + user_provided_df=user_df, + ) + self.assertAlmostEqual(results_df.loc[0, "theta[a]"], 4.2, places=12) + self.assertAlmostEqual(results_df.loc[0, "theta[b]"], 0.3, places=12) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' solver is not available") + def test_state_isolation_between_starts(self): + pest = _build_linear_estimator() + init = pd.DataFrame([[-9.0], [9.0]], columns=["theta"]) + results_df, _, _ = pest.theta_est_multistart( + theta_values=init, save_results=False + ) + # Initial starts should remain exactly as supplied. + self.assertAlmostEqual(results_df.loc[0, "theta"], -9.0, places=12) + self.assertAlmostEqual(results_df.loc[1, "theta"], 9.0, places=12) + # Both runs converge to the same optimum, showing no cross-start contamination. + self.assertAlmostEqual( + results_df.loc[0, "converged_theta"], + results_df.loc[1, "converged_theta"], + places=8, + ) + + def test_one_start_failure_returns_best_feasible(self): + pest = _build_linear_estimator() + theta_values = pd.DataFrame([[-1.0], [2.0]], columns=["theta"]) + + def fake_q_opt(*args, **kwargs): + theta = kwargs["theta_vals"]["theta"] + if theta < 0: + raise RuntimeError("boom") + return 1.25, {"theta": 1.0}, pyo.TerminationCondition.optimal + + with patch.object(pest, "_Q_opt", side_effect=fake_q_opt): + results_df, best_theta, best_obj = pest.theta_est_multistart( + theta_values=theta_values, save_results=False + ) + + self.assertTrue( + str(results_df.loc[0, "solver termination"]).startswith("exception(start=0") + ) + self.assertAlmostEqual(best_obj, 1.25, places=12) + self.assertAlmostEqual(best_theta["theta"], 1.0, places=12) + + def test_all_starts_fail_returns_diagnostics(self): + pest = _build_linear_estimator() + theta_values = pd.DataFrame([[1.0], [2.0]], columns=["theta"]) + + def fake_q_opt(*args, **kwargs): + raise RuntimeError("all failed") + + with patch.object(pest, "_Q_opt", side_effect=fake_q_opt): + results_df, best_theta, best_obj = pest.theta_est_multistart( + theta_values=theta_values, save_results=False + ) + + self.assertIsNone(best_theta) + self.assertTrue(math.isnan(best_obj)) + self.assertTrue( + results_df["solver termination"] + .astype(str) + .str.contains("exception\\(start=", regex=True) + .all() + ) + + def test_best_selection_filters_nonoptimal_status(self): + pest = _build_linear_estimator() + theta_values = pd.DataFrame([[1.0], [2.0]], columns=["theta"]) + + def fake_q_opt(*args, **kwargs): + theta = kwargs["theta_vals"]["theta"] + if theta < 1.5: + return 0.1, {"theta": 0.1}, pyo.TerminationCondition.maxIterations + return 0.2, {"theta": 0.2}, pyo.TerminationCondition.optimal + + with patch.object(pest, "_Q_opt", side_effect=fake_q_opt): + _, best_theta, best_obj = pest.theta_est_multistart( + theta_values=theta_values, save_results=False + ) + + self.assertAlmostEqual(best_obj, 0.2, places=12) + self.assertAlmostEqual(best_theta["theta"], 0.2, places=12) + + def test_tie_breaking_is_deterministic_first_index(self): + pest = _build_linear_estimator() + theta_values = pd.DataFrame([[5.0], [6.0], [7.0]], columns=["theta"]) + + def fake_q_opt(*args, **kwargs): + theta = kwargs["theta_vals"]["theta"] + return 1.0, {"theta": theta}, pyo.TerminationCondition.optimal + + with patch.object(pest, "_Q_opt", side_effect=fake_q_opt): + _, best_theta, best_obj = pest.theta_est_multistart( + theta_values=theta_values, save_results=False + ) + + self.assertAlmostEqual(best_obj, 1.0, places=12) + self.assertAlmostEqual(best_theta["theta"], 5.0, places=12) + + def test_indexed_unknown_parameters_supported_in_sampling(self): + pest = parmest.Estimator([IndexedThetaExperiment()], obj_function="SSE") + model = pest._create_parmest_model(0) + df = pest._generate_initial_theta( + parmest_model=model, + seed=10, + n_restarts=3, + multistart_sampling_method="uniform_random", + ) + self.assertTrue({"theta[a]", "theta[b]"}.issubset(set(df.columns))) + + def test_count_total_experiments_uses_one_output_family(self): + class MultiOutputExperiment(Experiment): + def create_model(self): + m = pyo.ConcreteModel() + m.theta = pyo.Var(initialize=0.0, bounds=(-10, 10)) + m.y = pyo.Var(initialize=1.0) + m.z = pyo.Var(initialize=2.0) + m.c1 = pyo.Constraint(expr=m.y == m.theta + 1.0) + m.c2 = pyo.Constraint(expr=m.z == 2.0 * m.theta + 2.0) + self.model = m + + def label_model(self): + m = self.model + m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.experiment_outputs.update([(m.y, 1.0), (m.z, 2.0)]) + m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.unknown_parameters.update([(m.theta, pyo.ComponentUID(m.theta))]) + m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.measurement_error.update([(m.y, None), (m.z, None)]) + + def get_labeled_model(self): + self.create_model() + self.label_model() + return self.model + + total_points = parmest._count_total_experiments( + [MultiOutputExperiment(), MultiOutputExperiment()] + ) + self.assertEqual(total_points, 2) From f9c8e3a2d4b7bf1bdb9c3646389b88aee21e6d42 Mon Sep 17 00:00:00 2001 From: Stephen Cini <114932899+sscini@users.noreply.github.com> Date: Mon, 9 Mar 2026 01:01:37 -0400 Subject: [PATCH 32/32] Fixed issue with repeat thetas, ran black --- pyomo/contrib/parmest/parmest.py | 392 +++++++++++------- .../parmest/tests/test_parmest_multistart.py | 172 +++++--- 2 files changed, 351 insertions(+), 213 deletions(-) diff --git a/pyomo/contrib/parmest/parmest.py b/pyomo/contrib/parmest/parmest.py index 63dc73ec26b..f131a2bdd3d 100644 --- a/pyomo/contrib/parmest/parmest.py +++ b/pyomo/contrib/parmest/parmest.py @@ -924,7 +924,32 @@ def _expand_indexed_unknowns(self, model_temp): def _create_parmest_model(self, experiment_number): """ - Modify the Pyomo model for parameter estimation + Build a parmest-ready model for a single experiment. + + This helper retrieves the labeled experiment model, prepares objective + components needed by parmest, and converts unknown parameters to + decision variables. The returned model is the one used to populate EF + scenario blocks. + + Parameters + ---------- + experiment_number : int + Index into ``self.exp_list`` selecting which experiment model to + load. + + Returns + ------- + ConcreteModel + A model configured for parmest optimization, including: + 1. a ``Total_Cost_Objective`` (if ``self.obj_function`` is set) + 2. converted unknown-parameter variables (unfixed) + + Notes + ----- + - Existing user objectives are deactivated before parmest objective + components are attached. + - Reserved component names are checked to avoid overriding user model + components. """ model = _get_labeled_model(self.exp_list[experiment_number]) @@ -985,29 +1010,53 @@ def _instance_creation_callback(self, experiment_number=None, cb_data=None): def _create_scenario_blocks( self, bootlist=None, theta_vals=None, fix_theta=False, multistart=False ): - # Create scenario block structure """ - Create scenario blocks for parameter estimation + Build the block-based extensive form (EF) model for estimation. + + The EF includes: + 1. a master theta variable container (``model.parmest_theta``), + 2. one child block per selected experiment (``model.exp_scenarios``), + 3. optional theta-linking constraints between master and child blocks, + 4. a single aggregate objective over all child blocks. + + In multistart mode, this method also refreshes experiment-level cached + model state before rebuilding each scenario so per-start initializations + are applied to the model that is actually solved. + Parameters ---------- bootlist : list, optional - List of bootstrap experiment numbers to use. If None, use all experiments in exp_list. - Default is None. + Experiment indices to include. If ``None``, all experiments in + ``self.exp_list`` are used. theta_vals : dict, optional - Dictionary of theta values to set in the model. If None, use default values from experiment class. - Default is None. + Theta values to apply as initial values to parent and child theta + variables. When ``multistart=True``, these values are also pushed to + experiment ``theta_initial`` (if present) before rebuilding. fix_theta : bool, optional - If True, fix the theta values in the model. If False, leave them free. - Default is False. + If ``True``, theta variables are fixed in each scenario and no + linking constraints are created. + multistart : bool, optional + If ``True``, force experiment model refresh between starts to avoid + stale cached model reuse. + Returns ------- - model : ConcreteModel - Pyomo model with scenario blocks for parameter estimation. Contains indexed block for - each experiment in exp_list or bootlist. + ConcreteModel + EF model used by parmest solve routines. + Raises + ------ + ValueError + If the selected scenario set is empty. """ # Build a clean parent EF container and attach one scenario model per block. model = pyo.ConcreteModel() + if multistart: + template_experiment = self.exp_list[0] + if theta_vals is not None and hasattr(template_experiment, "theta_initial"): + template_experiment.theta_initial = dict(theta_vals) + if hasattr(template_experiment, "model"): + template_experiment.model = None template_model = self._create_parmest_model(0) expanded_theta_names = self._expand_indexed_unknowns(template_model) model._parmest_theta_names = tuple(expanded_theta_names) @@ -1035,6 +1084,12 @@ def _create_scenario_blocks( # Create indexed block for holding scenario models model.exp_scenarios = pyo.Block(range(self.obj_probability_constant)) for i, experiment_number in enumerate(scenario_numbers): + if multistart: + experiment = self.exp_list[experiment_number] + if theta_vals is not None and hasattr(experiment, "theta_initial"): + experiment.theta_initial = dict(theta_vals) + if hasattr(experiment, "model"): + experiment.model = None parmest_model = self._create_parmest_model(experiment_number) for name in expanded_theta_names: child_theta_var = parmest_model.find_component(name) @@ -1077,31 +1132,66 @@ def total_obj(m): self.ef_instance = model return model - # TODO: Make so this generates the initial DATAFRAME, not the entire list of values. - # Make new private method, _generate_initial_theta: - # This method will be used to generate the initial theta values for multistart - # optimization. It will take the theta names and the initial theta values - # and return a dictionary of theta names and their corresponding values. def _generate_initial_theta( self, - parmest_model=None, seed=None, n_restarts=None, multistart_sampling_method=None, user_provided_df=None, + experiment_number=0, ): """ - Generate initial theta values for multistart optimization using selected sampling method. + Create the canonical multistart initialization/results DataFrame. + + Output schema is: + 1. theta columns (canonical order, quote-normalized names), + 2. ``converged_`` columns, + 3. ``final objective``, ``solver termination``, ``solve_time``. + + Initial theta rows are either sampled from bounds or taken from a + user-provided DataFrame. + + Parameters + ---------- + seed : int, optional + Random seed used by stochastic samplers. + n_restarts : int, optional + Number of starts to generate for sampled methods. Ignored when + ``user_provided_df`` is provided. + multistart_sampling_method : str, optional + Sampling method. Supported values: + ``uniform_random``, ``latin_hypercube``, ``sobol_sampling``. + user_provided_df : DataFrame, optional + Explicit initialization table. Must contain exactly the theta + columns (order may vary). Values must be finite and within bounds. + experiment_number : int, optional + Experiment index used to discover canonical theta names and bounds. + + Returns + ------- + DataFrame + Canonical initialization/results table ready for multistart solve + bookkeeping. + + Raises + ------ + ValueError + For missing/invalid bounds, invalid sampling method, malformed + user-provided starts, non-finite values, or out-of-bound starts. + TypeError + For invalid input types (for example, non-DataFrame + ``user_provided_df`` or non-integer ``n_restarts`` when required). + RuntimeError + If expected theta components cannot be located on the model. """ - if parmest_model is None: - raise ValueError("A labeled parmest model must be provided.") - if not isinstance(n_restarts, int): - raise TypeError("n_restarts must be an integer.") - if n_restarts <= 0: - raise ValueError("n_restarts must be greater than zero.") - - theta_names = self._expand_indexed_unknowns(parmest_model) - theta_vars = [parmest_model.find_component(name) for name in theta_names] + parmest_model = self._create_parmest_model(experiment_number) + + raw_theta_names = self._expand_indexed_unknowns(parmest_model) + theta_names = [n.replace("'", "") for n in raw_theta_names] + if len(theta_names) != len(set(theta_names)): + raise ValueError(f"Duplicate theta names are not allowed: {theta_names}") + + theta_vars = [parmest_model.find_component(name) for name in raw_theta_names] if any(v is None for v in theta_vars): raise RuntimeError( "Failed to locate one or more theta components on model." @@ -1119,7 +1209,36 @@ def _generate_initial_theta( "Each lower bound must be less than or equal to the corresponding upper bound." ) - if multistart_sampling_method == "uniform_random": + if user_provided_df is not None: + if not isinstance(user_provided_df, pd.DataFrame): + raise TypeError("user_provided_df must be a pandas DataFrame.") + if user_provided_df.shape[1] != len(theta_names): + raise ValueError( + "user_provided_df must have exactly one column per theta name." + ) + clean_cols = [str(c).replace("'", "") for c in user_provided_df.columns] + if len(clean_cols) != len(set(clean_cols)): + raise ValueError("Duplicate theta columns are not allowed.") + if set(clean_cols) != set(theta_names): + raise ValueError( + f"Provided columns {clean_cols} do not match expected theta names {theta_names}." + ) + df_multistart = user_provided_df.copy() + df_multistart.columns = clean_cols + df_multistart = df_multistart.reindex(columns=theta_names) + if df_multistart.shape[0] == 0: + raise ValueError("user_provided_df must contain at least one row.") + if n_restarts is not None and n_restarts != df_multistart.shape[0]: + raise ValueError( + "n_restarts must match the number of rows in user_provided_df." + ) + theta_vals_multistart = df_multistart.to_numpy(dtype=float) + n_restarts = df_multistart.shape[0] + elif multistart_sampling_method == "uniform_random": + if not isinstance(n_restarts, int): + raise TypeError("n_restarts must be an integer.") + if n_restarts <= 0: + raise ValueError("n_restarts must be greater than zero.") # Use a local RNG to avoid mutating global random state. rng = np.random.default_rng(seed) theta_vals_multistart = rng.uniform( @@ -1127,6 +1246,10 @@ def _generate_initial_theta( ) elif multistart_sampling_method == "latin_hypercube": + if not isinstance(n_restarts, int): + raise TypeError("n_restarts must be an integer.") + if n_restarts <= 0: + raise ValueError("n_restarts must be greater than zero.") # Generate theta values using Latin hypercube sampling or Sobol sampling # Generate theta values using Latin hypercube sampling # Create a Latin Hypercube sampler that uses the dimensions of the theta names @@ -1136,39 +1259,19 @@ def _generate_initial_theta( # Resulting samples should be size (n_restarts, len(theta_names)) elif multistart_sampling_method == "sobol_sampling": + if not isinstance(n_restarts, int): + raise TypeError("n_restarts must be an integer.") + if n_restarts <= 0: + raise ValueError("n_restarts must be greater than zero.") sampler = scipy.stats.qmc.Sobol(d=len(theta_names), seed=seed) # Generate theta values using Sobol sampling # The first value of the Sobol sequence is 0, so we skip it samples = sampler.random(n=n_restarts + 1)[1:] elif multistart_sampling_method == "user_provided_values": - if user_provided_df is None: - raise ValueError( - "The user must provide a pandas dataframe to use the 'user_provided_values' method." - ) - if not isinstance(user_provided_df, pd.DataFrame): - raise TypeError("user_provided_df must be a pandas DataFrame.") - if user_provided_df.shape[0] != n_restarts: - raise ValueError( - "The user provided dataframe must have the same number of rows as the number of restarts." - ) - if user_provided_df.shape[1] != len(theta_names): - raise ValueError( - "The user provided dataframe must have the same number of columns as the number of theta names." - ) - clean_cols = [str(c).replace("'", "") for c in user_provided_df.columns] - if len(clean_cols) != len(set(clean_cols)): - raise ValueError("Duplicate theta columns are not allowed.") - expected_clean = [t.replace("'", "") for t in theta_names] - if set(clean_cols) != set(expected_clean): - raise ValueError( - "The user provided dataframe must have the same theta names as the model." - ) - df_clean = user_provided_df.copy() - df_clean.columns = clean_cols - # Reindex by name to avoid column-order based value remapping. - df_clean = df_clean.reindex(columns=expected_clean) - theta_vals_multistart = df_clean.values + raise ValueError( + "multistart_sampling_method='user_provided_values' requires user_provided_df." + ) else: raise ValueError( @@ -1185,11 +1288,8 @@ def _generate_initial_theta( [lower_bound + (upper_bound - lower_bound) * theta for theta in samples] ) - # Create a DataFrame where each row is an initial theta vector for a restart, - # columns are theta_names, and values are the initial theta values for each restart - if multistart_sampling_method == "user_provided_values": - df_multistart = pd.DataFrame(theta_vals_multistart, columns=theta_names) - else: + # Create a DataFrame where each row is an initial theta vector for a restart + if user_provided_df is None: # Ensure theta_vals_multistart is 2D (n_restarts, len(theta_names)) arr = np.atleast_2d(theta_vals_multistart) if arr.shape[0] == 1 and n_restarts > 1: @@ -1227,15 +1327,13 @@ def _Q_opt( fix_theta=False, multistart=False, ): - ''' - Making new version of _Q_opt that uses scenario blocks, similar to DoE. + """ + Solve the EF parameter-estimation problem and return objective/theta data. - Steps: - 1. Load model - parmest model should be labeled - 2. Create scenario blocks (biggest redesign) - clone model to have one per experiment - 3. Define objective and constraints for the block - 4. Solve the block as a single problem - 5. Analyze results and extract parameter estimates + This routine creates the EF model via ``_create_scenario_blocks``, + solves it with the requested solver, and returns objective value plus + theta estimates. Depending on mode, it can also return variable values + and covariance estimates. Parameters ---------- @@ -1256,25 +1354,26 @@ def _Q_opt( fix_theta : bool, optional If True, fix the theta values in the model. If False, leave them free. Default is False. + multistart : bool, optional + If True, run in multistart mode. Non-optimal termination is + returned instead of raising assertion failure. + Returns ------- - If fix_theta is False: - obj_value : float - Objective value at optimal parameter estimates. - theta_estimates : pd.Series - Series of estimated parameter values. - If fix_theta is True: - obj_value : float - Objective value at fixed parameter values. - theta_estimates : dict - Dictionary of fixed parameter values. - WorstStatus : TerminationCondition - Solver termination condition. - - ''' + tuple + Return shape depends on mode: + 1. Standard solve: ``(obj_value, theta_series)`` + 2. Standard + return values: ``(obj_value, theta_series, var_values)`` + 3. Standard + covariance: ``(obj_value, theta_series, cov)`` or + ``(obj_value, theta_series, var_values, cov)`` + 4. Fixed-theta or multistart: ``(obj_value, theta_dict, worst_status)`` + """ # Create extended form model with scenario blocks model = self._create_scenario_blocks( - bootlist=bootlist, theta_vals=theta_vals, fix_theta=fix_theta + bootlist=bootlist, + theta_vals=theta_vals, + fix_theta=fix_theta, + multistart=multistart, ) expanded_theta_names = list(model._parmest_theta_names) @@ -2026,78 +2125,79 @@ def theta_est_multistart( multistart_sampling_method="uniform_random", user_provided_df=None, seed=None, - theta_values=None, # optional override: DataFrame of initial thetas - solver="ef_ipopt", save_results=False, file_name="multistart_results.csv", ): - if self.pest_deprecated is not None: - raise RuntimeError( - "Multistart is not supported in the deprecated parmest interface." - ) - if not isinstance(n_restarts, int): - raise TypeError("n_restarts must be an integer.") - if n_restarts <= 0: - raise ValueError("n_restarts must be greater than zero.") - - # ---- Build results_df in the canonical schema (theta cols + output cols) ---- - if theta_values is not None: - if not isinstance(theta_values, pd.DataFrame): - raise TypeError( - "theta_values must be a pandas DataFrame (columns = theta names)." - ) + """ + Run multistart parameter estimation and aggregate per-start results. - init_df = theta_values.copy() + A canonical starts/results table is created first, then each start is + solved (potentially in parallel with ``ParallelTaskManager``), and the + output table is populated with objective values, solver terminations, + solve times, and converged theta values. - # Normalize/validate names (same idea as your existing code) - clean_provided = [c.replace("'", "") for c in init_df.columns] - expected = [ - t.replace("'", "") - for t in self._expand_indexed_unknowns(self._create_parmest_model(0)) - ] - if len(clean_provided) != len(set(clean_provided)): - raise ValueError("Duplicate theta names are not allowed.") - if set(clean_provided) != set(expected): - raise ValueError( - f"Provided theta_values columns {clean_provided} do not match expected {expected}." - ) - init_df.columns = clean_provided - theta_names = list(expected) - init_df = init_df.reindex(columns=theta_names) - if init_df.shape[0] == 0: - raise ValueError("theta_values must contain at least one row.") - n_restarts = init_df.shape[0] - if not np.isfinite(init_df.to_numpy(dtype=float)).all(): - raise ValueError("theta_values must contain only finite values.") - - results_df = init_df.copy() - for name in theta_names: - results_df[f"converged_{name}"] = np.nan - results_df["final objective"] = np.nan - results_df["solver termination"] = "" - results_df["solve_time"] = np.nan + Parameters + ---------- + n_restarts : int, optional + Number of starts for sampled methods. Ignored when + ``user_provided_df`` is provided. + multistart_sampling_method : str, optional + Sampling method for generated starts. + user_provided_df : DataFrame, optional + User-provided starts. If provided, these rows define the restart + set directly. + seed : int, optional + Seed used by sampling methods. + save_results : bool, optional + If True, write the full results DataFrame to ``file_name``. + file_name : str, optional + Output CSV path used when ``save_results`` is True. - else: - # Use your canonical initializer - parmest_model_for_bounds = self._create_parmest_model(experiment_number=0) - results_df = self._generate_initial_theta( - parmest_model=parmest_model_for_bounds, - seed=seed, - n_restarts=n_restarts, - multistart_sampling_method=multistart_sampling_method, - user_provided_df=user_provided_df, + Returns + ------- + tuple + ``(results_df, best_theta, best_obj)``, where: + - ``results_df`` contains one row per start plus converged metadata + - ``best_theta`` is the selected best feasible theta dictionary or + ``None`` if no finite objective exists + - ``best_obj`` is the selected objective value or ``np.nan`` + + Notes + ----- + Best-run selection prioritizes acceptable solver terminations + (optimal/locallyOptimal/globallyOptimal) and then minimizes objective. + If no acceptable statuses exist, finite-objective rows are considered. + """ + if self.pest_deprecated is not None: + raise RuntimeError( + "Multistart is not supported in the deprecated parmest interface." ) - - # theta columns are the first |theta_names| columns (by construction) - # safest: infer from expected model names - theta_names = self._expand_indexed_unknowns(self._create_parmest_model(0)) - # also normalize in case of quotes: - theta_names = [t.replace("'", "") for t in theta_names] + if user_provided_df is None: + if not isinstance(n_restarts, int): + raise TypeError("n_restarts must be an integer.") + if n_restarts <= 0: + raise ValueError("n_restarts must be greater than zero.") + + n_restarts_for_generation = None if user_provided_df is not None else n_restarts + results_df = self._generate_initial_theta( + seed=seed, + n_restarts=n_restarts_for_generation, + multistart_sampling_method=multistart_sampling_method, + user_provided_df=user_provided_df, + experiment_number=0, + ) + theta_names = [ + c + for c in results_df.columns + if not c.startswith("converged_") + and c not in {"final objective", "solver termination", "solve_time"} + ] + n_restarts = results_df.shape[0] # Convert each row to (row_index, theta_dict) tasks = [] for i in range(results_df.shape[0]): - Theta = {name: float(results_df.loc[i, name]) for name in theta_names} + Theta = {name: float(results_df.iloc[i][name]) for name in theta_names} tasks.append((i, Theta)) task_mgr = utils.ParallelTaskManager(len(tasks)) @@ -2111,7 +2211,7 @@ def theta_est_multistart( t0 = time.time() try: final_obj, theta_hat, worst = self._Q_opt( - theta_vals=Theta, solver=solver, multistart=True + theta_vals=Theta, multistart=True ) solve_time = time.time() - t0 local_results.append((i, final_obj, str(worst), solve_time, theta_hat)) diff --git a/pyomo/contrib/parmest/tests/test_parmest_multistart.py b/pyomo/contrib/parmest/tests/test_parmest_multistart.py index b8d330603ae..e8770e07221 100644 --- a/pyomo/contrib/parmest/tests/test_parmest_multistart.py +++ b/pyomo/contrib/parmest/tests/test_parmest_multistart.py @@ -109,6 +109,44 @@ def get_labeled_model(self): return self.model +class StartCoupledExperiment(Experiment): + """ + Model intentionally couples a fixed term ("bias") to theta_initial at + build time. This exposes stale-model bugs in multistart paths. + """ + + def __init__(self, theta_initial=None): + self.theta_initial = ( + theta_initial if theta_initial is not None else {"theta": 0.0} + ) + self.model = None + + def create_model(self): + m = pyo.ConcreteModel() + m.theta = pyo.Var( + initialize=float(self.theta_initial["theta"]), bounds=(-10.0, 10.0) + ) + m.bias = pyo.Param(initialize=float(self.theta_initial["theta"]), mutable=False) + m.y = pyo.Var(initialize=0.0) + m.eq = pyo.Constraint(expr=m.y == m.theta + m.bias) + self.model = m + + def label_model(self): + m = self.model + m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.experiment_outputs.update([(m.y, 0.0)]) + m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.unknown_parameters.update([(m.theta, pyo.ComponentUID(m.theta))]) + m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.measurement_error.update([(m.y, None)]) + + def get_labeled_model(self): + if self.model is None: + self.create_model() + self.label_model() + return self.model + + def _build_linear_estimator(): exp_list = [LinearThetaExperiment(1.0, 2.0), LinearThetaExperiment(2.0, 3.0)] return parmest.Estimator(exp_list, obj_function="SSE") @@ -131,116 +169,99 @@ def test_multistart_baseline_equivalence_n1(self): def test_uniform_sampling_is_deterministic_with_seed(self): pest = _build_linear_estimator() - model = pest._create_parmest_model(0) df1 = pest._generate_initial_theta( - parmest_model=model, - seed=4, - n_restarts=5, - multistart_sampling_method="uniform_random", + seed=4, n_restarts=5, multistart_sampling_method="uniform_random" ) df2 = pest._generate_initial_theta( - parmest_model=model, - seed=4, - n_restarts=5, - multistart_sampling_method="uniform_random", + seed=4, n_restarts=5, multistart_sampling_method="uniform_random" ) self.assertTrue(df1[["theta"]].equals(df2[["theta"]])) def test_uniform_sampling_changes_with_different_seed(self): pest = _build_linear_estimator() - model = pest._create_parmest_model(0) df1 = pest._generate_initial_theta( - parmest_model=model, - seed=4, - n_restarts=5, - multistart_sampling_method="uniform_random", + seed=4, n_restarts=5, multistart_sampling_method="uniform_random" ) df2 = pest._generate_initial_theta( - parmest_model=model, - seed=5, - n_restarts=5, - multistart_sampling_method="uniform_random", + seed=5, n_restarts=5, multistart_sampling_method="uniform_random" ) self.assertFalse(df1[["theta"]].equals(df2[["theta"]])) def test_latin_hypercube_sampling_is_deterministic(self): pest = _build_linear_estimator() - model = pest._create_parmest_model(0) df1 = pest._generate_initial_theta( - parmest_model=model, - seed=11, - n_restarts=4, - multistart_sampling_method="latin_hypercube", + seed=11, n_restarts=4, multistart_sampling_method="latin_hypercube" ) df2 = pest._generate_initial_theta( - parmest_model=model, - seed=11, - n_restarts=4, - multistart_sampling_method="latin_hypercube", + seed=11, n_restarts=4, multistart_sampling_method="latin_hypercube" ) self.assertTrue(df1[["theta"]].equals(df2[["theta"]])) def test_sobol_sampling_is_deterministic(self): pest = _build_linear_estimator() - model = pest._create_parmest_model(0) df1 = pest._generate_initial_theta( - parmest_model=model, - seed=12, - n_restarts=4, - multistart_sampling_method="sobol_sampling", + seed=12, n_restarts=4, multistart_sampling_method="sobol_sampling" ) df2 = pest._generate_initial_theta( - parmest_model=model, - seed=12, - n_restarts=4, - multistart_sampling_method="sobol_sampling", + seed=12, n_restarts=4, multistart_sampling_method="sobol_sampling" ) self.assertTrue(df1[["theta"]].equals(df2[["theta"]])) def test_generated_starts_are_within_bounds(self): pest = _build_linear_estimator() - model = pest._create_parmest_model(0) for method in ("uniform_random", "latin_hypercube", "sobol_sampling"): df = pest._generate_initial_theta( - parmest_model=model, - seed=1, - n_restarts=8, - multistart_sampling_method=method, + seed=1, n_restarts=8, multistart_sampling_method=method ) self.assertTrue(((df["theta"] >= -10.0) & (df["theta"] <= 10.0)).all()) def test_missing_bounds_raise_error(self): pest = parmest.Estimator([NoBoundsExperiment()], obj_function="SSE") - model = pest._create_parmest_model(0) with self.assertRaisesRegex( ValueError, "lower and upper bounds for the theta values must be defined" ): pest._generate_initial_theta( - parmest_model=model, - seed=1, - n_restarts=2, - multistart_sampling_method="uniform_random", + seed=1, n_restarts=2, multistart_sampling_method="uniform_random" ) def test_invalid_bounds_raise_error(self): - pest = _build_linear_estimator() - model = pest._create_parmest_model(0) - model.theta.setlb(2.0) - model.theta.setub(1.0) + class InvalidBoundsExperiment(Experiment): + def __init__(self): + self.model = None + + def create_model(self): + m = pyo.ConcreteModel() + m.theta = pyo.Var(initialize=1.0) + m.theta.setlb(2.0) + m.theta.setub(1.0) + m.y = pyo.Var(initialize=2.0) + m.eq = pyo.Constraint(expr=m.y == m.theta + 1.0) + self.model = m + + def label_model(self): + m = self.model + m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.experiment_outputs.update([(m.y, 2.0)]) + m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.unknown_parameters.update([(m.theta, pyo.ComponentUID(m.theta))]) + m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.measurement_error.update([(m.y, None)]) + + def get_labeled_model(self): + self.create_model() + self.label_model() + return self.model + + pest = parmest.Estimator([InvalidBoundsExperiment()], obj_function="SSE") with self.assertRaisesRegex(ValueError, "lower bound must be less than"): pest._generate_initial_theta( - parmest_model=model, - seed=1, - n_restarts=2, - multistart_sampling_method="uniform_random", + seed=1, n_restarts=2, multistart_sampling_method="uniform_random" ) def test_user_provided_values_dimension_mismatch_raises(self): pest = _build_linear_estimator() user_df = pd.DataFrame([[1.0, 2.0]], columns=["theta", "extra"]) - with self.assertRaisesRegex( - ValueError, "same number of columns as the number of theta names" - ): + with self.assertRaisesRegex(ValueError, "exactly one column per theta name"): pest.theta_est_multistart( n_restarts=1, multistart_sampling_method="user_provided_values", @@ -265,7 +286,7 @@ def test_state_isolation_between_starts(self): pest = _build_linear_estimator() init = pd.DataFrame([[-9.0], [9.0]], columns=["theta"]) results_df, _, _ = pest.theta_est_multistart( - theta_values=init, save_results=False + user_provided_df=init, save_results=False ) # Initial starts should remain exactly as supplied. self.assertAlmostEqual(results_df.loc[0, "theta"], -9.0, places=12) @@ -289,7 +310,7 @@ def fake_q_opt(*args, **kwargs): with patch.object(pest, "_Q_opt", side_effect=fake_q_opt): results_df, best_theta, best_obj = pest.theta_est_multistart( - theta_values=theta_values, save_results=False + user_provided_df=theta_values, save_results=False ) self.assertTrue( @@ -307,7 +328,7 @@ def fake_q_opt(*args, **kwargs): with patch.object(pest, "_Q_opt", side_effect=fake_q_opt): results_df, best_theta, best_obj = pest.theta_est_multistart( - theta_values=theta_values, save_results=False + user_provided_df=theta_values, save_results=False ) self.assertIsNone(best_theta) @@ -331,7 +352,7 @@ def fake_q_opt(*args, **kwargs): with patch.object(pest, "_Q_opt", side_effect=fake_q_opt): _, best_theta, best_obj = pest.theta_est_multistart( - theta_values=theta_values, save_results=False + user_provided_df=theta_values, save_results=False ) self.assertAlmostEqual(best_obj, 0.2, places=12) @@ -347,7 +368,7 @@ def fake_q_opt(*args, **kwargs): with patch.object(pest, "_Q_opt", side_effect=fake_q_opt): _, best_theta, best_obj = pest.theta_est_multistart( - theta_values=theta_values, save_results=False + user_provided_df=theta_values, save_results=False ) self.assertAlmostEqual(best_obj, 1.0, places=12) @@ -355,12 +376,8 @@ def fake_q_opt(*args, **kwargs): def test_indexed_unknown_parameters_supported_in_sampling(self): pest = parmest.Estimator([IndexedThetaExperiment()], obj_function="SSE") - model = pest._create_parmest_model(0) df = pest._generate_initial_theta( - parmest_model=model, - seed=10, - n_restarts=3, - multistart_sampling_method="uniform_random", + seed=10, n_restarts=3, multistart_sampling_method="uniform_random" ) self.assertTrue({"theta[a]", "theta[b]"}.issubset(set(df.columns))) @@ -393,3 +410,24 @@ def get_labeled_model(self): [MultiOutputExperiment(), MultiOutputExperiment()] ) self.assertEqual(total_points, 2) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' solver is not available") + def test_multistart_results_reproducible_when_rerun_from_recorded_init(self): + pest = parmest.Estimator([StartCoupledExperiment()], obj_function="SSE") + init_df = pd.DataFrame([[-2.0], [1.5], [3.0]], columns=["theta"]) + results_df, _, _ = pest.theta_est_multistart( + user_provided_df=init_df, save_results=False + ) + + for _, row in results_df.iterrows(): + theta_init = {"theta": float(row["theta"])} + exp = StartCoupledExperiment(theta_initial=theta_init) + rerun = parmest.Estimator([exp], obj_function="SSE") + obj, theta = rerun.theta_est() + + self.assertTrue( + np.isclose(obj, row["final objective"], rtol=1e-6, atol=1e-8) + ) + self.assertTrue( + np.isclose(theta["theta"], row["converged_theta"], rtol=1e-6, atol=1e-8) + )