def generate_aux(self): auxnames = list(self.fspec._auxfnspecs.keys()) auxfns = {} # parameter and variable definitions # sorted version of var and par names sorted version of par # names (vars not #define'd in aux functions unless Jacobian) vnames = self.fspec.vars pnames = self.fspec.pars vnames.sort() pnames.sort() for auxname in auxnames: assert auxname not in ["auxvars", "vfieldfunc"], ( "auxiliary function name '" + auxname + "' clashes with internal" " names" ) # must add parameter argument so that we can name # parameters inside the functions! this would either # require all calls to include this argument (yuk!) or # else we add these extra parameters automatically to # every call found in the .c code (as is done currently. # this is still an untidy solution, but there you go...) for auxname in auxnames: auxspec = self.fspec._auxfnspecs[auxname] assert len(auxspec) == 2, "auxspec tuple must be of length 2" if not isinstance(auxspec[0], list): print("Found type " + type(auxspec[0])) print("Containing: " + auxspec[0]) raise TypeError("aux function arguments " "must be given as a list") if not isinstance(auxspec[1], str): print("Found type " + type(auxspec[1])) print("Containing: " + auxspec[1]) raise TypeError( "aux function specification " "must be a string of the function code" ) # Process Jacobian functions specially, if present if auxname == "Jacobian": sig = "void jacobian(" if not compareList(auxspec[0], ["t"] + self.fspec.vars): print(["t"] + self.fspec.vars) print("Auxspec =" + auxspec[0]) raise ValueError("Invalid argument list given in Jacobian.") if any([pt in auxspec[1] for pt in ("^", "**")]): auxstr = convertPowers(auxspec[1], "pow") else: auxstr = auxspec[1] parlist = "unsigned n_, unsigned np_, double t, double *Y_," ismat = True sig += ( parlist + " double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_)" ) specvars = self.fspec.vars specvars.sort() n = len(specvars) m = n specdict_temp = {}.fromkeys(specvars) if m == 1: assert ( "[" not in auxstr ), "'[' character invalid in Jacobian for 1D system" assert ( "]" not in auxstr ), "']' character invalid in Jacobian for 1D system" specdict_temp[specvars[0]] = auxstr else: specdict_temp = parseMatrixStrToDictStr(auxstr, specvars) reusestr, body_processed_dict = self._processReusedC( specvars, specdict_temp ) specdict = {}.fromkeys(specvars) for specname in specvars: temp = body_processed_dict[specname] specdict[specname] = splitargs( temp.replace("[", "").replace("]", "") ) body_processed = "" # C integrators expect column-major matrices for col in range(n): for row in range(m): try: body_processed += ( "f_[" + str(col) + "][" + str(row) + "] = " + specdict[specvars[row]][col] + ";\n" ) except IndexError: raise ValueError("Jacobian should be %sx%s" % (m, n)) body_processed += "\n" auxspec_processedDict = {auxname: body_processed} elif auxname == "Jacobian_pars": sig = "void jacobianParam(" if not compareList(auxspec[0], ["t"] + self.fspec.pars): print(["t"] + self.fspec.pars) print("Auxspec =" + auxspec[0]) raise ValueError("Invalid argument list given in Jacobian.") parlist = "unsigned n_, unsigned np_, double t, double *Y_," if any([pt in auxspec[1] for pt in ("^", "**")]): auxstr = convertPowers(auxspec[1], "pow") else: auxstr = auxspec[1] ismat = True # specials = ["t","Y_","n_","np_","wkn_","wk_"] sig += ( parlist + " double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_)" ) specvars = self.fspec.pars specvars.sort() n = len(specvars) if n == 0: raise ValueError( "Cannot have a Jacobian w.r.t. pars" " because no pars are defined" ) m = len(self.fspec.vars) specdict_temp = {}.fromkeys(self.fspec.vars) if m == n == 1: assert ( "[" not in auxstr ), "'[' character invalid in Jacobian for 1D system" assert ( "]" not in auxstr ), "']' character invalid in Jacobian for 1D system" specdict_temp[list(self.fspec.vars.values())[0]] = auxstr else: specdict_temp = parseMatrixStrToDictStr(auxstr, self.fspec.vars, m) reusestr, body_processed_dict = self._processReusedC( self.fspec.vars, specdict_temp ) specdict = {}.fromkeys(self.fspec.vars) for specname in self.fspec.vars: temp = body_processed_dict[specname] specdict[specname] = splitargs( temp.replace("[", "").replace("]", "") ) body_processed = "" # C integrators expect column-major matrices for col in range(n): for row in range(m): try: body_processed += ( "f_[" + str(col) + "][" + str(row) + "] = " + specdict[self.fspec.vars[row]][col] + ";\n" ) except (IndexError, KeyError): print("%d %r" % (n, specvars)) print("\nFound matrix:\n") info(specdict) raise ValueError("Jacobian should be %sx%s" % (m, n)) body_processed += "\n" auxspec_processedDict = {auxname: body_processed} elif auxname == "massMatrix": sig = "void massMatrix(" if not compareList(auxspec[0], ["t"] + self.fspec.vars): raise ValueError("Invalid argument list given in Mass Matrix.") if any([pt in auxspec[1] for pt in ("^", "**")]): auxstr = convertPowers(auxspec[1], "pow") else: auxstr = auxspec[1] parlist = "unsigned n_, unsigned np_," ismat = True # specials = ["n_","np_","wkn_","wk_"] sig += ( parlist + " double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_)" ) specvars = self.fspec.vars specvars.sort() n = len(specvars) m = n specdict_temp = {}.fromkeys(specvars) if m == 1: assert ( "[" not in auxstr ), "'[' character invalid in mass matrix for 1D system" assert ( "]" not in auxstr ), "']' character invalid in mass matrix for 1D system" specdict_temp[list(specvars.values())[0]] = auxstr else: specdict_temp = parseMatrixStrToDictStr(auxstr, specvars, m) reusestr, body_processed_dict = self._processReusedC( specvars, specdict_temp ) specdict = {}.fromkeys(specvars) for specname in specvars: temp = ( body_processed_dict[specname].replace("[", "").replace("]", "") ) specdict[specname] = splitargs(temp) body_processed = "" # C integrators expect column-major matrices for col in range(n): for row in range(m): try: body_processed += ( "f_[" + str(col) + "][" + str(row) + "] = " + specdict[specvars[row]][col] + ";\n" ) except KeyError: raise ValueError("Mass matrix should be %sx%s" % (m, n)) body_processed += "\n" auxspec_processedDict = {auxname: body_processed} else: ismat = False sig = "double " + auxname + "(" parlist = "" namemap = {} for parname in auxspec[0]: if parname == "": continue parlist += "double " + "__" + parname + "__, " namemap[parname] = "__" + parname + "__" sig += parlist + "double *p_, double *wk_, double *xv_)" auxstr = auxspec[1] if any([pt in auxspec[1] for pt in ("^", "**")]): auxstr = convertPowers(auxstr, "pow") prep_auxstr = self._processSpecialC(auxstr) prep_auxstr_quant = QuantSpec( "prep_q", prep_auxstr.replace(" ", "").replace("\n", ""), treatMultiRefs=False, preserveSpace=True, ) # have to do name map now in case function's formal arguments # coincide with state variable names, which may get tied up # in reused terms and not properly matched to the formal args. prep_auxstr_quant.mapNames(namemap) auxspec = (auxspec[0], prep_auxstr_quant()) reusestr, auxspec_processedDict = self._processReusedC( [auxname], {auxname: auxspec[1]} ) # addition of parameter done in Generator code # dummyQ = QuantSpec('dummy', auxspec_processedDict[auxname]) # auxspec_processed = "" # add pars argument to inter-aux fn call # auxfn_found = False # then expect a left brace next # for tok in dummyQ: # if auxfn_found: # expect left brace in this tok # if tok == '(': # auxspec_processed += tok + 'p_, ' # auxfn_found = False # else: # raise ValueError("Problem parsing inter-auxiliary" # " function call") # elif tok in self.fspec.auxfns and tok not in \ # ['Jacobian', 'Jacobian_pars']: # auxfn_found = True # auxspec_processed += tok # else: # auxspec_processed += tok # body_processed = "return "+auxspec_processed + ";\n\n" # add underscore to local names, to avoid clash with global # '#define' names dummyQ = QuantSpec( "dummy", auxspec_processedDict[auxname], treatMultiRefs=False, preserveSpace=True, ) body_processed = "return " * (not ismat) + dummyQ() + ";\n\n" # auxspecstr = sig + " {\n\n" + pardefines + vardefines*ismat \ auxspecstr = ( sig + " {\n\n" + "\n" + (len(reusestr) > 0) * "/* reused term definitions */\n" + reusestr + (len(reusestr) > 0) * "\n" + body_processed + "}" ) # + parundefines + varundefines*ismat + "}" # sig as second entry, whereas Python-coded specifications # have the fn name there auxfns[auxname] = (auxspecstr, sig) # Don't apply #define's for built-in functions auxfns["heav"] = ( "int heav(double x_, double *p_, double *wk_, double *xv_) {\n" + " if (x_>0.0) {return 1;} else {return 0;}\n}", "int heav(double x_, double *p_, double *wk_, double *xv_)", ) auxfns["__rhs_if"] = ( "double __rhs_if(int cond_, double e1_, " + "double e2_, double *p_, double *wk_, double *xv_) {\n" + " if (cond_) {return e1_;} else {return e2_;};\n}", "double __rhs_if(int cond_, double e1_, double e2_, double *p_, double *wk_, double *xv_)", ) auxfns["__maxof2"] = ( "double __maxof2(double e1_, double e2_, double *p_, double *wk_, double *xv_) {\n" + "if (e1_ > e2_) {return e1_;} else {return e2_;};\n}", "double __maxof2(double e1_, double e2_, double *p_, double *wk_, double *xv_)", ) auxfns["__minof2"] = ( "double __minof2(double e1_, double e2_, double *p_, double *wk_, double *xv_) {\n" + "if (e1_ < e2_) {return e1_;} else {return e2_;};\n}", "double __minof2(double e1_, double e2_, double *p_, double *wk_, double *xv_)", ) auxfns["__maxof3"] = ( "double __maxof3(double e1_, double e2_, double e3_, double *p_, double *wk_, double *xv_) {\n" + "double temp_;\nif (e1_ > e2_) {temp_ = e1_;} else {temp_ = e2_;};\n" + "if (e3_ > temp_) {return e3_;} else {return temp_;};\n}", "double __maxof3(double e1_, double e2_, double e3_, double *p_, double *wk_, double *xv_)", ) auxfns["__minof3"] = ( "double __minof3(double e1_, double e2_, double e3_, double *p_, double *wk_, double *xv_) {\n" + "double temp_;\nif (e1_ < e2_) {temp_ = e1_;} else {temp_ = e2_;};\n" + "if (e3_ < temp_) {return e3_;} else {return temp_;};\n}", "double __minof3(double e1_, double e2_, double e3_, double *p_, double *wk_, double *xv_)", ) auxfns["__maxof4"] = ( "double __maxof4(double e1_, double e2_, double e3_, double e4_, double *p_, double *wk_, double *xv_) {\n" + "double temp_;\nif (e1_ > e2_) {temp_ = e1_;} else {temp_ = e2_;};\n" + "if (e3_ > temp_) {temp_ = e3_;};\nif (e4_ > temp_) {return e4_;} else {return temp_;};\n}", "double __maxof4(double e1_, double e2_, double e3_, double e4_, double *p_, double *wk_, double *xv_)", ) auxfns["__minof4"] = ( "double __minof4(double e1_, double e2_, double e3_, double e4_, double *p_, double *wk_, double *xv_) {\n" + "double temp_;\nif (e1_ < e2_) {temp_ = e1_;} else {temp_ = e2_;};\n" + "if (e3_ < temp_) {temp_ = e3_;};\nif (e4_ < temp_) {return e4_;} else {return temp_;};\n}", "double __minof4(double e1_, double e2_, double e3_, double e4_, double *p_, double *wk_, double *xv_)", ) # temporary placeholders for these built-ins... cases_ic = "" cases_index = "" for i in range(len(self.fspec.vars)): if i == 0: command = "if" else: command = "else if" vname = self.fspec.vars[i] cases_ic += ( " " + command + " (strcmp(varname, " + '"' + vname + '"' + ")==0)\n\treturn gICs[" + str(i) + "];\n" ) cases_index += ( " " + command + " (strcmp(name, " + '"' + vname + '"' + ")==0)\n\treturn " + str(i) + ";\n" ) # add remaining par names for getindex for i in range(len(self.fspec.pars)): pname = self.fspec.pars[i] cases_index += ( " else if" + " (strcmp(name, " + '"' + pname + '"' + ")==0)\n\treturn " + str(i + len(self.fspec.vars)) + ";\n" ) cases_ic += ( """ else {\n\tfprintf(stderr, "Invalid variable name %s for """ + """initcond call\\n", varname);\n\treturn 0.0/0.0;\n\t}\n""" ) cases_index += ( """ else {\n\tfprintf(stderr, "Invalid name %s for """ + """getindex call\\n", name);\n\treturn 0.0/0.0;\n\t}\n""" ) auxfns["initcond"] = ( "double initcond(char *varname, double *p_, double *wk_, double *xv_) {\n" + "\n" + cases_ic + "}", "double initcond(char *varname, double *p_, double *wk_, double *xv_)", ) auxfns["getindex"] = ( "int getindex(char *name, double *p_, double *wk_, double *xv_) {\n" + "\n" + cases_index + "}", "int getindex(char *name, double *p_, double *wk_, double *xv_)", ) auxfns["globalindepvar"] = ( "double globalindepvar(double t, double *p_, double *wk_, double *xv_)" + " {\n return globalt0+t;\n}", "double globalindepvar(double t, double *p_, double *wk_, double *xv_)", ) auxfns["getbound"] = ( "double getbound(char *name, int which_bd, double *p_, double *wk_, double *xv_) {\n" + " return gBds[which_bd][getindex(name)];\n}", "double getbound(char *name, int which_bd, double *p_, double *wk_, double *xv_)", ) return auxfns
def generate_aux(self): auxnames = list(self.fspec._auxfnspecs.keys()) auxfns = {} # parameter and variable definitions # sorted version of var and par names sorted version of par # names (vars not #define'd in aux functions unless Jacobian) vnames = self.fspec.vars pnames = self.fspec.pars vnames.sort() pnames.sort() for auxname in auxnames: assert auxname not in ['auxvars', 'vfieldfunc'], \ ("auxiliary function name '" + auxname + "' clashes with internal" " names") # must add parameter argument so that we can name # parameters inside the functions! this would either # require all calls to include this argument (yuk!) or # else we add these extra parameters automatically to # every call found in the .c code (as is done currently. # this is still an untidy solution, but there you go...) for auxname in auxnames: auxspec = self.fspec._auxfnspecs[auxname] assert len(auxspec) == 2, 'auxspec tuple must be of length 2' if not isinstance(auxspec[0], list): print("Found type " + type(auxspec[0])) print("Containing: " + auxspec[0]) raise TypeError('aux function arguments ' 'must be given as a list') if not isinstance(auxspec[1], str): print("Found type " + type(auxspec[1])) print("Containing: " + auxspec[1]) raise TypeError('aux function specification ' 'must be a string of the function code') # Process Jacobian functions specially, if present if auxname == 'Jacobian': sig = "void jacobian(" if not compareList(auxspec[0], ['t'] + self.fspec.vars): print(['t'] + self.fspec.vars) print("Auxspec =" + auxspec[0]) raise ValueError( "Invalid argument list given in Jacobian.") if any([pt in auxspec[1] for pt in ('^', '**')]): auxstr = convertPowers(auxspec[1], 'pow') else: auxstr = auxspec[1] parlist = "unsigned n_, unsigned np_, double t, double *Y_," ismat = True sig += parlist + \ " double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_)" specvars = self.fspec.vars specvars.sort() n = len(specvars) m = n specdict_temp = {}.fromkeys(specvars) if m == 1: assert '[' not in auxstr, \ "'[' character invalid in Jacobian for 1D system" assert ']' not in auxstr, \ "']' character invalid in Jacobian for 1D system" specdict_temp[specvars[0]] = auxstr else: specdict_temp = parseMatrixStrToDictStr(auxstr, specvars) reusestr, body_processed_dict = self._processReusedC( specvars, specdict_temp) specdict = {}.fromkeys(specvars) for specname in specvars: temp = body_processed_dict[specname] specdict[specname] = splitargs( temp.replace("[", "").replace("]", "")) body_processed = "" # C integrators expect column-major matrices for col in range(n): for row in range(m): try: body_processed += "f_[" + str(col) + "][" + str(row) \ + "] = " + specdict[specvars[row]][col] + ";\n" except IndexError: raise ValueError( "Jacobian should be %sx%s" % (m, n)) body_processed += "\n" auxspec_processedDict = {auxname: body_processed} elif auxname == 'Jacobian_pars': sig = "void jacobianParam(" if not compareList(auxspec[0], ['t'] + self.fspec.pars): print(['t'] + self.fspec.pars) print("Auxspec =" + auxspec[0]) raise ValueError( "Invalid argument list given in Jacobian.") parlist = "unsigned n_, unsigned np_, double t, double *Y_," if any([pt in auxspec[1] for pt in ('^', '**')]): auxstr = convertPowers(auxspec[1], 'pow') else: auxstr = auxspec[1] ismat = True # specials = ["t","Y_","n_","np_","wkn_","wk_"] sig += parlist + \ " double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_)" specvars = self.fspec.pars specvars.sort() n = len(specvars) if n == 0: raise ValueError("Cannot have a Jacobian w.r.t. pars" " because no pars are defined") m = len(self.fspec.vars) specdict_temp = {}.fromkeys(self.fspec.vars) if m == n == 1: assert '[' not in auxstr, \ "'[' character invalid in Jacobian for 1D system" assert ']' not in auxstr, \ "']' character invalid in Jacobian for 1D system" specdict_temp[list(self.fspec.vars.values())[0]] = auxstr else: specdict_temp = parseMatrixStrToDictStr( auxstr, self.fspec.vars, m) reusestr, body_processed_dict = self._processReusedC( self.fspec.vars, specdict_temp) specdict = {}.fromkeys(self.fspec.vars) for specname in self.fspec.vars: temp = body_processed_dict[specname] specdict[specname] = splitargs( temp.replace("[", "").replace("]", "")) body_processed = "" # C integrators expect column-major matrices for col in range(n): for row in range(m): try: body_processed += "f_[" + str(col) + "][" + str(row) \ + "] = " + specdict[ self.fspec.vars[row]][col] + ";\n" except (IndexError, KeyError): print("%d %r" % (n, specvars)) print("\nFound matrix:\n") info(specdict) raise ValueError( "Jacobian should be %sx%s" % (m, n)) body_processed += "\n" auxspec_processedDict = {auxname: body_processed} elif auxname == 'massMatrix': sig = "void massMatrix(" if not compareList(auxspec[0], ['t'] + self.fspec.vars): raise ValueError( "Invalid argument list given in Mass Matrix.") if any([pt in auxspec[1] for pt in ('^', '**')]): auxstr = convertPowers(auxspec[1], 'pow') else: auxstr = auxspec[1] parlist = "unsigned n_, unsigned np_," ismat = True # specials = ["n_","np_","wkn_","wk_"] sig += parlist + \ " double t, double *Y_, double *p_, double **f_, unsigned wkn_, double *wk_, unsigned xvn_, double *xv_)" specvars = self.fspec.vars specvars.sort() n = len(specvars) m = n specdict_temp = {}.fromkeys(specvars) if m == 1: assert '[' not in auxstr, \ "'[' character invalid in mass matrix for 1D system" assert ']' not in auxstr, \ "']' character invalid in mass matrix for 1D system" specdict_temp[list(specvars.values())[0]] = auxstr else: specdict_temp = parseMatrixStrToDictStr( auxstr, specvars, m) reusestr, body_processed_dict = self._processReusedC( specvars, specdict_temp) specdict = {}.fromkeys(specvars) for specname in specvars: temp = body_processed_dict[ specname].replace("[", "").replace("]", "") specdict[specname] = splitargs(temp) body_processed = "" # C integrators expect column-major matrices for col in range(n): for row in range(m): try: body_processed += "f_[" + str(col) + "][" + str(row) \ + "] = " + specdict[specvars[row]][col] + ";\n" except KeyError: raise ValueError( "Mass matrix should be %sx%s" % (m, n)) body_processed += "\n" auxspec_processedDict = {auxname: body_processed} else: ismat = False sig = "double " + auxname + "(" parlist = "" namemap = {} for parname in auxspec[0]: if parname == '': continue parlist += "double " + "__" + parname + "__, " namemap[parname] = '__' + parname + '__' sig += parlist + "double *p_, double *wk_, double *xv_)" auxstr = auxspec[1] if any([pt in auxspec[1] for pt in ('^', '**')]): auxstr = convertPowers(auxstr, 'pow') prep_auxstr = self._processSpecialC(auxstr) prep_auxstr_quant = QuantSpec('prep_q', prep_auxstr.replace( ' ', '').replace('\n', ''), treatMultiRefs=False, preserveSpace=True) # have to do name map now in case function's formal arguments # coincide with state variable names, which may get tied up # in reused terms and not properly matched to the formal args. prep_auxstr_quant.mapNames(namemap) auxspec = (auxspec[0], prep_auxstr_quant()) reusestr, auxspec_processedDict = self._processReusedC( [auxname], {auxname: auxspec[1]}) # addition of parameter done in Generator code # dummyQ = QuantSpec('dummy', auxspec_processedDict[auxname]) # auxspec_processed = "" # add pars argument to inter-aux fn call # auxfn_found = False # then expect a left brace next # for tok in dummyQ: # if auxfn_found: # expect left brace in this tok # if tok == '(': # auxspec_processed += tok + 'p_, ' # auxfn_found = False # else: # raise ValueError("Problem parsing inter-auxiliary" # " function call") # elif tok in self.fspec.auxfns and tok not in \ # ['Jacobian', 'Jacobian_pars']: # auxfn_found = True # auxspec_processed += tok # else: # auxspec_processed += tok # body_processed = "return "+auxspec_processed + ";\n\n" # add underscore to local names, to avoid clash with global # '#define' names dummyQ = QuantSpec('dummy', auxspec_processedDict[auxname], treatMultiRefs=False, preserveSpace=True) body_processed = "return " * (not ismat) + dummyQ() + ";\n\n" # auxspecstr = sig + " {\n\n" + pardefines + vardefines*ismat \ auxspecstr = sig + " {\n\n" \ + "\n" + (len(reusestr) > 0) * "/* reused term definitions */\n" \ + reusestr + (len(reusestr) > 0) * "\n" + body_processed \ + "}" # + parundefines + varundefines*ismat + "}" # sig as second entry, whereas Python-coded specifications # have the fn name there auxfns[auxname] = (auxspecstr, sig) # Don't apply #define's for built-in functions auxfns['heav'] = ("int heav(double x_, double *p_, double *wk_, double *xv_) {\n" + " if (x_>0.0) {return 1;} else {return 0;}\n}", "int heav(double x_, double *p_, double *wk_, double *xv_)") auxfns['__rhs_if'] = ("double __rhs_if(int cond_, double e1_, " + "double e2_, double *p_, double *wk_, double *xv_) {\n" + " if (cond_) {return e1_;} else {return e2_;};\n}", "double __rhs_if(int cond_, double e1_, double e2_, double *p_, double *wk_, double *xv_)") auxfns['__maxof2'] = ("double __maxof2(double e1_, double e2_, double *p_, double *wk_, double *xv_) {\n" + "if (e1_ > e2_) {return e1_;} else {return e2_;};\n}", "double __maxof2(double e1_, double e2_, double *p_, double *wk_, double *xv_)") auxfns['__minof2'] = ("double __minof2(double e1_, double e2_, double *p_, double *wk_, double *xv_) {\n" + "if (e1_ < e2_) {return e1_;} else {return e2_;};\n}", "double __minof2(double e1_, double e2_, double *p_, double *wk_, double *xv_)") auxfns['__maxof3'] = ("double __maxof3(double e1_, double e2_, double e3_, double *p_, double *wk_, double *xv_) {\n" + "double temp_;\nif (e1_ > e2_) {temp_ = e1_;} else {temp_ = e2_;};\n" + "if (e3_ > temp_) {return e3_;} else {return temp_;};\n}", "double __maxof3(double e1_, double e2_, double e3_, double *p_, double *wk_, double *xv_)") auxfns['__minof3'] = ("double __minof3(double e1_, double e2_, double e3_, double *p_, double *wk_, double *xv_) {\n" + "double temp_;\nif (e1_ < e2_) {temp_ = e1_;} else {temp_ = e2_;};\n" + "if (e3_ < temp_) {return e3_;} else {return temp_;};\n}", "double __minof3(double e1_, double e2_, double e3_, double *p_, double *wk_, double *xv_)") auxfns['__maxof4'] = ("double __maxof4(double e1_, double e2_, double e3_, double e4_, double *p_, double *wk_, double *xv_) {\n" + "double temp_;\nif (e1_ > e2_) {temp_ = e1_;} else {temp_ = e2_;};\n" + "if (e3_ > temp_) {temp_ = e3_;};\nif (e4_ > temp_) {return e4_;} else {return temp_;};\n}", "double __maxof4(double e1_, double e2_, double e3_, double e4_, double *p_, double *wk_, double *xv_)") auxfns['__minof4'] = ("double __minof4(double e1_, double e2_, double e3_, double e4_, double *p_, double *wk_, double *xv_) {\n" + "double temp_;\nif (e1_ < e2_) {temp_ = e1_;} else {temp_ = e2_;};\n" + "if (e3_ < temp_) {temp_ = e3_;};\nif (e4_ < temp_) {return e4_;} else {return temp_;};\n}", "double __minof4(double e1_, double e2_, double e3_, double e4_, double *p_, double *wk_, double *xv_)") # temporary placeholders for these built-ins... cases_ic = "" cases_index = "" for i in range(len(self.fspec.vars)): if i == 0: command = 'if' else: command = 'else if' vname = self.fspec.vars[i] cases_ic += " " + command + " (strcmp(varname, " + '"' + vname + '"'\ + ")==0)\n\treturn gICs[" + str(i) + "];\n" cases_index += " " + command + " (strcmp(name, " + '"' + vname + '"'\ + ")==0)\n\treturn " + str(i) + ";\n" # add remaining par names for getindex for i in range(len(self.fspec.pars)): pname = self.fspec.pars[i] cases_index += " else if" + " (strcmp(name, " + '"' + pname + '"'\ + ")==0)\n\treturn " + str( i + len(self.fspec.vars)) + ";\n" cases_ic += """ else {\n\tfprintf(stderr, "Invalid variable name %s for """ \ + """initcond call\\n", varname);\n\treturn 0.0/0.0;\n\t}\n""" cases_index += """ else {\n\tfprintf(stderr, "Invalid name %s for """ \ + """getindex call\\n", name);\n\treturn 0.0/0.0;\n\t}\n""" auxfns['initcond'] = ("double initcond(char *varname, double *p_, double *wk_, double *xv_) {\n" + "\n" + cases_ic + "}", 'double initcond(char *varname, double *p_, double *wk_, double *xv_)') auxfns['getindex'] = ("int getindex(char *name, double *p_, double *wk_, double *xv_) {\n" + "\n" + cases_index + "}", 'int getindex(char *name, double *p_, double *wk_, double *xv_)') auxfns['globalindepvar'] = ("double globalindepvar(double t, double *p_, double *wk_, double *xv_)" + " {\n return globalt0+t;\n}", 'double globalindepvar(double t, double *p_, double *wk_, double *xv_)') auxfns['getbound'] = \ ("double getbound(char *name, int which_bd, double *p_, double *wk_, double *xv_) {\n" + " return gBds[which_bd][getindex(name)];\n}", 'double getbound(char *name, int which_bd, double *p_, double *wk_, double *xv_)') return auxfns