tee=True, solver_options=options, tolerance=1e-4, max_iter=40, subset_lambdas=A_set) print("\nThe estimated variances are:\n") for k, v in six.iteritems(results_variances.sigma_sq): print(k, v) print("The estimated parameters are:") for k, v in six.iteritems(pyomo_model2.P): print(k, v.value) sigmas = results_variances.sigma_sq optimizer = ParameterEstimator(pyomo_model2) optimizer.apply_discretization('dae.collocation', nfe=60, ncp=3, scheme='LAGRANGE-RADAU') # Provide good initial guess #p_guess = {'k1':0.006655} #raw_results = optimizer.run_lsq_given_P('ipopt',p_guess,tee=False) optimizer.initialize_from_trajectory('Z', results_variances.Z) optimizer.initialize_from_trajectory('S', results_variances.S) optimizer.initialize_from_trajectory('C', results_variances.C) #CheckInstanceFeasibility(pyomo_model2, 1e-3)
return exprs builder.set_odes_rule(rule_odes) opt_model = builder.create_pyomo_model(0.0, 10.0) #opt_model.C.pprint() #========================================================================= #USER INPUT SECTION - VARIANCE GIVEN #========================================================================= sigmas = {'A': 1e-10, 'B': 1e-11, 'C': 1e-10} #========================================================================= # USER INPUT SECTION - PARAMETER ESTIMATION #========================================================================= # In order to run the paramter estimation we create a pyomo model as described in section 4.3.4 # and define our parameter estimation problem and discretization strategy p_estimator = ParameterEstimator(opt_model) p_estimator.apply_discretization('dae.collocation', nfe=60, ncp=3, scheme='LAGRANGE-RADAU') # Again we provide options for the solver, this time providing the scaling that we set above options = dict() # options['nlp_scaling_method'] = 'user-scaling' # finally we run the optimization results_pyomo = p_estimator.run_opt('ipopt', variances=sigmas, tee=True, solver_opts=options)
exprs = dict() exprs['A'] = -m.P['k1']*m.Z[t,'A'] exprs['B'] = m.P['k1']*m.Z[t,'A']-m.P['k2']*m.Z[t,'B'] exprs['C'] = m.P['k2']*m.Z[t,'B'] return exprs builder.set_odes_rule(rule_odes) # Create instance pyomo_model = builder.create_pyomo_model(0.0,12.0) #========================================================================= # USER INPUT SECTION - PARAMETER ESTIMATION #========================================================================= optimizer = ParameterEstimator(pyomo_model) optimizer.apply_discretization('dae.collocation',nfe=30,ncp=1,scheme='LAGRANGE-RADAU') solver_options = dict() solver_options['mu_strategy'] = 'adaptive' # fix the variances sigmas = {'device':7.25435e-6, 'A':4.29616e-6, 'B':1.11297e-5, 'C':1.07905e-5} results_pyomo = optimizer.run_opt('ipopt_sens', variances=sigmas, tee=True,
print("\nThe estimated variances are:\n") for k, v in six.iteritems(results_variances.sigma_sq): print(k, v) sigmas = results_variances.sigma_sq #results_variances.sigma_sq ################################################################################# builder = TemplateBuilder() builder.add_mixture_component(concentrations) builder.add_parameter('k', bounds=(0.0, 1.0)) builder.add_spectral_data(results_sim.D) builder.set_odes_rule(rule_odes) opt_model = builder.create_pyomo_model(0.0, 200.0) p_estimator = ParameterEstimator(opt_model) p_estimator.apply_discretization('dae.collocation', nfe=4, ncp=1, scheme='LAGRANGE-RADAU') p_estimator.initialize_from_trajectory('Z', results_variances.Z) p_estimator.initialize_from_trajectory('S', results_variances.S) p_estimator.scale_variables_from_trajectory('Z', results_variances.Z) p_estimator.scale_variables_from_trajectory('S', results_variances.S) results_p = p_estimator.run_opt('ipopt', tee=True, variances=sigmas) print("The estimated parameters are:") for k, v in six.iteritems(opt_model.P):
#USER INPUT SECTION - Parameter Estimation #======================================================================== #In case the variances are known, they can also be fixed instead of running the Variance Estimation. #sigmas={'C': 1e-10, #'B': 1e-10, #'A': 1e-10, #'device': 1e-10} model =builder.create_pyomo_model(0.0,10) #Now introduce parameters as non fixed model.del_component(params) builder.add_parameter('k1',0.0055) builder.add_parameter('k2Tr',init=0.2265,bounds=(0.0, None)) builder.add_parameter('E',1655.3) model =builder.create_pyomo_model(0.0,10) p_estimator = ParameterEstimator(model) p_estimator.apply_discretization('dae.collocation', nfe=50, ncp=3, scheme='LAGRANGE-RADAU') # Certain problems may require initializations and scaling and these can be provided from the # variance estimation step. This is optional. p_estimator.initialize_from_trajectory('Z', results.Z) p_estimator.initialize_from_trajectory('S', results.S) p_estimator.initialize_from_trajectory('dZdt', results.dZdt) p_estimator.initialize_from_trajectory('C', results.C) p_estimator.scale_variables_from_trajectory('Z', results.Z) p_estimator.scale_variables_from_trajectory('S', results.S) p_estimator.scale_variables_from_trajectory('dZdt', results.dZdt) p_estimator.scale_variables_from_trajectory('C', results.C) # Again we provide options for the solver options = dict()
# Variances can then be displayed print("\nThe estimated variances are:\n") for k, v in six.iteritems(results_variances.sigma_sq): print(k, v) # and the sigmas for the parameter estimation step are now known and fixed sigmas = results_variances.sigma_sq #========================================================================= # USER INPUT SECTION - PARAMETER ESTIMATION #========================================================================= # In order to run the paramter estimation we create a pyomo model as described in section 4.3.4 opt_model = builder.create_pyomo_model(0.0, 10.0) # and define our parameter estimation problem and discretization strategy p_estimator = ParameterEstimator(opt_model) p_estimator.apply_discretization('dae.collocation', nfe=60, ncp=1, scheme='LAGRANGE-RADAU') # Certain problems may require initializations and scaling and these can be provided from the # varininace estimation step. This is optional. p_estimator.initialize_from_trajectory('Z', results_variances.Z) p_estimator.initialize_from_trajectory('S', results_variances.S) p_estimator.initialize_from_trajectory('C', results_variances.C) # Again we provide options for the solver options = dict() #options['mu_init'] = 1e-6
def wu_estimability(self, parameter_rankings = None, meas_scaling = None, sigmas = None): """This function performs the estimability analysis of Wu, McLean, Harris, and McAuley (2011) using the means squared error. Args: ---------- parameter_rankings: list A list containing the parameter rankings in order from most estimable to least estimable. Can be obtained using one of Kipet's parameter ranking functions. meas_scaling: int measurement scaling as used to scale the sensitivity matrix during param ranking sigmas: dict dictionary containing all the variances as required by the parameter estimator Returns: ----------- list of parameters that should remain in the parameter estimation, while all other parameters should be fixed. """ J = dict() params_estimated = list() cloned_full_model = dict() cloned_pestim = dict() results = dict() # For now, instead of using Levenberg-Marquardt least squares, we will use Kipet to perform the estimation # of every model. Here we generate each of the simplified models. # first we clone the main model so that we work with the full model at every iteration count = 1 for p in parameter_rankings: cloned_full_model[count] = self.cloned_before_k_aug.clone() count += 1 count = 1 # Then we go create each simplified model, fixing remaining variables for p in parameter_rankings: params_estimated.append(p) #print("performing parameter estimation for: ", params_estimated) for v,k in six.iteritems(cloned_full_model[count].P): if v in params_estimated: continue else: #print("fixing the parameters for:",v,k) #fix parameters not in simplified model ub = value(cloned_full_model[count].P[v]) lb = ub cloned_full_model[count].P[v].setlb(lb) cloned_full_model[count].P[v].setub(ub) # We then solve the Parameter estimaion problem for the SM options = dict() cloned_pestim[count] = ParameterEstimator(cloned_full_model[count]) results[count] = cloned_pestim[count].run_opt('ipopt', tee=False, solver_opts = options, variances=sigmas ) #for v,k in six.iteritems(results[count].P): #print(v,k) # Then compute the scaled residuals to obtain the Jk in the Wu et al paper J [count] = self._compute_scaled_residuals(results[count], meas_scaling) count += 1 #print(J) count = count - 1 # Since the estimability procedure suggested by Wu will always skip the last # parameter, we should check whether all parameters can be estimated # For now this is done by checking that the final parameter does not provide a massive decrease # the residuals low_MSE = J[1] listMSE = list() for k in J: listMSE.append(J[k]) if J[k] <= low_MSE: low_MSE = J[k] else: continue if J[count] == low_MSE: print("Lowest MSE is given by the lowest ranked parameter, therefore the full model should suffice") listMSE.sort() print("list of ordered mean squared errors of each :") print(listMSE) if listMSE[0]*10 <= listMSE[1]: print("all parameters are estimable! No need to reduce the model") return parameter_rankings # Now we move the the final steps of the algorithm where we compute critical ratio # and the corrected critical ratio # first we need the total number of responses N = 0 for c in self._sublist_components: for t in self._meas_times: N += 1 crit_rat = dict() cor_crit_rat = dict() for k in J: if k == count: break crit_rat[k] = (J[k] - J[count])/(count - k) crit_rat_Kub = max(crit_rat[k]-1,crit_rat[k]*(2/(count - k + 2))) cor_crit_rat[k] = (count - k)/N * (crit_rat_Kub - 1) #Finally we select the value of k with the lowest corrected critical value params_to_select = min(cor_crit_rat, key = lambda x: cor_crit_rat.get(x) ) print("The number of estimable parameters is:", params_to_select) print("optimization should be run wih the following parameters as variables and all others fixed") estimable_params = list() count=1 for p in parameter_rankings: print(p) estimable_params.append(p) if count >= params_to_select: break count += 1 return estimable_params
# Variances can then be displayed print("\nThe estimated variances are:\n") for k, v in six.iteritems(results_variances.sigma_sq): print(k, v) # and the sigmas for the parameter estimation step are now known and fixed sigmas = results_variances.sigma_sq #========================================================================= # USER INPUT SECTION - PARAMETER ESTIMATION #========================================================================= # In order to run the parameter estimation we create a pyomo model as described in section 4.3.4 opt_model = builder.create_pyomo_model(0.0, end_time) # and define our parameter estimation problem and discretization strategy p_estimator = ParameterEstimator(opt_model) p_estimator.apply_discretization('dae.collocation', nfe=nfe, ncp=ncp, scheme='LAGRANGE-RADAU') # Certain problems may require initializations and scaling and these can be provided from the # variance estimation step. This is optional. p_estimator.initialize_from_trajectory('Z', results_variances.Z) p_estimator.initialize_from_trajectory('S', results_variances.S) p_estimator.initialize_from_trajectory('C', results_variances.C) # Scaling for Ipopt can also be provided from the variance estimator's solution # these details are elaborated on in the manual p_estimator.scale_variables_from_trajectory('Z', results_variances.Z) p_estimator.scale_variables_from_trajectory('S', results_variances.S)
builder.add_parameter('k1', bounds=(0.0, 1.0)) builder.add_spectral_data(D_frame) # define explicit system of ODEs def rule_odes2(m, t): exprs = dict() exprs['A'] = -m.P['k1'] * m.Z[t, 'A'] * m.Z[t, 'B'] exprs['B'] = -m.P['k1'] * m.Z[t, 'A'] * m.Z[t, 'B'] exprs['C'] = m.P['k1'] * m.Z[t, 'A'] * m.Z[t, 'B'] return exprs builder.set_odes_rule(rule_odes2) pyomo_model2 = builder.create_pyomo_model(0.0, 200.0) optimizer = ParameterEstimator(pyomo_model2) optimizer.apply_discretization('dae.collocation', nfe=60, ncp=3, scheme='LAGRANGE-RADAU') # Provide good initial guess p_guess = {'k1': 0.006655} raw_results = optimizer.run_lsq_given_P('ipopt', p_guess, tee=False) optimizer.initialize_from_trajectory('Z', raw_results.Z) optimizer.initialize_from_trajectory('S', raw_results.S) optimizer.initialize_from_trajectory('dZdt', raw_results.dZdt) optimizer.initialize_from_trajectory('C', raw_results.C)
# Finally we run the variance estimatator using the arguments shown in Seciton 4.3.3 worst_case_device_var = v_estimator.solve_max_device_variance( 'ipopt', tee=False, # subset_lambdas = A_set, solver_opts=options) # following this, we can solve the parameter estimation problem # ========================================================================= # USER INPUT SECTION - PARAMETER ESTIMATION # ========================================================================= # In order to run the paramter estimation we create a pyomo model as described in section 4.3.4 # opt_model = builder.create_pyomo_model(0.0,10.0) # and define our parameter estimation problem and discretization strategy p_estimator = ParameterEstimator(opt_model) # p_estimator.apply_discretization('dae.collocation',nfe=100,ncp=1,scheme='LAGRANGE-RADAU') # Again we provide options for the solver, this time providing the scaling that we set above options = dict() # options['nlp_scaling_method'] = 'user-scaling' # options['linear_solver'] = 'ma57' # Since, for this case we only need delta and not the model variance, we add the additional option # to exclude model variance and then run the optimization results_pyomo = p_estimator.run_opt('k_aug', tee=False, model_variance=False, solver_opts=options, variances=worst_case_device_var, covariance=True)
'G':1e-10, 'device':1e-10} model = builder.create_pyomo_model(0., 600.)#0.51667 model.del_component(params) builder.add_parameter('k0', init=0.9*0.2545,bounds=(0.0, 100.0)) builder.add_parameter('k1', init=0.9*8.93156, bounds=(0.0,100.)) builder.add_parameter('k2', init=0.9*1.31765,bounds=(0.0,100.)) builder.add_parameter('k3', init=0.9*0.310870, bounds=(0.,100.)) builder.add_parameter('k4', init=0.9*3.87809,bounds=(0.0, 100.)) model = builder.create_pyomo_model(0., 600.) # and define our parameter estimation problem and discretization strategy p_estimator = ParameterEstimator(model) p_estimator.apply_discretization('dae.collocation', nfe=50, ncp=3, scheme='LAGRANGE-RADAU') # Certain problems may require initializations and scaling and these can be provided from the # variance estimation step. This is optional. ############## p_estimator.initialize_from_trajectory('Z', results_sim.Z) p_estimator.initialize_from_trajectory('S', results_sim.S) p_estimator.initialize_from_trajectory('C', results_sim.C) p_estimator.initialize_from_trajectory('dZdt', results_sim.dZdt) ################ # Again we provide options for the solver options = dict() options['mu_init'] = 1e-7 options['bound_push'] = 1e-8
#fD_frame = savitzky_golay(dataFrame = D_frame, window_size = 15, orderPoly = 2, orderDeriv=1) #Add H/UPLC data to model where at each time point the measurements have to sum up to 1 and the species have to match with #the ones in huplcabs builder.add_huplc_data(add_frame) opt_model = builder.create_pyomo_model(0.0, 10.0) huplcabs = ['A', 'C'] builder.set_huplc_absorbing_species(opt_model, huplcabs) # Here we assume that the UPLC data has the same variance as the IR data: sigmas['device-huplc'] = sigmas['device'] opt_model = builder.create_pyomo_model(0.0, 10.0) # and define our parameter estimation problem and discretization strategy p_estimator = ParameterEstimator(opt_model) p_estimator.apply_discretization('dae.collocation', nfe=60, ncp=1, scheme='LAGRANGE-RADAU') # Certain problems may require initializations and scaling and these can be provided from the # varininace estimation step. This is optional. p_estimator.initialize_from_trajectory('Z', results_variances.Z) p_estimator.initialize_from_trajectory('S', results_variances.S) p_estimator.initialize_from_trajectory('C', results_variances.C) # Scaling for Ipopt can also be provided from the variance estimator's solution # these details are elaborated on in the manual p_estimator.scale_variables_from_trajectory('Z', results_variances.Z) p_estimator.scale_variables_from_trajectory('S', results_variances.S)
exprs['A'] = -m.P['k1']*m.Z[t,'A']-m.P['k4']*m.Z[t,'A']- m.P['k5']*m.Z[t,'E']*m.Z[t,'A'] exprs['B'] = m.P['k1']*m.Z[t,'A']-m.P['k2']*m.Z[t,'B']-m.P['k3']*m.Z[t,'B'] exprs['C'] = m.P['k2']*m.Z[t,'B']-m.P['k4']*m.Z[t,'C'] exprs['D'] = m.P['k4']*m.Z[t,'A']-m.P['k3']*m.Z[t,'D'] exprs['E'] = m.P['k3']*m.Z[t,'B'] - m.P['k5']*m.Z[t,'E']*m.Z[t,'A'] exprs['F'] = m.P['k5']*m.Z[t,'E']*m.Z[t,'A'] - m.P['k6']*m.Z[t,'G']**2*m.Z[t,'F'] exprs['G'] = -m.P['k6']*m.Z[t,'G']**2*m.Z[t,'F'] exprs['H'] = m.P['k6']*m.Z[t,'G']**2*m.Z[t,'F'] return exprs builder.add_concentration_data(D_frame) #Add these ODEs to our model template builder.set_odes_rule(rule_odes) opt_model = builder.create_pyomo_model(0.0,20.0) p_estimator = ParameterEstimator(opt_model) p_estimator.apply_discretization('dae.collocation',nfe=60,ncp=3,scheme='LAGRANGE-RADAU') results_p = p_estimator.run_opt('k_aug', tee=True, variances=sigmas, covariance=True) print("The estimated parameters are:") for k,v in six.iteritems(opt_model.P): print(k, v.value) if with_plots: # display concentration and absorbance results results_p.C.plot.line(legend=True)
print("\nThe estimated variances are:\n") for k,v in six.iteritems(results_variances.sigma_sq): print(k,v) # and the sigmas for the parameter estimation step are now known and fixed # sigmas = sigmas sigmas = results_variances.sigma_sq #========================================================================= # USER INPUT SECTION - PARAMETER ESTIMATION #========================================================================= # In order to run the paramter estimation we create a pyomo model as described in section 4.3.4 opt_model = builder.create_pyomo_model(0.0,10.0) # and define our parameter estimation problem and discretization strategy p_estimator = ParameterEstimator(opt_model) p_estimator.apply_discretization('dae.collocation',nfe=100,ncp=3,scheme='LAGRANGE-RADAU') # Certain problems may require initializations and scaling and these can be provided from the # varininace estimation step. This is optional. p_estimator.initialize_from_trajectory('Z',results_variances.Z) p_estimator.initialize_from_trajectory('S',results_variances.S) p_estimator.initialize_from_trajectory('C',results_variances.C) # Scaling for Ipopt can also be provided from the variance estimator's solution # these details are elaborated on in the manual p_estimator.scale_variables_from_trajectory('Z',results_variances.Z) p_estimator.scale_variables_from_trajectory('S',results_variances.S) p_estimator.scale_variables_from_trajectory('C',results_variances.C) # Again we provide options for the solver, this time providing the scaling that we set above
plt.show() #========================================================================= #USER INPUT SECTION - Parameter Estimation #======================================================================== #Here with fixed variances! sigmas={'C': 1e-10, 'B': 1e-10, 'A': 1e-10, 'device': 1e-10} #Now introduce parameters as non fixed pyomo_model.del_component(params) builder.add_parameter('k_p',bounds=(0.0,8e7)) model = builder.create_pyomo_model(0.0,20.0) p_estimator = ParameterEstimator(model) p_estimator.apply_discretization('dae.collocation', nfe=40, ncp=3, scheme='LAGRANGE-RADAU') # # Again we provide options for the solver options = dict() # finally we run the optimization results_pyomo = p_estimator.run_opt('ipopt_sens', tee=True, solver_opts=options, variances=sigmas, covariance=True, #inputs_sub=inputs_sub, #trajectories=trajs, jump=True,
builder.add_parameter('k1', bounds=(0.0, 5.0)) builder.add_parameter('k2', bounds=(0.0, 1.0)) builder.add_spectral_data(D_frame) # define explicit system of ODEs def rule_odes(m, t): exprs = dict() exprs['A'] = -m.P['k1'] * m.Z[t, 'A'] exprs['B'] = m.P['k1'] * m.Z[t, 'A'] - m.P['k2'] * m.Z[t, 'B'] exprs['C'] = m.P['k2'] * m.Z[t, 'B'] return exprs builder.set_odes_rule(rule_odes) pyomo_model = builder.create_pyomo_model(0.0, 10.0) optimizer = ParameterEstimator(pyomo_model) optimizer.apply_discretization('dae.collocation', nfe=60, ncp=1, scheme='LAGRANGE-RADAU') # Provide good initial guess p_guess = {'k1': 4.0, 'k2': 0.5} raw_results = optimizer.run_lsq_given_P('ipopt', p_guess, tee=False) optimizer.initialize_from_trajectory('Z', raw_results.Z) optimizer.initialize_from_trajectory('S', raw_results.S) optimizer.initialize_from_trajectory('C', raw_results.C) optimizer.scale_variables_from_trajectory('Z', raw_results.Z)
builder.add_spectral_data(D_frame) # define explicit system of ODEs def rule_odes2(m, t): exprs = dict() exprs['A'] = -m.P['k1'] * m.Z[t, 'A'] exprs['B'] = m.P['k1'] * m.Z[t, 'A'] - m.P['k2'] * m.Z[t, 'B'] exprs['C'] = m.P['k2'] * m.Z[t, 'B'] return exprs builder.set_odes_rule(rule_odes2) pyomo_model2 = builder.create_pyomo_model(0.0, 10.0) src = pyomo_model2.clone() optimizer = ParameterEstimator(pyomo_model2) optimizer.apply_discretization('dae.collocation', nfe=30, ncp=3, scheme='LAGRANGE-RADAU') # optimizer.model.time.pprint() # Provide good initial guess p_guess = {'k1': 2.0, 'k2': 0.5} #: @dthierry: regular stuff for fe_factory param_dict = {} param_dict["P", "k1"] = 2.0 param_dict["P", "k2"] = 0.5 model = optimizer.model