Beispiel #1
0
def test_wrapArgInCall():
    """Test: wrapping delimiters around call arguments"""

    fs = 'initcond(v,p)'
    assert 'initcond("v",p)' == wrapArgInCall(fs, 'initcond', '"')
    assert 'initcond(v,"p")' == wrapArgInCall(fs, 'initcond', '"', argnums=[1])
    assert 'initcond([v],[p])' == wrapArgInCall(fs, 'initcond', '[', ']', [0, 1])
Beispiel #2
0
def test_wrapArgInCall():
    """Test: wrapping delimiters around call arguments"""

    fs = 'initcond(v,p)'
    assert 'initcond("v",p)' == wrapArgInCall(fs, 'initcond', '"')
    assert 'initcond(v,"p")' == wrapArgInCall(fs, 'initcond', '"', argnums=[1])
    assert 'initcond([v],[p])' == wrapArgInCall(fs, 'initcond', '[', ']',
                                                [0, 1])
Beispiel #3
0
 def _generate_fun(self, funcname, reusestr, specnames, pardefines,
                   vardefines, inpdefines, parundefines, varundefines,
                   inpundefines, docodeinserts):
     sig = "void " + funcname + "(unsigned n_, unsigned np_, double t, double *Y_, " \
           + \
         "double *p_, double *f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_)"
     # specstr = sig + "{\n\n" + pardefines + vardefines + "\n"
     specstr = sig + "{" + pardefines + vardefines + inpundefines + "\n"
     if docodeinserts and self.opts['start']:
         specstr += self._format_user_code(self.opts['start']) + '\n'
     specstr += (len(reusestr) > 0) * "/* reused term definitions */\n" \
         + reusestr + "\n"
     auxdefs_parsed = {}
     # add function body
     for i in range(len(specnames)):
         xname = specnames[i]
         fbody = self.fspec.varspecs[xname]
         fbody_parsed = self._processSpecialC(fbody)
         if self.fspec.auxfns:
             fbody_parsed = addArgToCalls(fbody_parsed,
                                          list(self.fspec.auxfns.keys()),
                                          "p_, wk_, xv_")
             if 'initcond' in self.fspec.auxfns:
                 # convert 'initcond(x)' to 'initcond("x")' for
                 # compatibility with C syntax
                 fbody_parsed = wrapArgInCall(fbody_parsed,
                                              'initcond', '"')
         specstr += "f_[" + str(i) + "] = " + fbody_parsed + ";\n"
         auxdefs_parsed[xname] = fbody_parsed
     if docodeinserts and self.opts['end']:
         specstr += '\n' + self._format_user_code(self.opts['end'])
     specstr += "\n" + parundefines + varundefines + inpundefines + "}\n\n"
     self.fspec._auxdefs_parsed = auxdefs_parsed
     return (specstr, funcname)
Beispiel #4
0
 def _generate_fun(self, funcname, reusestr, specnames, pardefines,
                   vardefines, inpdefines, parundefines, varundefines,
                   inpundefines, docodeinserts):
     sig = "void " + funcname + "(unsigned n_, unsigned np_, double t, double *Y_, " \
           + \
         "double *p_, double *f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_)"
     # specstr = sig + "{\n\n" + pardefines + vardefines + "\n"
     specstr = sig + "{" + pardefines + vardefines + inpundefines + "\n"
     if docodeinserts and self.opts['start']:
         specstr += self._format_user_code(self.opts['start']) + '\n'
     specstr += (len(reusestr) > 0) * "/* reused term definitions */\n" \
         + reusestr + "\n"
     auxdefs_parsed = {}
     # add function body
     for i in range(len(specnames)):
         xname = specnames[i]
         fbody = self.fspec.varspecs[xname]
         fbody_parsed = self._processSpecialC(fbody)
         if self.fspec.auxfns:
             fbody_parsed = addArgToCalls(fbody_parsed,
                                          list(self.fspec.auxfns.keys()),
                                          "p_, wk_, xv_")
             if 'initcond' in self.fspec.auxfns:
                 # convert 'initcond(x)' to 'initcond("x")' for
                 # compatibility with C syntax
                 fbody_parsed = wrapArgInCall(fbody_parsed,
                                              'initcond', '"')
         specstr += "f_[" + str(i) + "] = " + fbody_parsed + ";\n"
         auxdefs_parsed[xname] = fbody_parsed
     if docodeinserts and self.opts['end']:
         specstr += '\n' + self._format_user_code(self.opts['end'])
     specstr += "\n" + parundefines + varundefines + inpundefines + "}\n\n"
     self.fspec._auxdefs_parsed = auxdefs_parsed
     return (specstr, funcname)
