def __call__(self, calc_context, fignum, xstr, ystr, style): self.sim = calc_context.sim self.calc_context = calc_context fig = plt.figure(fignum) new_track = args(xstr=xstr, ystr=ystr, style=style) if fignum in self.figs: self.figs[fignum].tracked.append(new_track) else: self.figs[fignum] = args(figure=fig, tracked=[new_track]) self.sim.tracked_objects.append(self)
def _run_check_macros_2(ode, fnspecs): DSargs2 = args( name='test2', pars={ 'p0': 0, 'p1': 1, 'p2': 2 }, varspecs={ 'y[i]': 'for(i, 0, 1, y[i]+if(y[i+1]<2, 2+p[i]+getbound(%s,0), indexfunc([i])+y[i+1]) - 3)' % ('y2' if ode in [Vode_ODEsystem, Euler_ODEsystem] else '"y2"'), 'y2': '0' }, xdomain={'y2': [-10, 10]}, fnspecs=fnspecs, ics={ 'y0': 0, 'y1': 0, 'y2': 0.1 }) tm2 = ode(DSargs2) tm2.set(tdata=[0, 10]) tm2.compute('test') assert allclose(tm2.Rhs(0, { 'y0': 0, 'y1': 0.3, 'y2': 5 }), array([-11., 2.3 + pi, 0.]))
def compute_HO(self, initpoint='', name='HO1', ax=None, p1='a1', p2='a2'): PCargs = args() PCargs.name = name PCargs.type = 'H-C2' PCargs.initpoint = initpoint PCargs.freepars = [p1, p2] PCargs.MaxNumPoints = 800 PCargs.MinStepSize = 1e-5 PCargs.MaxStepSize = 1e-2 PCargs.StepSize = 1e-3 PCargs.LocBifPoints = 'all' PCargs.SaveEigen = True self.pc.newCurve(PCargs) print('Computing Hopf curve...') start = perf_counter() # PyCont[name].forward() self.pc[name].backward() print('done in %.3f seconds!' % (perf_counter() - start)) #PCargs.MaxNumPoints = 2000 # PyCont[name].forward() self.pc[name].display([p1, p2], figure=3) sol = self.pc[name].sol a1 = sol.coordarray[sol.coordnames.index(p1)] b1 = sol.coordarray[sol.coordnames.index(p2)] if not ax: fig, ax = plt.subplots(figsize=(4, 4)) fig.subplots_adjust(left=.2, bottom=0.17, right=0.98) ax.plot(a1, b1, label=name) return ax
def test_1D_example(): """ 1D example: a half-circle using newton's method (secant method for estimating derivative) Change sign of 'y' initial condition to solve for other half-circle """ fvarspecs = {"y": "t*t+y*y-r*r", "x": "t"} ##fnspecs = {'myauxfn': (['t'], '.5*cos(3*t)')} dsargs = args() ##dsargs.fnspecs = fnspecs dsargs.varspecs = fvarspecs dsargs.algparams = {'solvemethod': 'newton', 'atol': 1e-4} dsargs.xdomain = {'y': [-2, 2]} dsargs.ics = {'y': 0.75} dsargs.tdomain = [0, 2] dsargs.pars = {'r': 2} dsargs.vars = ['y'] dsargs.checklevel = 1 dsargs.name = 'imptest' ex1d = ImplicitFnGen(dsargs) assert not ex1d.defined traj1 = ex1d.compute('traj1') assert ex1d.defined assert allclose(traj1(1.5)['y'], 1.3228755105) assert traj1.dimension == 2
def compute_limit_cycle(self): PCargs = args() PCargs.name = 'LC1' PCargs.type = 'LC-C' PCargs.MaxNumPoints = 2500 # // 10 PCargs.NumIntervals = 30 PCargs.NumCollocation = 6 PCargs.initpoint = 'EQ1:H1' PCargs.SolutionMeasures = 'all' PCargs.NumSPOut = 200 PCargs.FuncTol = 1e-4 PCargs.VarTol = 1e-4 PCargs.TestTol = 1e-3 PCargs.SaveEigen = True self.pc.newCurve(PCargs) print('Computing limit-cycle curve...') start = perf_counter() self.pc['LC1'].forward() # PyCont['LC1'].backward() print('done in %.3f seconds!' % (perf_counter() - start)) # Get the lower branch of the cycle. self.pc['LC1'].display(('mu', 'R_min'), stability=True, figure=1) self.pc['LC1'].display(('mu', 'R'), stability=True, figure=1) self.pc['LC1'].display(stability=True, figure='new', axes=(1, 2, 1)) self.pc['LC1'].plot_cycles(coords=('R', 'r'), linewidth=1, axes=(1, 2, 2), figure='fig2')
def addFig(self, label, title="", xlabel="", ylabel="", tdom=None, display=True): """ User can add figures to plotter for data shown in different windows label String to specify name of figure title String to specify title to display on figure xlabel String to specify label on x-axis ylabel String to specify label on y-axis tdom time domain (if applicable, and optional) display Setting to determine whether or not figure is plotted when plotter is built (defaults to True) """ # Check to see if label already exists if self.figs.has_key(label): raise KeyError("Figure label already exists!") self.currFig = label figAttr = args() figAttr.title = title figAttr.xlabel = xlabel figAttr.ylabel = ylabel figAttr.display = display self._max_fig_num += 1 figAttr.fignum = self._max_fig_num figAttr.layers = {} figAttr.shape = [1,1] figAttr.arrange = [] figAttr.window = None figAttr.autoscaling = True figAttr.tdom = tdom self.figs.update({label: figAttr})
def copyFig(self, newFig, oldFig): """ Duplicates all figure, layer, and data information without arrangement information. """ # Check to see if label already exists # if self.figs.has_key(newFig): raise KeyError("New figure label already exists!") self.currFig = newFig old = self.figs[oldFig] figAttr = args() figAttr.title = old.title figAttr.xlabel = old.xlabel figAttr.ylabel = old.ylabel figAttr.display = old.display self._max_fig_num += 1 figAttr.fignum = self._max_fig_num figAttr.shape = [1,1] figAttr.arrange = [] figAttr.window = None figAttr.autoscaling = True figAttr.layers = {} self.figs.update({newFig: figAttr}) for layer in old.layers: oldLay = self.figs[oldFig].layers[layer] self.addLayer(layer, display=oldLay.display, zindex=oldLay.zindex, style=oldLay.style)
def _run_check_macros_1(ode, fnspecs): DSargs = args( name='test', pars={ 'p0': 0, 'p1': 1, 'p2': 2 }, # 'special_erfc' is not available for non-Python generators varspecs={ 'z[j]': 'for(j, 0, 1, 2*z[j+1] + p[j])', 'z2': '-z0 + p2 + special_erfc(2.0)' if ode is Vode_ODEsystem else '-z0 + p2 + 1', }, fnspecs=fnspecs) tmm = ode(DSargs) # test user interface to aux functions and different combinations of embedded # macros assert tmm.auxfns.testif(1.0) == 1.0 assert tmm.auxfns.testmin(1.0, 2.0) == 1.0 assert tmm.auxfns.testmax(1.0, 2.0) == 2.0 assert tmm.auxfns.testmin2(1.0, 2.0) == 2.25 assert tmm.Rhs(0, {'z0': 0.5, 'z1': 0.2, 'z2': 2.1})[1] == 5.2
def test_1D_example(): """ 1D example: a half-circle using newton's method (secant method for estimating derivative) Change sign of 'y' initial condition to solve for other half-circle """ fvarspecs = { "y": "t*t+y*y-r*r", "x": "t" } ##fnspecs = {'myauxfn': (['t'], '.5*cos(3*t)')} dsargs = args() ##dsargs.fnspecs = fnspecs dsargs.varspecs = fvarspecs dsargs.algparams = {'solvemethod': 'newton', 'atol': 1e-4} dsargs.xdomain = {'y': [-2, 2]} dsargs.ics = {'y': 0.75} dsargs.tdomain = [0, 2] dsargs.pars = {'r': 2} dsargs.vars = ['y'] dsargs.checklevel = 1 dsargs.name = 'imptest' ex1d = ImplicitFnGen(dsargs) assert not ex1d.defined traj1 = ex1d.compute('traj1') assert ex1d.defined assert allclose(traj1(1.5)['y'], 1.3228755105) assert traj1.dimension == 2
def _limit_cycle_curve(self, pars, index=-1): (name, PyCont) = self.cont_classes[index] # Limit cycle curve PCargs = args(freepars=PyCont[name].freepars) PCargs.name = 'LC1' PCargs.type = 'LC-C' PCargs.MaxNumPoints = 2500 # // 10 PCargs.NumIntervals = 20 PCargs.NumCollocation = 6 PCargs.initpoint = name + ':H1' PCargs.SolutionMeasures = 'all' PCargs.NumSPOut = 50 PCargs.FuncTol = 1e-10 PCargs.VarTol = 1e-10 PCargs.TestTol = 1e-8 PyCont.newCurve(PCargs) print('Computing limit-cycle curve...') start = perf_counter() PyCont['LC1'].backward() PyCont['LC1'].forward() print('done in %.3f seconds!' % (perf_counter() - start)) PyCont['LC1'].display(pars, stability=True) PyCont['LC1'].display((pars[0], pars[1] + '_min'), stability=True) # TODO(matthew-c21): Keep track of associated figures. PyCont['LC1'].display(stability=True, figure='new', axes=(1, 2, 1)) PyCont['LC1'].plot_cycles(coords=('R', 'r'), linewidth=1, axes=(1, 2, 2), figure='fig2') pass
def test_discrete_domain(): disc_dom = domain_test('disc_dom_test', pars=args(coordname='x', derivname='dxdt', interval=1, verbose_level=3)) ic_disc = numeric_to_traj([[1], [0]], 'test', ['x', 'dxdt'], 0.) assert disc_dom(ic_disc)
def fsargs(): fvarspecs = { 'z[i]': 'for(i, 0, 1, 2*a+myauxfn1(2+t) - ' + 'w*exp(-t)+ 3*z[i]**2 + z[i+1])', 'z2': '2*a+myauxfn1(2+t) - w*exp(-t) + 3*z2**2 + z0', 'w': 'k* w + a*sin(t)*itable + myauxfn1(t)*myauxfn2(w)/(a*sin(t))', 'aux_wdouble': 'w*2 + globalindepvar(t)-0.5*sin(t)', 'aux_other': 'myauxfn1(2*t) + initcond(w)', 'aux_iftest': '1+if(z1>0,(1e-2+w), k+0.4)' } fnspecs = { 'simpfn': ([''], '1+a'), 'myauxfn1': (['t'], '2.5*cos(3*t)*simpfn()+sin(t)*2.e-3'), 'myauxfn2': (['z0', 'w'], 'if(-z0<0,w/2+exp(-w),0)'), 'myauxfn3': (['w'], 'k*w/2+ pow(w,-3.0+k)'), # not supposed to be the actual Jacobian! 'Jacobian': (['t', 'z0', 'z1', 'z2', 'w'], """[[2e5*z0+.1, -w/2, 0, 1.], [-3.e-2 - a*w+z1, 1., z0+1, z0+sin(t)], [k, w*z1+exp(-t), 0., z2/3+w], [0, z1+a, 1., z0-w/3]]"""), # not supposed to be the actual Jacobian_pars! 'Jacobian_pars': (['t', 'k', 'a'], """[[0., 2.], [z0, 1], [3*w, 0.], [2-z1, sin(t)*z2]]""") } return { 'name': 'xfn', # vars is always unrolled by Gen base class if there are FOR loop macros 'vars': ['w', 'z0', 'z1', 'z2'], 'auxvars': ['aux_wdouble', 'aux_other', 'aux_iftest'], 'pars': ['k', 'a'], 'inputs': 'itable', 'varspecs': fvarspecs, 'fnspecs': fnspecs, # In practice, _for_macro_info created automatically by Generator base class '_for_macro_info': args( numfors=1, totforvars=2, varsbyforspec={ 'z[i]': ['z0', 'z1'], 'w': ['w'], 'z2': ['z2'], 'aux_wdouble': ['aux_wdouble'], 'aux_other': ['aux_other'], 'aux_iftest': ['aux_iftest'] } ), 'reuseterms': {'a*sin_t': 'ast', 'exp(-t)': 'expmt', 'sin(t)': 'sin_t', 'myauxfn1(2+t)': 'afn1call'}, 'codeinsert_end': """ print('code inserted at end')""", 'codeinsert_start': """ print('code inserted at start')""", 'targetlang': 'python' }
def __init__(self, name, model, ics): self.cont_classes = [] self.name = name self.model = model self.ics = [ics] self.DSargs = args(name=self.name) self.TestDS = None self._revise_dsargs()
def __call__(self, calc_context, fignum, attribute_name): self.sim = calc_context.sim self.calc_context = calc_context old_toolbar = plt.rcParams['toolbar'] plt.rcParams['toolbar'] = 'None' fig = plt.figure(fignum, figsize=(2, 6)) #, frameon=False) plt.rcParams['toolbar'] = old_toolbar if fignum in self.figs: self.figs[fignum].tracked.append(attribute_name) else: self.figs[fignum] = args(figure=fig, tracked=[attribute_name]) self.sim.tracked_objects.append(self)
def __call__(self, calc_context, fignum, attribute_name): self.sim = calc_context.sim self.calc_context = calc_context old_toolbar = plt.rcParams['toolbar'] plt.rcParams['toolbar'] = 'None' fig = plt.figure(fignum, figsize=(2,6)) #, frameon=False) plt.rcParams['toolbar'] = old_toolbar if fignum in self.figs: self.figs[fignum].tracked.append(attribute_name) else: self.figs[fignum] = args(figure=fig, tracked=[attribute_name]) self.sim.tracked_objects.append(self)
def _run_check_macros_3(ode, fnspecs): # show example of summing where i != p defines the sum range, and p is a # special value (here, 2) DSargs3 = args(name='test3', pars={'p0': 0, 'p1': 1, 'p2': 2}, varspecs={ 'x': 'sum(i, 0, 4, sum(j, 0, 1, if([i]==2, 0, indexfunc([j] + p[j]))))'}, fnspecs=fnspecs ) tm3 = ode(DSargs3) tm3.set(tdata=[0, 10], ics={'x': 1}) tm3.compute('test') assert allclose(tm3.Rhs(0, {'x': 0}), 8 * pi)
def _run_check_macros_3(ode, fnspecs): # show example of summing where i != p defines the sum range, and p is a # special value (here, 2) DSargs3 = args( name="test3", pars={"p0": 0, "p1": 1, "p2": 2}, varspecs={"x": "sum(i, 0, 4, sum(j, 0, 1, if([i]==2, 0, indexfunc([j] + p[j]))))"}, fnspecs=fnspecs, ) tm3 = ode(DSargs3) tm3.set(tdata=[0, 10], ics={"x": 1}) tm3.compute("test") assert allclose(tm3.Rhs(0, {"x": 0}), 8 * pi)
def test_get_spike_data(): """Test Context class and example of qualitative fitting of spikes""" sigma = 0.05 # import doesn't actually create a Pointset (it's slightly misnamed for this # purpose but it can do other things...) data = importPointset(path.join(path.dirname(__file__), 'test_spikes.dat'), t=0, sep='\t') vs = data['vararray'][0] # pick one of the signals ts = data['t'] traj = numeric_to_traj([vs], 'test_traj', ['x'], ts, discrete=False) # --------------------------------------------------------------------- # set debug = True and verbose_level = 2 for plot of fit is_spike = get_spike_data('one_spike', pars=args(height_tol=2000., thresh_pc=0.15, fit_width_max=20, weight=0, noise_tol=300, tlo=260, width_tol=ts[-1], coord='x', eventtol=1e-2, verbose_level=0, debug=False)) # compare # plot(ts, vs) # assert ensures that is_spike returns True when passed the particular # set of data assert is_spike(traj) # given that it returned true, try another time for next spike is_spike.pars.tlo = 268 assert is_spike(traj) # introspect the is_spike object with info(is_spike) # .results values now guaranteed to exist assert_allclose(is_spike.results.tlo, 269.98922, rtol=1e-5) assert_allclose(is_spike.results.thi, 272.0108, rtol=1e-5) assert_allclose(is_spike.results.spike_time, 270.5574, rtol=1e-5) assert_allclose(is_spike.results.spike_val, 5117.07697, rtol=1e-4)
def dual_bifurcation(self, name, initpoint, p1, p2): # TODO(matthew-c21): Fancy graph stuff. Possibly use smaller aggregate objects to keep track of that by itself. pcargs = args() pcargs.name = name pcargs.type = 'H-C2' pcargs.initpoint = initpoint pcargs.freepars = [p1, p2] pcargs.MaxNumPoints = 800 pcargs.MinStepSize = 1e-5 pcargs.MaxStepSize = 1e-2 pcargs.StepSize = 1e-3 pcargs.LocBifPoints = 'all' pcargs.SaveEigen = True self.compute(pcargs, 'Computing 2-parameter bifurcation analysis...')
def _find_steady_state(self, tdata): ssargs = args(name='steadyState') ssargs.tdata = tdata # Test code. ssargs.ics = ics ssargs.pars = self.model_params.pars ssargs.varspecs = self.model_params.varspecs ssargs.fnspecs = self.model_params.fnspecs ssargs.algparams = {'refine': True} ssDS = Generator.Radau_ODEsystem(ssargs) trajectory = ssDS.compute('steady state') pts = trajectory.sample() return pts
def limit_cycle(self, name, initpoint, freepars): # TODO(matthew-c21): See below comment. pcargs = args(name=name, type='LC-C') pcargs.MaxNumPoints = 2500 # // 10 pcargs.NumIntervals = 30 pcargs.NumCollocation = 6 pcargs.initpoint = initpoint pcargs.SolutionMeasures = 'all' pcargs.NumSPOut = 200 pcargs.FuncTol = 1e-4 pcargs.VarTol = 1e-4 pcargs.TestTol = 1e-3 pcargs.SaveEigen = True pcargs.freepars = freepars self.compute(pcargs, 'Computing limit cycle...')
def ode(): """Dummy system with all functions set""" DSargs = args( name='test_interfaces', fnspecs={ 'Jacobian': (['t', 'y0', 'y1', 'y2'], """[[-0.04, 1e4*y2 , 1e4*y1 ], [ 0.04, -1e4*y2-6e7*y1, -1e4*y1 ], [ 0.0 , 6e7*y1 , 0.0 ]]"""), 'Jacobian_pars': (['t', 'p1', 'p2', 'p3'], "[[1, 0, p1], [-1, 0, p2], [0, 0, p3]]"), 'ydot0': (['y0', 'y1', 'y2'], "-0.04*y0 + 1e4*y1*y2"), 'ydot2': (['y0', 'y1', 'y2'], "3e7*y1*y1"), 'massMatrix': (['t', 'y0', 'y1', 'y2'], """[[-0.04, 1e4*y2 , 1e4*y1 ], [ 0.04, -1e4*y2-6e7*y1, -1e4*y1 ], [ 0.0 , 6e7*y1 , 0.0 ]]"""), }, varspecs={ "y0": "ydot0(y0,y1,y2)", "y2": "ydot2(y0,y1,y2)", "y1": "-ydot0(y0,y1,y2)-ydot2(y0,y1,y2)", 'aux0': 'y0 + 2 * y1 - t', 'aux1': 'y2 - y1 - 2 * y0', }, auxvars=['aux0', 'aux1'], pars={ 'p1': 0.01, 'p2': 0.02, 'p3': 0.03 }, tdomain=[0., 1e20], ics={ 'y0': 1.0, 'y1': 0., 'y2': 0. }, algparams={ 'init_step': 0.4, 'rtol': 1e-4, 'atol': [1e-8, 1e-14, 1e-6] }, checklevel=2, ) return Radau_ODEsystem(DSargs)
def create_pcargs(name, freepars, StepSize, MaxNumPoints, LocBifPoints='all', alg_type='EP-C'): PCargs = args(name=name, type=alg_type) PCargs.freepars = freepars PCargs.StepSize = StepSize PCargs.MaxNumPoints = MaxNumPoints PCargs.LocBifPoints = LocBifPoints PCargs.verbosity = 2 PCargs.SaveJacobian = True PCargs.SaveEigen = True return PCargs
def test_event1a(self): pardict = {'Tmelt': self.params.Tmelt} icdict = {'Tp': 44.1} ode = {'Tp': '0'} DSargs = args(name='Event1aTest') DSargs.events = [event.event1(self.params)] DSargs.pars = pardict DSargs.tdata =[0, self.params.tfinal] DSargs.algparams = {'init_step': self.params.tstep, 'rtol':self.params.RelTol, 'atol': self.params.AbsTol} DSargs.varspecs = ode DSargs.ics = icdict event1aTest = PyDSTool.Generator.Vode_ODEsystem(DSargs) traj = event1aTest.compute('event1aTest') evs = traj.getEvents('event_melt_begin') assert evs is None
def test_event1b(self): pardict = {'Tmelt': self.params.Tmelt} icdict = {'Tp': 44.1} ode = {'Tp': '0.1'} DSargs = args(name='Event1bTest') DSargs.events = [event.event1(self.params)] DSargs.pars = pardict DSargs.tdata = [0, self.params.tfinal] DSargs.algparams = {'init_step': 0.5, 'rtol': self.params.RelTol, 'atol': self.params.AbsTol} DSargs.varspecs = ode DSargs.ics = icdict event1bTest = PyDSTool.Generator.Vode_ODEsystem(DSargs) traj = event1bTest.compute('event1bTest') evs = traj.getEvents('event_melt_begin') self.assertAlmostEqual(evs['t'][-1], 1, places=None, msg='event1b', delta=1e-10)
def _run_check_macros_2(ode, fnspecs): DSargs2 = args( name="test2", pars={"p0": 0, "p1": 1, "p2": 2}, varspecs={ "y[i]": "for(i, 0, 1, y[i]+if(y[i+1]<2, 2+p[i]+getbound(%s,0), indexfunc([i])+y[i+1]) - 3)" % ("y2" if ode in [Vode_ODEsystem, Euler_ODEsystem] else '"y2"'), "y2": "0", }, xdomain={"y2": [-10, 10]}, fnspecs=fnspecs, ics={"y0": 0, "y1": 0, "y2": 0.1}, ) tm2 = ode(DSargs2) tm2.set(tdata=[0, 10]) tm2.compute("test") assert allclose(tm2.Rhs(0, {"y0": 0, "y1": 0.3, "y2": 5}), array([-11.0, 2.3 + pi, 0.0]))
def test_event2b(self): pardict = {'Hf': self.params.Hf, 'Mp': self.params.Mp} icdict = {'Qp': 600000} ode = {'Qp': '0'} DSargs = args(name='Event2bTest') DSargs.events = [event.event2(self.params)] DSargs.pars = pardict DSargs.tdata = [0, self.params.tfinal] DSargs.algparams = {'init_step': self.params.tstep, 'rtol': self.params.RelTol, 'atol': self.params.AbsTol} DSargs.varspecs = ode DSargs.ics = icdict event2bTest = PyDSTool.Generator.Vode_ODEsystem(DSargs) traj = event2bTest.compute('event2bTest') evs = traj.getEvents('event_melt_end') assert evs is None
def test_event2c(self): pardict = {'Hf': self.params.Hf, 'Mp': self.params.Mp} icdict = {'Qp': 10654059.9} ode = {'Qp': '0.1'} DSargs = args(name='Event2cTest') DSargs.events = [event.event2(self.params)] DSargs.pars = pardict DSargs.tdata = [0, self.params.tfinal] DSargs.algparams = {'init_step': 0.5, 'rtol': self.params.RelTol, 'atol': self.params.AbsTol} DSargs.varspecs = ode DSargs.ics = icdict event2cTest = PyDSTool.Generator.Vode_ODEsystem(DSargs) traj = event2cTest.compute('event2cTest') evs = traj.getEvents('event_melt_end') self.assertAlmostEqual(evs['t'][-1], 1, places=None, msg='event2c', delta=1e-4)
def addLayer(self, layer_name, figure=None, **kwargs): """ User method to add data sets to a layer in a figure figure name layer name display toggle Boolean kind a user-defined kind, e.g. 'data', 'vline', 'hline', 'epoch', etc. scale a pair of axes scale pairs or None zindex (currently unused) """ fig_struct, figure = self._resolveFig(figure) # Check to see layer does not already exist # if fig_struct.layers.has_key(layer_name): raise KeyError("Layer name already exists in figure!") # default plot style generated from list of colors color = self.colors[len(fig_struct.layers)%len(self.colors)] line = '-' style = color+line layAttrs = args() layAttrs.data = {} layAttrs.display = True # default zindex based on order of layer declaration layAttrs.zindex = len(fig_struct.layers)+1 layAttrs.style = style #layAttrs.axes = None layAttrs.scale = None layAttrs.kind = 'data' layAttrs.dynamic = False layAttrs.trajs = {} layAttrs.axes_vars = [] for kw in kwargs: # Check to see that parameter exists in layers # ## Possibly change to account for different properties of specific artist objects? if not layAttrs.has_key(kw): raise KeyError("Parameter is not a property of the layer.") layAttrs[kw] = kwargs[kw] fig_struct.layers[layer_name] = layAttrs
def test_get_spike_data(): """Test Context class and example of qualitative fitting of spikes""" sigma = 0.05 # import doesn't actually create a Pointset (it's slightly misnamed for this # purpose but it can do other things...) data = importPointset(path.join(path.dirname(__file__), 'test_spikes.dat'),t=0,sep='\t') vs = data['vararray'][0] # pick one of the signals ts = data['t'] traj = numeric_to_traj([vs], 'test_traj', ['x'], ts, discrete=False) # --------------------------------------------------------------------- # set debug = True and verbose_level = 2 for plot of fit is_spike = get_spike_data('one_spike', pars=args( height_tol=2000., thresh_pc=0.15, fit_width_max=20, weight=0, noise_tol=300, tlo=260, width_tol=ts[-1], coord='x', eventtol=1e-2, verbose_level=0, debug=False)) # compare # plot(ts, vs) # assert ensures that is_spike returns True when passed the particular # set of data assert is_spike(traj) # given that it returned true, try another time for next spike is_spike.pars.tlo = 268 assert is_spike(traj) # introspect the is_spike object with info(is_spike) # .results values now guaranteed to exist assert_allclose(is_spike.results.tlo, 269.98922, rtol=1e-5) assert_allclose(is_spike.results.thi, 272.0108, rtol=1e-5) assert_allclose(is_spike.results.spike_time, 270.5574, rtol=1e-5) assert_allclose(is_spike.results.spike_val, 5117.07697, rtol=1e-4)
def _run_check_macros_1(ode, fnspecs): DSargs = args( name="test", pars={"p0": 0, "p1": 1, "p2": 2}, # 'special_erfc' is not available for non-Python generators varspecs={ "z[j]": "for(j, 0, 1, 2*z[j+1] + p[j])", "z2": "-z0 + p2 + special_erfc(2.0)" if ode is Vode_ODEsystem else "-z0 + p2 + 1", }, fnspecs=fnspecs, ) tmm = ode(DSargs) # test user interface to aux functions and different combinations of embedded # macros assert tmm.auxfns.testif(1.0) == 1.0 assert tmm.auxfns.testmin(1.0, 2.0) == 1.0 assert tmm.auxfns.testmax(1.0, 2.0) == 2.0 assert tmm.auxfns.testmin2(1.0, 2.0) == 2.25 assert tmm.Rhs(0, {"z0": 0.5, "z1": 0.2, "z2": 2.1})[1] == 5.2
def ode(): """Dummy system with all functions set""" DSargs = args( name='test_interfaces', fnspecs={ 'Jacobian': (['t', 'y0', 'y1', 'y2'], """[[-0.04, 1e4*y2 , 1e4*y1 ], [ 0.04, -1e4*y2-6e7*y1, -1e4*y1 ], [ 0.0 , 6e7*y1 , 0.0 ]]"""), 'Jacobian_pars': (['t', 'p1', 'p2', 'p3'], "[[1, 0, p1], [-1, 0, p2], [0, 0, p3]]"), 'ydot0': (['y0', 'y1', 'y2'], "-0.04*y0 + 1e4*y1*y2"), 'ydot2': (['y0', 'y1', 'y2'], "3e7*y1*y1"), 'massMatrix': (['t', 'y0', 'y1', 'y2'], """[[-0.04, 1e4*y2 , 1e4*y1 ], [ 0.04, -1e4*y2-6e7*y1, -1e4*y1 ], [ 0.0 , 6e7*y1 , 0.0 ]]"""), }, varspecs={"y0": "ydot0(y0,y1,y2)", "y2": "ydot2(y0,y1,y2)", "y1": "-ydot0(y0,y1,y2)-ydot2(y0,y1,y2)", 'aux0': 'y0 + 2 * y1 - t', 'aux1': 'y2 - y1 - 2 * y0', }, auxvars=['aux0', 'aux1'], pars={'p1': 0.01, 'p2': 0.02, 'p3': 0.03}, tdomain=[0., 1e20], ics={'y0': 1.0, 'y1': 0., 'y2': 0.}, algparams={ 'init_step': 0.4, 'rtol': 1e-4, 'atol': [1e-8, 1e-14, 1e-6]}, checklevel=2, ) return Radau_ODEsystem(DSargs)
import fovea.diagnostics as dgn from PyDSTool import args from pprint import pprint dm = dgn.diagnostic_manager('test') log = dm.log log = log.bind(user='******', val=3.1416) log.msg('begin', status='sofarsogood') log.user_error('user.forgot_towel') log.msg('done', status='nope') test_obj = args(name='test_obj', contents='stuff') dm.attach_obj(test_obj, 'dummy_objname') log = log.bind(user='******', val=-1.01) log.msg('begin', status='yarp') log.user_action('user.remembered_towel') log.msg('done') print("\n") pprint(log.dump_events()) pprint(dm.log_items_digest[dm.name_to_digest['dummy_objname']]) print("\n") print(dm.db.all())
def test_vode_events_compare_with_euler(): """ Test terminal and non-terminal event testing with VODE integrator, including some comparisons and tests of Euler integrator too. """ DSargs = args(varspecs={'w': 'k*sin(2*t) - w'}, name='ODEtest') DSargs.tdomain = [0, 10] DSargs.pars = {'k': 1, 'p_thresh': -0.25} DSargs.algparams = {'init_step': 0.001, 'atol': 1e-12, 'rtol': 1e-13} DSargs.checklevel = 2 DSargs.ics = {'w': -1.0} DSargs.tdata = [0, 10] ev_args_nonterm = {'name': 'monitor', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': False, 'precise': True} thresh_ev_nonterm = Events.makeZeroCrossEvent('w', 0, ev_args_nonterm, varnames=['w']) ev_args_term = {'name': 'threshold', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': True, 'precise': True} thresh_ev_term = Events.makeZeroCrossEvent('w-p_thresh', -1, ev_args_term, varnames=['w'], parnames=['p_thresh']) DSargs.events = [thresh_ev_nonterm, thresh_ev_term] testODE = Vode_ODEsystem(DSargs) # diagnostics and other possible user-defined python functions # for python solvers only (currently only Euler) # def before_func(euler): # print(euler.algparams['init_step']) # # def after_func(euler): # print(euler._solver.y) # ##DSargs.user_func_beforestep = before_func ##DSargs.user_func_afterstep = after_func testODE_Euler = Euler_ODEsystem(DSargs) traj = testODE.compute('traj') traj2 = testODE_Euler.compute('traj') pts = traj.sample() testODE.diagnostics.showWarnings() mon_evs_found = testODE.getEvents('monitor') term_evs_found = testODE.getEvents('threshold') # test Euler assert allclose(array(testODE.getEventTimes('monitor')), array(traj2.getEventTimes('monitor')), atol=1e-3) assert all(traj.getEvents('monitor') == mon_evs_found) assert all(traj.getEventTimes('threshold') == testODE.getEventTimes('threshold')) term_evs_found.info() # Alternative way to extract events: they are labelled in the # pointset! These return dictionaries indexing into the pointset. mon_evs_dict = pts.labels.by_label['Event:monitor'] mon_ev_points = pts[sort(mon_evs_dict.keys())] assert len(mon_evs_found) == len(mon_ev_points) == 2 assert all(mon_evs_found == mon_ev_points)
def test_bd_containment(): """Basic tests for boundary containment features.""" vals1 = linspace(-3, 3, 20) test_traj1 = numeric_to_traj([vals1], 'test', 'x', arange(len(vals1), dtype='d')) vals2 = array( [1., 1., 1.00000000001, 1.0000001, 1., 0.9999999999, 0.99999]) test_traj2 = numeric_to_traj([vals2], 'test', 'x', arange(len(vals2), dtype='d')) bc = boundary_containment_by_postproc('bc_test', description='Test BCs', pars=args(thresh=1, interior_dirn=-1, abseps=1e-4)) # Test whether test trajectory 1 remains below x_ref=1 # up to rounding error tolerance of 1e-4... assert not bc(test_traj1) # print "... failed at index", bc._find_idx() # print "\nbc.results -->\n" # print bc.results # Test whether test trajectory 2 remains below x_ref=1 # up to rounding error tolerance of 1e-4... assert bc(test_traj2) # Test whether initial condition lies within a domain # (includes transversality condition: derivative must point into interior # of domain): ic_inside = numeric_to_traj([[0.3], [-10.5]], 'test', ['x', 'dxdt'], 0.) ic_crit_ok = numeric_to_traj([[1], [-1.]], 'test', ['x', 'dxdt'], 0.) ic_crit_not_ok = numeric_to_traj([[1], [1.]], 'test', ['x', 'dxdt'], 0.) ic_outside = numeric_to_traj([[1.01], [-1.]], 'test', ['x', 'dxdt'], 0.) in_domain = domain_test('domain_test', pars=args(coordname='x', derivname='dxdt', interval=[-1, 1], verbose_level=3)) assert in_domain(ic_inside) assert in_domain(ic_crit_ok) assert not in_domain(ic_crit_not_ok) assert not in_domain(ic_outside) # Check that exterior IC failed at trajectory point index '0' with # in_domain._find_idx()==0 # ------------------------------------------------------------------ # Test for domain with rounding-error tolerated boundaries: in_domain_loose = domain_test('domain_test', pars=args(coordname='x', derivname='dxdt', interval=Interval('x', float, [-1, 1], abseps=1e-4), verbose_level=0)) ic_crit_round_ok = numeric_to_traj( [[1.000001], [-1.]], 'test', ['x', 'dxdt'], 0.) ic_crit_round_not_ok = numeric_to_traj( [[1.000001], [1.]], 'test', ['x', 'dxdt'], 0.) assert in_domain_loose(ic_inside) assert in_domain_loose(ic_crit_ok) assert not in_domain_loose(ic_crit_not_ok) assert not in_domain_loose(ic_outside) assert in_domain_loose(ic_crit_round_ok) assert not in_domain_loose(ic_crit_round_not_ok) zbd1 = domain_test( 'z', pars=args(coordname='z', derivname='D_z', interval=[0.0, 1.0], verbose_level=0)) zbd2 = domain_test( 'z', pars=args(coordname='z', derivname='D_z', interval=1.0, verbose_level=0)) ztraj = {} ztraj[0] = numeric_to_traj([[1], [0.437]], 'test', ['z', 'D_z'], 0) ztraj[1] = numeric_to_traj([[1], [1]], 'test', ['z', 'D_z'], 0) ztraj[2] = numeric_to_traj([[1.0], [1]], 'test', ['z', 'D_z'], 0) ztraj[3] = numeric_to_traj([[1], [1.0]], 'test', ['z', 'D_z'], 0) ztraj[4] = numeric_to_traj([[1], [1.0]], 'test', ['z', 'D_z'], 0) ztraj[5] = numeric_to_traj([[1.0], [5.0]], 'test', ['z', 'D_z'], 0) assert not zbd1(ztraj[0]) for i in range(1, 6): assert zbd2(ztraj[i])
import numpy as np from matplotlib import pyplot as plt # The approximate map for the triple-zero unfolding of the Lorenz ODEs # see http://www.math.pitt.edu/~bard/bardware/tut/newstyle.html#triple # Map given by: # z(n+1) = a+b*(z-c)^2 # with z(0)=2 # For Lyapunov exponent: # zp(n+1) = zp+log(abs(2*b*(z-c))) # with zp(0) = 0, so that Lyapunov Exponent L will be zp/(t+1) # (because t starts at 0) DSargs = args(name='Lorenz map') DSargs.varspecs = {'z': 'a+b*(z-c)**2', # note syntax for power 'zp': 'zp+log(abs(2*b*(z-c)))', 'L': 'zp/(t+1)'} # L is an auxiliary variable DSargs.tdomain = [0, 200] DSargs.pars = args(a=2.93, b=-1.44, c=1.85) DSargs.vars = ['z', 'zp'] # Implicitly, then, L must be an auxiliary variable DSargs.ics = {'z': 2, 'zp': 0} DSargs.ttype = int # force independent variable type to be integer (discrete time) lmap = dst.MapSystem(DSargs) traj = lmap.compute('test') pts = traj.sample() plt.figure(1) plt.plot(pts['t'], pts['z'], 'ko-')
pardict = {'Ap': params.Ap, 'Tmelt': params.Tmelt, 'Hf': params.Hf, 'Tc': params.Tc, 'hp': params.hp, 'Tinit': params.Tinit, 'tau_w': params.tau_w, 'eta': params.eta, 'Mp': params.Mp, 'tau_ps': params.tau_ps, 'tau_pl': params.tau_pl} icdict1 = {'Tw': pardict['Tinit'], 'Tp': pardict['Tinit']} DSargs1 = args(name='PreMelt') DSargs1.events = [event.event1(params)] DSargs1.pars = pardict DSargs1.tdata = [0, params.tfinal] DSargs1.algparams = {'init_step': params.tstep, 'rtol': params.RelTol, 'atol': params.AbsTol} DSargs1.varspecs = temperature.temperature1() DSargs1.ics = icdict1 preMelt = PyDSTool.Generator.Vode_ODEsystem(DSargs1) traj1 = preMelt.compute('preMelt') pts1 = traj1.sample() evs1 = traj1.getEvents('event_melt_begin') eWat = energy.energy1Wat(pts1['Tw'], params) ePCM = energy.energy1PCM(pts1['Tp'], params) time = [] for element in pts1['t']: time = time + [element]
from PyDSTool import args, Generator, perf_counter, ContClass, show import matplotlib.pyplot as plt from model import model_mmi2 as m, ics_1 as ics DSargs = args(name='bifurcation') DSargs.ics = ics DSargs.pars = m['pars'] DSargs.varspecs = m['vars'] DSargs.fnspecs = m['fns'] DSargs.algparams = {'refine': True, 'init_step': 1e-3} output_file = 'output.bin' class Continuation: def __init__(self, dsargs): self.ics = dsargs.ics self.model_params = dsargs self._init_ODESystem() def _init_ODESystem(self): self.model_params.ics = self.ics self.testDS = Generator.Radau_ODEsystem(self.model_params) self.pc = ContClass(self.testDS) def _find_steady_state(self, tdata): ssargs = args(name='steadyState') ssargs.tdata = tdata # Test code.
- b1 * 1 * 2 * kr * c1 \ - b2 * 2 * 1 * kr * c2)', 'R': \ 'g*(sR - kR * (R - 2 * c1 - 1 * c2) \ - 2 * kR * c1 * a1 - 1 * kR * c2 * a2)', 'c1':\ 'Ts * (K1 * (R - 2 * c1 - c2) * (r - 2 * c1 - 2 * c2) - c1)', 'c2':\ 'Ts * (K2 * c1 * (r - 2 * c1 - 2 * c2) - c2)', }, 'fns': {}, 'aux': [], 'name': 'mmi2'} ics_1 = {'r': 0.8, 'R': 0.1, 'c1': 0.0, 'c2': 0.0} DSargs = args(name='mmi2') DSargs.pars = model_mmi2['pars'] DSargs.varspecs = model_mmi2['vars'] DSargs.fnspecs = {} DSargs.ics = ics_1 DSargs.algparams = {'refine': True, } testDS = Generator.Radau_ODEsystem(DSargs) # Set up continuation class PyCont = ContClass(testDS) PCargs = args(name='EQ1', type='EP-C') PCargs.freepars = ['mu'] #PCargs.StepSize = 3e-6 #PCargs.MaxStepSize = 3e-5
def dsargs(): timeData = linspace(0, 10, 20) sindata = sin(20 * timeData) xData = {'in': sindata} my_input = InterpolateTable({ 'tdata': timeData, 'ics': xData, 'name': 'interp1d', 'method': 'linear', 'checklevel': 1, 'abseps': 1e-5 }).compute('interp') fvarspecs = { "w": "k*w + sin(t) + myauxfn1(t)*myauxfn2(w)", 'aux_wdouble': 'w*2 + globalindepvar(t)', 'aux_other': 'myauxfn1(2*t) + initcond(w)' } fnspecs = { 'myauxfn1': (['t'], '2.5*cos(3*t)'), 'myauxfn2': (['w'], 'w/2') } # targetlang is optional if the default python target is desired DSargs = args(fnspecs=fnspecs, name='event_test') DSargs.varspecs = fvarspecs DSargs.tdomain = [0.1, 2.1] DSargs.pars = {'k': 2, 'a': -0.5} DSargs.vars = 'w' DSargs.ics = {'w': 3} DSargs.inputs = {'in': my_input.variables['in']} DSargs.algparams = {'init_step': 0.01} DSargs.checklevel = 2 ev_args_nonterm = { 'name': 'monitor', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': False, 'precise': True } thresh_ev_nonterm = Events.makeZeroCrossEvent( 'in', 0, ev_args_nonterm, inputnames=['in'], targetlang='c' ) ev_args_term = { 'name': 'threshold', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': True, 'precise': True } thresh_ev_term = Events.makeZeroCrossEvent( 'w-20', 1, ev_args_term, ['w'], targetlang='c' ) DSargs.events = [thresh_ev_nonterm, thresh_ev_term] return DSargs
def test_symbolic(): assert doneg('-x-y') == 'x+y' assert doneg('(-x-y)') == '(x+y)' assert doneg('-(-x-y)') == '(-x-y)' assert dosub('1', '-x-y') == '(1+x+y)' g2 = expr2fun('1-max([0., -a+b*x])', **{'a': 3, 'b': 1.5}) assert g2._args == ['x'] assert g2(1) == 1.0 assert g2(10) == -11.0 ds = {'a': 3, 'bbb': 1} f = expr2fun('1+ds["a"]') assert f._args == ['ds'] assert f(ds) == 4 f2 = expr2fun('1+ds["a"]') assert f2(**{'ds': ds}) == 4 assert f2._args == ['ds'] g = expr2fun('1+ds["bbb"]', ds=ds) assert g() == 2 # g must be dynamic and not based on static eval of ds on initialization ds['bbb'] = 2 assert g._args == [] assert g() == 3 m = args(pars=copy(ds)) h = expr2fun('m.pars["a"]+c', m=m, c=1) assert h() == 4 assert h._args == [] h2 = expr2fun('1 + m.pars["a"]/2.', m=m) assert h2() == 2.5 assert h2._args == [] def func(x, y): return x * (y + 1) m.func = func i = expr2fun('1+func(x,y)+b', func=m.func, b=0.5) assert 1 + func(2, 3) + 0.5 == i(2, 3) j = expr2fun('i(x,func(2,y))*2', i=i, func=m.func) assert j(1, 0) == 9 fnspec = {'f': (['x', 'y'], 'x+1+2*y-a')} # a is expected to be in scope like a FuncSpec parameter # so can't use the above method of providing explicit functions k = expr2fun('-f(c,d)+b', f=fnspec['f'], b=0.5, a=1) assert k(1, 2) == -4.5 s = '1+a/(f(x,y)-3)+h(2)' t = s.replace('y', 'g(x,z)') u = t.replace('z', 'f(z)') r1, d1 = replaceCallsWithDummies(s, ['f', 'g', 'h']) r2, d2 = replaceCallsWithDummies(t, ['f', 'g', 'h']) r3, d3 = replaceCallsWithDummies(u, ['f', 'g', 'h']) assert r1 == '1+a/(__dummy1__-3)+__dummy2__' assert len(d1) == 2 assert r2 == '1+a/(__dummy2__-3)+__dummy3__' assert len(d2) == 3 assert r2 == '1+a/(__dummy2__-3)+__dummy3__' assert len(d3) == 4 ps = 'abs((HB9_fs_Vq-HB9_fs_V)*(-((HB9_fs_Lk_g*(HB9_fs_V-HB9_fs_Lk_vrev))+(-HB9_fs_Iapp_Ibias)+((HB9_fs_Na_g*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1-HB9_fs_K_n))*(HB9_fs_V-HB9_fs_Na_vrev))+(HB9_fs_K_g*HB9_fs_K_n*HB9_fs_K_n*HB9_fs_K_n*HB9_fs_K_n*(HB9_fs_V-HB9_fs_K_vrev))+(HB9_fs_isyn_g*(HB9_fs_V-HB9_fs_isyn_vrev))+(HB9_fs_esyn_g*(HB9_fs_V-HB9_fs_esyn_vrev)))/HB9_fs_C)+(HB9_fs_Knq-HB9_fs_K_n)*(((1.0/(1.0+exp((HB9_fs_V-HB9_fs_K_theta_n)/HB9_fs_K_k_n)))-HB9_fs_K_n)/(HB9_fs_K_taun_bar/cosh((HB9_fs_V-HB9_fs_K_theta_n)/(2*HB9_fs_K_k_n)))))/(sqrt(HB9_fs_Vq*HB9_fs_Vq+HB9_fs_Knq*HB9_fs_Knq)+sqrt(pow((-((HB9_fs_Lk_g*(HB9_fs_V-HB9_fs_Lk_vrev))+(-HB9_fs_Iapp_Ibias)+((HB9_fs_Na_g*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1-HB9_fs_K_n))*(HB9_fs_V-HB9_fs_Na_vrev))+(HB9_fs_K_g*HB9_fs_K_n*HB9_fs_K_n*HB9_fs_K_n*HB9_fs_K_n*(HB9_fs_V-HB9_fs_K_vrev))+(HB9_fs_isyn_g*(HB9_fs_V-HB9_fs_isyn_vrev))+(HB9_fs_esyn_g*(HB9_fs_V-HB9_fs_esyn_vrev)))/HB9_fs_C),2)+pow((((1.0/(1.0+exp((HB9_fs_V-HB9_fs_K_theta_n)/HB9_fs_K_k_n)))-HB9_fs_K_n)/(HB9_fs_K_taun_bar/cosh((HB9_fs_V-HB9_fs_K_theta_n)/(2*HB9_fs_K_k_n)))),2)))' parnames = [ 'HB9_fs_Vq', 'HB9_fs_Lk_g', 'HB9_fs_Lk_vrev', 'HB9_fs_Iapp_Ibias', 'HB9_fs_Na_g', 'HB9_fs_Na_theta_m', 'HB9_fs_Na_k_m', 'HB9_fs_Na_vrev', 'HB9_fs_K_g', 'HB9_fs_K_vrev', 'HB9_fs_isyn_g', 'HB9_fs_isyn_vrev', 'HB9_fs_esyn_g', 'HB9_fs_esyn_vrev', 'HB9_fs_C', 'HB9_fs_Knq', 'HB9_fs_K_theta_n', 'HB9_fs_K_k_n', 'HB9_fs_K_taun_bar' ] varnames = ['HB9_fs_V', 'HB9_fs_K_n'] ps2 = convertPowers(ps, 'pow') for n in parnames + varnames: v = rand(1)[0] + 1e-5 ps2 = ps2.replace(n, str(v)) ps = ps.replace(n, str(v)) eps = eval(ps) eps2 = eval(ps2) assert eps == eps2 a = Par('3.5', 'a') qa = Var(['a*3', 'b'], 'array_test') assert str(qa.eval(a=1)) == '[3,b]' # explicit exporting 'a' to globals to make this work as expected globals()['a'] = a assert str(qa.eval()) == '[10.5,b]' testq = QuantSpec('d', 'a') testq.simplify() assert testq() == 'a' assert str(testq.eval(a=3)) == '3' q = QuantSpec('q', 'zeta(yrel(y,initcond(y)),z)-1') print(q.eval({})) assert 'initcond' in str(q.eval({})) q2 = QuantSpec('q', 'Exp(-spikeTable+b)/k') assert 'spikeTable' in q2.freeSymbols # x = Var('x') # print x.isDefined() # xs = QuantSpec('x', '1-rel - 2*x + cos(z) + 2e10', 'RHSfuncSpec') # x.bindSpec(xs) # print x.isDefined(),"\n" x = Var(QuantSpec('x', '1-rel - 2*x + cos(z) + 2e10', 'RHSfuncSpec')) p = Par('p') az = Var(QuantSpec('z', 'myfunc(0,z)+abs(x+1)', 'RHSfuncSpec')) w = Var('x-1/w[i]', 'w[i,0,1]', specType='RHSfuncSpec') myLeaf1.compatibleContainers = (myNode, ) myLeaf2.compatibleContainers = (myNode, ) myNode.compatibleSubcomponents = (myLeaf1, myLeaf2) c = myLeaf1('leaf1') assert c.isDefined() == False c.add(x) print(c.freeSymbols, c.isDefined()) c.add(az) print(c.freeSymbols, c.isDefined()) c.add(w) print(c.freeSymbols, c.isDefined()) c.compileFuncSpec() print(c.funcSpecDict) empty_fn = Fun('1+exp(1)', [], 'dumb_fn') print(empty_fn()) q = Par('qpar') y = Var(QuantSpec('rel', 'v+p'), domain=[0, 1]) g = Fun(QuantSpec('qfunc', '-1.e-05+sin(qpar)*(10.e-5-xtol)'), ['xtol']) d = myLeaf2('leaf2') ## d.add(y) q_dummy = Var(QuantSpec('q_notpar', '-2+sin(30)')) g_dummy = Fun(QuantSpec('qfunc_dummy', 'sin(q_notpar)*(10.e-5-xtol)'), ['xtol']) d.add([q_dummy, g_dummy]) # will delete these later d.add([q, g]) d2 = myLeaf2('leaf3') d2.add([q, g]) v = Var(QuantSpec('v', 'v * myfunc(rel,v) - sin(p)*t', 'RHSfuncSpec')) # p is a global parameter so this is ok in v f = Fun(QuantSpec('myfunc', '2.0+s-t+exp(p)'), ['s', 't']) # t is just a local argument here, so it won't clash with its # occurrence in v (which we'll see is declared as a global # when we call flattenSpec()). ipar = Par('ipar') z = Var('z[i]+v/(i*ipar)', 'z[i,0,5]', specType='RHSfuncSpec') a = myNode('sys1') a.add([f, p, y]) print(a.isDefined(True)) a.add(c) print(a.freeSymbols, a.isDefined(), a.isComplete()) a.add(d) print(a.freeSymbols, a.isDefined(), a.isComplete()) a.add(d2) print(a.freeSymbols, a.isDefined(), a.isComplete()) a.add(v) print("Added v") print(a.freeSymbols, a.isDefined(), a.isComplete()) print("Removed v") a.remove(v) print(a.freeSymbols, a.isDefined(), a.isComplete()) a.add([z, ipar]) print(a.freeSymbols, a.isDefined(), a.isComplete()) print("\na._registry --> ") print(a._registry) print("Re-added v") a.add(v) print(a.freeSymbols, a.isDefined(), a.isComplete()) print("\nv in a -->", v in a) print("\n") with pytest.raises(TypeError): a.compileFuncSpec() a.remove(['leaf2.qfunc_dummy', 'leaf2.q_notpar']) print("--------- sys1: funcSpecDict ---------------------") a.compileFuncSpec() info(a.funcSpecDict) print("\n\n------------- Flatten spec with unravelling\n") print("\n\ninfo(a.flattenSpec()) --> \n") info(a.flattenSpec(globalRefs=['t']), "Model specification") print("\n\n------------- Flatten spec with no unravelling\n") print("\n\ninfo(a.flattenSpec(False, globalRefs=['t'])) --> \n") info(a.flattenSpec(False, globalRefs=['t']), "Model specification") print("\n\nDemos for functions (results are strings):\n") h = f(p, -x) z = QuantSpec('zero', '0') print("h = f(p, -x) --> ", h) print("z = QuantSpec('zero','0') --> ", z) print("f(g(3)*1,h) --> ", f(g(3) * 1, h)) print("f(g(p),h) --> ", f(g(p), h)) print("f(g(p),0*h) --> ", f(g(p), 0 * h)) print("f(g(x),h+z) --> ", f(g(x), h + z)) # e is the math constant, but it doesn't evaluate to a float! print("f(g(x()),(e+h)/2) --> ", f(g(x()), (e + h) / 2)) print("f(g(x()),-h) --> ", f(g(x()), -h)) print("f(g(x()),.5-h+0) --> ", f(g(x()), .5 - h + 0)) print("Sin(pi+q) --> ", Sin(pi + q)) qsin = QuantSpec('qsin', 'zv-sin(beta)') assert str(qsin.eval()) == 'zv-sin(beta)' print("\n\nDemos for local scope evaluation and **:\n") print("q=Var('xv+1','qv')") print("x=Var('3','xv')") q = Var('xv+1', 'qv') x = Var('3', 'xv') globals()['x'] = x globals()['q'] = q sc1 = str(q.eval()) == '4' print("q.eval() == 4? ", sc1) assert sc1 print("a=x/q") a = x / q sc2 = str(a) == 'xv/qv' print("a == xv/qv? ", sc2) assert sc2 sc3 = str(a.eval()) == '0.75' print("a.eval() == 0.75? ", sc3) assert sc3 sc4 = str(a.eval(xv=5)) == '5/qv' print("a.eval(xv=5) == 5/q? ", sc4) assert sc4 sc5 = (str(a.eval(xv=5, qv=q())), '0.83333333333333337') assert_approx_equal(*sc5) print("assert_approx_equal(%s,%s)" % sc5) sc6 = (str(a.eval({'xv': 10, 'qv': q()})), '0.90909090909090906') print("assert_approx_equal(%s,%s)" % sc6) assert_approx_equal(*sc6) print("qs=QuantSpec('qsv','xsv+1')") print("xs=QuantSpec('xsv','3')") qs = QuantSpec('qsv', 'xsv+1') xs = QuantSpec('xsv', '3') globals()['qs'] = qs globals()['xs'] = xs qse = qs.eval() qt1 = str(qse) == '4' print("qs.eval() == 4? ", qt1) assert qt1 assert qse.tonumeric() == 4 print("asq = xs/qs") asq = xs / qs qt2 = str(asq) == '3/(xsv+1)' print("asq == 3/(xsv+1)? ", qt2) assert qt2 qt3 = str(asq.eval()) == '0.75' print("as.eval() == 0.75? ", qt3) assert qt3 ps = asq**xs print("ps = as**xs") qt4 = str(ps) == 'Pow(3/(xsv+1),3)' print("ps == Pow(3/(xsv+1),3)? ", qt4) assert qt4 qt5 = str(ps.eval()) == str(0.75**3) print("ps.eval() == 0.421875? ", qt5) assert qt5 print("sq=QuantSpec('sv','sin(xsv)')") print("s2q=QuantSpec('s2v','Sin(xv)')") sq = QuantSpec('sv', 'sin(xsv)') s2q = QuantSpec('s2v', 'Sin(xv)') print("sq.eval() --> ", sq.eval()) print("s2q.eval() --> ", s2q.eval()) assert sq.eval().tonumeric() == s2q.eval().tonumeric() assert sq[:] == ['sin', '(', 'xsv', ')'] print("\n\nDemos for multiple quantity definitions:\n") mp = QuantSpec('p', 'a + 3*z[4*i-2]') m = Var(mp, 'z[i,2,5]', specType='RHSfuncSpec') v = Var('3*z[i-1]+z4-i', 'z[i,1,5]', specType='RHSfuncSpec') print("mp=QuantSpec('p','a + 3*z[4*i-2]')") print("m=Var(mp, 'z[i,2,5]', specType='RHSfuncSpec')") print("v=Var('3*z[i-1]+z4-i', 'z[i,1,5]', specType='RHSfuncSpec')") print("v[3] -->", v[3]) assert str(v[3]) == 'z3' print("v.freeSymbols -->", v.freeSymbols) assert v.freeSymbols == ['z0'] print("\nModelSpec a already contains 'z0', which was defined as part of") print("a multiple quantity definition, so check that attempting to add") print("v to a results in an error ...") with pytest.raises(AttributeError): a.add(v) print("\nTest of eval method, e.g. on a function f(s,t)...") print("f.eval(s='1', t='t_val') -->", f.eval(s='1', t='t_val')) print("f.eval(s=1, t='t_val', p=0.5) -->", f.eval(s=1, t='t_val', p=0.5)) print("\nTesting convertPowers():") cp_tests = [ "phi1dot^m3", "1+phi1dot^m3*s", "phi1dot**m3", "1+phi1dot**m3*s", "sin(x^3)**4", "(2/3)^2.5", "3^cos(x)-pi", "3^(cos(x)-pi)", "2^(sin(y**p))" ] for spec in cp_tests: print(spec, " --> ", convertPowers(spec)) globals().pop('a') qc = QuantSpec('t', "a+coot+b/'coot'") assert str(qc.eval()) == 'a+coot+b/"coot"' coot = QuantSpec('coot', "1.05") globals()['coot'] = coot assert str(qc.eval()) == 'a+1.05+b/"coot"' print("\nTest of function calling with argument names that clash with") print("bound names inside the function.") x0 = Var('x0') x1 = Var('x1') x2 = Var('x2') F = Fun([x0 * x2, x0 * 5, x2**0.5], [x0, x1, x2], 'F') print("F=Fun([x0*x2,x0*5,x2**0.5], [x0,x1,x2], 'F')") print("F(3,2,Sin(x0))) = [3*Sin(x0),15,Pow(Sin(x0),0.5)] ...") print(" ... even though x0 is a bound name inside definition of F") assert str(F(3, 2, Sin(x0))) == '[3*Sin(x0),15,Pow(Sin(x0),0.5)]'
def test_vode_events_compare_with_euler(): """ Test terminal and non-terminal event testing with VODE integrator, including some comparisons and tests of Euler integrator too. """ DSargs = args(varspecs={'w': 'k*sin(2*t) - w'}, name='ODEtest') DSargs.tdomain = [0, 10] DSargs.pars = {'k': 1, 'p_thresh': -0.25} DSargs.algparams = {'init_step': 0.001, 'atol': 1e-12, 'rtol': 1e-13} DSargs.checklevel = 2 DSargs.ics = {'w': -1.0} DSargs.tdata = [0, 10] ev_args_nonterm = {'name': 'monitor', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': False, 'precise': True} thresh_ev_nonterm = Events.makeZeroCrossEvent('w', 0, ev_args_nonterm, varnames=['w']) ev_args_term = {'name': 'threshold', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': True, 'precise': True} thresh_ev_term = Events.makeZeroCrossEvent('w-p_thresh', -1, ev_args_term, varnames=['w'], parnames=['p_thresh']) DSargs.events = [thresh_ev_nonterm, thresh_ev_term] testODE = Vode_ODEsystem(DSargs) # diagnostics and other possible user-defined python functions # for python solvers only (currently only Euler) # def before_func(euler): # print(euler.algparams['init_step']) # # def after_func(euler): # print(euler._solver.y) # ##DSargs.user_func_beforestep = before_func ##DSargs.user_func_afterstep = after_func testODE_Euler = Euler_ODEsystem(DSargs) traj = testODE.compute('traj') traj2 = testODE_Euler.compute('traj') pts = traj.sample() testODE.diagnostics.showWarnings() mon_evs_found = testODE.getEvents('monitor') term_evs_found = testODE.getEvents('threshold') # test Euler assert allclose(array(testODE.getEventTimes('monitor')), array(traj2.getEventTimes('monitor')), atol=1e-3) assert all(traj.getEvents('monitor') == mon_evs_found) assert all(traj.getEventTimes('threshold') == testODE.getEventTimes('threshold')) term_evs_found.info() # Alternative way to extract events: they are labelled in the # pointset! These return dictionaries indexing into the pointset. mon_evs_dict = pts.labels.by_label['Event:monitor'] mon_ev_points = pts[sort(list(mon_evs_dict.keys()))] assert len(mon_evs_found) == len(mon_ev_points) == 2 assert all(mon_evs_found == mon_ev_points)
def test_vode_events_with_external_input(my_input): """ Test Vode_ODEsystem with events involving external inputs. Robert Clewley, September 2006. """ xs = ['x1', 'x2', 'x3'] ys = [0, 0.5, 1] fvarspecs = {"w": "k*w + pcwfn(sin(t)) + myauxfn1(t)*myauxfn2(w)", 'aux_wdouble': 'w*2 + globalindepvar(t)', 'aux_other': 'myauxfn1(2*t) + initcond(w)'} fnspecs = {'myauxfn1': (['t'], '2.5*cos(3*t)'), 'myauxfn2': (['w'], 'w/2'), 'pcwfn': makeMultilinearRegrFn('x', xs, ys)} # targetlang is optional if the default python target is desired DSargs = args(fnspecs=fnspecs, name='ODEtest') DSargs.varspecs = fvarspecs DSargs.tdomain = [0.1, 2.1] DSargs.pars = {'k': 2, 'a': -0.5, 'x1': -3, 'x2': 0.5, 'x3': 1.5} DSargs.vars = 'w' DSargs.inputs = {'in': my_input.variables['example_input']} DSargs.algparams = {'init_step': 0.01} DSargs.checklevel = 2 testODE = Vode_ODEsystem(DSargs) assert not testODE.defined testODE.set(ics={'w': 3.0}, tdata=[0.11, 2.1]) traj1 = testODE.compute('traj1') assert testODE.defined assert_almost_equal(traj1(0.5, 'w'), 8.9771499, 5) assert not testODE.diagnostics.hasWarnings() assert_almost_equal(traj1(0.2, ['aux_other']), 3.905819936, 5) print("\nNow adding a terminating co-ordinate threshold event") print(" and non-terminating timer event") # Show off the general-purpose, language-independent event creator: # 'makeZeroCrossEvent' ev_args_nonterm = {'name': 'monitor', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': False, 'precise': True} thresh_ev_nonterm = Events.makeZeroCrossEvent('in', 0, ev_args_nonterm, inputnames=['in']) # Now show use of the python-target specific creator: # 'makePythonStateZeroCrossEvent', which is also only # able to make events for state variable threshold crossings ev_args_term = {'name': 'threshold', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': True, 'precise': True} thresh_ev_term = Events.makePythonStateZeroCrossEvent('w', 20, 1, ev_args_term) testODE.eventstruct.add([thresh_ev_nonterm, thresh_ev_term]) print("Recomputing trajectory:") print("traj2 = testODE.compute('traj2')") traj2 = testODE.compute('traj2') print("\ntestODE.diagnostics.showWarnings() => ") testODE.diagnostics.showWarnings() print("\ntraj2.indepdomain.get() => ", traj2.indepdomain.get()) indep1 = traj2.indepdomain[1] assert indep1 < 1.17 and indep1 > 1.16 mon_evs_found = testODE.getEvents('monitor') assert len(mon_evs_found) == 1
def test_mapsystem(): # datafn provides an external input to the map system -- this could have # been from an experimentally measured signal datafn = Generator.InterpolateTable( {'name': 'datafunction', 'tdata': [-30., 0., 5., 10., 30., 100., 180., 400.], 'ics': {'x': [4., 1., 0., 1., 2., 3., 4., 8.]} } ) fvarspecs = { "w": "15-a*w + 2*x", "v": "1+k*w/10", 'aux_wdouble': 'w*2 + globalindepvar(t)', 'aux_other': 'myauxfn(2*t) + initcond(w)' } fnspecs = { 'myauxfn': (['t'], '.5*cos(3*t)'), } # targetlang is optional if default=python is OK DSargs = args(name='maptest', fnspecs=fnspecs) DSargs.varspecs = fvarspecs DSargs.tdomain = [0, 400] DSargs.pars = {'k': 2.1, 'a': -0.5} DSargs.vars = ['w', 'v'] DSargs.ttype = int # force independent variable type to be integer DSargs.checklevel = 2 DSargs.inputs = datafn.variables testmap = MapSystem(DSargs) assert testmap.pars == DSargs.pars assert not testmap.defined assert_array_almost_equal([0, 400], testmap.tdata) testmap.set( ics={'w': 3.0, 'v': 2.}, tdata=[10, 400]) assert_array_almost_equal([10, 400], testmap.tdata) assert_almost_equal(3.0, testmap.initialconditions['w']) assert_almost_equal(2.0, testmap.initialconditions['v']) traj1 = testmap.compute('traj1') assert testmap.defined p = Point({'coorddict': { 'aux_other': 3.34962540324, 'aux_wdouble': 98.1981323242, 'v': 8.64360778809, 'w': 36.5990661621, }}) assert_almost_equal(p.toarray(), traj1(25).toarray()) assert testmap.diagnostics.hasWarnings() assert_array_almost_equal(testmap.tdata, traj1.indepdomain.get()) assert_almost_equal(2.70076996547, traj1(30, 'aux_other')) ps = traj1(range(10, 40)) assert isinstance(ps, Pointset) assert ps._parameterized ev_args = {'name': 'threshold', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': True, 'precise': False} thresh_ev = Events.makePythonStateZeroCrossEvent('w', 58, 1, ev_args) testmap.eventstruct.add(thresh_ev) traj2 = testmap.compute('traj2') assert testmap.getEventTimes()['threshold'] == [347.] assert_array_almost_equal([10, 347], traj2.indepdomain.get()) assert testmap.diagnostics.hasWarnings() assert testmap.diagnostics.findWarnings(10) != [] assert_almost_equal(58.0, traj2(traj2.indepdomain[1], 'w'))
def test_bd_containment(): """Basic tests for boundary containment features.""" vals1 = linspace(-3, 3, 20) test_traj1 = numeric_to_traj([vals1], 'test', 'x', arange(len(vals1), dtype='d')) vals2 = array( [1., 1., 1.00000000001, 1.0000001, 1., 0.9999999999, 0.99999]) test_traj2 = numeric_to_traj([vals2], 'test', 'x', arange(len(vals2), dtype='d')) bc = boundary_containment_by_postproc('bc_test', description='Test BCs', pars=args(thresh=1, interior_dirn=-1, abseps=1e-4)) # Test whether test trajectory 1 remains below x_ref=1 # up to rounding error tolerance of 1e-4... assert not bc(test_traj1) # print "... failed at index", bc._find_idx() # print "\nbc.results -->\n" # print bc.results # Test whether test trajectory 2 remains below x_ref=1 # up to rounding error tolerance of 1e-4... assert bc(test_traj2) # Test whether initial condition lies within a domain # (includes transversality condition: derivative must point into interior # of domain): ic_inside = numeric_to_traj([[0.3], [-10.5]], 'test', ['x', 'dxdt'], 0.) ic_crit_ok = numeric_to_traj([[1], [-1.]], 'test', ['x', 'dxdt'], 0.) ic_crit_not_ok = numeric_to_traj([[1], [1.]], 'test', ['x', 'dxdt'], 0.) ic_outside = numeric_to_traj([[1.01], [-1.]], 'test', ['x', 'dxdt'], 0.) in_domain = domain_test('domain_test', pars=args(coordname='x', derivname='dxdt', interval=[-1, 1], verbose_level=3)) assert in_domain(ic_inside) assert in_domain(ic_crit_ok) assert not in_domain(ic_crit_not_ok) assert not in_domain(ic_outside) # Check that exterior IC failed at trajectory point index '0' with # in_domain._find_idx()==0 # ------------------------------------------------------------------ # Test for domain with rounding-error tolerated boundaries: in_domain_loose = domain_test('domain_test', pars=args(coordname='x', derivname='dxdt', interval=Interval('x', float, [-1, 1], abseps=1e-4), verbose_level=0)) ic_crit_round_ok = numeric_to_traj([[1.000001], [-1.]], 'test', ['x', 'dxdt'], 0.) ic_crit_round_not_ok = numeric_to_traj([[1.000001], [1.]], 'test', ['x', 'dxdt'], 0.) assert in_domain_loose(ic_inside) assert in_domain_loose(ic_crit_ok) assert not in_domain_loose(ic_crit_not_ok) assert not in_domain_loose(ic_outside) assert in_domain_loose(ic_crit_round_ok) assert not in_domain_loose(ic_crit_round_not_ok) zbd1 = domain_test('z', pars=args(coordname='z', derivname='D_z', interval=[0.0, 1.0], verbose_level=0)) zbd2 = domain_test('z', pars=args(coordname='z', derivname='D_z', interval=1.0, verbose_level=0)) ztraj = {} ztraj[0] = numeric_to_traj([[1], [0.437]], 'test', ['z', 'D_z'], 0) ztraj[1] = numeric_to_traj([[1], [1]], 'test', ['z', 'D_z'], 0) ztraj[2] = numeric_to_traj([[1.0], [1]], 'test', ['z', 'D_z'], 0) ztraj[3] = numeric_to_traj([[1], [1.0]], 'test', ['z', 'D_z'], 0) ztraj[4] = numeric_to_traj([[1], [1.0]], 'test', ['z', 'D_z'], 0) ztraj[5] = numeric_to_traj([[1.0], [5.0]], 'test', ['z', 'D_z'], 0) assert not zbd1(ztraj[0]) for i in range(1, 6): assert zbd2(ztraj[i])
""" Cross-channel coupling for a biophysical neural network. Example courtesy of Mark Olenik (Bristol University). """ from PyDSTool import Var, Exp, Par, Pow, args from PyDSTool.Toolbox.neuralcomp import voltage, \ ModelConstructor, makeSoma, channel from matplotlib import pyplot as plt v = Var(voltage) # Create placeholder structs to collect together related symbols # (not used internally by PyDSTool) NMDA = args() KCa = args() # Calcium concentration through nmda channels # Ca_nmda won't create a current but will be used for KCa.I Ca_nmda = args() Iapp = args() NMDA.g = Par(0.75, 'g') NMDA.erev = Par(0., 'erev') KCa.g = Par(0.0072, 'g') KCa.erev = Par(-80., 'erev') Ca_nmda.erev = Par(20., 'Ca_erev') Ca_nmda.rho = Par(0.0004, 'rho') Ca_nmda.delta = Par(0.002, 'delta') Iapp.amp = Par(0.0, 'amp') NMDA.p = Var('p') # nmda gating variable Ca_nmda.c = Var('c') # concentration
def dsargs(): timeData = linspace(0, 10, 20) sindata = sin(20 * timeData) xData = {'in': sindata} my_input = InterpolateTable({ 'tdata': timeData, 'ics': xData, 'name': 'interp1d', 'method': 'linear', 'checklevel': 1, 'abseps': 1e-5 }).compute('interp') fvarspecs = { "w": "k*w + sin(t) + myauxfn1(t)*myauxfn2(w)", 'aux_wdouble': 'w*2 + globalindepvar(t)', 'aux_other': 'myauxfn1(2*t) + initcond(w)' } fnspecs = {'myauxfn1': (['t'], '2.5*cos(3*t)'), 'myauxfn2': (['w'], 'w/2')} # targetlang is optional if the default python target is desired DSargs = args(fnspecs=fnspecs, name='event_test') DSargs.varspecs = fvarspecs DSargs.tdomain = [0.1, 2.1] DSargs.pars = {'k': 2, 'a': -0.5} DSargs.vars = 'w' DSargs.ics = {'w': 3} DSargs.inputs = {'in': my_input.variables['in']} DSargs.algparams = {'init_step': 0.01} DSargs.checklevel = 2 ev_args_nonterm = { 'name': 'monitor', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': False, 'precise': True } thresh_ev_nonterm = Events.makeZeroCrossEvent('in', 0, ev_args_nonterm, inputnames=['in'], targetlang='c') ev_args_term = { 'name': 'threshold', 'eventtol': 1e-4, 'eventdelay': 1e-5, 'starttime': 0, 'active': True, 'term': True, 'precise': True } thresh_ev_term = Events.makeZeroCrossEvent('w-20', 1, ev_args_term, ['w'], targetlang='c') DSargs.events = [thresh_ev_nonterm, thresh_ev_term] return DSargs
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 vdp = dst.Vode_ODEsystem(DSargs)
def prep_boxplots(data, xlabel_str, figname='', fignum=1, do_legend=1, means=1, xlegoff=0, ylegstep=1, ylegoff=0, spacing=None): spacing_actual = { 'width': 0.1, 'wgapfac': 0.75, 'markersize': 12, 'off_fac': 0.7, 'x_step': 0.9, # 9 * width 'x_off': 0, 'box_to_marker': 1.1, 'notch_size': 0.2} if spacing is not None: spacing_actual.update(spacing) width = spacing_actual['width'] wgapfac = spacing_actual['wgapfac'] markersize = spacing_actual['markersize'] off_fac = spacing_actual['off_fac'] x_step = spacing_actual['x_step'] x_off = spacing_actual['x_off'] box_to_marker = spacing_actual['box_to_marker'] notch_size = spacing_actual['notch_size'] n = len(data) x_min = -width*3.8 #3.75 x_max = (n-1)*x_step+width*4.5 #3.75 if n > 1: halfticks = arange(1,n)*x_step-x_step/2 figure(fignum) # work out ordering of data from 'pos' key order = {} # `pos` position runs from 1 to n, `ns` runs from 0 to n-1 ns = [] for k, v in data.iteritems(): order[v['pos']] = k ns.append(v['pos']-1) ns.sort() assert ns == range(n) maxD = 0 max_dimval_markers = 0 labels = [] for pos in range(n): name = order[pos+1] pde_name = 'PD_E-'+name if 'known_dim' in data[name]: if n == 1: kdx1 = x_min kdx2 = x_max else: if pos == 0: kdx1 = x_min kdx2 = halfticks[0] elif pos == n-1: kdx1 = halfticks[n-2] kdx2 = x_max else: kdx1 = halfticks[pos-1] kdx2 = halfticks[pos] plot([[kdx1], [kdx2]], [data[name]['known_dim'],data[name]['known_dim']], 'k', linewidth=1, zorder=0) slope_data = loadObjects(pde_name)[2] ds_mins = array(slope_data[:,0])#,shape=(len(slope_data),1)) ds_mins.shape=(len(slope_data),1) ds_maxs = array(slope_data[:,1])#,shape=(len(slope_data),1)) ds_maxs.shape=(len(slope_data),1) max_ds = max([max(ds_mins[:,0]),max(ds_maxs[:,0])]) if max_ds > maxD: maxD = max_ds # limits args are ineffective here boxplot(ds_mins,positions=[pos*x_step-width*wgapfac+x_off],whis=100, means=means,monochrome=True,notch=2,notchsize=notch_size, limits=(),widths=width,fill=1) boxplot(ds_maxs,positions=[pos*x_step+width*wgapfac+x_off],whis=100, means=means,monochrome=True,notch=2,notchsize=notch_size, limits=(),widths=width,fill=1) if pos == 0: fa = figure(fignum).axes[0] fa.hold(True) if means: ds_all_mean = (mean(ds_mins[:,0])+mean(ds_maxs[:,0]))/2 plot([pos*x_step+x_off], [ds_all_mean], 'k^', markersize=markersize-2) pca_x = pos*x_step-width*(wgapfac+box_to_marker)+x_off isomap_x = pos*x_step+width*(wgapfac+box_to_marker)+x_off pca_ds = {} isomap_ds = {} try: pca_data = data[name]['pca'] except KeyError: pca_data = [] pca_ds, max_dimval_pca, pca_used = plot_markers(pca_data, pca_x, 'PCA', symbol_map['pca'], -1, width, off_fac, markersize) if max_dimval_pca > maxD: maxD = max_dimval_pca if max_dimval_pca > max_dimval_markers: max_dimval_markers = max_dimval_pca try: isomap_data = data[name]['isomap'] except KeyError: isomap_data = [] isomap_ds, max_dimval_iso, isomap_used = plot_markers(isomap_data, isomap_x, 'Isomap', symbol_map['isomap'], 1, width, off_fac, markersize) if max_dimval_iso > maxD: maxD = max_dimval_iso if max_dimval_iso > max_dimval_markers: max_dimval_markers = max_dimval_iso labels.append(data[name]['label']) ## legend if do_legend: font = FontProperties() font.set_family('sans-serif') font.set_size(11) x_legend = x_min + 3*width/4 + xlegoff y_legend = maxD+ylegoff # pca legend for k, s in pca_used: plot_markers([(k,s,y_legend)], x_legend, 'Legend', symbol_map['pca'], 1, width, off_fac, markersize) if k == 'var': legstr = "%s=%d%%"%(k,s) else: legstr = "%s=%d"%(k,s) text(x_legend+3*width/4, y_legend-width*2., legstr, fontproperties=font) y_legend -= ylegstep # isomap legend isomap_leg_data = [] for k, s in isomap_used: if y_legend-width*2. <= max_dimval_markers + 2: y_legend = maxD+ylegoff x_legend += x_step #-width*.75 plot_markers([(k,s,y_legend)], x_legend, 'Legend', symbol_map['isomap'], 1, width, off_fac, markersize) ## if k == 'eps': ## kstr = '\\epsilon' ## else: ## kstr = k text(x_legend+3*width/4, y_legend-width*2., "%s=%d"%(k,s), fontproperties=font) y_legend -= ylegstep ## tidy up axes, etc. fa.set_xticks(arange(n)*x_step) if n>1: for h in range(n-1): plot([halfticks[h], halfticks[h]], [0,maxD+1+ylegoff], 'k:') fa.set_xticklabels(labels) fa.set_position([0.07, 0.11, 0.9, 0.85]) fa.set_xlim(x_min,x_max) fa.set_ylim(0,maxD+1+ylegoff) if xlabel_str != '': xlabel(r'$\rm{'+xlabel_str+r'}$',args(fontsize=20,fontname='Times')) ylabel(r'$\rm{Dimension}$',args(fontsize=20,fontname='Times')) draw() if figname != '': save_fig(fignum, figname)
# coding=utf-8 import PyDSTool as dst from PyDSTool import args import numpy as np from matplotlib import pyplot as plt DSargs = args(name='Lorenz map') DSargs.varspecs = { 'z': 'a+b*(z-c)**2', # note syntax for power 'zp': 'zp+log(abs(2*b*(z-c)))', 'L': 'zp/(t+1)' } # L is an auxiliary variable DSargs.tdomain = [0, 200] # Default range of independent variable 't' DSargs.pars = args( a=2.93, b=-1.44, c=1.85 ) # Using args() class to specify parameters with less syntax than a dictionary DSargs.vars = ['z', 'zp'] # Implicitly, then, L will be an auxiliary variable DSargs.ics = {'z': 2, 'zp': 0} # Initial conditions DSargs.ttype = int # force independent variable type to be integer (discrete time) lmap = dst.Generator.MapSystem( DSargs) # an instance of the 'Generator' class for maps. traj = lmap.compute('test') # compute a trajectory named 'test' pts = traj.sample() # sample the points from the trajectory # PyPlot commands plt.figure(1) plt.plot(pts['t'], pts['z'], 'ko-') plt.title(lmap.name)
def test_symbolic(): assert doneg('-x-y') == 'x+y' assert doneg('(-x-y)') == '(x+y)' assert doneg('-(-x-y)') == '(-x-y)' assert dosub('1', '-x-y') == '(1+x+y)' g2 = expr2fun('1-max([0., -a+b*x])', **{'a': 3, 'b': 1.5}) assert g2._args == ['x'] assert g2(1) == 1.0 assert g2(10) == -11.0 ds = {'a': 3, 'bbb': 1} f=expr2fun('1+ds["a"]') assert f._args == ['ds'] assert f(ds) == 4 f2=expr2fun('1+ds["a"]') assert f2(**{'ds':ds}) == 4 assert f2._args == ['ds'] g=expr2fun('1+ds["bbb"]', ds=ds) assert g() == 2 # g must be dynamic and not based on static eval of ds on initialization ds['bbb'] = 2 assert g._args == [] assert g() == 3 m = args(pars=copy(ds)) h = expr2fun('m.pars["a"]+c', m=m, c=1) assert h() == 4 assert h._args == [] h2 = expr2fun('1 + m.pars["a"]/2.', m=m) assert h2() == 2.5 assert h2._args == [] def func(x, y): return x * (y+1) m.func = func i = expr2fun('1+func(x,y)+b', func=m.func, b=0.5) assert 1+func(2,3)+0.5 == i(2,3) j = expr2fun('i(x,func(2,y))*2', i=i, func=m.func) assert j(1,0) == 9 fnspec = {'f': (['x','y'], 'x+1+2*y-a')} # a is expected to be in scope like a FuncSpec parameter # so can't use the above method of providing explicit functions k = expr2fun('-f(c,d)+b', f=fnspec['f'], b=0.5, a=1) assert k(1,2) == -4.5 s='1+a/(f(x,y)-3)+h(2)' t=s.replace('y','g(x,z)') u=t.replace('z','f(z)') r1, d1 = replaceCallsWithDummies(s, ['f','g','h']) r2, d2 = replaceCallsWithDummies(t, ['f','g','h']) r3, d3 = replaceCallsWithDummies(u, ['f','g','h']) assert r1 == '1+a/(__dummy1__-3)+__dummy2__' assert len(d1) == 2 assert r2 == '1+a/(__dummy2__-3)+__dummy3__' assert len(d2) == 3 assert r2 == '1+a/(__dummy2__-3)+__dummy3__' assert len(d3) == 4 ps = 'abs((HB9_fs_Vq-HB9_fs_V)*(-((HB9_fs_Lk_g*(HB9_fs_V-HB9_fs_Lk_vrev))+(-HB9_fs_Iapp_Ibias)+((HB9_fs_Na_g*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1-HB9_fs_K_n))*(HB9_fs_V-HB9_fs_Na_vrev))+(HB9_fs_K_g*HB9_fs_K_n*HB9_fs_K_n*HB9_fs_K_n*HB9_fs_K_n*(HB9_fs_V-HB9_fs_K_vrev))+(HB9_fs_isyn_g*(HB9_fs_V-HB9_fs_isyn_vrev))+(HB9_fs_esyn_g*(HB9_fs_V-HB9_fs_esyn_vrev)))/HB9_fs_C)+(HB9_fs_Knq-HB9_fs_K_n)*(((1.0/(1.0+exp((HB9_fs_V-HB9_fs_K_theta_n)/HB9_fs_K_k_n)))-HB9_fs_K_n)/(HB9_fs_K_taun_bar/cosh((HB9_fs_V-HB9_fs_K_theta_n)/(2*HB9_fs_K_k_n)))))/(sqrt(HB9_fs_Vq*HB9_fs_Vq+HB9_fs_Knq*HB9_fs_Knq)+sqrt(pow((-((HB9_fs_Lk_g*(HB9_fs_V-HB9_fs_Lk_vrev))+(-HB9_fs_Iapp_Ibias)+((HB9_fs_Na_g*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1.0/(1.0+exp((HB9_fs_V-HB9_fs_Na_theta_m)/HB9_fs_Na_k_m)))*(1-HB9_fs_K_n))*(HB9_fs_V-HB9_fs_Na_vrev))+(HB9_fs_K_g*HB9_fs_K_n*HB9_fs_K_n*HB9_fs_K_n*HB9_fs_K_n*(HB9_fs_V-HB9_fs_K_vrev))+(HB9_fs_isyn_g*(HB9_fs_V-HB9_fs_isyn_vrev))+(HB9_fs_esyn_g*(HB9_fs_V-HB9_fs_esyn_vrev)))/HB9_fs_C),2)+pow((((1.0/(1.0+exp((HB9_fs_V-HB9_fs_K_theta_n)/HB9_fs_K_k_n)))-HB9_fs_K_n)/(HB9_fs_K_taun_bar/cosh((HB9_fs_V-HB9_fs_K_theta_n)/(2*HB9_fs_K_k_n)))),2)))' parnames = ['HB9_fs_Vq', 'HB9_fs_Lk_g', 'HB9_fs_Lk_vrev', 'HB9_fs_Iapp_Ibias', 'HB9_fs_Na_g', 'HB9_fs_Na_theta_m', 'HB9_fs_Na_k_m', 'HB9_fs_Na_vrev', 'HB9_fs_K_g', 'HB9_fs_K_vrev', 'HB9_fs_isyn_g', 'HB9_fs_isyn_vrev', 'HB9_fs_esyn_g', 'HB9_fs_esyn_vrev', 'HB9_fs_C', 'HB9_fs_Knq', 'HB9_fs_K_theta_n', 'HB9_fs_K_k_n', 'HB9_fs_K_taun_bar'] varnames = ['HB9_fs_V', 'HB9_fs_K_n'] ps2 = convertPowers(ps, 'pow') for n in parnames+varnames: v=rand(1)[0]+1e-5 ps2=ps2.replace(n,str(v)) ps=ps.replace(n,str(v)) eps=eval(ps) eps2=eval(ps2) assert eps==eps2 a = Par('3.5', 'a') qa = Var(['a*3', 'b'], 'array_test') assert str(qa.eval(a=1)) == '[3,b]' # explicit exporting 'a' to globals to make this work as expected globals()['a'] = a assert str(qa.eval()) == '[10.5,b]' testq = QuantSpec('d', 'a') testq.simplify() assert testq() == 'a' assert str(testq.eval(a=3)) == '3' q = QuantSpec('q', 'zeta(yrel(y,initcond(y)),z)-1') print q.eval({}) assert 'initcond' in str(q.eval({})) q2=QuantSpec('q','Exp(-spikeTable+b)/k') assert 'spikeTable' in q2.freeSymbols # x = Var('x') # print x.isDefined() # xs = QuantSpec('x', '1-rel - 2*x + cos(z) + 2e10', 'RHSfuncSpec') # x.bindSpec(xs) # print x.isDefined(),"\n" x = Var(QuantSpec('x', '1-rel - 2*x + cos(z) + 2e10', 'RHSfuncSpec')) p = Par('p') az = Var(QuantSpec('z', 'myfunc(0,z)+abs(x+1)', 'RHSfuncSpec')) w = Var('x-1/w[i]', 'w[i,0,1]', specType='RHSfuncSpec') myLeaf1.compatibleContainers=(myNode,) myLeaf2.compatibleContainers=(myNode,) myNode.compatibleSubcomponents=(myLeaf1,myLeaf2) c = myLeaf1('leaf1') assert c.isDefined() == False c.add(x) print c.freeSymbols, c.isDefined() c.add(az) print c.freeSymbols, c.isDefined() c.add(w) print c.freeSymbols, c.isDefined() c.compileFuncSpec() print c.funcSpecDict empty_fn = Fun('1+exp(1)', [], 'dumb_fn') print empty_fn() q = Par('qpar') y = Var(QuantSpec('rel', 'v+p'), domain=[0,1]) g = Fun(QuantSpec('qfunc', '-1.e-05+sin(qpar)*(10.e-5-xtol)'), ['xtol']) d = myLeaf2('leaf2') ## d.add(y) q_dummy = Var(QuantSpec('q_notpar', '-2+sin(30)')) g_dummy = Fun(QuantSpec('qfunc_dummy', 'sin(q_notpar)*(10.e-5-xtol)'), ['xtol']) d.add([q_dummy, g_dummy]) # will delete these later d.add([q,g]) d2 = myLeaf2('leaf3') d2.add([q,g]) v = Var(QuantSpec('v', 'v * myfunc(rel,v) - sin(p)*t', 'RHSfuncSpec')) # p is a global parameter so this is ok in v f = Fun(QuantSpec('myfunc', '2.0+s-t+exp(p)'), ['s','t']) # t is just a local argument here, so it won't clash with its # occurrence in v (which we'll see is declared as a global # when we call flattenSpec()). ipar = Par('ipar') z = Var('z[i]+v/(i*ipar)', 'z[i,0,5]', specType='RHSfuncSpec') a = myNode('sys1') a.add([f,p,y]) print a.isDefined(True) a.add(c) print a.freeSymbols, a.isDefined(), a.isComplete() a.add(d) print a.freeSymbols, a.isDefined(), a.isComplete() a.add(d2) print a.freeSymbols, a.isDefined(), a.isComplete() a.add(v) print "Added v" print a.freeSymbols, a.isDefined(), a.isComplete() print "Removed v" a.remove(v) print a.freeSymbols, a.isDefined(), a.isComplete() a.add([z,ipar]) print a.freeSymbols, a.isDefined(), a.isComplete() print "\na._registry --> " print a._registry print "Re-added v" a.add(v) print a.freeSymbols, a.isDefined(), a.isComplete() print "\nv in a -->", v in a print "\n" with pytest.raises(TypeError): a.compileFuncSpec() a.remove(['leaf2.qfunc_dummy', 'leaf2.q_notpar']) print "--------- sys1: funcSpecDict ---------------------" a.compileFuncSpec() info(a.funcSpecDict) print "\n\n------------- Flatten spec with unravelling\n" print "\n\ninfo(a.flattenSpec()) --> \n" info(a.flattenSpec(globalRefs=['t']), "Model specification") print "\n\n------------- Flatten spec with no unravelling\n" print "\n\ninfo(a.flattenSpec(False, globalRefs=['t'])) --> \n" info(a.flattenSpec(False, globalRefs=['t']), "Model specification") print "\n\nDemos for functions (results are strings):\n" h = f(p, -x) z = QuantSpec('zero','0') print "h = f(p, -x) --> ", h print "z = QuantSpec('zero','0') --> ", z print "f(g(3)*1,h) --> ", f(g(3)*1,h) print "f(g(p),h) --> ", f(g(p),h) print "f(g(p),0*h) --> ", f(g(p),0*h) print "f(g(x),h+z) --> ", f(g(x),h+z) # e is the math constant, but it doesn't evaluate to a float! print "f(g(x()),(e+h)/2) --> ", f(g(x()),(e+h)/2) print "f(g(x()),-h) --> ", f(g(x()),-h) print "f(g(x()),.5-h+0) --> ", f(g(x()),.5-h+0) print "Sin(pi+q) --> ", Sin(pi+q) qsin=QuantSpec('qsin','zv-sin(beta)') assert str(qsin.eval()) == 'zv-sin(beta)' print "\n\nDemos for local scope evaluation and **:\n" print "q=Var('xv+1','qv')" print "x=Var('3','xv')" q=Var('xv+1','qv') x=Var('3','xv') globals()['x'] = x globals()['q'] = q sc1 = str(q.eval()) == '4' print "q.eval() == 4? ", sc1 assert sc1 print "a=x/q" a=x/q sc2 = str(a) == 'xv/qv' print "a == xv/qv? ", sc2 assert sc2 sc3 = str(a.eval())=='0.75' print "a.eval() == 0.75? ", sc3 assert sc3 sc4 = str(a.eval(xv=5))=='5/qv' print "a.eval(xv=5) == 5/q? ", sc4 assert sc4 sc5 = (str(a.eval(xv=5,qv=q())),'0.83333333333333337') assert_approx_equal(*sc5) print "assert_approx_equal(%s,%s)" % sc5 sc6 = (str(a.eval({'xv': 10, 'qv': q()})),'0.90909090909090906') print "assert_approx_equal(%s,%s)" % sc6 assert_approx_equal(*sc6) print "qs=QuantSpec('qsv','xsv+1')" print "xs=QuantSpec('xsv','3')" qs=QuantSpec('qsv','xsv+1') xs=QuantSpec('xsv','3') globals()['qs'] = qs globals()['xs'] = xs qse = qs.eval() qt1 = str(qse) == '4' print "qs.eval() == 4? ", qt1 assert qt1 assert qse.tonumeric() == 4 print "asq = xs/qs" asq=xs/qs qt2 = str(asq) == '3/(xsv+1)' print "asq == 3/(xsv+1)? ", qt2 assert qt2 qt3 = str(asq.eval()) == '0.75' print "as.eval() == 0.75? ", qt3 assert qt3 ps = asq**xs print "ps = as**xs" qt4 = str(ps) == 'Pow(3/(xsv+1),3)' print "ps == Pow(3/(xsv+1),3)? ", qt4 assert qt4 qt5 = str(ps.eval()) == str(0.75**3) print "ps.eval() == 0.421875? ", qt5 assert qt5 print "sq=QuantSpec('sv','sin(xsv)')" print "s2q=QuantSpec('s2v','Sin(xv)')" sq=QuantSpec('sv','sin(xsv)') s2q=QuantSpec('s2v','Sin(xv)') print "sq.eval() --> ", sq.eval() print "s2q.eval() --> ", s2q.eval() assert sq.eval().tonumeric() == s2q.eval().tonumeric() assert sq[:] == ['sin','(','xsv',')'] print "\n\nDemos for multiple quantity definitions:\n" mp=QuantSpec('p','a + 3*z[4*i-2]') m=Var(mp, 'z[i,2,5]', specType='RHSfuncSpec') v=Var('3*z[i-1]+z4-i', 'z[i,1,5]', specType='RHSfuncSpec') print "mp=QuantSpec('p','a + 3*z[4*i-2]')" print "m=Var(mp, 'z[i,2,5]', specType='RHSfuncSpec')" print "v=Var('3*z[i-1]+z4-i', 'z[i,1,5]', specType='RHSfuncSpec')" print "v[3] -->", v[3] assert str(v[3])=='z3' print "v.freeSymbols -->", v.freeSymbols assert v.freeSymbols == ['z0'] print "\nModelSpec a already contains 'z0', which was defined as part of" print "a multiple quantity definition, so check that attempting to add" print "v to a results in an error ..." with pytest.raises(AttributeError): a.add(v) print "\nTest of eval method, e.g. on a function f(s,t)..." print "f.eval(s='1', t='t_val') -->", f.eval(s='1', t='t_val') print "f.eval(s=1, t='t_val', p=0.5) -->", f.eval(s=1, t='t_val', p=0.5) print "\nTesting convertPowers():" cp_tests = ["phi1dot^m3", "1+phi1dot^m3*s", "phi1dot**m3", "1+phi1dot**m3*s", "sin(x^3)**4", "(2/3)^2.5", "3^cos(x)-pi", "3^(cos(x)-pi)", "2^(sin(y**p))"] for spec in cp_tests: print spec, " --> ", convertPowers(spec) globals().pop('a') qc=QuantSpec('t', "a+coot+b/'coot'") assert str(qc.eval()) == 'a+coot+b/"coot"' coot=QuantSpec('coot', "1.05") globals()['coot'] = coot assert str(qc.eval()) == 'a+1.05+b/"coot"' print "\nTest of function calling with argument names that clash with" print "bound names inside the function." x0=Var('x0') x1=Var('x1') x2=Var('x2') F=Fun([x0*x2,x0*5,x2**0.5], [x0,x1,x2], 'F') print "F=Fun([x0*x2,x0*5,x2**0.5], [x0,x1,x2], 'F')" print "F(3,2,Sin(x0))) = [3*Sin(x0),15,Pow(Sin(x0),0.5)] ..." print " ... even though x0 is a bound name inside definition of F" assert str(F(3,2,Sin(x0)))=='[3*Sin(x0),15,Pow(Sin(x0),0.5)]'
def test_discrete_domain(): disc_dom = domain_test('disc_dom_test', pars=args( coordname='x', derivname='dxdt', interval=1, verbose_level=3)) ic_disc = numeric_to_traj([[1], [0]], 'test', ['x', 'dxdt'], 0.) assert disc_dom(ic_disc)
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 vdp = dst.Vode_ODEsystem(DSargs) traj = vdp.compute('test_traj') pts = traj.sample() evs = traj.getEvents('event_x_a')