def __init__(self, kw): discGen.__init__(self, kw) self._errmessages[E_COMPUTFAIL] = "Computation of trajectory failed" self.needKeys.extend(["varspecs"]) self.optionalKeys.extend( [ "tdomain", "xdomain", "inputs", "tdata", "ics", "events", "system", "ignorespecial", #'compiler', "auxvars", "vars", "fnspecs", "ttype", "xtype", "tstep", "checklevel", "pars", "pdomain", "vfcodeinsert_start", "vfcodeinsert_end", "enforcebounds", "activatedbounds", "reuseterms", ] ) fs_args = {} if "varspecs" in kw: self.foundKeys += 1 varspecs = ensureStrArgDict(kw["varspecs"]) else: raise PyDSTool_KeyError("Keyword 'varspecs' missing from " "argument") if "pars" in kw: self.pars = {} if type(kw["pars"]) == list: # may be a list of symbolic definitions for p in kw["pars"]: try: self.pars[p.name] = p.tonumeric() except (AttributeError, TypeError): raise TypeError, "Invalid parameter symbolic definition" else: for k, v in dict(kw["pars"]).iteritems(): self.pars[str(k)] = v fs_args["pars"] = self.pars.keys() self._register(self.pars) self.foundKeys += 1 if "vfcodeinsert_start" in kw: fs_args["codeinsert_start"] = kw["vfcodeinsert_start"] self.foundKeys += 1 if "vfcodeinsert_end" in kw: fs_args["codeinsert_end"] = kw["vfcodeinsert_end"] self.foundKeys += 1 if "system" in kw: self._solver = kw["system"] try: fs_args["ignorespecial"] = [self._solver.name] except: raise TypeError, "Invalid solver system provided" self.foundKeys += 1 if self.pars: # automatically pass par values on to embedded system # when Rhs called parlist = self.pars.keys() parstr = "".join(["'%s': %s, " % (parname, parname) for parname in parlist]) if "codeinsert_start" in fs_args: fs_args["codeinsert_start"] = ( " %s.set(pars={%s})\n" % (self._solver.name, parstr) + fs_args["codeinsert_start"] ) else: fs_args["codeinsert_start"] = " %s.set(pars={%s})\n" % (self._solver.name, parstr) else: fs_args["ignorespecial"] = [] self._solver = None if "ignorespecial" in kw: fs_args["ignorespecial"].extend(kw["ignorespecial"]) self.foundKeys += 1 if "tdomain" in kw: self._tdomain = kw["tdomain"] if self._tdomain[0] >= self._tdomain[1]: raise PyDSTool_ValueError("tdomain values must be in order of increasing size") self.foundKeys += 1 else: self._tdomain = [-Inf, Inf] if "ttype" in kw: indepvartype = kw["ttype"] assert indepvartype in _pynametype.keys(), "Invalid ttype" self.foundKeys += 1 else: indepvartype = "float" if "tdata" in kw: self._tdata = kw["tdata"] if self._tdata[0] >= self._tdata[1]: raise PyDSTool_ValueError("tdata values must be in order of increasing size") # _tdata is made into list to be consistent with # other uses of it in other Generators... if self._tdomain[0] > self._tdata[0]: print "tdata cannot be specified below smallest " "value in tdomain\n (possibly due to uncertain" "bounding). It has been automatically adjusted\n" " from\n ", self._tdata[ 0 ], "to", self._tdomain[ 0 ], "(difference of", self._tdomain[ 0 ] - self._tdata[ 0 ], ")" self._tdata[0] = self._tdomain[0] if self._tdomain[1] < self._tdata[1]: print "tdata cannot be specified above largest " "value in tdomain\n (possibly due to uncertain " "bounding). It has been automatically adjusted\n" " from\n ", self._tdata[ 1 ], "to", self._tdomain[ 1 ], "(difference of", self._tdata[ 1 ] - self._tdomain[ 1 ], ")" self._tdata[1] = self._tdomain[1] self.foundKeys += 1 else: self._tdata = self._tdomain # default needed if "tstep" in kw: self.tstep = kw["tstep"] if self.tstep > self._tdata[1] - self._tdata[0]: raise PyDSTool_ValueError("tstep too large") if indepvartype == "int" and round(self.tstep) != self.tstep: raise PyDSTool_ValueError("tstep must be an integer for integer ttype") self.foundKeys += 1 else: if indepvartype == "int": # default to 1 for integer types self.tstep = 1 else: # no reasonable default - so raise error raise PyDSTool_KeyError("tstep key needed for float ttype") if "inputs" in kw: inputs = copy(kw["inputs"]) self.inputs = {} if isinstance(inputs, Trajectory): # extract the variables self.inputs = inputs.variables elif isinstance(inputs, Variable): self.inputs = {inputs.name: inputs} elif isinstance(inputs, Pointset): # turn into Variables but only define at Pointset's # own independent variable values self.inputs = dict(zip(inputs.coordnames, [Variable(inputs[[n]], name=n) for n in inputs.coordnames])) elif isinstance(inputs, dict): self.inputs = inputs # ensure values are Variables or Pointsets for k, v in self.inputs.iteritems(): if not isinstance(v, Variable): try: self.inputs[k] = Variable(v) except: raise TypeError, "Invalid specification of inputs" else: raise TypeError, "Invalid specification of inputs" # don't check that variables have discrete domains in case wish # to use cts-valued ones sampled at discrete times fs_args["inputs"] = self.inputs.keys() self._register(self.inputs) self.foundKeys += 1 else: self.inputs = {} if "ics" in kw: self._xdatadict = {} for k, v in dict(kw["ics"]).iteritems(): self._xdatadict[str(k)] = v self.initialconditions = self._xdatadict for name in remain(varspecs.keys(), self._xdatadict.keys()): self.initialconditions[name] = NaN self.foundKeys += 1 else: self._xdatadict = {} for name in varspecs: self.initialconditions[name] = NaN if "xtype" in kw: depvartype = kw["xtype"] assert depvartype in _pynametype.keys(), "Invalid xtype" self.foundKeys += 1 else: depvartype = "float" if "auxvars" in kw: assert "vars" not in kw, "Cannot use both 'auxvars' and 'vars' " "keywords" if isinstance(kw["auxvars"], list): auxvars = [str(v) for v in kw["auxvars"]] else: auxvars = [str(kw["auxvars"])] vars = remain(varspecs.keys(), auxvars) self.foundKeys += 1 elif "vars" in kw: assert "auxvars" not in kw, "Cannot use both 'auxvars' and 'vars' keywords" if isinstance(kw["vars"], list): vars = [str(v) for v in kw["vars"]] else: vars = [str(kw["vars"])] auxvars = remain(varspecs.keys(), vars) self.foundKeys += 1 else: auxvars = [] vars = varspecs.keys() if auxvars != []: fs_args["auxvars"] = auxvars if "xdomain" in kw: self._xdomain = {} for k, v in dict(kw["xdomain"]).iteritems(): name = str(k) if type(v) in [list, Array, NArray]: assert len(v) == 2, "Invalid size of domain specification for " + name if v[0] >= v[1]: raise PyDSTool_ValueError("xdomain values must be in" "order of increasing size") else: self._xdomain[name] = copy(v) elif type(v) in [float, int]: self._xdomain[name] = [v, v] else: raise PyDSTool_TypeError("Invalid type for xdomain spec" " " + name) for name in remain(varspecs.keys(), self._xdomain.keys()): self._xdomain[name] = [-Inf, Inf] self.foundKeys += 1 else: self._xdomain = {} for name in varspecs: self._xdomain[name] = [-Inf, Inf] if "reuseterms" in kw: fs_args["reuseterms"] = kw["reuseterms"] self.foundKeys += 1 fs_args.update({"vars": vars, "varspecs": varspecs, "name": self.name}) if "pdomain" in kw: if self.pars: self._pdomain = {} for k, v in dict(kw["pdomain"]).iteritems(): assert len(v) == 2, "Invalid interval for parameter %s" % k self._pdomain[str(k)] = v for name in self._pdomain: if self._pdomain[name][0] >= self._pdomain[name][1]: raise PyDSTool_ValueError("pdomain values must be in order of increasing size") for name in remain(self.pars.keys(), self._pdomain.keys()): self._pdomain[name] = [-Inf, Inf] self.foundKeys += 1 else: raise ValueError("Cannot specify pdomain because no pars declared") else: if self.pars: self._pdomain = {} for pname in self.pars: self._pdomain[pname] = [-Inf, Inf] if self.pars: self.parameterDomains = {} for pname in self._pdomain: self.parameterDomains[pname] = Interval(pname, "float", self._pdomain[pname], self._abseps) try: cval = self.parameterDomains[pname].contains(self.pars[pname]) except KeyError: raise ValueError("Parameter %s is missing a value" % pname) if self.checklevel < 3: if cval is not notcontained: if cval is uncertain and self.checklevel == 2: print "Warning: Parameter value at bound" else: raise PyDSTool_ValueError, "Parameter value out of bounds" else: if cval is uncertain: raise PyDSTool_UncertainValueError, "Parameter value at bound" elif cval is notcontained: raise PyDSTool_ValueError, "Parameter value out of bounds" if "fnspecs" in kw: fs_args["fnspecs"] = ensureStrArgDict(kw["fnspecs"]) self.foundKeys += 1 ## fs_args['targetlang'] = 'python' ## if 'compiler' in kw: ## if fs_args['targetlang'] == 'python': ## print "Warning: redundant option 'compiler' for python target" ## self._compiler = kw['compiler'] ## self.foundKeys += 1 ## else: ## self._compiler = '' ## if fs_args['targetlang'] != 'python' and inputs: ## raise PyDSTool_ValueError('Cannot use external inputs with non-Python target language') self.funcspec = RHSfuncSpec(fs_args) # Holder and interface for events self.eventstruct = EventStruct() if "enforcebounds" in kw: if "activatedbounds" in kw: ab = kw["activatedbounds"] self.foundKeys += 1 else: ab = None if kw["enforcebounds"]: self._makeBoundsEvents(precise=False, activatedbounds=ab) self.foundKeys += 1 if "events" in kw: self._addEvents(kw["events"]) self.foundKeys += 1 self.checkArgs(kw) self.numpars = len(self.pars) tindepdomain = Interval("t_domain", indepvartype, self._tdomain, self._abseps) tdepdomain = Interval("t", indepvartype, self._tdata, self._abseps) self.indepvariable = Variable(listid, tindepdomain, tdepdomain, "t") self._register(self.indepvariable) self.dimension = len(self.funcspec.vars) for xname in self.funcspec.vars + self.funcspec.auxvars: # Add a temporary dependent variable domain, for validation testing # during integration self.variables[xname] = Variable( indepdomain=tdepdomain, depdomain=Interval(xname, depvartype, self._xdomain[xname], self._abseps) ) self._register(self.variables) self._generate_ixmaps() # Introduce any python-specified code to the local namespace ## if fs_args['targetlang'] == 'python': self.addMethods() # all registration completed self.validateSpec()
def __init__(self, kw): ctsGen.__init__(self, kw) self._errmessages[E_COMPUTFAIL] = 'Integration failed' self.needKeys.extend(['varspecs']) self.optionalKeys.extend(['tdomain', 'xdomain', 'inputs', 'tdata', 'ics', 'events', 'compiler', 'enforcebounds', 'activatedbounds', 'checklevel', 'algparams', 'auxvars', 'vars', 'pars', 'fnspecs', 'pdomain', 'reuseterms', 'vfcodeinsert_start', 'vfcodeinsert_end']) fs_args = {} if 'varspecs' in kw: self.foundKeys += 1 varspecs = ensureStrArgDict(kw['varspecs']) else: raise PyDSTool_KeyError("Keyword 'varspecs' missing from " "argument") if 'tdomain' in kw: self._tdomain = kw['tdomain'] if self._tdomain[0] >= self._tdomain[1]: print "Time domain specified: [%s, %s]"%(self._tdomain[0], self._tdomain[1]) raise PyDSTool_ValueError('tdomain values must be in order of increasing size') self.foundKeys += 1 else: self._tdomain = [-Inf, Inf] if 'tdata' in kw: self._tdata = kw['tdata'] if self._tdata[0] >= self._tdata[1]: raise PyDSTool_ValueError('tdata values must be in order of increasing size') # _tdata is made into list to be consistent with # other uses of it in other Generators... if self._tdomain[0] > self._tdata[0]: print 'tdata cannot be specified below smallest '\ 'value in tdomain\n (possibly due to uncertain'\ 'bounding). It has been automatically adjusted\n'\ ' from\n ', self._tdata[0], 'to', self._tdomain[0],\ '(difference of', self._tdomain[0]-self._tdata[0], ')' if self._modeltag: print 'Try reducing step size in model.' self._tdata[0] = self._tdomain[0] if self._tdomain[1] < self._tdata[1]: print 'tdata cannot be specified above largest '\ 'value in tdomain\n (possibly due to uncertain '\ 'bounding). It has been automatically adjusted\n'\ ' from\n ', self._tdata[1], 'to', self._tdomain[1],\ '(difference of', self._tdata[1]-self._tdomain[1], ')' if self._modeltag: print 'Try reducing step size in model.' self._tdata[1] = self._tdomain[1] self.foundKeys += 1 else: self._tdata = self._tdomain # default needed if 'inputs' in kw: inputs = copy(kw['inputs']) self.inputs = {} if isinstance(inputs, Trajectory): # extract the variables self.inputs = inputs.variables elif isinstance(inputs, Variable): self.inputs = {inputs.name: inputs} elif isinstance(inputs, Pointset): # turn into Variables with linear interpoolation between # independent variable values for n in inputs.coordnames: x_array = inputs[n] self.inputs[n] = Variable(interp1d(inputs.indepvararray, x_array), 't', Interval(n, 'float', extent(x_array)), name=n) elif isinstance(inputs, dict): self.inputs = inputs # ensure values are Variables or Pointsets for k, v in self.inputs.iteritems(): if not isinstance(v, Variable): try: self.inputs[k]=Variable(v) except: raise TypeError, "Invalid specification of inputs" else: raise TypeError, "Invalid specification of inputs" for v in self.inputs.values(): if not iscontinuous(v): raise ValueError, \ ("External inputs for ODE system must be " "continuously defined") fs_args['inputs'] = self.inputs.keys() self._register(self.inputs) self.foundKeys += 1 self._extInputsChanged = True else: self.inputs = {} self._extInputsChanged = False if 'ics' in kw: self._xdatadict = {} for k, v in dict(kw['ics']).iteritems(): self._xdatadict[str(k)] = v self.initialconditions = self._xdatadict for name in remain(varspecs.keys(), self._xdatadict.keys()): self.initialconditions[name] = NaN self.foundKeys += 1 else: self._xdatadict = {} for name in varspecs: self.initialconditions[name] = NaN if 'auxvars' in kw: assert 'vars' not in kw, ("Cannot use both 'auxvars' and 'vars' " "keywords") if isinstance(kw['auxvars'], list): auxvars = [str(v) for v in kw['auxvars']] else: auxvars = [str(kw['auxvars'])] vars = remain(varspecs.keys(), auxvars) self.foundKeys += 1 elif 'vars' in kw: assert 'auxvars' not in kw, \ "Cannot use both 'auxvars' and 'vars' keywords" if isinstance(kw['vars'], list): vars = [str(v) for v in kw['vars']] else: vars = [str(kw['vars'])] auxvars = remain(varspecs.keys(), vars) self.foundKeys += 1 else: auxvars = [] vars = varspecs.keys() if auxvars != []: fs_args['auxvars'] = auxvars if 'xdomain' in kw: self._xdomain = {} for k, v in dict(kw['xdomain']).iteritems(): name = str(k) if type(v) in [list, Array, NArray]: assert len(v) == 2, \ "Invalid size of domain specification for "+name if v[0] >= v[1]: raise PyDSTool_ValueError('xdomain values must be in' 'order of increasing size') else: self._xdomain[name] = copy(v) elif type(v) in [float, int]: self._xdomain[name] = [v, v] else: raise PyDSTool_TypeError('Invalid type for xdomain spec' ' '+name) for name in remain(varspecs.keys(), self._xdomain.keys()): self._xdomain[name] = [-Inf, Inf] self.foundKeys += 1 else: self._xdomain = {} for name in varspecs: self._xdomain[name] = [-Inf, Inf] if 'reuseterms' in kw: fs_args['reuseterms'] = kw['reuseterms'] self.foundKeys += 1 fs_args.update({'vars': vars, 'varspecs': varspecs, 'name': self.name }) if 'algparams' in kw: self._algparams = copy(kw['algparams']) self.foundKeys += 1 else: self._algparams = {} if 'pars' in kw: self.pars = {} if type(kw['pars']) == list: # may be a list of symbolic definitions for p in kw['pars']: try: self.pars[p.name] = p.tonumeric() except (AttributeError, TypeError): raise TypeError, "Invalid parameter symbolic definition" else: for k, v in dict(kw['pars']).iteritems(): self.pars[str(k)] = v fs_args['pars'] = self.pars.keys() self._register(self.pars) self.foundKeys += 1 if 'pdomain' in kw: if self.pars: self._pdomain = {} for k, v in dict(kw['pdomain']).iteritems(): assert len(v) == 2, \ "Invalid size of domain specification for "+k self._pdomain[str(k)] = v for name in self._pdomain: if self._pdomain[name][0] >= self._pdomain[name][1]: raise PyDSTool_ValueError('pdomain values must be in order of increasing size') for name in remain(self.pars.keys(), self._pdomain.keys()): self._pdomain[name] = [-Inf, Inf] self.foundKeys += 1 else: raise ValueError('Cannot specify pdomain because no pars declared') else: if self.pars: self._pdomain = {} for pname in self.pars: self._pdomain[pname] = [-Inf, Inf] if self.pars: self.parameterDomains = {} for pname in self._pdomain: self.parameterDomains[pname] = Interval(pname, 'float', self._pdomain[pname], self._abseps) try: cval = self.parameterDomains[pname].contains(self.pars[pname]) except KeyError: raise ValueError("Parameter %s is missing a value"%pname) if self.checklevel < 3: if cval is not notcontained: if cval is uncertain and self.checklevel == 2: print 'Warning: Parameter value at bound' else: raise PyDSTool_ValueError, 'Parameter value out of bounds' else: if cval is uncertain: raise PyDSTool_UncertainValueError, 'Parameter value at bound' elif cval is notcontained: raise PyDSTool_ValueError, 'Parameter value out of bounds' if 'fnspecs' in kw: fs_args['fnspecs'] = ensureStrArgDict(kw['fnspecs']) self.foundKeys += 1 fs_args['targetlang'] = theGenSpecHelper(self).lang if 'compiler' in kw: if fs_args['targetlang'] == 'python': print "Warning: redundant option 'compiler' for python target" self._compiler = kw['compiler'] self.foundKeys += 1 else: osname = os.name # os-specific defaults for C compiler if osname == 'nt': self._compiler = 'mingw32' elif osname == 'mac': self._compiler = 'mwerks' elif osname == 'posix' or osname == 'unix': self._compiler = 'unix' elif osname == 'os2emx': self._compiler = 'emx' else: self._compiler = '' if 'vfcodeinsert_start' in kw: fs_args['codeinsert_start'] = kw['vfcodeinsert_start'] self.foundKeys += 1 if 'vfcodeinsert_end' in kw: fs_args['codeinsert_end'] = kw['vfcodeinsert_end'] self.foundKeys += 1 self.funcspec = RHSfuncSpec(fs_args) # Holder and interface for events self.eventstruct = EventStruct() if 'enforcebounds' in kw: if 'activatedbounds' in kw: ab = kw['activatedbounds'] self.foundKeys += 1 else: ab = None if kw['enforcebounds']: self._makeBoundsEvents(precise=True, activatedbounds=ab) self.foundKeys += 1 if 'events' in kw: self._addEvents(kw['events']) self.foundKeys += 1 self.checkArgs(kw) self.numpars = len(self.pars) tindepdomain = Interval('t_domain', 'float', self._tdomain, self._abseps) tdepdomain = Interval('t', 'float', self._tdata, self._abseps) self.indepvariable = Variable(listid, tindepdomain, tdepdomain, 't') self._register(self.indepvariable) self.dimension = len(self.funcspec.vars) for xname in self.funcspec.vars + self.funcspec.auxvars: # Add a temporary dependent variable domain, for validation testing # during integration self.variables[xname] = Variable(indepdomain=tdepdomain, depdomain=Interval(xname, 'float', self._xdomain[xname], self._abseps)) self._register(self.variables) self._generate_ixmaps() # Introduce any python-specified code to the local namespace if fs_args['targetlang'] == 'python': self.addMethods() # all registration completed self.validateSpec()
def __init__(self, kw): discGen.__init__(self, kw) self._errmessages[E_COMPUTFAIL] = 'Computation of trajectory failed' self.needKeys.extend(['varspecs']) self.optionalKeys.extend(['tdomain', 'xdomain', 'inputs', 'tdata', 'ics', 'events', 'system', 'ignorespecial', #'compiler', 'auxvars', 'vars', 'fnspecs', 'ttype', 'xtype', 'tstep', 'checklevel', 'pars', 'pdomain', 'vfcodeinsert_start', 'vfcodeinsert_end', 'enforcebounds', 'activatedbounds', 'reuseterms']) fs_args = {} if 'varspecs' in kw: self.foundKeys += 1 varspecs = ensureStrArgDict(kw['varspecs']) else: raise PyDSTool_KeyError("Keyword 'varspecs' missing from " "argument") if 'pars' in kw: self.pars = {} if type(kw['pars']) == list: # may be a list of symbolic definitions for p in kw['pars']: try: self.pars[p.name] = p.tonumeric() except (AttributeError, TypeError): raise TypeError, "Invalid parameter symbolic definition" else: for k, v in dict(kw['pars']).iteritems(): self.pars[str(k)] = v fs_args['pars'] = self.pars.keys() self._register(self.pars) self.foundKeys += 1 if 'vfcodeinsert_start' in kw: fs_args['codeinsert_start'] = kw['vfcodeinsert_start'] self.foundKeys += 1 if 'vfcodeinsert_end' in kw: fs_args['codeinsert_end'] = kw['vfcodeinsert_end'] self.foundKeys += 1 if 'system' in kw: self._solver = kw['system'] try: fs_args['ignorespecial'] = [self._solver.name] except: raise TypeError, "Invalid solver system provided" self.foundKeys += 1 if self.pars: # automatically pass par values on to embedded system # when Rhs called parlist = self.pars.keys() parstr = "".join(["'%s': %s, "%(parname,parname) \ for parname in parlist]) if 'codeinsert_start' in fs_args: fs_args['codeinsert_start'] = \ ' %s.set(pars={%s})\n'%(self._solver.name, parstr) \ + fs_args['codeinsert_start'] else: fs_args['codeinsert_start'] = \ ' %s.set(pars={%s})\n'%(self._solver.name, parstr) else: fs_args['ignorespecial'] = [] self._solver = None if 'ignorespecial' in kw: fs_args['ignorespecial'].extend(kw['ignorespecial']) self.foundKeys += 1 if 'tdomain' in kw: self._tdomain = kw['tdomain'] if self._tdomain[0] >= self._tdomain[1]: raise PyDSTool_ValueError('tdomain values must be in order of increasing size') self.foundKeys += 1 else: self._tdomain = [-Inf, Inf] if 'ttype' in kw: indepvartype = kw['ttype'] assert indepvartype in _pynametype.keys(), 'Invalid ttype' self.foundKeys += 1 else: indepvartype = 'float' if 'tdata' in kw: self._tdata = kw['tdata'] if self._tdata[0] >= self._tdata[1]: raise PyDSTool_ValueError('tdata values must be in order of increasing size') # _tdata is made into list to be consistent with # other uses of it in other Generators... if self._tdomain[0] > self._tdata[0]: print 'tdata cannot be specified below smallest '\ 'value in tdomain\n (possibly due to uncertain'\ 'bounding). It has been automatically adjusted\n'\ ' from\n ', self._tdata[0], 'to', self._tdomain[0],\ '(difference of', self._tdomain[0]-self._tdata[0], ')' self._tdata[0] = self._tdomain[0] if self._tdomain[1] < self._tdata[1]: print 'tdata cannot be specified above largest '\ 'value in tdomain\n (possibly due to uncertain '\ 'bounding). It has been automatically adjusted\n'\ ' from\n ', self._tdata[1], 'to', self._tdomain[1],\ '(difference of', self._tdata[1]-self._tdomain[1], ')' self._tdata[1] = self._tdomain[1] self.foundKeys += 1 else: self._tdata = self._tdomain # default needed if 'tstep' in kw: self.tstep = kw['tstep'] if self.tstep > self._tdata[1]-self._tdata[0]: raise PyDSTool_ValueError('tstep too large') if indepvartype == 'int' and round(self.tstep) != self.tstep: raise PyDSTool_ValueError('tstep must be an integer for integer ttype') self.foundKeys += 1 else: if indepvartype == 'int': # default to 1 for integer types self.tstep = 1 else: # no reasonable default - so raise error raise PyDSTool_KeyError('tstep key needed for float ttype') if 'inputs' in kw: inputs = copy(kw['inputs']) self.inputs = {} if isinstance(inputs, Trajectory): # extract the variables self.inputs = inputs.variables elif isinstance(inputs, Variable): self.inputs = {inputs.name: inputs} elif isinstance(inputs, Pointset): # turn into Variables but only define at Pointset's # own independent variable values self.inputs = dict(zip(inputs.coordnames, [Variable(inputs[[n]],name=n) for n in inputs.coordnames])) elif isinstance(inputs, dict): self.inputs = inputs # ensure values are Variables or Pointsets for k, v in self.inputs.iteritems(): if not isinstance(v, Variable): try: self.inputs[k]=Variable(v) except: raise TypeError, "Invalid specification of inputs" else: raise TypeError, "Invalid specification of inputs" # don't check that variables have discrete domains in case wish # to use cts-valued ones sampled at discrete times fs_args['inputs'] = self.inputs.keys() self._register(self.inputs) self.foundKeys += 1 else: self.inputs = {} if 'ics' in kw: self._xdatadict = {} for k, v in dict(kw['ics']).iteritems(): self._xdatadict[str(k)] = v self.initialconditions = self._xdatadict for name in remain(varspecs.keys(), self._xdatadict.keys()): self.initialconditions[name] = NaN self.foundKeys += 1 else: self._xdatadict = {} for name in varspecs: self.initialconditions[name] = NaN if 'xtype' in kw: depvartype = kw['xtype'] assert depvartype in _pynametype.keys(), 'Invalid xtype' self.foundKeys += 1 else: depvartype = 'float' if 'auxvars' in kw: assert 'vars' not in kw, ("Cannot use both 'auxvars' and 'vars' " "keywords") if isinstance(kw['auxvars'], list): auxvars = [str(v) for v in kw['auxvars']] else: auxvars = [str(kw['auxvars'])] vars = remain(varspecs.keys(), auxvars) self.foundKeys += 1 elif 'vars' in kw: assert 'auxvars' not in kw, \ "Cannot use both 'auxvars' and 'vars' keywords" if isinstance(kw['vars'], list): vars = [str(v) for v in kw['vars']] else: vars = [str(kw['vars'])] auxvars = remain(varspecs.keys(), vars) self.foundKeys += 1 else: auxvars = [] vars = varspecs.keys() if auxvars != []: fs_args['auxvars'] = auxvars if 'xdomain' in kw: self._xdomain = {} for k, v in dict(kw['xdomain']).iteritems(): name = str(k) if type(v) in [list, Array, NArray]: assert len(v) == 2, \ "Invalid size of domain specification for "+name if v[0] >= v[1]: raise PyDSTool_ValueError('xdomain values must be in' 'order of increasing size') else: self._xdomain[name] = copy(v) elif type(v) in [float, int]: self._xdomain[name] = [v, v] else: raise PyDSTool_TypeError('Invalid type for xdomain spec' ' '+name) for name in remain(varspecs.keys(), self._xdomain.keys()): self._xdomain[name] = [-Inf, Inf] self.foundKeys += 1 else: self._xdomain = {} for name in varspecs: self._xdomain[name] = [-Inf, Inf] if 'reuseterms' in kw: fs_args['reuseterms'] = kw['reuseterms'] self.foundKeys += 1 fs_args.update({'vars': vars, 'varspecs': varspecs, 'name': self.name }) if 'pdomain' in kw: if self.pars: self._pdomain = {} for k, v in dict(kw['pdomain']).iteritems(): assert len(v) == 2, "Invalid interval for parameter %s"%k self._pdomain[str(k)] = v for name in self._pdomain: if self._pdomain[name][0] >= self._pdomain[name][1]: raise PyDSTool_ValueError('pdomain values must be in order of increasing size') for name in remain(self.pars.keys(), self._pdomain.keys()): self._pdomain[name] = [-Inf, Inf] self.foundKeys += 1 else: raise ValueError('Cannot specify pdomain because no pars declared') else: if self.pars: self._pdomain = {} for pname in self.pars: self._pdomain[pname] = [-Inf, Inf] if self.pars: self.parameterDomains = {} for pname in self._pdomain: self.parameterDomains[pname] = Interval(pname, 'float', self._pdomain[pname], self._abseps) try: cval = self.parameterDomains[pname].contains(self.pars[pname]) except KeyError: raise ValueError("Parameter %s is missing a value"%pname) if self.checklevel < 3: if cval is not notcontained: if cval is uncertain and self.checklevel == 2: print 'Warning: Parameter value at bound' else: raise PyDSTool_ValueError, 'Parameter value out of bounds' else: if cval is uncertain: raise PyDSTool_UncertainValueError, 'Parameter value at bound' elif cval is notcontained: raise PyDSTool_ValueError, 'Parameter value out of bounds' if 'fnspecs' in kw: fs_args['fnspecs'] = ensureStrArgDict(kw['fnspecs']) self.foundKeys += 1 ## fs_args['targetlang'] = 'python' ## if 'compiler' in kw: ## if fs_args['targetlang'] == 'python': ## print "Warning: redundant option 'compiler' for python target" ## self._compiler = kw['compiler'] ## self.foundKeys += 1 ## else: ## self._compiler = '' ## if fs_args['targetlang'] != 'python' and inputs: ## raise PyDSTool_ValueError('Cannot use external inputs with non-Python target language') self.funcspec = RHSfuncSpec(fs_args) # Holder and interface for events self.eventstruct = EventStruct() if 'enforcebounds' in kw: if 'activatedbounds' in kw: ab = kw['activatedbounds'] self.foundKeys += 1 else: ab = None if kw['enforcebounds']: self._makeBoundsEvents(precise=False, activatedbounds=ab) self.foundKeys += 1 if 'events' in kw: self._addEvents(kw['events']) self.foundKeys += 1 self.checkArgs(kw) self.numpars = len(self.pars) tindepdomain = Interval('t_domain', indepvartype, self._tdomain, self._abseps) tdepdomain = Interval('t', indepvartype, self._tdata, self._abseps) self.indepvariable = Variable(listid, tindepdomain, tdepdomain, 't') self._register(self.indepvariable) self.dimension = len(self.funcspec.vars) for xname in self.funcspec.vars + self.funcspec.auxvars: # Add a temporary dependent variable domain, for validation testing # during integration self.variables[xname] = Variable(indepdomain=tdepdomain, depdomain=Interval(xname, depvartype, self._xdomain[xname], self._abseps)) self._register(self.variables) self._generate_ixmaps() # Introduce any python-specified code to the local namespace ## if fs_args['targetlang'] == 'python': self.addMethods() # all registration completed self.validateSpec()
def __init__(self, kw): ctsGen.__init__(self, kw) self.needKeys.extend(['varspecs', 'ics']) self.optionalKeys.extend([ 'tdomain', 'pars', 'pdomain', 'xdomain', 'auxvars', 'vars', 'events', 'algparams', 'fnspecs', 'tdata' ]) fs_args = {} if 'varspecs' in kw: self.foundKeys += 1 varspecs = ensureStrArgDict(kw['varspecs']) else: raise PyDSTool_KeyError("Keyword 'varspecs' missing in argument") if 'tdomain' in kw: self._tdomain = kw['tdomain'] self.foundKeys += 1 else: self._tdomain = [-Inf, Inf] if 'tdata' in kw: self._tdata = kw['tdata'] # _tdata is made into list to be consistent with # other uses of it in other Dynamical Systems... if self._tdomain[0] > self._tdata[0]: print 'tdata cannot be specified below smallest '\ 'value in tdomain\n (possibly due to uncertain'\ 'bounding). It has been automatically adjusted\n'\ ' from\n ', self._tdata[0], 'to', self._tdomain[0],\ '(difference of', self._tdomain[0]-self._tdata[0], ')' self._tdata[0] = self._tdomain[0] if self._tdomain[1] < self._tdata[1]: print 'tdata cannot be specified above largest '\ 'value in tdomain\n (possibly due to uncertain '\ 'bounding). It has been automatically adjusted\n'\ ' from\n ', self._tdata[1], 'to', self._tdomain[1],\ '(difference of', self._tdata[1]-self._tdomain[1], ')' self._tdata[1] = self._tdomain[1] self.foundKeys += 1 else: self._tdata = self._tdomain # default needed if 'inputs' in kw: raise PyDSTool_KeyError, 'inputs option invalid for ImplicitFnGen class' if 'xdomain' in kw: self._xdomain = {} for k, v in dict(kw['xdomain']).iteritems(): name = str(k) if type(v) in [list, Array, NArray]: assert len(v) == 2, \ "Invalid size of domain specification for "+name if v[0] >= v[1]: raise PyDSTool_ValueError('xdomain values must be in' 'order of increasing size') else: self._xdomain[name] = copy(v) elif type(v) in [float, int]: self._xdomain[name] = [v, v] else: raise PyDSTool_TypeError('Invalid type for xdomain spec' ' ' + name) for name in remain(varspecs.keys(), self._xdomain.keys()): self._xdomain[name] = [-Inf, Inf] self.foundKeys += 1 else: self._xdomain = {} for name in varspecs: self._xdomain[name] = [-Inf, Inf] if 'ics' in kw: self._xdatadict = {} for k, v in dict(kw['ics']).iteritems(): self._xdatadict[str(k)] = v # initial condition for implicit function solver algorithm self.initialconditions = self._xdatadict for name in remain(varspecs.keys(), self._xdatadict.keys()): self.initialconditions[name] = NaN self.foundKeys += 1 if 'auxvars' in kw: assert 'vars' not in kw, \ "Cannot use both 'auxvars' and 'vars' keywords" if isinstance(kw['auxvars'], list): auxvars = [str(v) for v in kw['auxvars']] else: auxvars = [str(kw['auxvars'])] vars = remain(varspecs.keys(), auxvars) self.foundKeys += 1 elif 'vars' in kw: assert 'auxvars' not in kw, \ "Cannot use both 'auxvars' and 'vars' keywords" if isinstance(kw['vars'], list): vars = [str(v) for v in kw['vars']] else: vars = [str(kw['vars'])] auxvars = remain(varspecs.keys(), vars) self.foundKeys += 1 else: auxvars = [] vars = remain(self._xdomain.keys(), auxvars) if auxvars != []: fs_args['auxvars'] = auxvars fs_args.update({'vars': vars, 'varspecs': varspecs, 'name': self.name}) if 'pars' in kw: self.pars = {} if type(kw['pars']) == list: # may be a list of symbolic definitions for p in kw['pars']: try: self.pars[p.name] = p.tonumeric() except (AttributeError, TypeError): raise TypeError, "Invalid parameter symbolic definition" else: for k, v in dict(kw['pars']).iteritems(): self.pars[str(k)] = v fs_args['pars'] = self.pars.keys() self.foundKeys += 1 if 'pdomain' in kw: if self.pars: self._pdomain = {} for k, v in dict(kw['pdomain']).iteritems(): assert len(v) == 2, \ "Invalid size of domain specification for "+k self._pdomain[str(k)] = v for name in self._pdomain: if self._pdomain[name][0] >= self._pdomain[name][1]: raise PyDSTool_ValueError( 'pdomain values must be in order of increasing size' ) for name in remain(self.pars.keys(), self._pdomain.keys()): self._pdomain[name] = [-Inf, Inf] self.foundKeys += 1 else: raise ValueError( 'Cannot specify pdomain because no pars declared') else: if self.pars: self._pdomain = {} for pname in self.pars: self._pdomain[pname] = [-Inf, Inf] if self.pars: self.parameterDomains = {} for pname in self._pdomain: self.parameterDomains[pname] = Interval( pname, 'float', self._pdomain[pname], self._abseps) try: cval = self.parameterDomains[pname].contains( self.pars[pname]) except KeyError: raise ValueError("Parameter %s is missing a value" % pname) if self.checklevel < 3: if cval is not notcontained: if cval is uncertain and self.checklevel == 2: print 'Warning: Parameter value at bound' else: raise PyDSTool_ValueError, 'Parameter value out of bounds' else: if cval is uncertain: raise PyDSTool_UncertainValueError, 'Parameter value at bound' elif cval is notcontained: raise PyDSTool_ValueError, 'Parameter value out of bounds' if 'fnspecs' in kw: fs_args['fnspecs'] = ensureStrArgDict(kw['fnspecs']) self.foundKeys += 1 fs_args['targetlang'] = 'python' self.funcspec = ImpFuncSpec(fs_args) for s in self.funcspec.spec[0]: if s.find('x[') > -1: raise ValueError( 'Variable values cannot depend on ' 'other variables in implicit function specs -- ' 'in function:\n' + s) if 'algparams' in kw: self._algparams = copy(kw['algparams']) self.foundKeys += 1 else: self._algparams = {} if 'solvemethod' in self._algparams: if self._algparams['solvemethod'] not in _implicitSolveMethods: raise PyDSTool_ValueError, 'Invalid implicit solver type' # Holder and interface for events self.eventstruct = EventStruct() if 'events' in kw: raise PyDSTool_ValueError('ImplicitFnGen does not presently' \ ' support events') ## self._addEvents(kw['events']) ## assert self.eventstruct.getLowLevelEvents() == [], \ ## "Can only pass high level events to ImplicitFnGen objects" ## assert self.eventstruct.query(['highlevel', 'varlinked']) == [], \ ## "Only non-variable linked events are valid for this class" ## self.foundKeys += 1 self.checkArgs(kw) if self.pars: # is defined self._register(self.pars) self.numpars = len(self.pars) else: self.numpars = 0 assert self.funcspec.targetlang == 'python', \ ('Wrong target language for functional specification. ' 'Python needed for this class') self.newTempVars() self._generate_ixmaps() self.dimension = len(self.funcspec.vars)
def __init__(self, kw): ctsGen.__init__(self, kw) self.needKeys.extend(['varspecs', 'ics']) self.optionalKeys.extend(['tdomain', 'pars', 'pdomain', 'xdomain', 'auxvars', 'vars', 'events', 'algparams', 'fnspecs', 'tdata']) fs_args = {} if 'varspecs' in kw: self.foundKeys += 1 varspecs = ensureStrArgDict(kw['varspecs']) else: raise PyDSTool_KeyError("Keyword 'varspecs' missing in argument") if 'tdomain' in kw: self._tdomain = kw['tdomain'] self.foundKeys += 1 else: self._tdomain = [-Inf, Inf] if 'tdata' in kw: self._tdata = kw['tdata'] # _tdata is made into list to be consistent with # other uses of it in other Dynamical Systems... if self._tdomain[0] > self._tdata[0]: print 'tdata cannot be specified below smallest '\ 'value in tdomain\n (possibly due to uncertain'\ 'bounding). It has been automatically adjusted\n'\ ' from\n ', self._tdata[0], 'to', self._tdomain[0],\ '(difference of', self._tdomain[0]-self._tdata[0], ')' self._tdata[0] = self._tdomain[0] if self._tdomain[1] < self._tdata[1]: print 'tdata cannot be specified above largest '\ 'value in tdomain\n (possibly due to uncertain '\ 'bounding). It has been automatically adjusted\n'\ ' from\n ', self._tdata[1], 'to', self._tdomain[1],\ '(difference of', self._tdata[1]-self._tdomain[1], ')' self._tdata[1] = self._tdomain[1] self.foundKeys += 1 else: self._tdata = self._tdomain # default needed if 'inputs' in kw: raise PyDSTool_KeyError, 'inputs option invalid for ImplicitFnGen class' if 'xdomain' in kw: self._xdomain = {} for k, v in dict(kw['xdomain']).iteritems(): name = str(k) if type(v) in [list, Array, NArray]: assert len(v) == 2, \ "Invalid size of domain specification for "+name if v[0] >= v[1]: raise PyDSTool_ValueError('xdomain values must be in' 'order of increasing size') else: self._xdomain[name] = copy(v) elif type(v) in [float, int]: self._xdomain[name] = [v, v] else: raise PyDSTool_TypeError('Invalid type for xdomain spec' ' '+name) for name in remain(varspecs.keys(), self._xdomain.keys()): self._xdomain[name] = [-Inf, Inf] self.foundKeys += 1 else: self._xdomain = {} for name in varspecs: self._xdomain[name] = [-Inf, Inf] if 'ics' in kw: self._xdatadict = {} for k, v in dict(kw['ics']).iteritems(): self._xdatadict[str(k)] = v # initial condition for implicit function solver algorithm self.initialconditions = self._xdatadict for name in remain(varspecs.keys(), self._xdatadict.keys()): self.initialconditions[name] = NaN self.foundKeys += 1 if 'auxvars' in kw: assert 'vars' not in kw, \ "Cannot use both 'auxvars' and 'vars' keywords" if isinstance(kw['auxvars'], list): auxvars = [str(v) for v in kw['auxvars']] else: auxvars = [str(kw['auxvars'])] vars = remain(varspecs.keys(), auxvars) self.foundKeys += 1 elif 'vars' in kw: assert 'auxvars' not in kw, \ "Cannot use both 'auxvars' and 'vars' keywords" if isinstance(kw['vars'], list): vars = [str(v) for v in kw['vars']] else: vars = [str(kw['vars'])] auxvars = remain(varspecs.keys(), vars) self.foundKeys += 1 else: auxvars = [] vars = remain(self._xdomain.keys(), auxvars) if auxvars != []: fs_args['auxvars'] = auxvars fs_args.update({'vars': vars, 'varspecs': varspecs, 'name': self.name }) if 'pars' in kw: self.pars = {} if type(kw['pars']) == list: # may be a list of symbolic definitions for p in kw['pars']: try: self.pars[p.name] = p.tonumeric() except (AttributeError, TypeError): raise TypeError, "Invalid parameter symbolic definition" else: for k, v in dict(kw['pars']).iteritems(): self.pars[str(k)] = v fs_args['pars'] = self.pars.keys() self.foundKeys += 1 if 'pdomain' in kw: if self.pars: self._pdomain = {} for k, v in dict(kw['pdomain']).iteritems(): assert len(v) == 2, \ "Invalid size of domain specification for "+k self._pdomain[str(k)] = v for name in self._pdomain: if self._pdomain[name][0] >= self._pdomain[name][1]: raise PyDSTool_ValueError('pdomain values must be in order of increasing size') for name in remain(self.pars.keys(), self._pdomain.keys()): self._pdomain[name] = [-Inf, Inf] self.foundKeys += 1 else: raise ValueError('Cannot specify pdomain because no pars declared') else: if self.pars: self._pdomain = {} for pname in self.pars: self._pdomain[pname] = [-Inf, Inf] if self.pars: self.parameterDomains = {} for pname in self._pdomain: self.parameterDomains[pname] = Interval(pname, 'float', self._pdomain[pname], self._abseps) try: cval = self.parameterDomains[pname].contains(self.pars[pname]) except KeyError: raise ValueError("Parameter %s is missing a value"%pname) if self.checklevel < 3: if cval is not notcontained: if cval is uncertain and self.checklevel == 2: print 'Warning: Parameter value at bound' else: raise PyDSTool_ValueError, 'Parameter value out of bounds' else: if cval is uncertain: raise PyDSTool_UncertainValueError, 'Parameter value at bound' elif cval is notcontained: raise PyDSTool_ValueError, 'Parameter value out of bounds' if 'fnspecs' in kw: fs_args['fnspecs'] = ensureStrArgDict(kw['fnspecs']) self.foundKeys += 1 fs_args['targetlang'] = 'python' self.funcspec = ImpFuncSpec(fs_args) for s in self.funcspec.spec[0]: if s.find('x[') > -1: raise ValueError('Variable values cannot depend on ' 'other variables in implicit function specs -- ' 'in function:\n'+s) if 'algparams' in kw: self._algparams = copy(kw['algparams']) self.foundKeys += 1 else: self._algparams = {} if 'solvemethod' in self._algparams: if self._algparams['solvemethod'] not in _implicitSolveMethods: raise PyDSTool_ValueError, 'Invalid implicit solver type' # Holder and interface for events self.eventstruct = EventStruct() if 'events' in kw: raise PyDSTool_ValueError('ImplicitFnGen does not presently' \ ' support events') ## self._addEvents(kw['events']) ## assert self.eventstruct.getLowLevelEvents() == [], \ ## "Can only pass high level events to ImplicitFnGen objects" ## assert self.eventstruct.query(['highlevel', 'varlinked']) == [], \ ## "Only non-variable linked events are valid for this class" ## self.foundKeys += 1 self.checkArgs(kw) if self.pars: # is defined self._register(self.pars) self.numpars = len(self.pars) else: self.numpars = 0 assert self.funcspec.targetlang == 'python', \ ('Wrong target language for functional specification. ' 'Python needed for this class') self.newTempVars() self._generate_ixmaps() self.dimension = len(self.funcspec.vars)