Beispiel #5
0
    def makeAutoLibSource(self, include=[]):
        """makeAutoLibSource generates the C source for the vector field specification.
        It should be called only once per vector field."""

        # Make vector field (and event) file for compilation
        assert isinstance(include, list), "includes must be in form of a list"
        # codes for library types (default is USERLIB, since compiler will look in standard library d
        STDLIB = 0
        USERLIB = 1
        libinclude = dict([('math.h', STDLIB), ('stdio.h', STDLIB), ('stdlib.h', STDLIB),
                           ('string.h', STDLIB), ('autovfield.h', USERLIB),
                           ('auto_c.h', USERLIB)])
        include_str = '#include "auto_f2c.h"\n' # This must come first
        for libstr, libtype in libinclude.items():
            if libtype == STDLIB:
                quoteleft = '<'
                quoteright = '>'
            else:
                quoteleft = '"'
                quoteright = '"'
            include_str += "#include " + quoteleft + libstr + quoteright + "\n"
        if include != []:
            assert isUniqueSeq(include), "list of library includes must not contain repeats"
            for libstr in include:
                if libstr in libinclude:
                    # don't repeat libraries
                    print("Warning: library '" + libstr + "' already appears in list"\
                          + " of imported libraries")
                else:
                    include_str += "#include " + '"' + libstr + '"\n'

        # f2c auto conventions (dirty trick!)
        #define_str = "\n#define double    doublereal\n#define int   integer\n\n"
        define_str = ""

        allfilestr = "/*  Vector field and other functions for Auto continuer.\n " \
            + "  This code was automatically generated by PyDSTool, but may be modified " \
            + "by hand. */\n\n" + include_str + define_str + """
double *gICs;
double **gBds;
double globalt0;

static double pi = 3.1415926535897931;

"""
        pardefines = ""
##        parundefines = ""
        vardefines = ""
##        varundefines = ""
        inpdefines = ""
##        inpundefines = ""
        # sorted version of var, par, and input names
        vnames = self.gensys._var_ixmap
        pnames = self.funcspec.pars
        inames = self.funcspec.inputs
        pnames.sort()
        inames.sort()
        for i in range(self.gensys.numpars):
            p = pnames[i]
            # add to defines (WATCH OUT FOR PERIOD _T!!!)
            if (i < 10):
                pardefines += self.funcspec._defstr+" "+p+"\tp_["+str(i)+"]\n"
            elif (i >= 10):
                pardefines += self.funcspec._defstr+" "+p+"\tp_["+str(i+40)+"]\n"
        # add period _T
        pardefines += self.funcspec._defstr+" _T\tp_[10]\n"
        for i in range(self.gensys.dimension):
            v = vnames[i]
            # add to defines
            vardefines += self.funcspec._defstr+" "+v+"\tY_["+str(i)+"]\n"
##            # add to undefines
##            varundefines += self.funcspec._undefstr+" "+v+"\n"
        for i in range(len(self.funcspec.inputs)):
            inp = inames[i]
            # add to defines
            inpdefines += self.funcspec._defstr+" "+inp+"\txv_["+str(i)+"]\n"
