problem with Pow and symbolic definition

  • Alexei R. Brazhe

    Hi all,

    I have the latest version of PyDSTool. I encountered a problem with Symbolic definition of the ODE:

    The problem can be reproduced in the simple example of FitzHugh-Nagumo model:

    The code below works:

    I = Par(0.6, 'I')
    v = Var('v')
    w = Var('w')
    dv = v - v*v*v/3 - w + I # this works
    #dv = v - v**3/3 - w + I # this doesn't
    dw = 0.08 * (1.73*v - w + 0.5)
    DSargs2 = args(name="FH2",
                   pars = [I],
                   varspecs = {'v':dv, 'w':dw},
                   ics = {'v':0,'w':0})
    fh2 = Generator.Vode_ODEsystem(DSargs2)
    traj2 = fh2.compute('test')
    pts2 = traj2.sample(dt=0.1)
    plot(pts2['t'], pts2['v'], 'g')

    If I change
    use the line

    dv = v - v**3/3 - w + I

    instead of 

     dv = v - v*v*v/3 - w + I

    , I get the following error:

    ValueError: Undeclared or illegal token `Pow` in spec string `v`

    Using Pow(v,3) fails with the same problem as well.

    How can I fix this problem?

  • Rob Clewley

    Rob Clewley - 2013-07-16

    I didn't originally have support for the Symbolic objects going straight into an ODE argument list like that. They were primarily intended to be used as part of a ModelSpec/ModelConstructor approach to building the ODE, but honestly yours is a perfectly reasonable use case and should be expected to work! Fortunately, the addition to support this is trivial - not sure why it hasn't come up before! Here's the diff, or you can just fetch the updated from the bzr repository:

    === modified file 'Generator/'
    --- Generator/    2013-06-23 18:07:11 +0000
    +++ Generator/    2013-07-16 17:47:06 +0000
    @@ -4,7 +4,7 @@
     from allimports import *
     from PyDSTool.utils import *
     from PyDSTool.common import *
    -from PyDSTool.Symbolic import ensureStrArgDict, Quantity, QuantSpec
    +from PyDSTool.Symbolic import ensureStrArgDict, Quantity, QuantSpec, mathNameMap
     from PyDSTool.Trajectory import Trajectory
     from PyDSTool.parseUtils import symbolMapClass, readArgs
     from PyDSTool.Variable import Variable, iscontinuous
    @@ -30,6 +30,8 @@
     # -----------------------------------------------------------------------------
    +smap_mathnames = symbolMapClass(mathNameMap)
     class genDBClass(object):
         """This class keeps a record of which non-Python Generators have been
         created in a session. A single global instance of this class is created,
    @@ -264,14 +266,15 @@
                 self.foundKeys += 1
                 self._modeltag = None
    +        # the default map allows title-cased quantity objects like
    +        # Pow, Exp, etc. to be used in FuncSpec defs, but no need
    +        # to keep an inverse map of these below
    +        self._FScompatibleNames = smap_mathnames
             if 'FScompatibleNames' in kw:
                 sm = kw['FScompatibleNames']
    -            if sm is None:
    -                sm = symbolMapClass()
    -            self._FScompatibleNames = sm
    +            if sm is not None:
    +                self._FScompatibleNames.update(sm)
                 self.foundKeys += 1
    -        else:
    -            self._FScompatibleNames = symbolMapClass()
             if 'FScompatibleNamesInv' in kw:
                 sm = kw['FScompatibleNamesInv']
                 if sm is None:
  • Alexei R. Brazhe

    Thank you very much for the help! The code works now.

    The reason I didn't use the ModelSpec/ModelConstructor approach in the first place was that I'm a beginner with pydstool, and didn't find a clear manual, example or tutorial on that topic.

    There are examples in tests/  of course but they seemed rather advanced and used a compneuro toolbox, which is then another thing to learn before understanding the ModelSpec.

    May be I just overlooked and couldn't find a specific example or documentation on usage of the ModelSpec approach? I.e. something with step-by-step explanation of how one comes from  a bunch of Pars, Vars and Funs to  a ModelSpec, and later flattens it to a FuncSpec for a relatively simple model…


Log in to post a comment.