def computePPlaneObjects(gen, xvar, yvar, state=None, tol=1e-8, x_scale=1, max_step=1, subdomain=None, seed_pts=None, only_var=None, do_fps=True, num_x_points=100, num_y_points=100, strict_domains=True, with_jac=True, fast_vars=None, verbose=0, as_array=True): """ THIS VERSION IS HARDWIRED FOR USE WITH HODGKIN-HUXLEY MODELS. Compute basic phase plane objects (fixed points and nullclines) given certain parameters (system params will come from generator): gen Generator object from which to build nullcline from xvar Variable to be treated as independent yvar Variable to be treated as dependent fast_vars Any fast variables set to their adiabatic equilibrium values state Point or dictionary of state values tol Tolerance scalar max_step Maximum step in arc-length that nullcline computation will use subdomain Optional sub-domain of calculation (default to whole variable domains given by Generator) given as dictionary with [xlo, xhi] values for each x string key. seed_pts Seed points (list of dictionaries or Points) for any known nullcline points on either/both nullclines. only_var Select one variable to compute nullclines for only. do_fps Boolean switch (default True) to control computation of fixed points. num_x_points number of mesh points for x nullcline (default 100) num_y_points number of mesh points for y nullcline (default 100) strict_domains Boolean switch (default True) to control strict domain cropping of nullclines computed. with_jac Toggle to create Jacobian for use in fixed point and nullcline calculations (default True) verbose 0 = No text output; No graphic output 1 = Text output only 2 = Graphic output from this function only No grahphic output from functions called within 3+ = Pull output from subsequently lower-level functions called within as_array Optional Boolean to return nullclines as array data rather than fully interpolated spline nullcline objects (default True) """ ## ------------------------------------------------------------ ## JACOBIAN ## ------------------------------------------------------------ state = dict(state) # ensure updatable! yvarFS = gen._FScompatibleNames(yvar) xvarFS = gen._FScompatibleNames(xvar) stateFS = filteredDict(gen._FScompatibleNames(state), gen.funcspec.vars) varPars = filteredDict(stateFS, [xvarFS, yvarFS], neg=True) # TEMP #with_jac = False #do_fps = False if with_jac: jacFS, new_fnspecsFS = prepJacobian(gen.funcspec._initargs['varspecs'], [xvarFS, yvarFS], gen.funcspec._initargs['fnspecs']) scopeFS = gen.pars.copy() scopeFS.update(varPars) scopeFS.update(new_fnspecsFS) jac_fnFS = expr2fun(jacFS, ensure_args=['t'], **scopeFS) jac = gen._FScompatibleNamesInv(jacFS) scope = gen._FScompatibleNamesInv(gen.pars) scope.update(filteredDict(state, [xvar, yvar], neg=True)) new_fnspecs = {} # don't convert the new_fnspecs keys to . notation keymap = Symbolic.symbolMapClass(dict(zip(gen._FScompatibleNamesInv(new_fnspecsFS.keys()), new_fnspecsFS.keys()))) for k, v in new_fnspecsFS.items(): new_fnspecs[k] = Symbolic.mapNames(keymap, gen._FScompatibleNamesInv(v)) scope.update(new_fnspecs) jac_fn = expr2fun(jac, ensure_args=['t'], **scope) else: jac_fn = jac_fnFS = None ## ------------------------------------------------------------ ## FIXED POINTS ## ------------------------------------------------------------ if verbose >= 1: print("Computing fixed points") if subdomain is not None: stateFS.update(filteredDict(gen._FScompatibleNames(subdomain), (xvarFS, yvarFS))) if do_fps: # create Intervals to test inclusion in subdomain int_x = Interval(xvar, float, subdomain[xvar]) int_y = Interval(yvar, float, subdomain[yvar]) # temporarily overwriting state with xdomains from gen, # for fussy fsolve in find_fixedpoints for v in (xvarFS, yvarFS): stateFS[v] = gen.xdomain[v] fp_coords = find_fixedpoints(gen, n=10, jac=jac_fnFS, subdomain=stateFS, eps=tol) fps = [] for fp in fp_coords: if fp[xvar] in int_x and fp[yvar] in int_y: fps.append(fixedpoint_2D(gen, Point(fp), coords=[xvar, yvar], jac=jac_fn, description='', eps=1e-5)) # reset stateFS to use subdomain if subdomain is not None: stateFS.update(filteredDict(gen._FScompatibleNames(subdomain), (xvarFS, yvarFS))) else: fp_coords = None fps = [] ## ------------------------------------------------------------ ## NULLCLINES ## ------------------------------------------------------------ gen.set(ics=varPars) if verbose >= 1: print("Computing nullclines") assert 'V' in (xvar, yvar) if 'V' == xvar: #Vs = linspace(gen.xdomain['V'][0], gen.xdomain['V'][1], num_x_points) Vs = linspace(stateFS['V'][0], stateFS['V'][1], num_x_points) other = yvar otherFS = yvarFS os = linspace(stateFS[yvarFS][0], stateFS[yvarFS][1], num_y_points) n = num_y_points else: Vs = linspace(stateFS['V'][0], stateFS['V'][1], num_y_points) other = xvar otherFS = xvarFS os = linspace(stateFS[xvarFS][0], stateFS[xvarFS][1], num_x_points) n = num_x_points # yes, this gets recalc'd even if only_var is 'V' but this is a cheap calc compared to # nullcline object creation ofn = getattr(gen.auxfns, other.split('.')[0]+'_dssrt_fn_'+other.split('.')[1]+'inf') oinfs = [ofn(V) for V in Vs] fn_args = gen.funcspec._initargs['fnspecs']['dssrt_fn_Vinf'][0] # Dictionary to map Na_m into m, etc. model_vars = gen.query('vars') varnamemap = Symbolic.symbolMapClass(dict([(v,v.split('.')[-1]) \ for v in model_vars])) pt = filteredDict(Symbolic.mapNames(varnamemap, filteredDict(state, model_vars)), fn_args) vinfs = np.zeros((n,),float) oarg = varnamemap[other] if other not in model_vars and fast_vars is not None and other in fast_vars: oarg = oarg.split('.')[-1] os = oinfs if fast_vars is not None and 'Na.m' in fast_vars: pt['m'] = gen.auxfns.Na_dssrt_fn_minf(state['V']) for i, o in enumerate(os): pt[oarg] = o vinfs[i] = gen.auxfns.dssrt_fn_Vinf(**pt) if 'V' == xvar: nulls_x = array([vinfs, os]).T nulls_y = array([Vs, oinfs]).T else: nulls_y = array([os, vinfs]).T nulls_x = array([oinfs, Vs]).T if as_array: nullcX = nulls_x nullcY = nulls_y else: if only_var is None: nullcX = nullcline(xvar, yvar, nulls_x, x_relative_scale=x_scale) nullcY = nullcline(xvar, yvar, nulls_y, x_relative_scale=x_scale) elif only_var == xvar: nullcX = nullcline(xvar, yvar, nulls_x, x_relative_scale=x_scale) nullcY = None elif only_var == yvar: nullcX = None nullcY = nullcline(xvar, yvar, nulls_y, x_relative_scale=x_scale) else: raise ValueError("Invalid variable name for only_var: %s" % only_var) return {'nullcX': nullcX, 'nullcY': nullcY, 'fps': fps}
# n=3 uses three starting points in the domain to find nullcline parts, to an # accuracy of eps=1e-8, and a maximum step for the solver of 0.1 units. # The fixed points found is also provided to help locate the nullclines. if all_plots: nulls_x, nulls_y = pp.find_nullclines(ode_sys, 'phi', 'nu', n=3, eps=1e-6, max_step=0.1, fps=fp_coords) # plot the nullclines if all_plots: plt.plot(nulls_x[:,0], nulls_x[:,1], 'b') plt.plot(nulls_y[:,0], nulls_y[:,1], 'g') # plot the fixed points fps = [] for fp_coord in fp_coords: fps.append( pp.fixedpoint_2D(ode_sys, dst.Point(fp_coord)) ) saddle = fps[1] plotter.set_active_layer('fp_data') plot_PP_fp(saddle, 'fp_data', do_evecs=True, markersize=7) gui.buildPlotter2D((8,8), with_times=False) # magBound change ensures quicker determination of divergence during # manifold computations. max_pts must be larger when we are further # away from the fixed point. ode_sys.set(algparams={'magBound': 10000}) def plot_manifold(man, which, style='k.-'): for sgn in (-1, 1):
# let solution settle transient = fhn.compute('trans') fhn.set(ics=transient(10), tdata=[0,20]) # More of your code here # Your code here for the frequency plot 1/0 # comment this to apply phase plane picture to whatever # are the current parameters of FHN model ## Optional code fp_coord = pp.find_fixedpoints(fhn, n=25, eps=1e-6)[0] fp = pp.fixedpoint_2D(fhn, Point(fp_coord), eps=1e-6) nulls_x, nulls_y = pp.find_nullclines(fhn, 'x', 'y', n=3, eps=1e-6, max_step=0.1, fps=[fp_coord]) plt.figure(3) pp.plot_PP_fps(fp) plt.plot(nulls_x[:,0], nulls_x[:,1], 'b') plt.plot(nulls_y[:,0], nulls_y[:,1], 'g') plt.show()
} DSargs.ics = icdict vdp = Dopri_ODEsystem(DSargs) # Vode_ODEsystem vdp_e = Euler_ODEsystem(DSargs) traj = vdp.compute('v') pts = traj.sample() traj_e = vdp_e.compute('e') pts_e = traj_e.sample() plt.plot(pts['x'], pts['y'], 'k.-', linewidth=2) plt.plot(pts_e['x'], pts_e['y'], 'r.-', linewidth=2) fp_coord = pp.find_fixedpoints(vdp, n=4, eps=1e-8)[0] fp = pp.fixedpoint_2D(vdp, Point(fp_coord), eps=1e-8) nulls_x, nulls_y = pp.find_nullclines(vdp, 'x', 'y', n=3, eps=1e-8, max_step=0.1, fps=[fp_coord]) pp.plot_PP_fps(fp) plt.plot(nulls_x[:, 0], nulls_x[:, 1], 'b') plt.plot(nulls_y[:, 0], nulls_y[:, 1], 'g') plt.show() PC = ContClass(vdp)
# n=3 uses three starting points in the domain to find nullcline parts, to an # accuracy of eps=1e-8, and a maximum step for the solver of 0.1 units. # The fixed points found is also provided to help locate the nullclines. nulls_x, nulls_y = pp.find_nullclines(ode_sys, 'phi', 'nu', n=3, eps=1e-6, max_step=0.1, fps=fp_coords) # plot the fixed points fps = [] for fp_coord in fp_coords: fps.append(pp.fixedpoint_2D(ode_sys, dst.Point(fp_coord))) for fp_obj in fps: plot_PP_fps_custom(fp_obj, do_evecs=True, markersize=7, flip_coords=True) # plot the nullclines plt.plot(nulls_x[:, 0], nulls_x[:, 1], 'b') plt.plot(nulls_y[:, 0], nulls_y[:, 1], 'g') plt.axis('tight') plt.title('Phase plane') plt.xlabel('phi') plt.ylabel('nu') # you may not need to run these commands on your system plt.draw()
plt.plot(pts['t'], pts['y'], 'r', linewidth=2) # figure 2 is the phase plane plt.figure(2) # phase plane tools are in the Toolbox module from PyDSTool.Toolbox import phaseplane as pp # plot vector field, using a scale exponent to ensure arrows are well spaced # and sized pp.plot_PP_vf(vdp, 'x', 'y', scale_exp=-1) # only one fixed point, hence [0] at end. # n=4 uses three starting points in the domain to find any fixed points, to an # accuracy of eps=1e-8. fp_coord = pp.find_fixedpoints(vdp, n=4, eps=1e-8)[0] fp = pp.fixedpoint_2D(vdp, dst.Point(fp_coord), eps=1e-8) # n=3 uses three starting points in the domain to find nullcline parts, to an # accuracy of eps=1e-8, and a maximum step for the solver of 0.1 units. # The fixed point found is also provided to help locate the nullclines. nulls_x, nulls_y = pp.find_nullclines(vdp, 'x', 'y', n=3, eps=1e-8, max_step=0.1, fps=[fp_coord]) # plot the fixed point pp.plot_PP_fps(fp) # plot the nullclines plt.plot(nulls_x[:,0], nulls_x[:,1], 'b') plt.plot(nulls_y[:,0], nulls_y[:,1], 'g')
nulls_x, nulls_y = pp.find_nullclines(dmModel, 's1', 's2', n=3, \ eps=1e-8, max_step=0.01, fps=fp_coord) plot(nulls_x[:,0], nulls_x[:,1], 'b') plot(nulls_y[:,0], nulls_y[:,1], 'g') # compute the jacobian matrix jac, new_fnspecs = dst.prepJacobian(dmModel.funcspec._initargs['varspecs'], ['s1','s2'],dmModel.funcspec._initargs['fnspecs']) scope = dst.copy(dmModel.pars) scope.update(new_fnspecs) jac_fn = dst.expr2fun(jac, ensure_args=['t'],**scope) # add fixed points to the phase portrait for i in range(0,len(fp_coord)): fp = pp.fixedpoint_2D(dmModel, dst.Point(fp_coord[i]), jac = jac_fn, eps=1e-8) pp.plot_PP_fps(fp) # compute and plot projectories traj = dmModel.compute('trajectory1') pts = traj.sample() plot(pts['s1'], pts['s2'], 'r-o') xlabel('s_1') ylabel('s_2') title('Phase plane I1=0.035 nA, I2=0.035 nA') # savefig('pp2') # show()
# Your code here for the frequency plot Is = linspace(0, 2, 100) fs = [] for I in Is: fs.append(freq(I)) plt.figure(2) plt.plot(Is, fs, 'k.') plt.xlabel('I') plt.ylabel('frequencies') 1/0 # comment this to apply phase plane picture to whatever # are the current parameters of FHN model ## Optional code fp_coord = pp.find_fixedpoints(fhn, n=25, eps=1e-6)[0] fp = pp.fixedpoint_2D(fhn, Point(fp_coord), eps=1e-6) nulls_x, nulls_y = pp.find_nullclines(fhn, 'x', 'y', n=3, eps=1e-6, max_step=0.1, fps=[fp_coord]) plt.figure(3) pp.plot_PP_fps(fp) plt.plot(nulls_x[:,0], nulls_x[:,1], 'b') plt.plot(nulls_y[:,0], nulls_y[:,1], 'g') plt.show()