##            # add to undefines
##            inpundefines += self.funcspec._undefstr+" "+inp+"\n"
        allfilestr += "\n/* Variable, parameter, and input definitions: */ \n" \
            + pardefines + vardefines + inpdefines + "\n"
        # add signature for auxiliary functions
        if self.funcspec.auxfns:
            allfilestr += "\n"
            for finfo in self.funcspec.auxfns.values():
                allfilestr += finfo[1] + ";\n"
        allfilestr += "\nvoid auxvars(unsigned, unsigned, double, double*, double*, " \
            + "double*, unsigned, double*, unsigned, double*);\n" \
            + """void jacobian(unsigned, unsigned, double, double*, double*, double**, unsigned, double*, unsigned, double*);
void jacobianParam(unsigned, unsigned, double, double*, double*, double**, unsigned, double*, unsigned, double*);
"""
        if self.funcspec.auxvars == []:
            allfilestr += "int N_AUXVARS = 0;\n\n\n"
        else:
            allfilestr += "int N_AUXVARS = " + str(len(self.funcspec.auxvars)) \
                + ";\n\n\n"
        allfilestr += self.funcspec.spec[0] + "\n\n"

        if self.funcspec.auxfns:
            for fname, finfo in self.funcspec.auxfns.items():
                fbody = finfo[0]
                # subs _p into auxfn-to-auxfn calls (but not to the signature)
                fbody_parsed = addArgToCalls(fbody,
                                             list(self.funcspec.auxfns.keys()),
                                             "p_, wk_, xv_", notFirst=fname)
                if 'initcond' in self.funcspec.auxfns:
                    # convert 'initcond(x)' to 'initcond("x")' for
                    # compatibility with C syntax, but don't affect the
                    # function signature!
                    fbody_parsed = wrapArgInCall(fbody_parsed,
                                                 'initcond', '"', notFirst=True)
                allfilestr += "\n" + fbody_parsed + "\n\n"
        # add auxiliary variables (shell of the function always present)
        # add event functions
        allfilestr += self.funcspec.auxspec[0]
        # if jacobians or mass matrix not present, fill in dummy
        if not self.gensys.haveJacobian():
            allfilestr += """
void jacobian(unsigned n_, unsigned np_, double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {
}
"""
        if not self.gensys.haveJacobian_pars():
            allfilestr += """
void jacobianParam(unsigned n_, unsigned np_, double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {
}
""" #+ "\n/* Variable and parameter substitutions undefined:*/\n" + parundefines + varundefines + "\n"
        # write out C file
        vffile = os.path.join(self._compilation_tempdir, self._vf_file)
        try:
            file = open(vffile, 'w')
            #allfilestr = allfilestr.replace("double ","doublereal ")
            #allfilestr = allfilestr.replace("double*","doublereal *")
            #allfilestr = allfilestr.replace("double**","doublereal **")
            file.write(allfilestr)
            file.close()
        except IOError as e:
            print("Error opening file "+self._vf_file+" for writing")
            raise IOError(e)
