def make_shooter(): # no friction # cos(atan(x)) = 1/(sqrt(1+x^2)) Fx_str = '0' # '-speed_fn()*cos(atan2(vy,vx))' Fy_str = '-10' DSargs = dst.args() DSargs.varspecs = { 'vx': Fx_str, 'x': 'vx', 'vy': Fy_str, 'y': 'vy', 'Fx_out': 'Fx(x,y)', 'Fy_out': 'Fy(x,y)', 'speed': 'speed_fn(vx, vy)', 'bearing': '90-180*atan2(vy,vx)/pi' } auxfndict = { 'Fx': (['x', 'y'], Fx_str), 'Fy': (['x', 'y'], Fy_str), 'speed_fn': (['vx', 'vy'], 'sqrt(vx*vx+vy*vy)'), } DSargs.auxvars = ['Fx_out', 'Fy_out', 'speed', 'bearing'] DSargs.fnspecs = auxfndict DSargs.algparams = { 'init_step': 0.001, 'max_step': 0.1, 'max_pts': 20000, 'maxevtpts': 2, 'refine': 5 } ground_event = dst.Events.makeZeroCrossEvent('y', -1, { 'name': 'ground', 'eventtol': 1e-3, 'precise': True, 'term': True }, varnames=['y'], targetlang='python') peak_event = dst.Events.makeZeroCrossEvent('vy', -1, { 'name': 'peak', 'eventtol': 1e-3, 'precise': True, 'term': False }, varnames=['vy'], targetlang='python') DSargs.events = [ground_event, peak_event] DSargs.checklevel = 2 DSargs.ics = {'x': 0, 'y': 0, 'vx': 0, 'vy': 0} DSargs.ics.update(make_vel_ics(5, 20)) DSargs.name = 'cannon' DSargs.tdomain = [0, 100000] DSargs.tdata = [0, 10] return dst.embed(dst.Generator.Vode_ODEsystem(DSargs))
def get_pycont(param_dict): DSargs = dst.args(name='Whi5_Sbf_module') # parameters DSargs.pars = { "kasSW": 1.67, "kdisSW": 1.67e-4, "kPhWhi5": 1e-3, "kDphWhi5": 5e-4, "fac": 58, "kdCln12": 0.0015, "Sbft": 1.1, "Whi50": 65, "V": 20, "Cln3": 1.0 } DSargs.varspecs = { 'Cln12': 'kdCln12*fac*Sbf/Sbft - kdCln12*Cln12', 'Sbf': '-kasSW*(Whi50/V+Sbf-Sbft-Whi5P)*Sbf + (kdisSW + kPhWhi5*(Cln12+Cln3))*(Sbft-Sbf)', 'Whi5P': '(kPhWhi5*(Cln12+Cln3))*(Whi50/V-Whi5P) - kDphWhi5*Whi5P', } set_params_from_dict(DSargs.pars, param_dict) DSargs.ics = get_steady_states(param_dict) ode = dst.Generator.Vode_ODEsystem(DSargs) return dst.ContClass(ode)
def figure4b1_continuation(): """Actual continuation analysis for 4B1. Contains commands to pyDSTool. Performs some formatting and continuation. Plotting commands are contained with continuation commands to keep pycont objects together :return: None """ # Set parameters and convert to symbolic representation parameters = default_parameters(i_app=0 * uA_PER_CM2) striped_parameters = {k: strip_dimension(v) for k, v in parameters.items()} v, h, i_app = symbols("v h i_app") striped_parameters["i_app"] = i_app dydt = ode_2d([v, h], 0, striped_parameters, exp=exp) DSargs_1 = PyDSTool.args(name="bifn_1") DSargs_1.pars = {"i_app": 0} DSargs_1.varspecs = { "v": PyDSTool.convertPowers(str(dydt[0])), "h": PyDSTool.convertPowers(str(dydt[1])), } DSargs_1.ics = {"v": 0, "h": 0} ode_1 = PyDSTool.Generator.Vode_ODEsystem(DSargs_1) ode_1.set(pars={"i_app": 0}) ode_1.set(ics={"v": -49, "h": 0.4}) PyCont_1 = PyDSTool.ContClass(ode_1) PCargs_1 = PyDSTool.args(name="EQ1_1", type="EP-C") PCargs_1.freepars = ["i_app"] PCargs_1.MaxNumPoints = 500 PCargs_1.MaxStepSize = 0.05 PCargs_1.MinStepSize = 1e-5 PCargs_1.StepSize = 1e-2 PCargs_1.LocBifPoints = "all" PCargs_1.SaveEigen = True PyCont_1.newCurve(PCargs_1) PyCont_1["EQ1_1"].backward() PyCont_1["EQ1_1"].forward() PyCont_1["EQ1_1"].backward() PyCont_1["EQ1_1"].display(["i_app", "v"], stability=True, figure=1) PCargs_1.name = "LC1_1" PCargs_1.type = "LC-C" PCargs_1.initpoint = "EQ1_1:H1" PCargs_1.freepars = ["i_app"] PCargs_1.MaxNumPoints = 500 PCargs_1.MaxStepSize = 0.1 PCargs_1.LocBifPoints = "all" PCargs_1.SaveEigen = True PyCont_1.newCurve(PCargs_1) PyCont_1["LC1_1"].backward() PyCont_1["LC1_1"].display(("i_app", "v_min"), stability=True, figure=1) PyCont_1["LC1_1"].display(("i_app", "v_max"), stability=True, figure=1) PyCont_1.plot.toggleLabels(visible="off", bytype=["P", "RG", "LP"]) PyCont_1.plot.togglePoints(visible="off", bytype=["P", "RG", "LP"]) plt.gca().set_title("")
def make_jac_pydstool(ode): jac, new_fnspecs = dst.prepJacobian(ode.funcspec._initargs['varspecs'], ['X', 'Y', 'A', 'B'], ode.funcspec._initargs['fnspecs']) scope = dst.copy(ode.pars) scope.update(new_fnspecs) jac_fn = dst.expr2fun(jac, ensure_args=['t'], **scope) return jac_fn
def model(): K = 0.4 E = 7.0 M = 10.5 N = 15 Lambda = 0.9 Gamma = 12 R = 0.7 PP = 20 lamb_p = (K*Gamma)/M eta_p = E*K p_p = (Lambda*PP)/(K*Gamma*M) nu_p = N/M rho_p = R # Declare names and initial values for (symbolic) parameters lamb = dst.Par(lamb_p, 'lamb') eta = dst.Par(eta_p, 'eta') p = dst.Par(p_p, 'p') nu = dst.Par(nu_p, 'nu') rho = dst.Par(rho_p, 'rho') # Compute nontrivial boundary equilibrium initial condition from parameters (see reference) b_0 = 0.0 w_0 = p_p/nu_p # Declare symbolic variables b = dst.Var('b') w = dst.Var('w') t = dst.Var('t') # Create Symbolic Quantity objects for definitions brhs = dst.Fun(lamb*w*b*((1+eta*b)**2)*(1-b) - b,[b,w],'brhs') wrhs = dst.Fun(p - nu*w*(1-rho*b) - lamb*w*b*((1+eta*b)**2),[b,w],'wrhs') F = dst.Fun([brhs(b,w),wrhs(b,w)], [b,w], 'F') jac = dst.Fun(dst.Diff(F,[b,w]), [t,b,w], 'Jacobian') # Build Generator DSargs = dst.args(name='fairy_circles_ode') DSargs.fnspecs = [jac, brhs,wrhs] DSargs.varspecs = {b:brhs(b,w) , w:wrhs(b,w)} DSargs.pars = [lamb,eta,p,nu,rho] # Use eval method to get a float value from the symbolic definitions given in # terms of parameter values DSargs.ics = dst.args(b=b_0, w=w_0) return DSargs
def make(self, dsargs): # use cache if available for gen_ver, prev_dsargs in self.used_dsargs.items(): if dst.filteredDict(dsargs, 'name', True) == dst.filteredDict(prev_dsargs, 'name', True): # compare everything but the name, but check all up to final '_ver<X>' parts1 = dsargs.name.split('_') parts2 = prev_dsargs.name.split('_') # will have one more part if parts1 == parts2[:-2]: print("Reusing identical build") return dst.loadObjects(os.path.join(self.cwd, 'models', prev_dsargs.name+'.sav'))[0] # no matches return self.build(dsargs)
def __figure4b1_continuation__(): parameters = default_parameters(i_app=0) v, h, i_app = symbols('v h i_app') parameters[0] = i_app dydt = ode_2d([v, h], 0, parameters, exp=exp) DSargs_1 = PyDSTool.args(name='bifn_1') DSargs_1.pars = {'i_app': 0} DSargs_1.varspecs = { 'v': PyDSTool.convertPowers(str(dydt[0])), 'h': PyDSTool.convertPowers(str(dydt[1])) } DSargs_1.ics = {'v': 0, 'h': 0} ode_1 = PyDSTool.Generator.Vode_ODEsystem(DSargs_1) ode_1.set(pars={'i_app': 0}) ode_1.set(ics={'v': -49, "h": 0.4}) PyCont_1 = PyDSTool.ContClass(ode_1) PCargs_1 = PyDSTool.args(name='EQ1_1', type='EP-C') PCargs_1.freepars = ['i_app'] PCargs_1.MaxNumPoints = 500 PCargs_1.MaxStepSize = 0.05 PCargs_1.MinStepSize = 1e-5 PCargs_1.StepSize = 1e-2 PCargs_1.LocBifPoints = 'all' PCargs_1.SaveEigen = True PyCont_1.newCurve(PCargs_1) PyCont_1['EQ1_1'].backward() PyCont_1['EQ1_1'].forward() PyCont_1['EQ1_1'].backward() PyCont_1['EQ1_1'].display(['i_app', 'v'], stability=True, figure=1) PCargs_1.name = 'LC1_1' PCargs_1.type = 'LC-C' PCargs_1.initpoint = 'EQ1_1:H1' PCargs_1.freepars = ['i_app'] PCargs_1.MaxNumPoints = 500 PCargs_1.MaxStepSize = 0.1 PCargs_1.LocBifPoints = 'all' PCargs_1.SaveEigen = True PyCont_1.newCurve(PCargs_1) PyCont_1['LC1_1'].backward() PyCont_1['LC1_1'].display(('i_app', 'v_min'), stability=True, figure=1) PyCont_1['LC1_1'].display(('i_app', 'v_max'), stability=True, figure=1) PyCont_1.plot.toggleLabels(visible='off', bytype=['P', 'RG']) PyCont_1.plot.togglePoints(visible='off', bytype=['P', 'RG']) plt.gca().set_title('')
def make_shooter(): # no friction # cos(atan(x)) = 1/(sqrt(1+x^2)) Fx_str = '0' # '-speed_fn()*cos(atan2(vy,vx))' Fy_str = '-10' DSargs = dst.args() DSargs.varspecs = {'vx': Fx_str, 'x': 'vx', 'vy': Fy_str, 'y': 'vy', 'Fx_out': 'Fx(x,y)', 'Fy_out': 'Fy(x,y)', 'speed': 'speed_fn(vx, vy)', 'bearing': '90-180*atan2(vy,vx)/pi'} auxfndict = {'Fx': (['x', 'y'], Fx_str), 'Fy': (['x', 'y'], Fy_str), 'speed_fn': (['vx', 'vy'], 'sqrt(vx*vx+vy*vy)'), } DSargs.auxvars = ['Fx_out', 'Fy_out', 'speed', 'bearing'] DSargs.fnspecs = auxfndict DSargs.algparams = {'init_step':0.001, 'max_step': 0.1, 'max_pts': 20000, 'maxevtpts': 2, 'refine': 5} ground_event = dst.Events.makeZeroCrossEvent('y', -1, {'name': 'ground', 'eventtol': 1e-3, 'precise': True, 'term': True}, varnames=['y'], targetlang='python') peak_event = dst.Events.makeZeroCrossEvent('vy', -1, {'name': 'peak', 'eventtol': 1e-3, 'precise': True, 'term': False}, varnames=['vy'], targetlang='python') DSargs.events = [ground_event, peak_event] DSargs.checklevel = 2 DSargs.ics = {'x': 0, 'y': 0, 'vx': 0, 'vy': 0} DSargs.ics.update(make_vel_ics(5,20)) DSargs.name = 'cannon' DSargs.tdomain = [0, 100000] DSargs.tdata = [0, 10] return dst.embed(dst.Generator.Vode_ODEsystem(DSargs))
def make(self, dsargs): # use cache if available for gen_ver, prev_dsargs in self.used_dsargs.items(): if dst.filteredDict(dsargs, 'name', True) == dst.filteredDict( prev_dsargs, 'name', True): # compare everything but the name, but check all up to final '_ver<X>' parts1 = dsargs.name.split('_') parts2 = prev_dsargs.name.split('_') # will have one more part if parts1 == parts2[:-2]: print("Reusing identical build") return dst.loadObjects( os.path.join(self.cwd, 'models', prev_dsargs.name + '.sav'))[0] # no matches return self.build(dsargs)
def build(self, dsargs, is_stiff=False): # re-compute in case gen type has been changed self.targetlang = self._targetlangs[self.gen_type] if is_stiff and self.targetlang == 'python' and self.gen_type == 'vode': dsargs.algparams['stiff'] = True name = dsargs.name if self.gen_version == 0: self.gen_version = 1 # assume it's sufficient to check if .sav file there rather than .so found_new = False while not found_new: filename = os.path.join(self.cwd, 'models', name + '_' + \ self.gen_type + \ '_ver%i'%self.gen_version+'.sav') if not os.path.exists(filename): found_new = True else: print(filename + ' already exists') self.gen_version += 1 dsargs.name = name+'_'+self.gen_type+'_ver%i'%self.gen_version gen = self.classes[self.gen_type](dsargs) model = dst.embed(gen, name=self.model_name, dsi_name='gen') self.used_dsargs[self.gen_version] = dsargs.copy() self.save_gen(model, name) return model
def build(self, dsargs, is_stiff=False): # re-compute in case gen type has been changed self.targetlang = self._targetlangs[self.gen_type] if is_stiff and self.targetlang == 'python' and self.gen_type == 'vode': dsargs.algparams['stiff'] = True name = dsargs.name if self.gen_version == 0: self.gen_version = 1 # assume it's sufficient to check if .sav file there rather than .so found_new = False while not found_new: filename = os.path.join(self.cwd, 'models', name + '_' + \ self.gen_type + \ '_ver%i'%self.gen_version+'.sav') if not os.path.exists(filename): found_new = True else: print(filename + ' already exists') self.gen_version += 1 dsargs.name = name + '_' + self.gen_type + '_ver%i' % self.gen_version gen = self.classes[self.gen_type](dsargs) model = dst.embed(gen, name=self.model_name, dsi_name='gen') self.used_dsargs[self.gen_version] = dsargs.copy() self.save_gen(model, name) return model
def __init__(self, cwd, model_name, name_base, gen_type, gen_version=0): """ Internal utility to manage versions of Generator objects within single session. cwd = current working directory (string) Option to set known gen version # to reuse: Version 0 means not yet created. Works across saved and restarted sessions """ self.cwd = cwd self.model_name = model_name self.name_base = name_base self.gen_version = gen_version self.gen_type = gen_type # keyed by version self.used_dsargs = {} self.logfile = os.path.join(self.cwd, 'models', 'gen_dsargs_log.sav') if os.path.exists(self.logfile): # reload previous list of versions self.used_dsargs = dst.loadObjects(self.logfile)[0] self.classes = { 'vode': dst.Generator.Vode_ODEsystem, 'dopri': dst.Generator.Dopri_ODEsystem, 'radau': dst.Generator.Radau_ODEsystem, 'euler': dst.Generator.Euler_ODEsystem } self.targetlang = self._targetlangs[gen_type]
def simulate(args): modelname,ptargs,tdomain,captcnt,captincr,icdict,pardict,vardict,varspecdict,fnspecdict = args dsargs = pdt.args() dsargs.name = modelname dsargs.ics = icdict dsargs.pars = pardict dsargs.tdata = tdomain #dsargs.vars = vardict dsargs.varspecs = varspecdict #dsargs.fnspecs = fnspecdict dsargs.algparams = { 'init_step':captincr/10.0, 'atol':0.1, } dsys = pdt.Generator.Vode_ODEsystem(dsargs) #dsys = pdt.Generator.Radau_ODEsystem(dsargs) traj = dsys.compute('demo') pts = traj.sample() rshape = (len(ptargs),captcnt) result = numpy.zeros(shape = rshape,dtype = numpy.float) result[0,:] = numpy.arange(tdomain[0],tdomain[1]+0.000000001,captincr) for timedx in range(result.shape[1]): itraj = traj(result[0,timedx]) for targdx in range(1,result.shape[0]): result[targdx,timedx] = itraj[ptargs[targdx]] return result
def test_func_attr(x, eps=1e-8): """ mock function that would use a tolerance eps and return a numerical object that does contain reference to that tolerance """ res = dst.args(val=x, eps=eps) return res
def test_goal(mesh_pts, goal_tol=L2_tol): errors_array = error_pts(mesh_pts) max_error = np.max(errors_array) result = condition(max_error, goal_tol) return dst.args(result=result, errors=errors_array, max_error=max_error)
def __init__(self, cwd, model_name, name_base, gen_type, gen_version=0): """ Internal utility to manage versions of Generator objects within single session. cwd = current working directory (string) Option to set known gen version # to reuse: Version 0 means not yet created. Works across saved and restarted sessions """ self.cwd = cwd self.model_name = model_name self.name_base = name_base self.gen_version = gen_version self.gen_type = gen_type # keyed by version self.used_dsargs = {} self.logfile = os.path.join(self.cwd, 'models', 'gen_dsargs_log.sav') if os.path.exists(self.logfile): # reload previous list of versions self.used_dsargs = dst.loadObjects(self.logfile)[0] self.classes = {'vode': dst.Generator.Vode_ODEsystem, 'dopri': dst.Generator.Dopri_ODEsystem, 'radau': dst.Generator.Radau_ODEsystem, 'euler': dst.Generator.Euler_ODEsystem} self.targetlang = self._targetlangs[gen_type]
def __figure3c_continuation__(): parameters = default_parameters(i_app=0.16) v, h, h_s = symbols('v h h_s') dydt = hs_clamp([v, h, h_s], 0, parameters) DSargs_3 = PyDSTool.args(name='bifn_3') DSargs_3.pars = {'h_s': 0} DSargs_3.varspecs = { 'v': PyDSTool.convertPowers(str(dydt[0])), 'h': PyDSTool.convertPowers(str(dydt[1])) } DSargs_3.ics = {'v': 0, 'h': 0} ode_3 = PyDSTool.Generator.Vode_ODEsystem(DSargs_3) ode_3.set(pars={'h_s': 0}) ode_3.set(ics={'v': -49, "h": 0.4}) PyCont_3 = PyDSTool.ContClass(ode_3) PCargs_3 = PyDSTool.args(name='EQ1_3', type='EP-C') PCargs_3.freepars = ['h_s'] PCargs_3.MaxNumPoints = 350 PCargs_3.MaxStepSize = 0.1 PCargs_3.MinStepSize = 1e-5 PCargs_3.StepSize = 1e-2 PCargs_3.LocBifPoints = 'all' PCargs_3.SaveEigen = True PyCont_3.newCurve(PCargs_3) PyCont_3['EQ1_3'].backward() PyCont_3['EQ1_3'].display(['h_s', 'v'], stability=True, figure=1) PCargs_3.name = 'LC1_3' PCargs_3.type = 'LC-C' PCargs_3.initpoint = 'EQ1_3:H2' PCargs_3.freepars = ['h_s'] PCargs_3.MaxNumPoints = 500 PCargs_3.MaxStepSize = 0.1 PCargs_3.LocBifPoints = 'all' PCargs_3.SaveEigen = True PyCont_3.newCurve(PCargs_3) PyCont_3['LC1_3'].backward() PyCont_3['LC1_3'].display(('h_s', 'v_min'), stability=True, figure=1) PyCont_3['LC1_3'].display(('h_s', 'v_max'), stability=True, figure=1) PyCont_3.plot.toggleLabels(visible='off', bytype=['P', 'RG']) PyCont_3.plot.togglePoints(visible='off', bytype=['P', 'RG']) plt.gca().set_title('')
def construct_system(I, alpha, init=(0, 0), T=10): theta0, w0 = init args = pd.args(name='Pendulum') args.pars = {'alpha': alpha, 'I': I} args.varspecs = {'theta': 'w', 'w': 'I - sin(theta) - alpha * w'} args.ics = {'theta': theta0, 'w': w0} args.tdomain = [-T, T] ode = pd.Generator.Vode_ODEsystem(args) return ode
def construct_system( I, alpha, init=(0,0), T = 10 ): theta0, w0 = init args = pd.args( name = 'Pendulum' ) args.pars = { 'alpha' : alpha, 'I' : I } args.varspecs = { 'theta' : 'w', 'w' : 'I - sin(theta) - alpha * w' } args.ics = { 'theta' : theta0, 'w' : w0 } args.tdomain = [-T, T ] ode = pd.Generator.Vode_ODEsystem( args ) return ode
def event1(params): event_args = {'name': 'event_melt_begin', 'eventtol': params.RelTol, 'active': True, 'term': True} event_melt_begin = PyDSTool.makeZeroCrossEvent('Tmelt - Tp', 0, event_args, varnames=['Tp'], parnames=['Tmelt']) return event_melt_begin
def event2(params): event_args = {'name': 'event_melt_end', 'eventtol': params.RelTol, 'active': True, 'term': True} event_melt_end = PyDSTool.makeZeroCrossEvent('Qp / (Hf * Mp) - 1', 0, event_args, varnames=['Qp'], parnames=['Hf', 'Mp']) return event_melt_end
def outer_sne(PC): print("Computing Outer SNE") PCargs = PyDSTool.args(name='SNE2', type='LP-C') PCargs.initpoint = 'EQ1:LP2' PCargs.freepars = ['ox', 'oy'] PCargs.MaxStepSize = 1e-10 PCargs.LocBifPoints = ['BT'] PCargs.MaxNumPoints = 1000 PC.newCurve(PCargs) PC['SNE2'].forward() return PC
def inner_outer_init(PC): print("Initialising boundary") PCargs = PyDSTool.args(name='EQ1', type='EP-C') PCargs.freepars = ['ox'] PCargs.MaxNumPoints = 200 PCargs.MaxStepSize = 0.001 PCargs.LocBifPoints = 'LP' PC.newCurve(PCargs) PC['EQ1'].forward() return PC
def trace_zero_lower(PC): print("Computing tr0 loop lower") PCargs = PyDSTool.args(name='TR02', type='H-C2') PCargs.initpoint = 'SNE1:BT2' PCargs.freepars = ['ox', 'oy'] PCargs.MaxStepSize = 1e-10 PCargs.LocBifPoints = ['BT'] PCargs.MaxNumPoints = 1600 PC.newCurve(PCargs) PC['TR02'].forward() return PC
def create_model(): pars = {'g': 9.8} #, 'pi': np.pi} #ODE ode_def = { 'x': 'vx', 'y': 'vy', 'vx': '-(pi**2)*x', 'vy': '-g', 'tt': '1.0', } event_bounce = dst.makeZeroCrossEvent( 'x-y', 1, { 'name': 'bounce', 'eventtol': 1e-3, 'term': True, 'active': True, 'eventinterval': 1, 'eventdelay': 1e-2, 'starttime': 0, 'precise': True }, varnames=['x', 'y'], targetlang='python') # targetlang is redundant (defaults to python) DSargs = dst.args(name='bball_sin') # struct-like data DSargs.events = [event_bounce] #DSargs.pars = pars #DSargs.tdata = [0, 10] #DSargs.algparams = {'max_pts': 3000, 'stiff': False} DSargs.algparams = {'stiff': False, 'init_step': 0.01} DSargs.varspecs = ode_def DSargs.pars = pars #DSargs.xdomain = {'y': [0, 100]} DS_fall = dst.embed(dst.Generator.Vode_ODEsystem(DSargs)) DS_fall_MI = dst.intModelInterface(DS_fall) # Reset ev_map = dst.EvMapping({ 'y': 'x+0.001', 'vy': '0.9*(vx-vy)' }, model=DS_fall) #ev_map = dst.EvMapping({'y': '10', 'x': '20'}, model=DS_fall) DS_BBall = dst.makeModelInfoEntry(DS_fall_MI, ['bball_sin'], [('bounce', ('bball_sin', ev_map))]) modelInfoDict = dst.makeModelInfo([DS_BBall]) bball_sin_model = dst.Model.HybridModel({ 'name': 'Bouncing_Ball_Sinusiodal', 'modelInfo': modelInfoDict }) return bball_sin_model
def bifurk(cont, maxval, freepar): label = "EQ{}".format(len(cont.curves)) PCargs = dst.args(name=label, type="EP-C") PCargs.freepars = [freepar] PCargs.MaxNumPoints = 50 PCargs.StepSize = 1e-2 PCargs.MaxStepSize = 0.5 PCargs.LocBifPoints = ["LP"] PCargs.SaveEigen = True cont.newCurve(PCargs) while cont[label].parsdict[freepar] < maxval: cont[label].forward()
def build_lin(): # make local linear system spec if can_cache: print("I'm not building this model twice!") DSargs = dst.args(name='lin') xfn_str = '(x0+yfx*y - x)/taux' yfn_str = '(y0+xfy*x - y)/tauy' DSargs.varspecs = {'x': xfn_str, 'y': yfn_str} DSargs.xdomain = {'x': xdom, 'y': ydom} DSargs.pars = {'x0': xdom_half, 'y0': ydom_half, 'xfy': 1, 'yfx': 1, 'taux': 1, 'tauy': 1} DSargs.algparams = {'init_step':0.001, 'max_step': 0.001, 'max_pts': 10000} DSargs.checklevel = 0 DSargs.tdata = [0, 10] DSargs.ics = {'x': xdom_half*1.1, 'y': ydom_half*1.1} DSargs.fnspecs = {'Jacobian': (['t', 'x', 'y'], """[[-1/taux, yfx/taux], [xfy/tauy, -1/tauy]]""")} return dst.embed(dst.Generator.Vode_ODEsystem(DSargs))
def bifurcation(self, mode='ode'): """Code to generate bifuraction diagrams using PYDSTool, not working framework to be added to Args: mode (str, optional): ode for the ode model and pde for the travelling wave pde model """ if mode == 'ode': DSargs = dst.args(name='oligodendrocyte calcium model') DSargs.pars = self.params DSargs.fnspecs = {} DSargs.varspecs = {} DSargs.ics = {} DSargs.tdomain = [0, self.tend] ode = dst.Generator.Vode_ODEsystem(DSargs) ode.set(pars={}) ode.set(ics={}) PC = dst.args(name='EQ1', type='EP-C') PCargs.freepars = [] PCargs.MaNumPoints = 450 PCargs.MaxStepSize = 2 PCargs.MinStepSize = 1e-5 PCargs.StepSize = 2e-2 PCargs.LocBifPoints = 'LP' # detect limit points / saddle-node bifurcations PCargs.SaveEigen = True # to tell unstable from stable branches PC.newCurve(PCargs) PC['EQ1'].forward() PC.display([], stability=True, figure=3) PC['EQ1'].info() print(PC['EQ1'].getSpecialPoint('')) if mode == 'pde': pass
def map_workspace(con, pts, *args): """ Returns a list of dictionaries, each representing the state of the calc_context workspace for each of the points given. Optional positional arguments will be passed first to the calc_context when calling it. This assumes the calc_context local_init accepts `pt` as an argument. """ wseq = [] for pt in pts: con(*args, pt=pt) wseq.append(dst.filteredDict(con.workspace.__dict__, ['_name'], neg=True)) return wseq
def SPoCK_plot_traj(alt_ics_dict, exp_num): pardict, fndict, vardict, icsdict = init_SPoCK() DSargs = dst.args() DSargs.pars = pardict DSargs.varspecs = vardict DSargs.fnspecs = fndict DSargs.ics = alt_ics_dict #Load initial conditions given my argument DSargs.name = 'SPoCK' DSargs.tdata = [0, 600] DSargs.xdomain = { 'X': [0, 10**9], 'Y': [0, 10**9], 'A': [0, 10**9], 'B': [0, 10**9], } spock_ode = dst.Vode_ODEsystem(DSargs) fixedpoints_csv_path = "/Users/behzakarkaria/Documents/UCL/Barnes Lab/PhD Project/research_code/SPoCK_model/parameter_csv/fixedponts.csv" plot_out_path = "/Users/behzakarkaria/Documents/UCL/Barnes Lab/PhD Project/research_code/SPoCK_model/parameter_csv/fixedpoint_plots/" traj = spock_ode.compute('traj_1') pts = traj.sample() with PdfPages(plot_out_path + "exp_" + str(exp_num) + ".pdf") as pdf: plt.figure(1) plt.plot(pts['t'], pts['X'], label="X") plt.plot(pts['t'], pts['Y'], label="Y") plt.xlabel("t") plt.ylabel("population") plt.yscale('log') plt.legend(loc=4) # bottom left location pdf.savefig(plt.figure(1)) plt.show() plt.close()
def args(): """ This function creates a PyDSTool 'args' object for the 'vanderpol' vector field. """ DSargs = PyDSTool.args() DSargs.name = 'vanderpol' DSargs.pars = {'epsilon':2.0000000000000001e-01} DSargs.varspecs = {'x':'( x+y+-3.3333333333333331e-01*(x*x*x))/epsilon', 'y':'-x'} DSargs.fnspecs = {'Jacobian': (['t', 'x', 'y'], """[[(-(x*x)+1.0)/epsilon, 1.0/(epsilon)], [-1.0, 0.0]]""")} DSargs.ics = {'x':1.0000000000000000e-02, 'y':0.0} DSargs.tdomain = [0,10] return DSargs
def args(): """ This function creates a PyDSTool 'args' object for the 'MorrisLecar' vector field. """ DSargs = PyDSTool.args() DSargs.name = 'MorrisLecar' DSargs.pars = {'gca':5.5000000000000000e+00, 'gk':8.0000000000000000e+00, 'gl':2.0000000000000000e+00, 'vca':1.1500000000000000e+02, 'vk':-8.4000000000000000e+01, 'vl':-5.5000000000000000e+01, 'c':2.0000000000000000e+01, 'phi':2.2000000000000000e-01, 'ic':9.0000000000000000e+01, 'v1':-1.2000000000000000e+00, 'v2':1.8000000000000000e+01, 'v3':2.0000000000000000e+00, 'v4':3.0000000000000000e+01} DSargs.varspecs = {'v':'-(1.0/2.0)*1.0/c*( 2.0*( v-vl)*gl-( vca-v)*gca*( tanh(-1.0/v2*( v1-v))+1.0)+-2.0*ic+-2.0*( vk-v)*gk*w)', 'w':'(1.0/2.0)*cosh(-(1.0/2.0)*( v3-v)/v4)*phi*( tanh(-( v3-v)/v4)+-2.0*w+1.0)'} DSargs.fnspecs = {'Jacobian': (['t', 'v', 'w'], """[[-(1.0/2.0)*1.0/c*( 2.0*gk*w+gca*( tanh(-1.0/v2*( v1-v))+1.0)+( vca-v)*gca/v2*( pow(tanh(-1.0/v2*( v1-v)),2.0)-1.0)+2.0*gl), 1.0/c*( vk-v)*gk], [-cosh(-(1.0/2.0)*( v3-v)/v4)*phi*( pow(tanh(-( v3-v)/v4),2.0)-1.0)/v4/2.0+sinh(-(1.0/2.0)*( v3-v)/v4)*phi*( tanh(-( v3-v)/v4)+-2.0*w+1.0)/v4/4.0, -cosh(-(1.0/2.0)*( v3-v)/v4)*phi]]""")} DSargs.ics = {'v':0.0, 'w':0.0} DSargs.tdomain = [0,10] return DSargs
def create_model(): pars = {'g': 1} icdict = {'y': 5, 'vy': 0} y_str = 'vy' vy_str = '-g' event_bounce = dst.makeZeroCrossEvent( 'y', 0, { 'name': 'bounce', 'eventtol': 1e-3, 'term': True, 'active': True }, varnames=['y'], parnames=['g'], targetlang='python') # targetlang is redundant (defaults to python) DSargs = dst.args(name='bball') # struct-like data DSargs.events = [event_bounce] #DSargs.pars = pars #DSargs.tdata = [0, 10] #DSargs.algparams = {'max_pts': 3000, 'stiff': False} DSargs.algparams = {'stiff': False} DSargs.varspecs = {'y': y_str, 'vy': vy_str} DSargs.pars = pars #DSargs.xdomain = {'y': [0, 100], 'vy': [-100, 100]} DSargs.ics = icdict DS_fall = dst.embed(dst.Generator.Vode_ODEsystem(DSargs)) DS_fall_MI = dst.intModelInterface(DS_fall) ev_map = dst.EvMapping({'y': 0, 'vy': '-0.75*vy'}, model=DS_fall) DS_BBall = dst.makeModelInfoEntry(DS_fall_MI, ['bball'], [('bounce', ('bball', ev_map))]) modelInfoDict = dst.makeModelInfo([DS_BBall]) bball_model = dst.Model.HybridModel({ 'name': 'Bouncing_Ball', 'modelInfo': modelInfoDict }) return bball_model
def __figure4b2_continuation__(): parameters = default_parameters(i_app=-0.1) v, h, h_s, i_app = symbols('v h h_s i_app') parameters[0] = i_app dydt = ode_3d([v, h, h_s], 0, parameters, exp=exp) DSargs_2 = PyDSTool.args(name='bifn_2') DSargs_2.pars = {'i_app': 0} DSargs_2.varspecs = { 'v': PyDSTool.convertPowers(str(dydt[0])), 'h': PyDSTool.convertPowers(str(dydt[1])), 'h_s': PyDSTool.convertPowers(str(dydt[2])) } DSargs_2.ics = {'v': 0, 'h': 0, 'h_s': 0} ode_2 = PyDSTool.Generator.Vode_ODEsystem(DSargs_2) ode_2.set(pars={'i_app': -0.1}) ode_2.set(ics={'v': -67, "h": 0.77, "h_s": 1}) PyCont_2 = PyDSTool.ContClass(ode_2) PCargs_2 = PyDSTool.args(name='EQ1_2', type='EP-C') PCargs_2.freepars = ['i_app'] PCargs_2.MaxNumPoints = 300 PCargs_2.MaxStepSize = 0.1 PCargs_2.MinStepSize = 1e-5 PCargs_2.StepSize = 1e-2 PCargs_2.LocBifPoints = 'all' PCargs_2.SaveEigen = True PyCont_2.newCurve(PCargs_2) PyCont_2['EQ1_2'].backward() PyCont_2['EQ1_2'].display(['i_app', 'v'], stability=True, figure=1) PCargs_2.name = 'LC1_2' PCargs_2.type = 'LC-C' PCargs_2.initpoint = 'EQ1_2:H2' PCargs_2.freepars = ['i_app'] PCargs_2.MaxNumPoints = 400 PCargs_2.MaxStepSize = 0.1 PCargs_2.StepSize = 1e-2 PCargs_2.LocBifPoints = 'all' PCargs_2.SaveEigen = True PyCont_2.newCurve(PCargs_2) PyCont_2['LC1_2'].forward() PyCont_2['LC1_2'].display(('i_app', 'v_min'), stability=True, figure=1) PyCont_2['LC1_2'].display(('i_app', 'v_max'), stability=True, figure=1) PyCont_2.plot.toggleLabels(visible='off', bytype=['P', 'RG']) PyCont_2.plot.togglePoints(visible='off', bytype=['P', 'RG']) plt.gca().set_title('')
def create_model(): pars = {'g': 9.8}#, 'pi': np.pi} #ODE ode_def = { 'x': 'vx', 'y': 'vy', 'vx': '-(pi**2)*x', 'vy': '-g', 'tt': '1.0', } event_bounce = dst.makeZeroCrossEvent( 'x-y', 1, {'name': 'bounce', 'eventtol': 1e-3, 'term': True, 'active': True, 'eventinterval': 1, 'eventdelay': 1e-2, 'starttime': 0, 'precise': True }, varnames=['x', 'y'], targetlang='python') # targetlang is redundant (defaults to python) DSargs = dst.args(name='bball_sin') # struct-like data DSargs.events = [event_bounce] #DSargs.pars = pars #DSargs.tdata = [0, 10] #DSargs.algparams = {'max_pts': 3000, 'stiff': False} DSargs.algparams = {'stiff': False, 'init_step': 0.01} DSargs.varspecs = ode_def DSargs.pars = pars #DSargs.xdomain = {'y': [0, 100]} DS_fall = dst.embed(dst.Generator.Vode_ODEsystem(DSargs)) DS_fall_MI = dst.intModelInterface(DS_fall) # Reset ev_map = dst.EvMapping({'y': 'x+0.001', 'vy': '0.9*(vx-vy)'}, model=DS_fall) #ev_map = dst.EvMapping({'y': '10', 'x': '20'}, model=DS_fall) DS_BBall = dst.makeModelInfoEntry(DS_fall_MI, ['bball_sin'], [('bounce', ('bball_sin', ev_map))]) modelInfoDict = dst.makeModelInfo([DS_BBall]) bball_sin_model = dst.Model.HybridModel( {'name': 'Bouncing_Ball_Sinusiodal', 'modelInfo': modelInfoDict}) return bball_sin_model
def make_system(M, ics, pars=None): n = len(M) xvarlist = ["x%i" % i for i in range(1, n + 1)] xvars = [Var(x) for x in xvarlist] varspecs = {} jac_str_list = [] for i, xv in enumerate(xvars): M_row = M[i] varspecs[str(xv)] = pt.QuantSpec( str(xv) + "_DE", "+".join([str(M_row[j] * xvars[j]) for j in range(n)])) jac_str_list.append("[" + ",".join([str(M_row[j]) for j in range(n)]) + "]") jac_str = "[" + ",".join(jac_str_list) + "]" print(jac_str) DSargs = args(name="linear_net") DSargs.varspecs = varspecs DSargs.ics = dict(zip(xvars, ics)) DSargs.pars = pars DSargs.tdata = [0, 1000] DSargs.fnspecs = {"Jacobian": (["t"] + xvarlist, jac_str)} return Generator.Vode_ODEsystem(DSargs)
def cont(model, maxnum=450,maxstep=2.0,minstep=1e-5,stepsize=2e-2,direction="forward"): ode = dst.Generator.Vode_ODEsystem(model) # Prepare the system to start close to a steady state # ode.set(pars = {'p': 0.078} ) # Lower bound of the control parameter 'i' # ode.set(ics = {'b': 0.0, 'w': 0.0} ) # Close to one of the steady states present for i=-220 PC = dst.ContClass(ode) # Set up continuation class PCargs = dst.args(name='EQ1', type='EP-C') # 'EP-C' stands for Equilibrium Point Curve. The branch will be labeled 'EQ1'. PCargs.freepars = ['p'] # control parameter(s) (it should be among those specified in DSargs.pars) PCargs.MaxNumPoints = maxnum # The following 3 parameters are set after trial-and-error PCargs.MaxStepSize = maxstep PCargs.MinStepSize = minstep PCargs.StepSize = stepsize PCargs.LocBifPoints = 'LP' # detect limit points / saddle-node bifurcations PCargs.SaveEigen = True PC.newCurve(PCargs) if direction == "forward": PC['EQ1'].forward() elif direction=="backward": PC['EQ1'].backward() PC.display(['p','b'], stability=True, figure=3) # stable and unstable branches as solid and dashed curves, resp. return PC
def gchidp_model(pars): """Creates PyDSTool DSargs object for the 'ChI' model vector field """ auxfuncs = { 'hill': (['x', 'k', 'n'], 'pow(x,n)/(pow(x,n)+pow(k,n))'), 'minf': (['ip3'], 'hill(ip3,d1,1)'), 'ninf': (['ca'], 'hill(ca,d5,1)'), 'Jchan': (['ca', 'h', 'ip3'], 'rc*pow(minf(ip3)*ninf(ca)*h,3)*(c0-(1+c1)*ca)'), 'Jleak': (['ca'], 'rl*(c0-(1+c1)*ca)'), 'Jpump': (['ca'], 'ver*hill(ca,KER,2)'), 'vglu': (['gammaa'], 'vbeta*gammaa'), 'vplcd': (['ca', 'ip3'], 'vdelta/(1+ip3/kappad)*hill(ca,Kdelta,2)'), 'v3keff': (['ca', 'ip3'], 'v3k*hill(ca,Kd,4)*hill(ip3,K3,1)'), 'v5peff': (['ip3'], 'r5p*ip3'), 'vpkc': (['ca', 'dag'], 'vkd*dag*hill(ca,Kkc,1)'), 'vdagk': (['ca', 'dag'], 'vd*hill(ca,Kdc,2)*hill(dag,Kdd,2)') } rhs = { 'gammaa': 'Op*(1-gammaa)*yrel-OmegaP*(1+vk*pkc/OmegaP)*gammaa', 'ip3': 'vbias+vglu(gammaa)+vplcd(ca,ip3)-v3keff(ca,ip3)-v5peff(ip3)', 'ca': 'Jchan(ca,h,ip3)-Jpump(ca)+Jleak(ca)', 'h': '(a2*d2*(ip3+d1)/(ip3+d3))*(1-h)-a2*ca*h', 'dag': 'vbias+vglu(gammaa)+vplcd(ca,ip3)-vpkc(ca,dag)-vdagk(ca,dag)-OmegaD*dag', 'pkc': 'vpkc(ca,dag)-OmegaKD*pkc' } ICs = {'gammaa': 0, 'ip3': 0, 'ca': 0, 'h': 0.9, 'dag': 0, 'pkc': 0} DSargs = dst.args(name='GChIDP') DSargs.pars = pars DSargs.fnspecs = auxfuncs DSargs.varspecs = rhs DSargs.ics = ICs return DSargs
def create_model(): pars = {'g': 1} icdict = {'y': 5, 'vy': 0} y_str = 'vy' vy_str = '-g' event_bounce = dst.makeZeroCrossEvent('y', 0, {'name': 'bounce', 'eventtol': 1e-3, 'term': True, 'active': True}, varnames=['y'], parnames=['g'], targetlang='python') # targetlang is redundant (defaults to python) DSargs = dst.args(name='bball') # struct-like data DSargs.events = [event_bounce] #DSargs.pars = pars #DSargs.tdata = [0, 10] #DSargs.algparams = {'max_pts': 3000, 'stiff': False} DSargs.algparams = {'stiff': False} DSargs.varspecs = {'y': y_str, 'vy': vy_str} DSargs.pars = pars #DSargs.xdomain = {'y': [0, 100], 'vy': [-100, 100]} DSargs.ics = icdict DS_fall = dst.embed(dst.Generator.Vode_ODEsystem(DSargs)) DS_fall_MI = dst.intModelInterface(DS_fall) ev_map = dst.EvMapping({'y': 0, 'vy': '-0.75*vy'}, model=DS_fall) DS_BBall = dst.makeModelInfoEntry(DS_fall_MI, ['bball'], [('bounce', ('bball', ev_map))]) modelInfoDict = dst.makeModelInfo([DS_BBall]) bball_model = dst.Model.HybridModel({'name': 'Bouncing_Ball', 'modelInfo': modelInfoDict}) return bball_model
# # Ariel Camacho # Doctorate Thesis # Guanajuato, Mexico, 2019 import PyDSTool import numpy as np import pylab as plt from mpl_toolkits.mplot3d import Axes3D import sympy as sp plt.rc('text', usetex=True) plt.rc('font', family='serif') # name of system DSargs = PyDSTool.args(name='ode') # parameters DSargs.pars = { #'aC': 3.2e-1, #farhat (check: OBs) 'aC': 3.0e0, #komarova #'aC': 1.0e-2, #---estimate---# #'aC': 2.0e-1, #---estimate---# 'bC': 3.0e-1, #farhat (same) #'bC': 2.0e-1, #komarova (same) #'bC': 5.0e-1, #--estimate--# #'bC': 1.0e0, #--estimate--# #'bCT': 1.2, #farhat (check: mass action) 'bCT': 1.3e-1, #ross #'bCT': 1.0e-3, #--estimate--#
import PyDSTool as dst from PyDSTool.Toolbox import phaseplane as pp #initialize model parameters structure DSargs = dst.args(name='Decision_making_model') #model parameters DSargs.pars = {'tauS' : 0.06, 'gam' : 0.641, 'a' : 270.0, 'b' : 108.0, 'd' : 0.154, 'J11' : 0.3725, 'J12' : 0.1137, #'I0' : 0.3297, 'I1' : 0, 'I2' : 0 'I0' : 0.3297, 'I1' : 0.035, 'I2' : 0.0351 #'I0' : 0.3297, 'I1' : 0.03, 'I2' : 0.04 #'I0' : 0.3297, 'I1' : 0, 'I2' : 0.07 } # auxiliary functions: fI-curce and recurrent current DSargs.fnspecs = {'fRate' : (['I'], '(a*I-b)/(1.0-exp(-d*(a*I-b)))'), 'recCurr' : (['x','y'], 'J11*x-J12*y+I0') } # rhs of the differential equations DSargs.varspecs = { 's1': '-s1/tauS+(1-s1)*gam*fRate(recCurr(s1,s2)+I1)', 's2': '-s2/tauS+(1-s2)*gam*fRate(recCurr(s2,s1)+I2)'} # initial conditions DSargs.ics = {'s1': 0.06,
# no1_ant = 20e3 k7 = 800.0 #0.74 k8 = 0.7 #0.05 k9 = 0.58 #0.37 k10 = 0.48#0.47 no_atp = 3800 #number of atphase cm = 3e3 #nr.of particles = 12mM #adp+atp = cm a12 = 24 a21 = 40.0 a23 = 4.0 a32 = 5e3 DSargs = PyDSTool.args(name='ex') DSargs.pars = { 'k1_on':'4.0',# #KDo 'k1_off':'100', # #KDo 'k2_on': '6.4',# #KTi 'k2_off':'40000.0',# #KTi 'k5_on':'0.4', #KTo 'k5_off':'200.0', #KTo 'k6_on':'4.0', #KDi 'k6_off':'40000.0', #KDi 'k7': k7, #kp 'k8': k8, #kcp 'k9': k9, #kt 'k10': k10, #kd 'no_ant': no1_ant, 'a12': a12, #s-1
import PyDSTool as dst from PyDSTool import args import numpy as np from matplotlib import pyplot as plt pars = {'eps': 1e-2, 'a': 0.5} icdict = {'x': pars['a'], 'y': pars['a'] - pars['a']**3/3} xstr = '(y - (x*x*x/3 - x))/eps' ystr = 'a - x' event_x_a = dst.makeZeroCrossEvent('x-a', 0, {'name': 'event_x_a', 'eventtol': 1e-6, 'term': False, 'active': True}, varnames=['x'], parnames=['a'], targetlang='python') # targetlang is redundant (defaults to python) DSargs = args(name='vanderpol') # struct-like data DSargs.events = [event_x_a] DSargs.pars = pars DSargs.tdata = [0, 3] DSargs.algparams = {'max_pts': 3000, 'init_step': 0.02, 'stiff': True} DSargs.varspecs = {'x': xstr, 'y': ystr} DSargs.xdomain = {'x': [-2.2, 2.5], 'y': [-2, 2]} DSargs.fnspecs = {'Jacobian': (['t','x','y'], """[[(1-x*x)/eps, 1/eps ], [ -1, 0 ]]""")} DSargs.ics = icdict
def solve(self, time_points, terminate=None): # Common parts as superclass if terminate is None: terminate = lambda u, t, step_no: False self.t = np.asarray(time_points) self.initialize_for_solve() N = self.t.size - 1 # no of intervals self.validate_data() # As a main designing priciple of PyDSTool, most of data structures in # PyDSTool are index-free. That is, the numerical data are stored mainly # through Python dictionaries with string keys. # Start setting for PyDSTool import PyDSTool neq, f, u0 = self.neq, self.f, self.U0 # Initialize variables as trajectories in PyDSTOOL # Each item of u has to be defined separately: y0,y1,y2,... name_list = ["y%d" % i for i in range(neq)] y, t, ydot = [PyDSTool.Var(name) for name in name_list], PyDSTool.Var("t"), [] # f has to be wrapped from f(y,t) to f(y0,y1,y2,...,t) f_wrap = eval("lambda *args: f(args[:-1], args[-1])") # f_wrap = eval('lambda *args: f(args[:-1], args[-1])', locals()) # Error # f_wrap = lambda *args: f(args[:-1], args[-1]) # Error! # Define differiential functions in PyDSTOOL, item by item string2 = ",".join(["y[%d]" % i for i in range(neq)]) # y[0],y[1],y[2],... ydot = [eval('PyDSTool.Fun(f_wrap(%s,t)[%d],[%s],"ydot%d")' % (string2, i, string2, i)) for i in range(neq)] # Jacobian matrix if getattr(self, "jac") is None: # apply Diff() to calculate jacobian matrix approximately. # Diff will return a QuantSpecct object F = eval('PyDSTool.Fun(f_wrap(%s,t),[%s],"F")' % (string2, string2)) JAC = eval('PyDSTool.Fun(PyDSTool.Diff(F,[%s]),[t,%s],"JAC")' % (string2, string2)) else: jac = self.jac # Wrap user-supplied jacobian function in the same manner as f # jac_wrap = lambda *args: jac(args[1:],args[0]) # Error jac_wrap = eval("lambda *args: jac(args[1:],args[0])") JAC = eval('PyDSTool.Fun(jac_wrap(t,%s),[t,%s],"JAC")' % (string2, string2)) # Settings in PyDSTOOL DSargs = PyDSTool.args(name="pydstest", checklevel=2) # Function set is {JAC, ydot[0],ydot[1],...} string3 = ",".join(["ydot[%d]" % i for i in range(neq)]) DSargs.fnspecs = eval("[JAC,%s]" % string3) # Variable set is {y[i]:ydot[i](y[0],y[1]...)} for any i from 0 to neq-1 string4 = ",".join(["y[%d]: ydot[%d](%s)" % (i, i, string2) for i in range(neq)]) DSargs.varspecs = eval("{%s}" % string4) # Time domain DSargs.tdomain = [time_points[0], time_points[-1]] # Initial status {y[0]:self.U0[0],y[1]:self.U0[1],...} string5 = ",".join(["y[%d]:%g" % (i, self.U0[i]) for i in range(neq)]) DSargs.ics = eval("{%s}" % string5) # Optional parameters DSargs.algparams = getattr(self, "params_pydstool", {}) # Start computation test = eval(self._name_pydstool)(DSargs) result = test.compute("test", "c") # A trajectory returned # Extract and set values at points in time range self.u = np.asarray([[result(time)["y%d" % j] for j in range(neq)] for time in time_points]) return self.u, self.t
- xM: cancer cell Scenarios: - Homeostasis - Osteoporosis - Oscillations """ import PyDSTool import numpy as np import pylab as plt plt.rc('text', usetex=True) plt.rc('font', family='serif') DSargs = PyDSTool.args(name='ode') #--- HOMEOSTASIS [p0,p1,p2,p3,p4,p5,p6,p7,p8,p9] = [ 2.72e-01, 1.9e-01, 8.18e-02, 9.38e-03, 9.37e-03, 5.88e-01, 1.51e+01, 1.0, 2.57e+01, 2.57e+01] # osteoclast #aCMpar = 1.0e0 #aBMpar = 0.0e-3 #bBMpar = 0.5
import MorrisLecar # Use the function created by VFGEN to define the 'args' object for # the Morris-Lecar system. ds = MorrisLecar.args() # Set ics to (1.5,0). This is not an equilibrium point, but # with these values, the PyCont code will find one. ds.ics = {'v': 1.5, 'w': 0.0} ode = PyDSTool.Generator.Vode_ODEsystem(ds) cont = PyDSTool.ContClass(ode) print "Setting up for one parameter continuation of an equilibrium point." PCargs = PyDSTool.args(name='EQ1', type='EP-C') PCargs.freepars = ['ic'] PCargs.StepSize = 1e-3 PCargs.MaxNumPoints = 200 PCargs.MaxStepSize = 0.2 PCargs.LocBifPoints = ['LP', 'H', 'BP'] print "Computing the curve." cont.newCurve(PCargs) cont['EQ1'].forward() print "Setting up for two parameter continuation of the Hopf point." PCargs = PyDSTool.args(name='Hopf', type='H-C2') PCargs.initpoint = 'EQ1:H1' PCargs.freepars = ['ic', 'gca'] PCargs.MaxStepSize = 1.0
def clip_to_pt(): """Extract clipboard point from gui to a dictionary""" pt = dst.filteredDict(gui.capturedPts['Master'], ['V', 'm', 'n']) return {'V': pt['V'], 'Na.m': pt['m'], 'K.n': pt['n']}
import PyDSTool as dst import numpy as np from matplotlib import pyplot as plt import time # we must give a name DSargs = dst.args(name='Calcium channel model') # parameters DSargs.pars = { 'vl': -60, 'vca': 120, 'i': 0, 'gl': 2, 'gca': 4, 'c': 20, 'v1': -1.2, 'v2': 18 } # auxiliary helper function(s) -- function name: ([func signature], definition) DSargs.fnspecs = {'minf': (['v'], '0.5 * (1 + tanh( (v-v1)/v2 ))')} # rhs of the differential equation, including dummy variable w DSargs.varspecs = { 'v': '( i + gl * (vl - v) - gca * minf(v) * (v-vca) )/c', 'w': 'v-w' } # initial conditions DSargs.ics = {'v': 0, 'w': 0} DSargs.tdomain = [0, 30] # set the range of integration. ode = dst.Generator.Vode_ODEsystem( DSargs) # an instance of the 'Generator' class.
def plot_PP_vf_custom(gen, xname, yname, N=20, subdomain=None, scale_exp=0): """Draw 2D vector field in (xname, yname) coordinates of given Generator, sampling on a uniform grid of n by n points. Optional subdomain dictionary specifies axes limits in each variable, otherwise Generator's xdomain attribute will be used. For systems of dimension > 2, the non-phase plane variables will be held constant at their initial condition values set in the Generator. Optional scale_exp is an exponent (domain is all reals) which rescales size of arrows in case of disparate scales in the vector field. Larger values of scale magnify the arrow sizes. For stiff vector fields, values from -3 to 3 may be necessary to resolve arrows in certain regions. Requires matplotlib 0.99 or later """ assert N > 1 xdom = gen.xdomain[xname] ydom = gen.xdomain[yname] if subdomain is not None: try: xdom = subdomain[xname] except KeyError: pass try: ydom = subdomain[yname] except KeyError: pass assert all(dst.isfinite(xdom)), "Must specify a finite domain for x direction" assert all(dst.isfinite(ydom)), "Must specify a finite domain for y direction" w = xdom[1]-xdom[0] h = ydom[1]-ydom[0] xdict = gen.initialconditions.copy() xix = gen.funcspec.vars.index(xname) yix = gen.funcspec.vars.index(yname) xs = np.linspace(xdom[0], xdom[1], N) ys = np.linspace(ydom[0], ydom[1], N) X, Y = np.meshgrid(xs, ys) dxs, dys = np.meshgrid(xs, ys) dz_big = 0 vec_dict = {} for xi, x in enumerate(xs): for yi, y in enumerate(ys): xdict.update({xname: x, yname: y}) dx, dy = gen.Rhs(0, xdict)[[xix, yix]] # note order of indices dxs[yi,xi] = dx dys[yi,xi] = dy dz = np.linalg.norm((dx,dy)) if dz > dz_big: dz_big = dz plt.quiver(X, Y, dxs, dys, angles='xy', pivot='middle', units='inches', scale=dz_big*max(h,w)/(10*np.exp(2*scale_exp)), lw=0.01/np.exp(scale_exp-1), headwidth=max(2,1.5/(np.exp(scale_exp-1))), #headlength=2*max(2,1.5/(exp(scale_exp-1))), width=0.001*max(h,w), minshaft=2, minlength=0.001) ax = plt.gca() print("xdom: ", xdom) print("ydom: ", ydom) ax.set_xlim(xdom) ax.set_ylim(ydom) plt.draw()
def build_sys(): # we must give a name DSargs = dst.args(name='M345_A3_Bead_on_a_rotating_hoop') # parameters DSargs.pars = {'g': 0, 'd': 0.3} # rhs of the differential equation DSargs.varspecs = {'phi': 'nu', 'nu': '-d*nu + g*sin(phi)*cos(phi) - sin(phi)'} # initial conditions DSargs.ics = {'phi': 0, 'nu': 0} # set the domain of integration. # (increased domain size to explore around phi=-pi saddle) DSargs.xdomain = {'phi': [-2*np.pi, 2*np.pi], 'nu': [-4, 4]} # allow tdomain to be infinite, set default tdata here DSargs.tdata = [0, 50] # to avoid typos / bugs, use built-in Symbolic differentation! f = [DSargs.varspecs['phi'], DSargs.varspecs['nu']] Df=dst.Diff(f, ['phi', 'nu']) DSargs.fnspecs = {'Jacobian': (['t','phi','nu'], str(Df.renderForCode()))} # yields """[[0, 1], [g*cos(phi)*cos(phi) - g*sin(phi)*sin(phi) - cos(phi), -d]]""")} print("Jacobian computed as:\n" + str(Df.renderForCode())) # Make auxiliary functions to define event lines near saddle res = pp.make_distance_to_line_auxfn('Gamma_out_plus', 'Gamma_out_plus_fn', ('phi','nu'), True) man_pars = res['pars'] man_auxfns = res['auxfn'] res = pp.make_distance_to_line_auxfn('Gamma_out_minus', 'Gamma_out_minus_fn', ('phi','nu'), True) man_pars.extend(res['pars']) man_auxfns.update(res['auxfn']) # update param values with defaults (0) for p in man_pars: DSargs.pars[p] = 0 if gentype in [dst.Generator.Vode_ODEsystem, dst.Generator.Euler_ODEsystem]: targetlang = 'python' else: targetlang = 'c' DSargs.fnspecs.update(man_auxfns) ev_plus = dst.Events.makeZeroCrossEvent(expr='Gamma_out_plus_fn(%s,%s)'%('phi','nu'), dircode=0, argDict={'name': 'Gamma_out_plus', 'eventtol': 1e-5, 'eventdelay': 1e-3, 'starttime': 0, 'precise': False, 'active': False, 'term': True}, targetlang=targetlang, varnames=['phi','nu'], fnspecs=man_auxfns, parnames=man_pars ) ev_minus = dst.Events.makeZeroCrossEvent(expr='Gamma_out_minus_fn(%s,%s)'%('phi','nu'), dircode=0, argDict={'name': 'Gamma_out_minus', 'eventtol': 1e-5, 'eventdelay': 1e-3, 'starttime': 0, 'precise': False, 'active': False, 'term': True}, targetlang=targetlang, varnames=['phi','nu'], fnspecs=man_auxfns, parnames=man_pars ) DSargs.events = [ev_plus, ev_minus] # an instance of the 'Generator' class. print("Initializing generator...") return gentype(DSargs)
''' Created on Jul 18, 2016 @author: andrewkennedy ''' import PyDSTool as dst import numpy as np from matplotlib import pyplot as plt # we must give a name DSargs = dst.args(name='Calcium channel model') # parameters DSargs.pars = { 'vl': -60, 'vca': 120, 'i': 0, 'gl': 2, 'gca': 4, 'c': 20, 'v1': -1.2, 'v2': 18 } # auxiliary helper function(s) -- function name: ([func signature], definition) DSargs.fnspecs = {'minf': (['v'], '0.5 * (1 + tanh( (v-v1)/v2 ))') } # rhs of the differential equation, including dummy variable w DSargs.varspecs = {'v': '( i + gl * (vl - v) - gca * minf(v) * (v-vca) )/c', 'w': 'v-w' } # initial conditions DSargs.ics = {'v': 0, 'w': 0 } DSargs.tdomain = [0,30] # set the range of integration. ode = dst.Generator.Vode_ODEsystem(DSargs) # an instance of the 'Generator' class. traj = ode.compute('polarization') # integrate ODE
def save_gen(self, model, name): dst.saveObjects(model, os.path.join(self.cwd, 'models', name + '_' + \ self.gen_type + \ '_ver%i'%self.gen_version+'.sav')) dst.saveObjects(self.used_dsargs, self.logfile, force=True)
def load_gen(self, name): if self.gen_version == 0: raise ValueError("No current version known: set gen_version") return dst.loadObjects(os.path.join(self.cwd, 'models', name + '_' + \ self.gen_type + \ '_ver%i'%self.gen_version+'.sav'))[0]
def make_measure(fn_name, fn_spec, **defs): """Dynamically create a python function for use with calculation context. """ all_defs = defs.copy() q = dst.QuantSpec('_dummy_', fn_spec, treatMultiRefs=False) import PyDSTool.parseUtils as pu mapping = pu.symbolMapClass() assumed_modules = [] tokens = q.parser.tokenized for sym in q.freeSymbols: # Hack, for now: if first (therefore, assumed all) # occurrences of symbol are in quotes, then don't convert. # Better solution would be to make parser create "x" as a single # symbol, at least with a detect quote option first_ix = tokens.index(sym) if first_ix == 0 or (first_ix > 0 and tokens[first_ix-1] not in ['"', "'"]): if pu.isHierarchicalName(sym): parts = sym.split('.') if parts[0] == 'sim': mapping[sym] = 'con.'+sym ## elif parts[0] == 'bombardier': ## # special case as this factory function is defined in that ## # module so that reference will fail at runtime: remove ## # 'bombardier' prefix ## rest_sym = '.'.join(parts[1:]) ## mapping[sym] = rest_sym ## scope = globals() ## # locals override ## scope.update(locals()) ## if parts[1] in scope: ## all_defs[parts[1]] = scope[parts[1]] ## else: ## raise ValueError("Cannot resolve scope of symbol '%s'"%sym) else: # assume module reference assumed_modules.append(parts[0]) # record here to ensure inclusion in dyn_dummy mapping[sym] = 'self.'+sym else: mapping[sym] = 'con.workspace.'+sym elif first_ix > 0 and tokens[first_ix-1] in ['"', "'"]: # put this symbol in the mapping values to ensure not included # as an argument to the function mapping[sym] = sym q.mapNames(mapping) import types for module_name in assumed_modules: global_scope = globals() # test if module name in scope if module_name in global_scope: _mod = global_scope[module_name] if isinstance(_mod, types.ModuleType): all_defs[module_name] = _mod # dyn_dummy contains dummy mappings but declares symbols to leave # evaluating until runtime dyn_dummy = dict(zip(mapping.values(), ['']*len(mapping))) funq = dst.expr2fun(q, ensure_args=['con'], ensure_dynamic=dyn_dummy, for_funcspec=False, fn_name=fn_name, **all_defs) # decorate output funq.attr_name = fn_name return funq
import PyDSTool #from numpy import (sin, cos, pi) #from PyDSTool.Toolbox import phaseplane as pp #import numpy as np import matplotlib.pyplot as plt from rhc_cont import Ode import pickle from bmk import Bmk #from ode import Ode from rhc_cont import RhcCont bmk = Bmk({'ox': 0, 'oy': 0}) ode = bmk.get_ode() #Setting Continuation class PC = PyDSTool.ContClass(ode) ########################################################## # # # ########################################################## def inner_outer_init(PC): print("Initialising boundary") PCargs = PyDSTool.args(name='EQ1', type='EP-C') PCargs.freepars = ['ox'] PCargs.MaxNumPoints = 200 PCargs.MaxStepSize = 0.001 PCargs.LocBifPoints = 'LP'
import PyDSTool from pylab import plot, show, linspace, xlabel, ylabel # we must give a name DSargs = PyDSTool.args(name='Calcium') # parameters DSargs.pars = { 'vl': -60, 'vca': 120, 'i': 0, 'gl': 2, 'gca': 4, 'c': 20, 'v1': -1.2, 'v2': 18 } # auxiliary helper function(s) DSargs.fnspecs = {'minf': (['v'], '0.5 * (1 + tanh( (v-v1)/v2 ))') } # rhs of the differential equation, including dummy variable w DSargs.varspecs = {'v': '( i + gl * (vl - v) - gca * minf(v) * (v-vca) )/c', 'w': 'v-w' } # initial conditions DSargs.ics = {'v': 0, 'w': 0 } DSargs.tdomain = [0,40] # set the range of integration. ode = PyDSTool.Generator.Vode_ODEsystem(DSargs) # an instance of the 'Generator' class. traj = ode.compute('polarization') # pd = traj.sample() # Data for plotting plot(pd['t'], pd['v']) xlabel('time') # Axes labels ylabel('voltage') # ... show()
import PyDSTool as dst import numpy as np from matplotlib import pyplot as plt # we must give a name DSargs = dst.args(name='Calcium channel model') # parameters DSargs.pars = {'alpha': 0.1, 'beta': 0.01, 'k': 0.25, 'gamm': 0.01} # auxiliary helper function(s) -- function name: ([func signature], definition) #DSargs.fnspecs = {'minf': (['v'], '0.5 * (1 + tanh( (v-v1)/v2 ))') } DSargs.fnspecs = { 'growth': (['a'], '(beta + a*a)/(1 + a*a)'), 'suppression': (['b'], '1/(1+(b/k)**2)') } # rhs of the differential equation, including dummy variable w DSargs.varspecs = { 'a': 'alpha * growth(a) * suppression(b) - a', 'b': 'gamm * (a - b)', 'w': 'a-w' } # initial conditions DSargs.ics = {'a': 10, 'b': 0, 'w': 0} DSargs.tdomain = [0, 100] # set the range of integration. ode = dst.Generator.Vode_ODEsystem( DSargs) # an instance of the 'Generator' class. traj = ode.compute('polarization') # integrate ODE pts = traj.sample(dt=0.1) # Data for plotting # PyPlot commands plt.plot(pts['t'], pts['a'])
DSargs.events = [ground_event, peak_event] DSargs.checklevel = 2 DSargs.ics = {'x': 0, 'y': 0, 'vx': 0, 'vy': 0} DSargs.ics.update(make_vel_ics(5,20)) DSargs.name = 'cannon' DSargs.tdomain = [0, 100000] DSargs.tdata = [0, 10] return dst.embed(dst.Generator.Vode_ODEsystem(DSargs)) shooter = make_shooter() # sim.model is a PyDSTool Model sim = dst.args(tracked_objects=[], model=shooter, name='sim_cannon_traj', pts=None) calc = cc.calc_context(sim, 'cannon_traj') w = calc.workspace shot_num = 0 def go(speed, angle, do_tracker=True): global shot_num, w shot_num += 1 w.angle = angle w.speed = speed sim.model.set(ics=make_vel_ics(speed, angle)) sim.model.compute('shot%i' % shot_num)