def daeIn(t = None, x = None, p = None): if t is None: return ca.daeIn(x = x, p = p) else: return ca.daeIn(t = t, x = x, p = p)
def phase_of_point(self, point, error=False, tol=1E-3): """ Finds the phase at which the distance from the point to the limit cycle is minimized. phi=0 corresponds to the definition of y0, returns the phase and the minimum distance to the limit cycle """ point = np.asarray(point) #set up integrator so we only have to once... intr = cs.Integrator('cvodes',self.model) intr.setOption("abstol", self.intoptions['bvp_abstol']) intr.setOption("reltol", self.intoptions['bvp_reltol']) intr.setOption("tf", self.T) intr.setOption("max_num_steps", self.intoptions['transmaxnumsteps']) intr.setOption("disable_internal_warnings", True) intr.init() for i in xrange(100): dist = cs.SX.sym("dist") x = self.model.inputExpr(cs.DAE_X) ode = self.model.outputExpr()[0] dist_ode = cs.sumAll(2.*(x - point)*ode) cat_x = cs.vertcat([x, dist]) cat_ode = cs.vertcat([ode, dist_ode]) dist_model = cs.SXFunction( cs.daeIn(t=self.model.inputExpr(cs.DAE_T), x=cat_x, p=self.model.inputExpr(cs.DAE_P)), cs.daeOut(ode=cat_ode)) dist_model.setOption("name","distance model") dist_0 = ((self.y0 - point)**2).sum() if dist_0 < tol: # catch the case where we start at 0 return 0. cat_y0 = np.hstack([self.y0, dist_0]) roots_class = Oscillator(dist_model, self.param, cat_y0) roots_class.intoptions = self.intoptions #return roots_class roots_class.solve_bvp() roots_class.limit_cycle() roots_class.roots() phases = self._t_to_phi(roots_class.tmin[-1]) distances = roots_class.ymin[-1] distance = np.min(distances) if distance < tol: phase_ind = np.argmin(distances) # for multiple minima return phases[phase_ind]#, roots_class intr.setInput(point, cs.INTEGRATOR_X0) intr.setInput(self.param, cs.INTEGRATOR_P) intr.evaluate() point = intr.output().toArray().flatten() #advance by one cycle raise RuntimeError("Point failed to converge to limit cycle")
def solve_ode(self): """ Solve the ODE using casadi's CVODES wrapper to ensure that the collocated dynamics match the error-controlled dynamics of the ODE """ self.ts.sort() # Assert ts is increasing f_integrator = cs.SXFunction( 'ode', cs.daeIn(t=self.dxdt.inputExpr(0), x=self.dxdt.inputExpr(1), p=self.dxdt.inputExpr(2)), cs.daeOut(ode=self.dxdt.outputExpr(0))) integrator = cs.Integrator('int', 'cvodes', f_integrator) simulator = cs.Simulator('sim', integrator, self.ts) simulator.setInput(self.sol[0], 'x0') simulator.setInput(self.var.p_op, 'p') simulator.evaluate() x_sim = self.sol_sim = np.array(simulator.getOutput()).T err = ((self.sol - x_sim).mean(0) / (self.sol.mean(0))).mean() if err > 1E-3: warn('Collocation does not match ODE Solution: \ {:.2%} Error'.format(err))
def _create_ARC_model(self, numstates=1): """ Create model with quadrature for amplitude sensitivities numstates might allow us to calculate entire sARC at once, but now will use seed method. """ # Allocate symbolic vectors for the model dphidx = cs.SX.sym('dphidx', numstates) t = self.model.inputExpr(cs.DAE_T) # time xd = self.model.inputExpr(cs.DAE_X) # differential state s = cs.SX.sym("s", self.neq, numstates) # sensitivities p = cs.vertcat([self.model.inputExpr(2), dphidx]) # parameters # Symbolic function (from input model) ode_rhs = self.model.outputExpr()[0] f_tilde = self.T*ode_rhs/(2*np.pi) # symbolic jacobians jac_x = self.model.jac(cs.DAE_X, cs.DAE_X) sens_rhs = jac_x.mul(s) quad = cs.SX.sym('q', self.neq, numstates) for i in xrange(numstates): quad[:,i] = 2*(s[:,i] - dphidx[i]*f_tilde)*(xd - self.avg) shape = (self.neq*numstates, 1) x = cs.vertcat([xd, s.reshape(shape)]) ode = cs.vertcat([ode_rhs, sens_rhs.reshape(shape)]) ffcn = cs.SXFunction(cs.daeIn(t=t, x=x, p=p), cs.daeOut(ode=ode, quad=quad)) return ffcn
def solve_ode(self): """ Solve the ODE using casadi's CVODES wrapper to ensure that the collocated dynamics match the error-controlled dynamics of the ODE """ f_integrator = cs.SXFunction( "ode", cs.daeIn(t=self.model.inputExpr(0), x=self.model.inputExpr(1), p=self.model.inputExpr(2)), cs.daeOut(ode=self.model.outputExpr(0)), ) integrator = cs.Integrator("int", "cvodes", f_integrator) simulator = cs.Simulator("sim", integrator, self._tgrid) simulator.setInput(self._output["x_opt"][0], "x0") simulator.setInput(self._output["p_opt"], "p") simulator.evaluate() x_sim = self._output["x_sim"] = np.array(simulator.getOutput()).T err = ((self._output["x_opt"] - x_sim).mean(0) / (self._output["x_opt"].mean(0))).mean() if err > 1e-3: warn( "Collocation does not match ODE Solution: \ {:.2f}% Error".format( 100 * err ) )
def model(): # Time Variable t = cs.ssym("t") # Variable Assignments X = cs.ssym("X") Y = cs.ssym("Y") y = cs.vertcat([X, Y]) # Parameter Assignments u = cs.ssym("u") ode = [[]] * NEQ ode[0] = u * (X - (X**3 / 3.) - Y) ode[1] = X / u ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=y, p=cs.vertcat([ u, ])), cs.daeOut(ode=ode)) fn.setOption("name", "Van der Pol oscillator") return fn
def model(): # Variable Assignments X = cs.ssym("X") Y = cs.ssym("Y") y = cs.vertcat([X,Y]) # vector version of y # Parameter Assignments P = cs.ssym("P") kt = cs.ssym("kt") kd = cs.ssym("kd") a0 = cs.ssym("a0") a1 = cs.ssym("a1") a2 = cs.ssym("a2") symparamset = cs.vertcat([P, kt, kd, a0, a1, a2]) # Time Variable (typically unused for autonomous odes) t = cs.ssym("t") ode = [[]]*NEQ ode[0] = 1 / (1 + Y**P) - X ode[1] = kt*X - kd*Y - Y/(a0 + a1*Y + a2*Y**2) ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=y, p=symparamset), cs.daeOut(ode=ode)) fn.setOption("name","Simple Hysteresis model") return fn
def initialize(self, scale=1.0, pump_level=1e5, A_V_ratio=1e-3, des_scale=1e-3, constTem=None): ''' Build the dae system of transient CSTR model :param tau: space time of CSTR model ''' self.pump_ratio = pump_level / float(A_V_ratio) self._Tem = self._T0 + self._beta * self._t self.build_kinetic(constTem=constTem) self.build_rate(scale=1, des_scale=des_scale) for j in range(self.ngas): self._d_partP[j] = -pump_level * self._partP[j] for i in range(self.nrxn): self._d_partP[ j] += A_V_ratio * self.stoimat[i][j] * self._rate[i] for j in range(self.nsurf): self._d_cover[j] = 0 for i in range(self.nrxn): self._d_cover[j] += self.stoimat[i][j + self.ngas] * self._rate[i] self._x = cas.vertcat([self._partP, self._cover]) self._p = cas.vertcat([self._dEa, self._dBE, self._T0, self._beta]) self._xdot = cas.vertcat([self._d_partP, self._d_cover]) self._dae_ = cas.SXFunction("dae", cas.daeIn(x=self._x, p=self._p, t=self._t), cas.daeOut(ode=self._xdot))
def kiss_model_ode(): # For two oscillators e1 = cs.ssym('e1') tht1 = cs.ssym('tht1') e2 = cs.ssym('e2') tht2 = cs.ssym('tht2') state_set = cs.vertcat([e1, tht1, e2, tht2]) # Parameter Assignments A1Rind1 = cs.ssym('A1Rind1') A2Rind2 = cs.ssym('A2Rind2') V = cs.ssym('V') Ch = cs.ssym('Ch') a = cs.ssym('a') b = cs.ssym('b') c = cs.ssym('c') gam1 = cs.ssym('gam1') gam2 = cs.ssym('gam2') AR = cs.ssym('AR') # AR is coupling strength, = 50.5 for model in paper param_set = cs.vertcat([A1Rind1, A2Rind2, V, Ch, a, b, c, gam1, gam2, AR]) # Time t = cs.ssym('t') ode = [[]]*neq # oscillator 1 ode[0] = (V-e1)/A1Rind1 - \ ( Ch*cs.exp(0.5*e1)/(1+Ch*cs.exp(e1)) + a*cs.exp(e1) )*(1-tht1) -\ (e1-e2-np.sin(freq/(2*np.pi)*t))/AR ode[1] = (1/gam1)*(\ (cs.exp(0.5*e1)/(1+Ch*cs.exp(e1)))*(1-tht1) -\ b*Ch*cs.exp(2*e1)*tht1/(c*Ch+cs.exp(e1))\ ) # oscillator 2 ode[2] = (V-e2-np.sin(freq/(2*np.pi)*t))/A2Rind2 - \ ( Ch*cs.exp(0.5*e2-np.sin(freq/(2*np.pi)*t))/(1+Ch*cs.exp(e2-np.sin(freq/(2*np.pi)*t))) + a*cs.exp(e2-np.sin(freq/(2*np.pi)*t)) )*(1-tht2) -\ (e2+np.sin(freq/(2*np.pi)*t)-e1)/AR ode[3] = (1/gam2)*(\ (cs.exp(0.5*e2-np.sin(freq/(2*np.pi)*t))/(1+Ch*cs.exp(e2-np.sin(freq/(2*np.pi)*t))))*(1-tht2) -\ b*Ch*cs.exp(2*e2-np.sin(freq/(2*np.pi)*t))*tht2/(c*Ch+cs.exp(e2-np.sin(freq/(2*np.pi)*t)))\ ) ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t,x=state_set,p=param_set), cs.daeOut(ode=ode)) fn.setOption("name","kiss_oscillator_2011") return fn
def model(): """ Create an ODE casadi SXFunction """ # State Variables Y1 = cs.SX.sym("Y1") Y2 = cs.SX.sym("Y2") Y3 = cs.SX.sym("Y3") y = cs.vertcat([Y1, Y2, Y3]) # Parameters c1x1 = cs.SX.sym("c1x1") c2 = cs.SX.sym("c2") c3x2 = cs.SX.sym("c3x2") c4 = cs.SX.sym("c4") c5x3 = cs.SX.sym("c5x3") symparamset = cs.vertcat([c1x1, c2, c3x2, c4, c5x3]) # Time t = cs.SX.sym("t") # ODES ode = [[]] * EqCount ode[0] = c1x1 * Y2 - c2 * Y1 * Y2 + c3x2 * Y1 - c4 * Y1**2 ode[1] = -c1x1 * Y2 - c2 * Y1 * Y2 + c5x3 * Y3 ode[2] = c3x2 * Y1 - c5x3 * Y3 ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=y, p=symparamset), cs.daeOut(ode=ode)) fn.setOption("name", "Oregonator") return fn
def computeJacobians(self, x, u, measurmentTags): ocp = self.ocp sysIn = C.daeIn(x=ocp.x, z=ocp.z, p=ocp.u, t=ocp.t) sysOut = C.daeOut(ode=ocp.ode(ocp.x), alg=ocp.alg) odeF = C.SXFunction(sysIn, sysOut) odeF.init() mSX = C.vertcat([ ocp.variable(measurmentTags[k]).beq for k in range(len(measurmentTags)) ]) mSXF = C.SXFunction(sysIn, [mSX]) mSXF.init() AS = odeF.jac('x', 'ode') BS = odeF.jac('p', 'ode') CS = mSXF.jac('x', 0) DS = mSXF.jac('p', 0) funcJacs = C.SXFunction(sysIn, [AS, BS, CS, DS]) funcJacs.init() funcJacs.setInput(x, 'x') funcJacs.setInput(u, 'p') funcJacs.evaluate() a = funcJacs.getOutput(0) b = funcJacs.getOutput(1) c = funcJacs.getOutput(2) d = funcJacs.getOutput(3) return a, b, c, d
def model(): #====================================================================== # Variable Assignments #====================================================================== m1 = cs.ssym("m1") m2 = cs.ssym("m2") m3 = cs.ssym("m3") y = cs.vertcat([m1, m2, m3]) #====================================================================== # Parameter Assignments #====================================================================== alpha1 = cs.ssym("alpha1") alpha2 = cs.ssym("alpha2") alpha3 = cs.ssym("alpha3") n = cs.ssym("n") symparamset = cs.vertcat([alpha1, alpha2, alpha3, n]) # Time Variable t = cs.ssym("t") ode = [[]] * NEQ ode[0] = alpha1 / (1. + m2**n) - m1 ode[1] = alpha2 / (1. + m3**n) - m2 ode[2] = alpha3 / (1. + m1**n) - m3 ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=y, p=symparamset), cs.daeOut(ode=ode)) fn.setOption("name", "Small repressilator") return fn
def model(): """ Create an ODE casadi SXFunction """ # State Variables Y1 = cs.ssym("Y1") Y2 = cs.ssym("Y2") y = cs.vertcat([Y1, Y2]) # Parameters c1x1 = cs.ssym("c1x1") c2x2 = cs.ssym("c2x2") c3 = cs.ssym("c3") c4 = cs.ssym("c4") symparamset = cs.vertcat([c1x1, c2x2, c3, c4]) # Time t = cs.ssym("t") # ODES ode = [[]] * NEQ ode[0] = c1x1 - c2x2 * Y1 + (c3 / 2.) * (Y1**2) * Y2 - c4 * Y1 ode[1] = c2x2 * Y1 - (c3 / 2.) * (Y1**2) * Y2 ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=y, p=symparamset), cs.daeOut(ode=ode)) fn.setOption("name", "Brusselator") return fn
def solve_ode(self): """ Solve the ODE using casadi's CVODES wrapper to ensure that the collocated dynamics match the error-controlled dynamics of the ODE """ self.ts.sort() # Assert ts is increasing f_integrator = cs.SXFunction('ode', cs.daeIn( t = self.dxdt.inputExpr(0), x = self.dxdt.inputExpr(1), p = self.dxdt.inputExpr(2)), cs.daeOut( ode = self.dxdt.outputExpr(0))) integrator = cs.Integrator('int', 'cvodes', f_integrator) simulator = cs.Simulator('sim', integrator, self.ts) simulator.setInput(self.sol[0], 'x0') simulator.setInput(self.var.p_op, 'p') simulator.evaluate() x_sim = self.sol_sim = np.array(simulator.getOutput()).T err = ((self.sol - x_sim).mean(0) / (self.sol.mean(0))).mean() if err > 1E-3: warn( 'Collocation does not match ODE Solution: \ {:.2%} Error'.format(err))
def ODEmodel(): #================================================================== #State variable definitions #================================================================== S1a = cs.ssym("S1a") S2a = cs.ssym("S2a") S1b = cs.ssym("S1b") S2b = cs.ssym("S2b") S1c = cs.ssym("S1c") S2c = cs.ssym("S2c") S1d = cs.ssym("S1d") S2d = cs.ssym("S2d") #for Casadi y = cs.vertcat([S1a,S2a,S1b,S2b,S1c,S2c,S1d,S2d]) # Time Variable t = cs.ssym("t") #=================================================================== #Parameter definitions #=================================================================== p1 = cs.ssym('p1') p2 = cs.ssym('p2') p3 = cs.ssym('p3') p4 = cs.ssym('p4') paramset = cs.vertcat([p1,p2,p3,p4]) #=================================================================== # Model Equations #=================================================================== ode = [[]]*EqCount #Rxns ode[0] = (1/p1)*(S1a - (1/3)*S1a**3 - S2a) + couplingstr*(S1b-S1a) ode[1] = S1a + p1*S2a ode[2] = (1/p1)*(S1b - (1/3)*S1b**3 - S2b) + couplingstr*(S1a-S1b) + couplingstr*(S1c-S1b) ode[3] = S1b + p1*S2b ode[4] = (1/p1)*(S1c - (1/3)*S1c**3 - S2c) + couplingstr*(S1b-S1c) + couplingstr*(S1d-S1c) ode[5] = S1c + p1*S2c ode[6] = (1/p1)*(S1d - (1/3)*S1d**3 - S2d) + couplingstr*(S1c-S1d) ode[7] = S1d + p1*S2d ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=y, p=paramset), cs.daeOut(ode=ode)) fn.setOption("name","simple") return fn
def _initialize_polynomial_coefs(self): """ Setup radau polynomials and initialize the weight factor matricies """ self.col_vars['tau_root'] = cs.collocationPoints(self.d, "radau") # Dimensionless time inside one control interval tau = cs.SX.sym("tau") # For all collocation points L = [[]]*(self.d+1) for j in range(self.d+1): # Construct Lagrange polynomials to get the polynomial basis at the # collocation point L[j] = 1 for r in range(self.d+1): if r != j: L[j] *= ( (tau - self.col_vars['tau_root'][r]) / (self.col_vars['tau_root'][j] - self.col_vars['tau_root'][r])) self.col_vars['lfcn'] = lfcn = cs.SXFunction( 'lfcn', [tau], [cs.vertcat(L)]) # Evaluate the polynomial at the final time to get the coefficients of # the continuity equation # Coefficients of the continuity equation self.col_vars['D'] = lfcn([1.0])[0].toArray().squeeze() # Evaluate the time derivative of the polynomial at all collocation # points to get the coefficients of the continuity equation tfcn = lfcn.tangent() # Coefficients of the collocation equation self.col_vars['C'] = np.zeros((self.d+1, self.d+1)) for r in range(self.d+1): self.col_vars['C'][:,r] = tfcn([self.col_vars['tau_root'][r]] )[0].toArray().squeeze() # Find weights for gaussian quadrature: approximate int_0^1 f(x) by # Sum( xtau = cs.SX.sym("xtau") Phi = [[]] * (self.d+1) for j in range(self.d+1): tau_f_integrator = cs.SXFunction('ode', cs.daeIn(t=tau, x=xtau), cs.daeOut(ode=L[j])) tau_integrator = cs.Integrator( "integrator", "cvodes", tau_f_integrator, {'t0':0., 'tf':1}) Phi[j] = np.asarray(tau_integrator({'x0' : 0})['xf'])[0][0] self.col_vars['Phi'] = np.array(Phi) self.col_vars['alpha'] = cs.SX.sym('alpha')
def simulatePlot(self, x0, U=None, outputVars=None): if U is None: U = self.USOL outs = [] tout = [] if outputVars is not None: outputSX = C.vertcat([ self.ocp.variable(outputVars[k]).beq for k in range(len(outputVars)) ]) fout = C.SXFunction( C.daeIn(x=self.ocp.x, z=self.ocp.z, p=self.ocp.u, t=self.ocp.t), [outputSX]) fout.init() zf = C.vertcat([ self.ocp.variable(self.ocp.z[k].getName()).start for k in range(self.ocp.z.size()) ]) xh = [] zh = [] xk = x0 for k in range(len(U)): self.G.setInput(xk, 'x0') self.G.setInput(zf, 'z0') self.G.setInput(U[k], 'p') self.G.evaluate() xk = self.G.getOutput('xf') zf = self.G.getOutput('zf') xh.append(xk) zh.append(zf) tout.append((k + 1) * self.DT) if outputVars is not None: fout.setInput(xk, 'x') fout.setInput(zf, 'z') fout.setInput(U[k], 'p') fout.setInput((k + 1) * self.DT, 't') fout.evaluate() fouk = fout.getOutput() outs.append(fouk) return tout, xh, zh, outs
def _initialize_polynomial_coefs(self): """ Setup radau polynomials and initialize the weight factor matricies """ self.col_vars['tau_root'] = cs.collocationPoints(self.d, "radau") # Dimensionless time inside one control interval tau = cs.SX.sym("tau") # For all collocation points L = [[]]*(self.d+1) for j in range(self.d+1): # Construct Lagrange polynomials to get the polynomial basis at the # collocation point L[j] = 1 for r in range(self.d+1): if r != j: L[j] *= ( (tau - self.col_vars['tau_root'][r]) / (self.col_vars['tau_root'][j] - self.col_vars['tau_root'][r])) self.col_vars['lfcn'] = lfcn = cs.SXFunction( 'lfcn', [tau], [cs.vertcat(L)]) # Evaluate the polynomial at the final time to get the coefficients of # the continuity equation # Coefficients of the continuity equation self.col_vars['D'] = lfcn([1.0])[0].toArray().squeeze() # Evaluate the time derivative of the polynomial at all collocation # points to get the coefficients of the continuity equation tfcn = lfcn.tangent() # Coefficients of the collocation equation self.col_vars['C'] = np.zeros((self.d+1, self.d+1)) for r in range(self.d+1): self.col_vars['C'][:,r] = tfcn([self.col_vars['tau_root'][r]] )[0].toArray().squeeze() # Find weights for gaussian quadrature: approximate int_0^1 f(x) by # Sum( xtau = cs.SX.sym("xtau") Phi = [[]] * (self.d+1) for j in range(self.d+1): tau_f_integrator = cs.SXFunction('ode', cs.daeIn(t=tau, x=xtau), cs.daeOut(ode=L[j])) tau_integrator = cs.Integrator( "integrator", "cvodes", tau_f_integrator, {'t0':0., 'tf':1}) Phi[j] = np.asarray(tau_integrator({'x0' : 0})['xf'])[0][0] self.col_vars['Phi'] = np.array(Phi)
def model(): """ Function for the L-P process model of human circadian rhythms. Calculation of phase shifts must be done via the """ #================================================================== #setup of symbolics #================================================================== x = cs.SX.sym("x") xc = cs.SX.sym("xc") sys = cs.vertcat([x, xc]) #=================================================================== #Parameter definitions #=================================================================== mu = cs.SX.sym("mu") k = cs.SX.sym("k") q = cs.SX.sym("q") taux = cs.SX.sym("taux") alpha0 = cs.SX.sym("alpha0") beta = cs.SX.sym("beta") G = cs.SX.sym("G") p = cs.SX.sym("p") I0 = cs.SX.sym("I0") Bhat = cs.SX.sym("B") paramset = cs.vertcat([mu, k, q, taux, Bhat]) # Time t = cs.SX.sym("t") #=================================================================== # set up the ode system #=================================================================== def B(bhat): return (1 - 0.4 * x) * (1 - 0.4 * xc) * bhat ode = [[]] * EqCount #initializes vector ode[0] = (cs.pi / 12) * (xc + mu * (x / 3. + (4 / 3.) * x**3 - (256 / 105.) * x**7) + B(Bhat)) ode[1] = (cs.pi / 12) * (q * B(Bhat) * xc - ((24 / (0.99729 * taux))**2 + k * B(Bhat)) * x) ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=sys, p=paramset), cs.daeOut(ode=ode)) fn.setOption("name", "kronauer_P") return fn
def solve_bvp_casadi(self): """ Uses casadi's interface to sundials to solve the boundary value problem using a single-shooting method with automatic differen- tiation. Related to PCSJ code. """ self.bvpint = cs.Integrator('cvodes', self.modlT) self.bvpint.setOption('abstol', self.intoptions['bvp_abstol']) self.bvpint.setOption('reltol', self.intoptions['bvp_reltol']) self.bvpint.setOption('tf', 1) self.bvpint.setOption('disable_internal_warnings', True) self.bvpint.setOption('fsens_err_con', True) self.bvpint.init() # Vector of unknowns [y0, T] V = cs.MX.sym("V", self.neq + 1) y0 = V[:-1] T = V[-1] param = cs.vertcat([self.param, T]) yf = self.bvpint.call(cs.integratorIn(x0=y0, p=param))[0] fout = self.modlT.call(cs.daeIn(t=T, x=y0, p=param))[0] # objective: continuity obj = (yf - y0)**2 # yf and y0 are the same ..i.e. 2 ends of periodic fcn obj.append( fout[0]) # y0 is a peak for state 0, i.e. fout[0] is slope state 0 #set up the matrix we want to solve F = cs.MXFunction([V], [obj]) F.init() guess = np.append(self.y0, self.T) solver = cs.ImplicitFunction('kinsol', F) solver.setOption('abstol', self.intoptions['bvp_ftol']) solver.setOption('strategy', 'linesearch') solver.setOption('exact_jacobian', False) solver.setOption('pretype', 'both') solver.setOption('use_preconditioner', True) if self.intoptions['constraints'] == 'positive': solver.setOption('constraints', (2, ) * (self.neq + 1)) solver.setOption('linear_solver_type', 'dense') solver.init() solver.setInput(guess) solver.evaluate() sol = solver.output().toArray().squeeze() self.y0 = sol[:-1] self.T = sol[-1]
def sxFun(self): self._freeze('sxFun()') algRes = None if hasattr(self,'_algRes'): algRes = self._algRes odeRes = self._odeRes if isinstance(odeRes,list): odeRes = C.veccat(odeRes) if isinstance(algRes,list): algRes = C.veccat(algRes) return C.SXFunction( C.daeIn( x=self.xVec(), z=self.zVec(), p=C.veccat([self.uVec(),self.pVec()]), xdot=self.stateDotDummy ), C.daeOut( alg=algRes, ode=odeRes) )
def solveBVP_casadi(self): """ Uses casadi's interface to sundials to solve the boundary value problem using a single-shooting method with automatic differen- tiation. """ # Here we create and initialize the integrator SXFunction self.bvpint = cs.CVodesIntegrator(self.modlT) self.bvpint.setOption('abstol',self.intoptions['bvp_abstol']) self.bvpint.setOption('reltol',self.intoptions['bvp_reltol']) self.bvpint.setOption('tf',1) self.bvpint.setOption('disable_internal_warnings', True) self.bvpint.setOption('fsens_err_con', True) self.bvpint.init() # Vector of unknowns [y0, T] V = cs.msym("V",self.NEQ+1) y0 = V[:-1] T = V[-1] t = cs.msym('t') param = cs.vertcat([self.paramset, T]) yf = self.bvpint.call(cs.integratorIn(x0=y0,p=param))[0] fout = self.modlT.call(cs.daeIn(t=t, x=y0,p=param))[0] obj = (yf - y0)**2 obj.append(fout[0]) F = cs.MXFunction([V],[obj]) F.init() solver = cs.KinsolSolver(F) solver.setOption('abstol',self.intoptions['bvp_ftol']) solver.setOption('ad_mode', "forward") solver.setOption('strategy','linesearch') solver.setOption('numeric_jacobian', True) solver.setOption('exact_jacobian', False) solver.setOption('pretype', 'both') solver.setOption('use_preconditioner', True) solver.setOption('numeric_hessian', True) solver.setOption('constraints', (2,)*(self.NEQ+1)) solver.setOption('verbose', False) solver.setOption('sparse', False) solver.setOption('linear_solver', 'dense') solver.init() solver.output().set(self.y0) solver.solve() self.y0 = solver.output().toArray().squeeze()
def phase_of_point(self, point, error=False, tol=1E-3): """ Finds the phase at which the distance from the point to the limit cycle is minimized. phi=0 corresponds to the definition of y0, returns the phase and the minimum distance to the limit cycle """ point = np.asarray(point) for i in xrange(100): dist = cs.ssym("dist") x = self.model.inputSX(cs.DAE_X) ode = self.model.outputSX() dist_ode = cs.sumAll(2*(x - point)*ode) cat_x = cs.vertcat([x, dist]) cat_ode = cs.vertcat([ode, dist_ode]) dist_model = cs.SXFunction( cs.daeIn(t=self.model.inputSX(cs.DAE_T), x=cat_x, p=self.model.inputSX(cs.DAE_P)), cs.daeOut(ode=cat_ode)) dist_model.setOption("name","distance model") dist_0 = ((self.y0[:-1] - point)**2).sum() cat_y0 = np.hstack([self.y0[:-1], dist_0, self.y0[-1]]) roots_class = pBase(dist_model, self.paramset, cat_y0) # roots_class.solveBVP() roots_class.roots() phase = self._t_to_phi(roots_class.Tmin[-1]) distance = roots_class.Ymin[-1] if distance < tol: return phase, distance intr = cs.CVodesIntegrator(self.model) intr.setOption("abstol", self.intoptions['transabstol']) intr.setOption("reltol", self.intoptions['transreltol']) intr.setOption("tf", self.y0[-1]) intr.setOption("max_num_steps", self.intoptions['transmaxnumsteps']) intr.setOption("disable_internal_warnings", True) intr.init() intr.setInput(point, cs.INTEGRATOR_X0) intr.setInput(self.paramset, cs.INTEGRATOR_P) intr.evaluate() point = intr.output().toArray().flatten() raise RuntimeError("Point failed to converge to limit cycle")
def build_model(self): """ Takes inputs from self.states, self.params and self.odes to build a casadi SXFunction model in self.model. Also calculates self.NP and self.NEQ """ x = cs.vertcat(self.states) p = cs.vertcat(self.params) ode = cs.vertcat(self.odes) t = cs.ssym('t') fn = cs.SXFunction(cs.daeIn(t=t, x=x, p=p), cs.daeOut(ode=ode)) self.model = fn self.NP = len(self.params) self.NEQ = len(self.states)
def model(): #================================================================== #setup of symbolics #================================================================== x = cs.SX.sym("x") y = cs.SX.sym("y") sys = cs.vertcat([x,y]) #=================================================================== #Parameter definitions #=================================================================== k1 = cs.SX.sym("k1") Kd = cs.SX.sym("Kd") P = cs.SX.sym("P") kdx = cs.SX.sym("kdx") ksy = cs.SX.sym("ksy") kdy = cs.SX.sym("kdy") k2 = cs.SX.sym("k2") Km = cs.SX.sym("Km") KI = cs.SX.sym("KI") paramset = cs.vertcat([k1,Kd,P,kdx,ksy,kdy,k2,Km,KI]) # Time t = cs.SX.sym("t") #=================================================================== # set up the ode system #=================================================================== ode = [[]]*EqCount #initializes vector ode[0] = k1*(Kd**P)/((Kd**P) + (y**P)) - kdx*x ode[1] = ksy*x - kdy*y - k2*y/(Km + y + KI*y**2) ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=sys, p=paramset), cs.daeOut(ode=ode)) fn.setOption("name","2state") return fn
def modifiedModel(self): """ Creates a new casadi model with period as a parameter, such that the model has an oscillatory period of 1. Necessary for the exact determinination of the period and initial conditions through the BVP method. (see Wilkins et. al. 2009 SIAM J of Sci Comp) """ pSX = self.model.inputSX(cs.DAE_P) T = cs.ssym("T") pTSX = cs.vertcat([pSX, T]) self.modlT = cs.SXFunction( cs.daeIn(t=self.model.inputSX(cs.DAE_T), x=self.model.inputSX(cs.DAE_X), p=pTSX), cs.daeOut(ode=cs.vertcat([self.model.outputSX()*T]))) self.modlT.setOption("name","T-shifted model")
def casadiDae(self): # I have: # 0 = fg(xdot,x,z) # # I need dot(x') = f(x',z') # 0 = g(x',z') # # let x' = x # z' = [z,xdot] # dot(x') = xdot # 0 = g(x',z') = g(x,[z,xdot]) = fg(xdot,x,z) self._freezeXzup('casadiDae()') f = self.getResidual() xdot = C.veccat([self.ddt(name) for name in self.xNames()]) return C.SXFunction( C.daeIn( x=self.xVec(), z=C.veccat([self.zVec(),xdot]), p=C.veccat([self.uVec(),self.pVec()]) ), C.daeOut( alg=f, ode=xdot) )
def changeMeasurement(self, measuremntsList): measurementScaling = C.vertcat( [self.ocp.variable(k).nominal for k in measuremntsList]) ocp = self.ocp mSX = C.vertcat([ ocp.variable(measuremntsList[k]).beq for k in range(len(measuremntsList)) ]) mSX = C.substitute( mSX, C.vertcat([ocp.x, ocp.z, ocp.u]), C.vertcat([ self.stateScaling * ocp.x, self.algStateScaling * ocp.z, self.controlScaling * ocp.u ])) / measurementScaling sysIn = C.daeIn(x=ocp.x, z=ocp.z, p=ocp.u, t=ocp.t) mSXF = C.SXFunction(sysIn, [mSX]) mSXF.init() self.measurementScaling = measurementScaling self.mSXF = mSXF
def model(): #====================================================================== # Variable Assignments #====================================================================== m1 = cs.ssym("m1") p1 = cs.ssym("p1") m2 = cs.ssym("m2") p2 = cs.ssym("p2") m3 = cs.ssym("m3") p3 = cs.ssym("p3") y = cs.vertcat([m1, p1, m2, p2, m3, p3]) #====================================================================== # Parameter Assignments #====================================================================== alpha = cs.ssym("alpha") alpha0 = cs.ssym("alpha0") n = cs.ssym("n") beta = cs.ssym("beta") symparamset = cs.vertcat([alpha, alpha0, n, beta]) # Time Variable t = cs.ssym("t") ode = [[]] * NEQ ode[0] = alpha0 + alpha / (1 + p3**n) - m1 ode[1] = beta * (m1 - p1) ode[2] = alpha0 + alpha / (1 + p1**n) - m2 ode[3] = beta * (m2 - p2) ode[4] = alpha0 + alpha / (1 + p2**n) - m3 ode[5] = beta * (m3 - p3) ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=y, p=symparamset), cs.daeOut(ode=ode)) fn.setOption("name", "Tyson 2 State Model") return fn
def model(): #====================================================================== # Variable Assignments #====================================================================== X = cs.ssym("X") Y = cs.ssym("Y") y = cs.vertcat([X,Y]) #====================================================================== # Parameter Assignments #====================================================================== k1 = cs.ssym("k1") Kd = cs.ssym("Kd") P = cs.ssym("P") kdx = cs.ssym("kdx") ksy = cs.ssym("ksy") kdy = cs.ssym("kdy") k2 = cs.ssym("k2") Km = cs.ssym("Km") KI = cs.ssym("KI") symparamset = cs.vertcat([k1,Kd,P,kdx,ksy,kdy,k2,Km,KI]) # Time Variable t = cs.ssym("t") ode = [[]]*NEQ ode[0] = k1*(Kd**P)/((Kd**P) + (Y**P)) - kdx*X ode[1] = ksy*X - kdy*Y - k2*Y/(Km + Y + KI*Y**2) ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=y, p=symparamset), cs.daeOut(ode=ode)) fn.setOption("name","Tyson 2 State Model") return fn
def checkStability(self, x, u): stateScaling = self.stateScaling algStateScaling = self.algStateScaling controlScaling = self.controlScaling ocp = self.ocp odeS = C.substitute( ocp.ode(ocp.x), C.vertcat([ocp.x, ocp.z, ocp.u]), C.vertcat([ stateScaling * ocp.x, algStateScaling * ocp.z, controlScaling * ocp.u ])) / stateScaling algS = C.substitute( ocp.alg, C.vertcat([ocp.x, ocp.z, ocp.u]), C.vertcat([ stateScaling * ocp.x, algStateScaling * ocp.z, controlScaling * ocp.u ])) sysIn = C.daeIn(x=ocp.x, z=ocp.z, p=ocp.u, t=ocp.t) sysOut = C.daeOut(ode=odeS, alg=algS) odeF = C.SXFunction(sysIn, sysOut) odeF.init() dG = odeF.jacobian('x', 'ode') dG.init() dG.setInput(x / stateScaling, 'x') dG.setInput(u / controlScaling, 'p') dG.evaluate() dGdx = dG.getOutput() eigVals, eigVecs = scipy.linalg.eig(dGdx) return eigVals, dGdx, odeS
def ODEModel(): # Variable Assignments X = cs.ssym("X") Y = cs.ssym("Y") sys = cs.vertcat([X, Y]) # vector version of y # Parameter Assignments P = cs.ssym("P") kt = cs.ssym("kt") kd = cs.ssym("kd") a0 = cs.ssym("a0") a1 = cs.ssym("a1") a2 = cs.ssym("a2") kdx = cs.ssym("kdx") paramset = cs.vertcat([P, kt, kd, a0, a1, a2, kdx]) #================================================================================ # Model Equations #================================================================================ ode = [[]] * EqCount # MRNA Species t = cs.ssym("t") ode = [[]] * EqCount ode[0] = 1 / (1 + Y**P) - kdx * X ode[1] = kt * X - kd * Y - Y / (a0 + a1 * Y + a2 * Y**2) ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=sys, p=paramset), cs.daeOut(ode=ode)) fn.setOption("name", "2state") return fn
def model(): # Variable Assignments x = cs.ssym("x") y = cs.ssym("y") z = cs.ssym("z") symy = cs.vertcat([x, y, z]) # Parameter Assignments b = cs.ssym("b") d1 = cs.ssym("d1") d2 = cs.ssym("d2") d3 = cs.ssym("d3") t1 = cs.ssym("t1") h = cs.ssym("h") V = cs.ssym("V") K = cs.ssym("K") symparamset = cs.vertcat([b, d1, d2, d3, t1, h, V, K]) # Time Variable t = cs.ssym("t") ode = [[]] * NEQ # /* mRNA of per */ ode[0] = V / (1 + (z / K)**h) - d1 * x ode[1] = b * x - (d2 + t1) * y ode[2] = t1 * y - d3 * z ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=symy, p=symparamset), cs.daeOut(ode=ode)) fn.setOption("name", "Reischl Model") return fn
def model(): """ Deterministic model """ # State Variables X1 = cs.ssym('X1') X2 = cs.ssym('X2') X3 = cs.ssym('X3') y = cs.vertcat([X1, X2, X3]) # Parameters h = cs.ssym('h') a = cs.ssym('a') i = cs.ssym('i') r = cs.ssym('r') symparamset = cs.vertcat([h, a, i, r]) # Time t = cs.ssym('t') # ODES ode = [[]]*NEQ ode[0] = 1./(1. + X3**h) - a*X1 ode[1] = X1 - i*X2 ode[2] = X2 - r*X3 ode = cs.vertcat(ode) fn = cs.SXFunction(cs.daeIn(t=t, x=y, p=symparamset), cs.daeOut(ode=ode)) fn.setOption("name", "Goodwin") return fn
def solve_ode(self): """ Solve the ODE using casadi's CVODES wrapper to ensure that the collocated dynamics match the error-controlled dynamics of the ODE """ f_integrator = cs.SXFunction( 'ode', cs.daeIn(t=self.model.inputExpr(0), x=self.model.inputExpr(1), p=self.model.inputExpr(2)), cs.daeOut(ode=self.model.outputExpr(0))) integrator = cs.Integrator('int', 'cvodes', f_integrator) simulator = cs.Simulator('sim', integrator, self._tgrid) simulator.setInput(self._output['x_opt'][0], 'x0') simulator.setInput(self._output['p_opt'], 'p') simulator.evaluate() x_sim = self._output['x_sim'] = np.array(simulator.getOutput()).T err = ((self._output['x_opt'] - x_sim).mean(0) / (self._output['x_opt'].mean(0))).mean() if err > 1E-3: warn('Collocation does not match ODE Solution: \ {:.2f}% Error'.format(100 * err))
x0Sim, z0Sim, y_0Sim = daeModelSim.findSteadyState(u0Sim, None, None, 0, consList=['net.w1sim.z1', 'net.w2sim.z1', 'net.p.z']) uOpt, xOpt, zOpt, yOpt = daeModel.findOptimalPoint(u0, x0=x0, z0=z0, simCount=0, consList=['net.w1.z1', 'net.w2.z1', 'net.p.z']) uOptSim, xOptSim, zOptSim, yOptSim = daeModelSim.findOptimalPoint(u0Sim, x0=x0Sim, z0=z0Sim, simCount=0, consList=['net.w1sim.z1', 'net.w2sim.z1', 'net.p.z']) print 'uOpt:', uOpt print 'yOpt:', yOpt sys.stdout.flush() ## jacobian calculation Test sysIn = ca.daeIn(x=ocp.x, z=ocp.z, p=ocp.u, t=ocp.t) sysOut = ca.daeOut(ode=ocp.ode(ocp.x), alg=ocp.alg) odeF = ca.SXFunction(sysIn, sysOut) odeF.init() measTags = ['Obj'] mSX = ca.vertcat([ocp.variable(measTags[k]).beq for k in range(len(measTags))]) mSXF = ca.SXFunction(sysIn, [mSX]) mSXF.init() AS = odeF.jac('x', 'ode') BS = odeF.jac('p', 'ode') CS = mSXF.jac('x', 0) DS = mSXF.jac('p', 0) funcJacs = ca.SXFunction(sysIn, [AS, BS, CS, DS])
def setUp(self): self.x = ca.MX.sym("x") self.f = ca.MX.sym("f") self.dae = ca.MXFunction("dae", ca.daeIn(x=self.x), ca.daeOut(ode=self.f))
denom = l * ( 4. / 3. - mp * cost*cost / (mc + mp) ) ddtheta = num / denom ddx = (-u + mp * l * ( x[0] * x[0] * sint - ddtheta * cost ) - fric) / (mc + mp) x_err = x-x_target cost_mat = np.diag( [1,1,1,1] ) ode = ca.vertcat([ ddtheta, \ x[0], \ ddx, \ x[2] ] ) # ca.mul( [ x_err.T, cost_mat, x_err ] ) dae = ca.SXFunction( 'dae', ca.daeIn( x=x, p=u, t=t ), ca.daeOut( ode=ode ) ) # Create an integrator opts = { 'tf': tf/nk } # final time if coll: opts[ 'number_of_finite_elements' ] = 5 opts['interpolation_order'] = 5 opts['collocation_scheme'] = 'legendre' opts['implicit_solver'] = 'kinsol' opts['implicit_solver_options'] = {'linear_solver' : 'csparse'} opts['expand_f'] = True integrator = ca.Integrator('integrator', 'oldcollocation', dae, opts) else: opts['abstol'] = 1e-1 # tolerance opts['reltol'] = 1e-1 # tolerance # opts['steps_per_checkpoint'] = 1000
import matplotlib.pyplot as plt from operator import itemgetter nk = 20 # Control discretization tf = 10.0 # End time # Declare variables (use scalar graph) u = ca.SX.sym("u") # control x = ca.SX.sym("x",2) # states # ODE right hand side and quadratures xdot = ca.vertcat( [(1 - x[1]*x[1])*x[0] - x[1] + u, x[0]] ) qdot = x[0]*x[0] + x[1]*x[1] + u*u # DAE residual function dae = ca.SXFunction("dae", ca.daeIn(x=x, p=u), ca.daeOut(ode=xdot, quad=qdot)) # Create an integrator integrator = ca.Integrator("integrator", "cvodes", dae, {"tf":tf/nk}) # All controls (use matrix graph) x = ca.MX.sym("x",nk) # nk-by-1 symbolic variable U = ca.vertsplit(x) # cheaper than x[0], x[1], ... # The initial state (x_0=0, x_1=1) X = ca.MX([0,1]) # Objective function f = 0 # Build a graph of integrator calls
def freeModel(endTimeSteps=None): stateNames = [ "x" # state 0 , "y" # state 1 , "z" # state 2 , "e11" # state 3 , "e12" # state 4 , "e13" # state 5 , "e21" # state 6 , "e22" # state 7 , "e23" # state 8 , "e31" # state 9 , "e32" # state 10 , "e33" # state 11 , "dx" # state 12 , "dy" # state 13 , "dz" # state 14 , "w1" # state 15 , "w2" # state 16 , "w3" # state 17 ] uNames = [ "tc" , "aileron" , "elevator" , "rudder" # , 'ddr' ] pNames = [ "wind_x" ] uSyms = [C.ssym(name) for name in uNames] uDict = dict(zip(uNames,uSyms)) uVec = C.veccat( uSyms ) pSyms = [C.ssym(name) for name in pNames] pDict = dict(zip(pNames,pSyms)) pVec = C.veccat( pSyms ) stateSyms = [C.ssym(name) for name in stateNames] stateDict = dict(zip(stateNames,stateSyms)) stateVec = C.veccat( stateSyms ) dx = stateDict['dx'] dy = stateDict['dy'] dz = stateDict['dz'] outputs = {} outputs['aileron(deg)']=uDict['aileron']*180/C.pi outputs['elevator(deg)']=uDict['elevator']*180/C.pi outputs['rudder(deg)']=uDict['rudder']*180/C.pi (massMatrix, rhs, dRexp) = modelInteg(stateDict, uDict, pDict, outputs) zVec = C.solve(massMatrix, rhs) ddX = zVec[0:3] dw = zVec[3:6] ode = C.veccat( [ C.veccat([dx,dy,dz]) , dRexp.trans().reshape([9,1]) , ddX , dw ] ) if endTimeSteps is not None: endTime,nSteps = endTimeSteps pNames.append("endTime") pDict["endTime"] = endTime pVec = C.veccat([pVec,endTime]) ode = ode#/(endTime/(nSteps-1)) dae = C.SXFunction( C.daeIn( x=stateVec, p=C.veccat([uVec,pVec])), C.daeOut( ode=ode)) return (dae, {'xVec':stateVec,'xDict':stateDict,'xNames':stateNames, 'uVec':uVec,'uNames':uNames, 'pVec':pVec,'pNames':pNames}, outputs)
def run_simulation(self, \ x0 = None, tsim = None, usim = None, psim = None, method = "rk"): r''' :param x0: initial value for the states :math:`x_0 \in \mathbb{R}^{n_x}` :type x0: list, numpy,ndarray, casadi.DMatrix :param tsim: optional, switching time points for the controls :math:`t_{sim} \in \mathbb{R}^{L}` to be used for the simulation :type tsim: list, numpy,ndarray, casadi.DMatrix :param usim: optional, control values :math:`u_{sim} \in \mathbb{R}^{n_u \times L}` to be used for the simulation :type usim: list, numpy,ndarray, casadi.DMatrix :param psim: optional, parameter set :math:`p_{sim} \in \mathbb{R}^{n_p}` to be used for the simulation :type psim: list, numpy,ndarray, casadi.DMatrix :param method: optional, CasADi integrator to be used for the simulation :type method: str This function performs a simulation of the system for a given parameter set :math:`p_{sim}`, starting from a user-provided initial value for the states :math:`x_0`. If the argument ``psim`` is not specified, the estimated parameter set :math:`\hat{p}` is used. For this, a parameter estimation using :func:`run_parameter_estimation()` has to be done beforehand, of course. By default, the switching time points for the controls :math:`t_u` and the corresponding controls :math:`u_N` will be used for simulation. If desired, other time points :math:`t_{sim}` and corresponding controls :math:`u_{sim}` can be passed to the function. For the moment, the function can only be used for systems of type :class:`pecas.systems.ExplODE`. ''' intro.pecas_intro() print('\n' + 27 * '-' + \ ' PECas system simulation ' + 26 * '-') print('\nPerforming system simulation, this might take some time ...') if not type(self.pesetup.system) is systems.ExplODE: raise NotImplementedError("Until now, this function can only " + \ "be used for systems of type ExplODE.") if x0 == None: raise ValueError("You have to provide an initial value x0 " + \ "to run the simulation.") x0 = np.squeeze(np.asarray(x0)) if np.atleast_1d(x0).shape[0] != self.pesetup.nx: raise ValueError("Wrong dimension for initial value x0.") if tsim == None: tsim = self.pesetup.tu if usim == None: usim = self.pesetup.uN if psim == None: try: psim = self.phat except AttributeError: errmsg = ''' You have to either perform a parameter estimation beforehand to obtain a parameter set that can be used for simulation, or you have to provide a parameter set in the argument psim. ''' raise AttributeError(errmsg) else: if not np.atleast_1d(np.squeeze(psim)).shape[0] == self.pesetup.np: raise ValueError("Wrong dimension for parameter set psim.") fp = ca.MXFunction("fp", \ [self.pesetup.system.t, self.pesetup.system.u, \ self.pesetup.system.x, self.pesetup.system.eps_e, \ self.pesetup.system.eps_u, self.pesetup.system.p], \ [self.pesetup.system.f]) fpeval = fp([\ self.pesetup.system.t, self.pesetup.system.u, \ self.pesetup.system.x, np.zeros(self.pesetup.neps_e), \ np.zeros(self.pesetup.neps_u), psim])[0] fsim = ca.MXFunction("fsim", \ ca.daeIn(t = self.pesetup.system.t, \ x = self.pesetup.system.x, \ p = self.pesetup.system.u), \ ca.daeOut(ode = fpeval)) Xsim = [] Xsim.append(x0) u0 = ca.DMatrix() for k,e in enumerate(tsim[:-1]): try: integrator = ca.Integrator("integrator", method, \ fsim, {"t0": e, "tf": tsim[k+1]}) except RuntimeError as err: errmsg = ''' It seems like you want to use an integration method that is not currently supported by CasADi. Please refer to the CasADi documentation for a list of supported integrators, or use the default RK4-method by not setting the method-argument of the function. ''' raise RuntimeError(errmsg) if not self.pesetup.nu == 0: u0 = usim[:,k] Xk_end = itemgetter('xf')(integrator({'x0':x0,'p':u0})) Xsim.append(Xk_end) x0 = Xk_end self.Xsim = ca.horzcat(Xsim) print( \ '''System simulation finished.''')
sigma_u = 0.005 sigma_y = pl.array([0.01, 0.01, 0.01, 0.01]) udata = u0 * pl.sin(2 * pl.pi*time_points[:-1]) udata_noise = udata + sigma_u * pl.randn(*udata.shape) simulation_true_parameters.run_system_simulation( \ x0 = x0, time_points = time_points, udata = udata_noise) ydata = simulation_true_parameters.simulation_results.T ydata_noise = ydata + sigma_y * pl.randn(*ydata.shape) ffcn = ca.MXFunction("ffcn", \ ca.daeIn(x = x, p = ca.vertcat([u, eps_u, p])), \ ca.daeOut(ode = f)) ffcn = ffcn.expand() rk4 = ca.Integrator("rk4", "rk", ffcn, {"t0": 0, "tf": dt, \ "number_of_finite_elements": 1}) P = ca.MX.sym("P", 3) EPS_U = ca.MX.sym("EPS_U", int(N)) X0 = ca.MX.sym("X0", 4) V = ca.vertcat([P, EPS_U, X0]) x_end = X0 obj = [x_end - ydata[0,:].T]