Beispiel #6
0
    def generate_user_module(self, fspec, eventstruct, name="", include=None):
        include = include or []
        # Make vector field (and event) file for compilation
        assert isinstance(include, list), "includes must be in form of a list"
        # codes for library types (default is USERLIB, since compiler will look in standard library d
        STDLIB = 0
        USERLIB = 1
        libinclude = [
            ("math.h", STDLIB),
            ("Python.h", STDLIB),
            ("stdio.h", STDLIB),
            ("stdlib.h", STDLIB),
            ("string.h", STDLIB),
            ("events.h", USERLIB),
            ("maxmin.h", USERLIB),
            ("signum.h", USERLIB),
            ("vfield.h", USERLIB),
        ]
        include_str = ""
        for libstr, libtype in libinclude:
            if libtype == STDLIB:
                quoteleft = "<"
                quoteright = ">"
            else:
                quoteleft = '"'
                quoteright = '"'
            include_str += "#include " + quoteleft + libstr + quoteright + "\n"
        if include != []:
            incs = [libstr for libstr, _ in libinclude]
            assert isUniqueSeq(
                include
            ), "list of library includes must not contain repeats"
            for libstr in include:
                if libstr in incs:
                    # don't repeat libraries
                    print(
                        "Warning: library '%s' already appears in list" % libstr
                        + " of imported libraries"
                    )
                else:
                    include_str += "#include " + '"' + libstr + '"\n'
        allfilestr = (
            "/*  Vector field function and events for %s integrator.\n" % name
            + "  This code was automatically generated by PyDSTool, but may be modified "
            + "by hand. */\n\n"
            + include_str
            + """
extern double *gICs;
extern double **gBds;
extern double globalt0;

static double pi = 3.1415926535897931;

double signum(double x)
{
  if (x<0) {
    return -1;
  }
  else if (x==0) {
    return 0;
  }
  else if (x>0) {
    return 1;
  }
  else {
    /* must be that x is Not-a-Number */
    return x;
  }
}

"""
        )
        pardefines = ""
        vardefines = ""
        auxvardefines = ""
        inpdefines = ""
        for i, p in enumerate(fspec.pars):
            pardefines += fspec._defstr + " " + p + "\tp_[" + str(i) + "]\n"
        for i, v in enumerate(fspec.vars):
            vardefines += fspec._defstr + " " + v + "\tY_[" + str(i) + "]\n"
        for i, v in enumerate(fspec.auxvars):
            auxvardefines += (
                fspec._defstr + " " + v + "\t(" + fspec._auxdefs_parsed[v] + ")\n"
            )
        for i, inp in enumerate(fspec.inputs):
            inpdefines += fspec._defstr + " " + inp + "\txv_[" + str(i) + "]\n"

        allfilestr += (
            "\n/* Variable, aux variable, parameter, and input definitions: */ \n"
            + pardefines
            + vardefines
            + auxvardefines
            + inpdefines
            + "\n"
        )
        # preprocess event code
        allevs = ""
        eventNames = eventstruct.sortedEventNames()
        numevs = len(eventNames)
        for evname in eventNames:
            ev = eventstruct.events[evname]
            evfullfn = ""
            from PyDSTool.Events import LowLevelEvent

            assert isinstance(ev, LowLevelEvent), (
                "Radau can only " "accept low level events"
            )
            evsig = ev._LLreturnstr + " " + ev.name + ev._LLargstr
            assert ev._LLfuncstr.index(";") > 1, (
                "Event function code "
                "error: Have you included a ';' character at the end of"
                "your 'return' statement?"
            )
            fbody = ev._LLfuncstr
            # check fbody for calls to user-defined aux fns
            # and add hidden p argument
            if fspec.auxfns:
                fbody_parsed = addArgToCalls(
                    fbody, list(fspec.auxfns.keys()), "p_, wk_, xv_"
                )
                if "initcond" in fspec.auxfns:
                    # convert 'initcond(x)' to 'initcond("x")' for
                    # compatibility with C syntax
                    fbody_parsed = wrapArgInCall(fbody_parsed, "initcond", '"')
            else:
                fbody_parsed = fbody
            evbody = " {\n" + fbody_parsed + "\n}\n\n"
            allevs += evsig + evbody
            allfilestr += evsig + ";\n"
        # add signature for auxiliary functions
        if fspec.auxfns:
            allfilestr += "\n"
            for finfo in sorted(fspec.auxfns.values()):
                allfilestr += finfo[1] + ";\n"
        assignEvBody = "".join(
            ["events[%d] = &%s;\n" % (i, name) for i, name in enumerate(eventNames)]
        )
        allfilestr += (
            "\nint N_EVENTS = "
            + str(numevs)
            + ";\nvoid assignEvents("
            + "EvFunType *events){\n "
            + assignEvBody
            + "\n}\n\nvoid auxvars(unsigned, unsigned, double, double*, double*, "
            + "double*, unsigned, double*, unsigned, double*);\n"
            + """void jacobian(unsigned, unsigned, double, double*, double*, double**, unsigned, double*, unsigned, double*);
void jacobianParam(unsigned, unsigned, double, double*, double*, double**, unsigned, double*, unsigned, double*);
"""
        )
        allfilestr += "int N_AUXVARS = %d;\n\n\n" % len(fspec.auxvars)
        allfilestr += "int N_EXTINPUTS = %d;\n\n\n" % len(fspec.inputs)
        allfilestr += fspec.spec[0] + "\n\n"
        if fspec.auxfns:
            for fname, finfo in sortedDictItems(fspec.auxfns):
                fbody = finfo[0]
                # subs _p into auxfn-to-auxfn calls (but not to the signature)
                fbody_parsed = addArgToCalls(
                    fbody, list(fspec.auxfns.keys()), "p_, wk_, xv_", notFirst=fname
                )
                if "initcond" in fspec.auxfns:
                    # convert 'initcond(x)' to 'initcond("x")' for
                    # compatibility with C syntax, but don't affect the
                    # function signature!
                    fbody_parsed = wrapArgInCall(
                        fbody_parsed, "initcond", '"', notFirst=True
                    )
                allfilestr += "\n" + fbody_parsed + "\n\n"
        # add auxiliary variables (shell of the function always present)
        # add event functions
        allfilestr += fspec.auxspec[0] + allevs
        # if jacobians or mass matrix not present, fill in dummy
        if "massMatrix" not in fspec.auxfns:
            allfilestr += """
void massMatrix(unsigned n_, unsigned np_, double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {
}
"""

        if "Jacobian" not in fspec.auxfns:
            allfilestr += """
void jacobian(unsigned n_, unsigned np_, double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {
}
"""
        if "Jacobian_pars" not in fspec.auxfns:
            allfilestr += """
void jacobianParam(unsigned n_, unsigned np_, double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {
}
"""
        return allfilestr
