def run_demo(with_plots=True): """ Demonstrate how to solve and calculate sensitivity for initial conditions. See "http://sundials.2283335.n4.nabble.com/Forward-sensitivities-for- \ initial-conditions-td3239724.html" """ curr_dir = os.path.dirname(os.path.abspath(__file__)); jmu_name = compile_jmu("LeadTransport", curr_dir+"/files/leadtransport.mop") model = JMUModel(jmu_name) opts = model.simulate_options() opts["IDA_options"]["sensitivity"] = True opts["IDA_options"]["rtol"] = 1e-7 opts["IDA_options"]["suppress_sens"] = False #Use the sensitivity variablers #in the error test. res = model.simulate(final_time=400, options=opts) # Extract variable profiles y1,y2,y3 = res['y1'], res["y2"], res["y3"] dy1p1,dy2p1,dy3p1 = res['dy1/dp1'], res['dy2/dp1'], res['dy3/dp1'] dy1p2,dy2p2,dy3p2 = res['dy1/dp2'], res['dy2/dp2'], res['dy3/dp2'] dy1p3,dy2p3,dy3p3 = res['dy1/dp3'], res['dy2/dp3'], res['dy3/dp3'] t=res['time'] assert N.abs(res.initial('dy1/dp1') - 1.000) < 1e-3 assert N.abs(res.initial('dy1/dp2') - 1.000) < 1e-3 assert N.abs(res.initial('dy2/dp2') - 1.000) < 1e-3 if with_plots: # Plot plt.figure(1) plt.clf() plt.subplot(221) plt.plot(t,y1,t,y2,t,y3) plt.grid() plt.legend(("y1","y2","y3")) plt.subplot(222) plt.plot(t,dy1p1,t,dy2p1,t,dy3p1) plt.grid() plt.legend(("dy1/dp1","dy2/dp1","dy3/dp1")) plt.subplot(223) plt.plot(t,dy1p2,t,dy2p2,t,dy3p2) plt.grid() plt.legend(("dy1/dp2","dy2/dp2","dy3/dp2")) plt.subplot(224) plt.plot(t,dy1p3,t,dy2p3,t,dy3p3) plt.grid() plt.legend(("dy1/dp3","dy2/dp3","dy3/dp3")) plt.suptitle("Lead transport through the body") plt.show()
def run_demo(with_plots=True): """ This example demonstrates how to solve parameter estimation problmes. The data used in the example was recorded by Kristian Soltesz at the Department of Automatic Control. """ curr_dir = os.path.dirname(os.path.abspath(__file__)); # Load measurement data from file data = loadmat(curr_dir+'/files/qt_par_est_data.mat',appendmat=False) # Extract data series t_meas = data['t'][6000::100,0]-60 y1_meas = data['y1_f'][6000::100,0]/100 y2_meas = data['y2_f'][6000::100,0]/100 y3_meas = data['y3_d'][6000::100,0]/100 y4_meas = data['y4_d'][6000::100,0]/100 u1 = data['u1_d'][6000::100,0] u2 = data['u2_d'][6000::100,0] # Plot measurements and inputs if with_plots: plt.figure(1) plt.clf() plt.subplot(2,2,1) plt.plot(t_meas,y3_meas) plt.title('x3') plt.grid() plt.subplot(2,2,2) plt.plot(t_meas,y4_meas) plt.title('x4') plt.grid() plt.subplot(2,2,3) plt.plot(t_meas,y1_meas) plt.title('x1') plt.xlabel('t[s]') plt.grid() plt.subplot(2,2,4) plt.plot(t_meas,y2_meas) plt.title('x2') plt.xlabel('t[s]') plt.grid() plt.figure(2) plt.clf() plt.subplot(2,1,1) plt.plot(t_meas,u1) plt.hold(True) plt.title('u1') plt.grid() plt.subplot(2,1,2) plt.plot(t_meas,u2) plt.title('u2') plt.xlabel('t[s]') plt.hold(True) plt.grid() # Build input trajectory matrix for use in simulation u = N.transpose(N.vstack((t_meas,u1,u2))) # compile FMU fmu_name = compile_fmu('QuadTankPack.Sim_QuadTank', curr_dir+'/files/QuadTankPack.mop') # Load model model = load_fmu(fmu_name) # Simulate model response with nominal parameters res = model.simulate(input=(['u1','u2'],u),start_time=0.,final_time=60) # Load simulation result x1_sim = res['qt.x1'] x2_sim = res['qt.x2'] x3_sim = res['qt.x3'] x4_sim = res['qt.x4'] t_sim = res['time'] u1_sim = res['u1'] u2_sim = res['u2'] # Plot simulation result if with_plots: plt.figure(1) plt.subplot(2,2,1) plt.plot(t_sim,x3_sim) plt.subplot(2,2,2) plt.plot(t_sim,x4_sim) plt.subplot(2,2,3) plt.plot(t_sim,x1_sim) plt.subplot(2,2,4) plt.plot(t_sim,x2_sim) plt.figure(2) plt.subplot(2,1,1) plt.plot(t_sim,u1_sim,'r') plt.subplot(2,1,2) plt.plot(t_sim,u2_sim,'r') # Compile parameter optimization model jmu_name = compile_jmu("QuadTankPack.QuadTank_ParEst", curr_dir+"/files/QuadTankPack.mop") # Load the model qt_par_est = JMUModel(jmu_name) # Number of measurement points N_meas = N.size(u1,0) # Set measurement data into model for i in range(0,N_meas): qt_par_est.set("t_meas["+`i+1`+"]",t_meas[i]) qt_par_est.set("y1_meas["+`i+1`+"]",y1_meas[i]) qt_par_est.set("y2_meas["+`i+1`+"]",y2_meas[i]) n_e = 30 # Numer of element in collocation algorithm # Get an options object for the optimization algorithm opt_opts = qt_par_est.optimize_options() # Set the number of collocation points opt_opts['n_e'] = n_e opt_opts['init_traj'] = res.result_data # Solve parameter optimization problem res = qt_par_est.optimize(options=opt_opts) # Extract optimal values of parameters a1_opt = res.final("qt.a1") a2_opt = res.final("qt.a2") # Print optimal parameter values print('a1: ' + str(a1_opt*1e4) + 'cm^2') print('a2: ' + str(a2_opt*1e4) + 'cm^2') assert N.abs(a1_opt*1.e6 - 2.6574) < 1e-3 assert N.abs(a2_opt*1.e6 - 2.7130) < 1e-3 # Load state profiles x1_opt = res["qt.x1"] x2_opt = res["qt.x2"] x3_opt = res["qt.x3"] x4_opt = res["qt.x4"] u1_opt = res["qt.u1"] u2_opt = res["qt.u2"] t_opt = res["time"] # Plot if with_plots: plt.figure(1) plt.subplot(2,2,1) plt.plot(t_opt,x3_opt,'k') plt.subplot(2,2,2) plt.plot(t_opt,x4_opt,'k') plt.subplot(2,2,3) plt.plot(t_opt,x1_opt,'k') plt.subplot(2,2,4) plt.plot(t_opt,x2_opt,'k') # Compile second parameter estimation model jmu_name = compile_jmu("QuadTankPack.QuadTank_ParEst2", curr_dir+"/files/QuadTankPack.mop") # Load model qt_par_est2 = JMUModel(jmu_name) # Number of measurement points N_meas = N.size(u1,0) # Set measurement data into model for i in range(0,N_meas): qt_par_est2.set("t_meas["+`i+1`+"]",t_meas[i]) qt_par_est2.set("y1_meas["+`i+1`+"]",y1_meas[i]) qt_par_est2.set("y2_meas["+`i+1`+"]",y2_meas[i]) qt_par_est2.set("y3_meas["+`i+1`+"]",y3_meas[i]) qt_par_est2.set("y4_meas["+`i+1`+"]",y4_meas[i]) # Solve parameter estimation problem res_opt2 = qt_par_est2.optimize(options=opt_opts) # Get optimal parameter values a1_opt2 = res_opt2.final("qt.a1") a2_opt2 = res_opt2.final("qt.a2") a3_opt2 = res_opt2.final("qt.a3") a4_opt2 = res_opt2.final("qt.a4") # Print optimal parameter values print('a1:' + str(a1_opt2*1e4) + 'cm^2') print('a2:' + str(a2_opt2*1e4) + 'cm^2') print('a3:' + str(a3_opt2*1e4) + 'cm^2') print('a4:' + str(a4_opt2*1e4) + 'cm^2') assert N.abs(a1_opt2*1.e6 - 2.6579) < 1e-3, "Wrong value of parameter a1" assert N.abs(a2_opt2*1.e6 - 2.7038) < 1e-3, "Wrong value of parameter a2" assert N.abs(a3_opt2*1.e6 - 3.0031) < 1e-3, "Wrong value of parameter a3" assert N.abs(a4_opt2*1.e6 - 2.9342) < 1e-3, "Wrong value of parameter a4" # Extract state and input profiles x1_opt2 = res_opt2["qt.x1"] x2_opt2 = res_opt2["qt.x2"] x3_opt2 = res_opt2["qt.x3"] x4_opt2 = res_opt2["qt.x4"] u1_opt2 = res_opt2["qt.u1"] u2_opt2 = res_opt2["qt.u2"] t_opt2 = res_opt2["time"] # Plot if with_plots: plt.figure(1) plt.subplot(2,2,1) plt.plot(t_opt2,x3_opt2,'r') plt.subplot(2,2,2) plt.plot(t_opt2,x4_opt2,'r') plt.subplot(2,2,3) plt.plot(t_opt2,x1_opt2,'r') plt.subplot(2,2,4) plt.plot(t_opt2,x2_opt2,'r') plt.show() # Compute parameter standard deviations for case 1 # compile JMU jmu_name = compile_jmu('QuadTankPack.QuadTank_Sens1', curr_dir+'/files/QuadTankPack.mop') # Load model model = JMUModel(jmu_name) model.set('a1',a1_opt) model.set('a2',a2_opt) sens_opts = model.simulate_options() # Enable sensitivity computations sens_opts['IDA_options']['sensitivity'] = True #sens_opts['IDA_options']['atol'] = 1e-12 # Simulate sensitivity equations sens_res = model.simulate(input=(['u1','u2'],u),start_time=0.,final_time=60, options = sens_opts) # Get result trajectories x1_sens = sens_res['x1'] x2_sens = sens_res['x2'] dx1da1 = sens_res['dx1/da1'] dx1da2 = sens_res['dx1/da2'] dx2da1 = sens_res['dx2/da1'] dx2da2 = sens_res['dx2/da2'] t_sens = sens_res['time'] # Compute Jacobian # Create a trajectory object for interpolation traj=TrajectoryLinearInterpolation(t_sens,N.transpose(N.vstack((x1_sens,x2_sens,dx1da1,dx1da2,dx2da1,dx2da2)))) # Jacobian jac = N.zeros((61*2,2)) # Error vector err = N.zeros(61*2) # Extract Jacobian and error information i = 0 for t_p in t_meas: vals = traj.eval(t_p) for j in range(2): for k in range(2): jac[i+j,k] = vals[0,2*j+k+2] err[i] = vals[0,0] - y1_meas[i/2] err[i+1] = vals[0,1] - y2_meas[i/2] i = i + 2 # Compute estimated variance of measurement noice v_err = N.sum(err**2)/(61*2-2) # Compute J^T*J A = N.dot(N.transpose(jac),jac) # Compute parameter covariance matrix P = v_err*N.linalg.inv(A) # Compute standard deviations for parameters sigma_a1 = N.sqrt(P[0,0]) sigma_a2 = N.sqrt(P[1,1]) print "a1: " + str(sens_res['a1']) + ", standard deviation: " + str(sigma_a1) print "a2: " + str(sens_res['a2']) + ", standard deviation: " + str(sigma_a2) # Compute parameter standard deviations for case 2 # compile JMU jmu_name = compile_jmu('QuadTankPack.QuadTank_Sens2', curr_dir+'/files/QuadTankPack.mop') # Load model model = JMUModel(jmu_name) model.set('a1',a1_opt2) model.set('a2',a2_opt2) model.set('a3',a3_opt2) model.set('a4',a4_opt2) sens_opts = model.simulate_options() # Enable sensitivity computations sens_opts['IDA_options']['sensitivity'] = True #sens_opts['IDA_options']['atol'] = 1e-12 # Simulate sensitivity equations sens_res = model.simulate(input=(['u1','u2'],u),start_time=0.,final_time=60, options = sens_opts) # Get result trajectories x1_sens = sens_res['x1'] x2_sens = sens_res['x2'] x3_sens = sens_res['x3'] x4_sens = sens_res['x4'] dx1da1 = sens_res['dx1/da1'] dx1da2 = sens_res['dx1/da2'] dx1da3 = sens_res['dx1/da3'] dx1da4 = sens_res['dx1/da4'] dx2da1 = sens_res['dx2/da1'] dx2da2 = sens_res['dx2/da2'] dx2da3 = sens_res['dx2/da3'] dx2da4 = sens_res['dx2/da4'] dx3da1 = sens_res['dx3/da1'] dx3da2 = sens_res['dx3/da2'] dx3da3 = sens_res['dx3/da3'] dx3da4 = sens_res['dx3/da4'] dx4da1 = sens_res['dx4/da1'] dx4da2 = sens_res['dx4/da2'] dx4da3 = sens_res['dx4/da3'] dx4da4 = sens_res['dx4/da4'] t_sens = sens_res['time'] # Compute Jacobian # Create a trajectory object for interpolation traj=TrajectoryLinearInterpolation(t_sens,N.transpose(N.vstack((x1_sens,x2_sens,x3_sens,x4_sens, dx1da1,dx1da2,dx1da3,dx1da4, dx2da1,dx2da2,dx2da3,dx2da4, dx3da1,dx3da2,dx3da3,dx3da4, dx4da1,dx4da2,dx4da3,dx4da4)))) # Jacobian jac = N.zeros((61*4,4)) # Error vector err = N.zeros(61*4) # Extract Jacobian and error information i = 0 for t_p in t_meas: vals = traj.eval(t_p) for j in range(4): for k in range(4): jac[i+j,k] = vals[0,4*j+k+4] err[i] = vals[0,0] - y1_meas[i/4] err[i+1] = vals[0,1] - y2_meas[i/4] err[i+2] = vals[0,2] - y3_meas[i/4] err[i+3] = vals[0,3] - y4_meas[i/4] i = i + 4 # Compute estimated variance of measurement noice v_err = N.sum(err**2)/(61*4-4) # Compute J^T*J A = N.dot(N.transpose(jac),jac) # Compute parameter covariance matrix P = v_err*N.linalg.inv(A) # Compute standard deviations for parameters sigma_a1 = N.sqrt(P[0,0]) sigma_a2 = N.sqrt(P[1,1]) sigma_a3 = N.sqrt(P[2,2]) sigma_a4 = N.sqrt(P[3,3]) print "a1: " + str(sens_res['a1']) + ", standard deviation: " + str(sigma_a1) print "a2: " + str(sens_res['a2']) + ", standard deviation: " + str(sigma_a2) print "a3: " + str(sens_res['a3']) + ", standard deviation: " + str(sigma_a3) print "a4: " + str(sens_res['a4']) + ", standard deviation: " + str(sigma_a4)
def run_demo(with_plots=True): """ This example demonstrates how to solve parameter estimation problmes. The data used in the example was recorded by Kristian Soltesz at the Department of Automatic Control. """ curr_dir = os.path.dirname(os.path.abspath(__file__)) # Load measurement data from file data = loadmat(curr_dir + '/files/qt_par_est_data.mat', appendmat=False) # Extract data series t_meas = data['t'][6000::100, 0] - 60 y1_meas = data['y1_f'][6000::100, 0] / 100 y2_meas = data['y2_f'][6000::100, 0] / 100 y3_meas = data['y3_d'][6000::100, 0] / 100 y4_meas = data['y4_d'][6000::100, 0] / 100 u1 = data['u1_d'][6000::100, 0] u2 = data['u2_d'][6000::100, 0] # Plot measurements and inputs if with_plots: plt.figure(1) plt.clf() plt.subplot(2, 2, 1) plt.plot(t_meas, y3_meas) plt.title('x3') plt.grid() plt.subplot(2, 2, 2) plt.plot(t_meas, y4_meas) plt.title('x4') plt.grid() plt.subplot(2, 2, 3) plt.plot(t_meas, y1_meas) plt.title('x1') plt.xlabel('t[s]') plt.grid() plt.subplot(2, 2, 4) plt.plot(t_meas, y2_meas) plt.title('x2') plt.xlabel('t[s]') plt.grid() plt.figure(2) plt.clf() plt.subplot(2, 1, 1) plt.plot(t_meas, u1) plt.hold(True) plt.title('u1') plt.grid() plt.subplot(2, 1, 2) plt.plot(t_meas, u2) plt.title('u2') plt.xlabel('t[s]') plt.hold(True) plt.grid() # Build input trajectory matrix for use in simulation u = N.transpose(N.vstack((t_meas, u1, u2))) # compile FMU fmu_name = compile_fmu('QuadTankPack.Sim_QuadTank', curr_dir + '/files/QuadTankPack.mop') # Load model model = load_fmu(fmu_name) # Simulate model response with nominal parameters res = model.simulate(input=(['u1', 'u2'], u), start_time=0., final_time=60) # Load simulation result x1_sim = res['qt.x1'] x2_sim = res['qt.x2'] x3_sim = res['qt.x3'] x4_sim = res['qt.x4'] t_sim = res['time'] u1_sim = res['u1'] u2_sim = res['u2'] # Plot simulation result if with_plots: plt.figure(1) plt.subplot(2, 2, 1) plt.plot(t_sim, x3_sim) plt.subplot(2, 2, 2) plt.plot(t_sim, x4_sim) plt.subplot(2, 2, 3) plt.plot(t_sim, x1_sim) plt.subplot(2, 2, 4) plt.plot(t_sim, x2_sim) plt.figure(2) plt.subplot(2, 1, 1) plt.plot(t_sim, u1_sim, 'r') plt.subplot(2, 1, 2) plt.plot(t_sim, u2_sim, 'r') # Compile parameter optimization model jmu_name = compile_jmu("QuadTankPack.QuadTank_ParEst", curr_dir + "/files/QuadTankPack.mop") # Load the model qt_par_est = JMUModel(jmu_name) # Number of measurement points N_meas = N.size(u1, 0) # Set measurement data into model for i in range(0, N_meas): qt_par_est.set("t_meas[" + ` i + 1 ` + "]", t_meas[i]) qt_par_est.set("y1_meas[" + ` i + 1 ` + "]", y1_meas[i]) qt_par_est.set("y2_meas[" + ` i + 1 ` + "]", y2_meas[i]) n_e = 30 # Numer of element in collocation algorithm # Get an options object for the optimization algorithm opt_opts = qt_par_est.optimize_options() # Set the number of collocation points opt_opts['n_e'] = n_e opt_opts['init_traj'] = res.result_data # Solve parameter optimization problem res = qt_par_est.optimize(options=opt_opts) # Extract optimal values of parameters a1_opt = res.final("qt.a1") a2_opt = res.final("qt.a2") # Print optimal parameter values print('a1: ' + str(a1_opt * 1e4) + 'cm^2') print('a2: ' + str(a2_opt * 1e4) + 'cm^2') assert N.abs(a1_opt * 1.e6 - 2.6574) < 1e-3 assert N.abs(a2_opt * 1.e6 - 2.7130) < 1e-3 # Load state profiles x1_opt = res["qt.x1"] x2_opt = res["qt.x2"] x3_opt = res["qt.x3"] x4_opt = res["qt.x4"] u1_opt = res["qt.u1"] u2_opt = res["qt.u2"] t_opt = res["time"] # Plot if with_plots: plt.figure(1) plt.subplot(2, 2, 1) plt.plot(t_opt, x3_opt, 'k') plt.subplot(2, 2, 2) plt.plot(t_opt, x4_opt, 'k') plt.subplot(2, 2, 3) plt.plot(t_opt, x1_opt, 'k') plt.subplot(2, 2, 4) plt.plot(t_opt, x2_opt, 'k') # Compile second parameter estimation model jmu_name = compile_jmu("QuadTankPack.QuadTank_ParEst2", curr_dir + "/files/QuadTankPack.mop") # Load model qt_par_est2 = JMUModel(jmu_name) # Number of measurement points N_meas = N.size(u1, 0) # Set measurement data into model for i in range(0, N_meas): qt_par_est2.set("t_meas[" + ` i + 1 ` + "]", t_meas[i]) qt_par_est2.set("y1_meas[" + ` i + 1 ` + "]", y1_meas[i]) qt_par_est2.set("y2_meas[" + ` i + 1 ` + "]", y2_meas[i]) qt_par_est2.set("y3_meas[" + ` i + 1 ` + "]", y3_meas[i]) qt_par_est2.set("y4_meas[" + ` i + 1 ` + "]", y4_meas[i]) # Solve parameter estimation problem res_opt2 = qt_par_est2.optimize(options=opt_opts) # Get optimal parameter values a1_opt2 = res_opt2.final("qt.a1") a2_opt2 = res_opt2.final("qt.a2") a3_opt2 = res_opt2.final("qt.a3") a4_opt2 = res_opt2.final("qt.a4") # Print optimal parameter values print('a1:' + str(a1_opt2 * 1e4) + 'cm^2') print('a2:' + str(a2_opt2 * 1e4) + 'cm^2') print('a3:' + str(a3_opt2 * 1e4) + 'cm^2') print('a4:' + str(a4_opt2 * 1e4) + 'cm^2') assert N.abs(a1_opt2 * 1.e6 - 2.6579) < 1e-3, "Wrong value of parameter a1" assert N.abs(a2_opt2 * 1.e6 - 2.7038) < 1e-3, "Wrong value of parameter a2" assert N.abs(a3_opt2 * 1.e6 - 3.0031) < 1e-3, "Wrong value of parameter a3" assert N.abs(a4_opt2 * 1.e6 - 2.9342) < 1e-3, "Wrong value of parameter a4" # Extract state and input profiles x1_opt2 = res_opt2["qt.x1"] x2_opt2 = res_opt2["qt.x2"] x3_opt2 = res_opt2["qt.x3"] x4_opt2 = res_opt2["qt.x4"] u1_opt2 = res_opt2["qt.u1"] u2_opt2 = res_opt2["qt.u2"] t_opt2 = res_opt2["time"] # Plot if with_plots: plt.figure(1) plt.subplot(2, 2, 1) plt.plot(t_opt2, x3_opt2, 'r') plt.subplot(2, 2, 2) plt.plot(t_opt2, x4_opt2, 'r') plt.subplot(2, 2, 3) plt.plot(t_opt2, x1_opt2, 'r') plt.subplot(2, 2, 4) plt.plot(t_opt2, x2_opt2, 'r') plt.show() # Compute parameter standard deviations for case 1 # compile JMU jmu_name = compile_jmu('QuadTankPack.QuadTank_Sens1', curr_dir + '/files/QuadTankPack.mop') # Load model model = JMUModel(jmu_name) model.set('a1', a1_opt) model.set('a2', a2_opt) sens_opts = model.simulate_options() # Enable sensitivity computations sens_opts['IDA_options']['sensitivity'] = True #sens_opts['IDA_options']['atol'] = 1e-12 # Simulate sensitivity equations sens_res = model.simulate(input=(['u1', 'u2'], u), start_time=0., final_time=60, options=sens_opts) # Get result trajectories x1_sens = sens_res['x1'] x2_sens = sens_res['x2'] dx1da1 = sens_res['dx1/da1'] dx1da2 = sens_res['dx1/da2'] dx2da1 = sens_res['dx2/da1'] dx2da2 = sens_res['dx2/da2'] t_sens = sens_res['time'] # Compute Jacobian # Create a trajectory object for interpolation traj = TrajectoryLinearInterpolation( t_sens, N.transpose( N.vstack((x1_sens, x2_sens, dx1da1, dx1da2, dx2da1, dx2da2)))) # Jacobian jac = N.zeros((61 * 2, 2)) # Error vector err = N.zeros(61 * 2) # Extract Jacobian and error information i = 0 for t_p in t_meas: vals = traj.eval(t_p) for j in range(2): for k in range(2): jac[i + j, k] = vals[0, 2 * j + k + 2] err[i] = vals[0, 0] - y1_meas[i / 2] err[i + 1] = vals[0, 1] - y2_meas[i / 2] i = i + 2 # Compute estimated variance of measurement noice v_err = N.sum(err**2) / (61 * 2 - 2) # Compute J^T*J A = N.dot(N.transpose(jac), jac) # Compute parameter covariance matrix P = v_err * N.linalg.inv(A) # Compute standard deviations for parameters sigma_a1 = N.sqrt(P[0, 0]) sigma_a2 = N.sqrt(P[1, 1]) print "a1: " + str( sens_res['a1']) + ", standard deviation: " + str(sigma_a1) print "a2: " + str( sens_res['a2']) + ", standard deviation: " + str(sigma_a2) # Compute parameter standard deviations for case 2 # compile JMU jmu_name = compile_jmu('QuadTankPack.QuadTank_Sens2', curr_dir + '/files/QuadTankPack.mop') # Load model model = JMUModel(jmu_name) model.set('a1', a1_opt2) model.set('a2', a2_opt2) model.set('a3', a3_opt2) model.set('a4', a4_opt2) sens_opts = model.simulate_options() # Enable sensitivity computations sens_opts['IDA_options']['sensitivity'] = True #sens_opts['IDA_options']['atol'] = 1e-12 # Simulate sensitivity equations sens_res = model.simulate(input=(['u1', 'u2'], u), start_time=0., final_time=60, options=sens_opts) # Get result trajectories x1_sens = sens_res['x1'] x2_sens = sens_res['x2'] x3_sens = sens_res['x3'] x4_sens = sens_res['x4'] dx1da1 = sens_res['dx1/da1'] dx1da2 = sens_res['dx1/da2'] dx1da3 = sens_res['dx1/da3'] dx1da4 = sens_res['dx1/da4'] dx2da1 = sens_res['dx2/da1'] dx2da2 = sens_res['dx2/da2'] dx2da3 = sens_res['dx2/da3'] dx2da4 = sens_res['dx2/da4'] dx3da1 = sens_res['dx3/da1'] dx3da2 = sens_res['dx3/da2'] dx3da3 = sens_res['dx3/da3'] dx3da4 = sens_res['dx3/da4'] dx4da1 = sens_res['dx4/da1'] dx4da2 = sens_res['dx4/da2'] dx4da3 = sens_res['dx4/da3'] dx4da4 = sens_res['dx4/da4'] t_sens = sens_res['time'] # Compute Jacobian # Create a trajectory object for interpolation traj = TrajectoryLinearInterpolation( t_sens, N.transpose( N.vstack( (x1_sens, x2_sens, x3_sens, x4_sens, dx1da1, dx1da2, dx1da3, dx1da4, dx2da1, dx2da2, dx2da3, dx2da4, dx3da1, dx3da2, dx3da3, dx3da4, dx4da1, dx4da2, dx4da3, dx4da4)))) # Jacobian jac = N.zeros((61 * 4, 4)) # Error vector err = N.zeros(61 * 4) # Extract Jacobian and error information i = 0 for t_p in t_meas: vals = traj.eval(t_p) for j in range(4): for k in range(4): jac[i + j, k] = vals[0, 4 * j + k + 4] err[i] = vals[0, 0] - y1_meas[i / 4] err[i + 1] = vals[0, 1] - y2_meas[i / 4] err[i + 2] = vals[0, 2] - y3_meas[i / 4] err[i + 3] = vals[0, 3] - y4_meas[i / 4] i = i + 4 # Compute estimated variance of measurement noice v_err = N.sum(err**2) / (61 * 4 - 4) # Compute J^T*J A = N.dot(N.transpose(jac), jac) # Compute parameter covariance matrix P = v_err * N.linalg.inv(A) # Compute standard deviations for parameters sigma_a1 = N.sqrt(P[0, 0]) sigma_a2 = N.sqrt(P[1, 1]) sigma_a3 = N.sqrt(P[2, 2]) sigma_a4 = N.sqrt(P[3, 3]) print "a1: " + str( sens_res['a1']) + ", standard deviation: " + str(sigma_a1) print "a2: " + str( sens_res['a2']) + ", standard deviation: " + str(sigma_a2) print "a3: " + str( sens_res['a3']) + ", standard deviation: " + str(sigma_a3) print "a4: " + str( sens_res['a4']) + ", standard deviation: " + str(sigma_a4)