Beispiel #7
0
    def makeAutoLibSource(self, include=[]):
        """makeAutoLibSource generates the C source for the vector field specification.
        It should be called only once per vector field."""

        # Make vector field (and event) file for compilation
        assert isinstance(include, list), "includes must be in form of a list"
        # codes for library types (default is USERLIB, since compiler will look in standard library d
        STDLIB = 0
        USERLIB = 1
        libinclude = dict([('math.h', STDLIB), ('stdio.h', STDLIB),
                           ('stdlib.h', STDLIB), ('string.h', STDLIB),
                           ('autovfield.h', USERLIB), ('auto_c.h', USERLIB)])
        include_str = '#include "auto_f2c.h"\n'  # This must come first
        for libstr, libtype in libinclude.items():
            if libtype == STDLIB:
                quoteleft = '<'
                quoteright = '>'
            else:
                quoteleft = '"'
                quoteright = '"'
            include_str += "#include " + quoteleft + libstr + quoteright + "\n"
        if include != []:
            assert isUniqueSeq(
                include), "list of library includes must not contain repeats"
            for libstr in include:
                if libstr in libinclude:
                    # don't repeat libraries
                    print("Warning: library '" + libstr + "' already appears in list"\
                          + " of imported libraries")
                else:
                    include_str += "#include " + '"' + libstr + '"\n'

        # f2c auto conventions (dirty trick!)
        #define_str = "\n#define double    doublereal\n#define int   integer\n\n"
        define_str = ""

        allfilestr = "/*  Vector field and other functions for Auto continuer.\n " \
            + "  This code was automatically generated by PyDSTool, but may be modified " \
            + "by hand. */\n\n" + include_str + define_str + """
double *gICs;
double **gBds;
double globalt0;

static double pi = 3.1415926535897931;

"""
        pardefines = ""
        ##        parundefines = ""
        vardefines = ""
        ##        varundefines = ""
        inpdefines = ""
        ##        inpundefines = ""
        # sorted version of var, par, and input names
        vnames = self.gensys._var_ixmap
        pnames = self.funcspec.pars
        inames = self.funcspec.inputs
        pnames.sort()
        inames.sort()
        for i in range(self.gensys.numpars):
            p = pnames[i]
            # add to defines (WATCH OUT FOR PERIOD _T!!!)
            if (i < 10):
                pardefines += self.funcspec._defstr + " " + p + "\tp_[" + str(
                    i) + "]\n"
            elif (i >= 10):
                pardefines += self.funcspec._defstr + " " + p + "\tp_[" + str(
                    i + 40) + "]\n"
        # add period _T
        pardefines += self.funcspec._defstr + " _T\tp_[10]\n"
        for i in range(self.gensys.dimension):
            v = vnames[i]
            # add to defines
            vardefines += self.funcspec._defstr + " " + v + "\tY_[" + str(
                i) + "]\n"
##            # add to undefines
##            varundefines += self.funcspec._undefstr+" "+v+"\n"
        for i in range(len(self.funcspec.inputs)):
            inp = inames[i]
            # add to defines
            inpdefines += self.funcspec._defstr + " " + inp + "\txv_[" + str(
                i) + "]\n"
##            # add to undefines
##            inpundefines += self.funcspec._undefstr+" "+inp+"\n"
        allfilestr += "\n/* Variable, parameter, and input definitions: */ \n" \
            + pardefines + vardefines + inpdefines + "\n"
        # add signature for auxiliary functions
        if self.funcspec.auxfns:
            allfilestr += "\n"
            for finfo in self.funcspec.auxfns.values():
                allfilestr += finfo[1] + ";\n"
        allfilestr += "\nvoid auxvars(unsigned, unsigned, double, double*, double*, " \
            + "double*, unsigned, double*, unsigned, double*);\n" \
            + """void jacobian(unsigned, unsigned, double, double*, double*, double**, unsigned, double*, unsigned, double*);
void jacobianParam(unsigned, unsigned, double, double*, double*, double**, unsigned, double*, unsigned, double*);
"""
        if self.funcspec.auxvars == []:
            allfilestr += "int N_AUXVARS = 0;\n\n\n"
        else:
            allfilestr += "int N_AUXVARS = " + str(len(self.funcspec.auxvars)) \
                + ";\n\n\n"
        allfilestr += self.funcspec.spec[0] + "\n\n"

        if self.funcspec.auxfns:
            for fname, finfo in self.funcspec.auxfns.items():
                fbody = finfo[0]
                # subs _p into auxfn-to-auxfn calls (but not to the signature)
                fbody_parsed = addArgToCalls(fbody,
                                             list(self.funcspec.auxfns.keys()),
                                             "p_, wk_, xv_",
                                             notFirst=fname)
                if 'initcond' in self.funcspec.auxfns:
                    # convert 'initcond(x)' to 'initcond("x")' for
                    # compatibility with C syntax, but don't affect the
                    # function signature!
                    fbody_parsed = wrapArgInCall(fbody_parsed,
                                                 'initcond',
                                                 '"',
                                                 notFirst=True)
                allfilestr += "\n" + fbody_parsed + "\n\n"
        # add auxiliary variables (shell of the function always present)
        # add event functions
        allfilestr += self.funcspec.auxspec[0]
        # if jacobians or mass matrix not present, fill in dummy
        if not self.gensys.haveJacobian():
            allfilestr += """
void jacobian(unsigned n_, unsigned np_, double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {
}
"""
        if not self.gensys.haveJacobian_pars():
            allfilestr += """
void jacobianParam(unsigned n_, unsigned np_, double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {
}
""" #+ "\n/* Variable and parameter substitutions undefined:*/\n" + parundefines + varundefines + "\n"
        # write out C file
        vffile = os.path.join(self._compilation_tempdir, self._vf_file)
        try:
            file = open(vffile, 'w')
            #allfilestr = allfilestr.replace("double ","doublereal ")
            #allfilestr = allfilestr.replace("double*","doublereal *")
            #allfilestr = allfilestr.replace("double**","doublereal **")
            file.write(allfilestr)
            file.close()
        except IOError as e:
            print("Error opening file " + self._vf_file + " for writing")
            raise IOError(e)
Beispiel #8
0
def test_combo_wrapArgInCall_and_addArgToCalls():
    """Test combo of addArgToCalls and wrapArgInCall with embedded calls"""

    fs = "1/zeta(y_rel(y,initcond(y)+initcond(z)),z-initcond(x))+zeta(0.)"
    fs_p = addArgToCalls(fs, ['zeta', 'y_rel', 'initcond', 'nothing'], "p")
    assert '1/zeta(y_rel(y,initcond(y, p)+initcond(z, p), p),z-initcond(x, p), p)+zeta(0., p)' == fs_p
    assert '1/zeta(y_rel(y,initcond("y", p)+initcond("z", p), p),z-initcond("x", p), p)+zeta(0., p)' == wrapArgInCall(
        fs_p, 'initcond', '"')
Beispiel #9
0
    def generate_user_module(self, fspec, eventstruct, name='', include=None):
        include = include or []
        # Make vector field (and event) file for compilation
        assert isinstance(include, list), "includes must be in form of a list"
        # codes for library types (default is USERLIB, since compiler will look in standard library d
        STDLIB = 0
        USERLIB = 1
        libinclude = [
            ('math.h', STDLIB),
            ('Python.h', STDLIB),
            ('stdio.h', STDLIB),
            ('stdlib.h', STDLIB),
            ('string.h', STDLIB),
            ('events.h', USERLIB),
            ('maxmin.h', USERLIB),
            ('signum.h', USERLIB),
            ('vfield.h', USERLIB),
        ]
        include_str = ''
        for libstr, libtype in libinclude:
            if libtype == STDLIB:
                quoteleft = '<'
                quoteright = '>'
            else:
                quoteleft = '"'
                quoteright = '"'
            include_str += "#include " + quoteleft + libstr + quoteright + "\n"
        if include != []:
            incs = [libstr for libstr, _ in libinclude]
            assert isUniqueSeq(include), "list of library includes must not contain repeats"
            for libstr in include:
                if libstr in incs:
                    # don't repeat libraries
                    print("Warning: library '%s' already appears in list" % libstr\
                          + " of imported libraries")
                else:
                    include_str += "#include " + '"' + libstr + '"\n'
        allfilestr = "/*  Vector field function and events for %s integrator.\n" % name \
            + "  This code was automatically generated by PyDSTool, but may be modified " \
            + "by hand. */\n\n" + include_str + """
extern double *gICs;
extern double **gBds;
extern double globalt0;

static double pi = 3.1415926535897931;

double signum(double x)
{
  if (x<0) {
    return -1;
  }
  else if (x==0) {
    return 0;
  }
  else if (x>0) {
    return 1;
  }
  else {
    /* must be that x is Not-a-Number */
    return x;
  }
}

"""
        pardefines = ""
        vardefines = ""
        auxvardefines = ""
        inpdefines = ""
        for i, p in enumerate(fspec.pars):
            pardefines += fspec._defstr + " " + p + "\tp_[" + str(i) + "]\n"
        for i, v in enumerate(fspec.vars):
            vardefines += fspec._defstr + " " + v + "\tY_[" + str(i) + "]\n"
        for i, v in enumerate(fspec.auxvars):
            auxvardefines += fspec._defstr+" "+v+"\t("+fspec._auxdefs_parsed[v]+")\n"
        for i, inp in enumerate(fspec.inputs):
            inpdefines += fspec._defstr + " " + inp + "\txv_[" + str(i) + "]\n"

        allfilestr += "\n/* Variable, aux variable, parameter, and input definitions: */ \n" \
                      + pardefines + vardefines + auxvardefines + inpdefines + "\n"
        # preprocess event code
        allevs = ""
        eventNames = eventstruct.sortedEventNames()
        numevs = len(eventNames)
        for evname in eventNames:
            ev = eventstruct.events[evname]
            evfullfn = ""
            from PyDSTool.Events import LowLevelEvent
            assert isinstance(ev, LowLevelEvent), ("Radau can only "
                                                "accept low level events")
            evsig = ev._LLreturnstr + " " + ev.name + ev._LLargstr
            assert ev._LLfuncstr.index(';') > 1, ("Event function code "
                    "error: Have you included a ';' character at the end of"
                                            "your 'return' statement?")
            fbody = ev._LLfuncstr
            # check fbody for calls to user-defined aux fns
            # and add hidden p argument
            if fspec.auxfns:
                fbody_parsed = addArgToCalls(fbody,
                                        list(fspec.auxfns.keys()),
                                        "p_, wk_, xv_")
                if 'initcond' in fspec.auxfns:
                    # convert 'initcond(x)' to 'initcond("x")' for
                    # compatibility with C syntax
                    fbody_parsed = wrapArgInCall(fbody_parsed,
                                        'initcond', '"')
            else:
                fbody_parsed = fbody
            evbody = " {\n" + fbody_parsed + "\n}\n\n"
            allevs += evsig + evbody
            allfilestr += evsig + ";\n"
        # add signature for auxiliary functions
        if fspec.auxfns:
            allfilestr += "\n"
            for finfo in sorted(fspec.auxfns.values()):
                allfilestr += finfo[1] + ";\n"
        assignEvBody = ''.join([
            "events[%d] = &%s;\n" % (i, name) for i, name in enumerate(eventNames)
        ])
        allfilestr += "\nint N_EVENTS = " + str(numevs) + ";\nvoid assignEvents(" \
              + "EvFunType *events){\n " + assignEvBody  \
              + "\n}\n\nvoid auxvars(unsigned, unsigned, double, double*, double*, " \
              + "double*, unsigned, double*, unsigned, double*);\n" \
              + """void jacobian(unsigned, unsigned, double, double*, double*, double**, unsigned, double*, unsigned, double*);
void jacobianParam(unsigned, unsigned, double, double*, double*, double**, unsigned, double*, unsigned, double*);
"""
        allfilestr += "int N_AUXVARS = %d;\n\n\n" % len(fspec.auxvars)
        allfilestr += "int N_EXTINPUTS = %d;\n\n\n" % len(fspec.inputs)
        allfilestr += fspec.spec[0] + "\n\n"
        if fspec.auxfns:
            for fname, finfo in sortedDictItems(fspec.auxfns):
                fbody = finfo[0]
                # subs _p into auxfn-to-auxfn calls (but not to the signature)
                fbody_parsed = addArgToCalls(fbody,
                                        list(fspec.auxfns.keys()),
                                        "p_, wk_, xv_", notFirst=fname)
                if 'initcond' in fspec.auxfns:
                    # convert 'initcond(x)' to 'initcond("x")' for
                    # compatibility with C syntax, but don't affect the
                    # function signature!
                    fbody_parsed = wrapArgInCall(fbody_parsed,
                                        'initcond', '"', notFirst=True)
                allfilestr += "\n" + fbody_parsed + "\n\n"
        # add auxiliary variables (shell of the function always present)
        # add event functions
        allfilestr += fspec.auxspec[0] + allevs
        # if jacobians or mass matrix not present, fill in dummy
        if 'massMatrix' not in fspec.auxfns:
            allfilestr += """
void massMatrix(unsigned n_, unsigned np_, double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {
}
"""

        if 'Jacobian' not in fspec.auxfns:
            allfilestr += """
void jacobian(unsigned n_, unsigned np_, double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {
}
"""
        if 'Jacobian_pars' not in fspec.auxfns:
            allfilestr += """
void jacobianParam(unsigned n_, unsigned np_, double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_) {
}
"""
        return allfilestr
Beispiel #10
0
def test_combo_wrapArgInCall_and_addArgToCalls():
    """Test combo of addArgToCalls and wrapArgInCall with embedded calls"""

    fs = "1/zeta(y_rel(y,initcond(y)+initcond(z)),z-initcond(x))+zeta(0.)"
    fs_p = addArgToCalls(fs, ['zeta', 'y_rel', 'initcond', 'nothing'], "p")
    assert '1/zeta(y_rel(y,initcond(y, p)+initcond(z, p), p),z-initcond(x, p), p)+zeta(0., p)' == fs_p
    assert '1/zeta(y_rel(y,initcond("y", p)+initcond("z", p), p),z-initcond("x", p), p)+zeta(0., p)' == wrapArgInCall(fs_p, 'initcond', '"')