示例#1
0
 def __init__(self, kw):
     ctsGen.__init__(self, kw)
     self.diagnostics._errmessages[E_COMPUTFAIL] = "Integration failed"
     # user auxiliary function interface
     self.auxfns = auxfn_container(self)
     dispatch_list = [
         "varspecs",
         "tdomain",
         "tdata",
         "inputs",
         "ics",
         "allvars",
         "xtype",
         "xdomain",
         "reuseterms",
         "algparams",
         "pars",
         "pdomain",
         "fnspecs",
         "target",
         "vfcodeinserts",
         "ignorespecial",
     ]
     # process keys and build func spec
     self.funcspec = RHSfuncSpec(self._kw_process_dispatch(dispatch_list, kw))
     self.indepvartype = float
     for v in self.inputs.values():
         if not iscontinuous(v):
             raise ValueError("External inputs for ODE system must be " "continuously defined")
     self._kw_process_events(kw)
     self.checkArgs(kw)
     tindepdomain = Interval("t_domain", self.indepvartype, self.tdomain, self._abseps)
     tdepdomain = Interval("t", self.indepvartype, self.tdata, self._abseps)
     self.indepvariable = Variable(listid, tindepdomain, tdepdomain, "t")
     self._register(self.indepvariable)
     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, self.xtype[xname], self.xdomain[xname], self._abseps)
         )
     self._register(self.variables)
     self._generate_ixmaps()
     # Introduce any python-specified code to the local namespace
     self.addMethods()
     # all registration completed
     self.validateSpec()
示例#2
0
 def __init__(self, kw):
     ctsGen.__init__(self, kw)
     self.diagnostics._errmessages[E_COMPUTFAIL] = 'Integration failed'
     # user auxiliary function interface
     self.auxfns = auxfn_container(self)
     dispatch_list = [
         'varspecs', 'tdomain', 'tdata', 'inputs', 'ics', 'allvars',
         'xtype', 'xdomain', 'reuseterms', 'algparams', 'pars', 'pdomain',
         'fnspecs', 'target', 'vfcodeinserts', 'ignorespecial'
     ]
     # process keys and build func spec
     self.funcspec = RHSfuncSpec(
         self._kw_process_dispatch(dispatch_list, kw))
     self.indepvartype = float
     for v in self.inputs.values():
         if not iscontinuous(v):
             raise ValueError("External inputs for ODE system must be "
                              "continuously defined")
     self._kw_process_events(kw)
     self.checkArgs(kw)
     tindepdomain = Interval('t_domain', self.indepvartype, self.tdomain,
                             self._abseps)
     tdepdomain = Interval('t', self.indepvartype, self.tdata, self._abseps)
     self.indepvariable = Variable(listid, tindepdomain, tdepdomain, 't')
     self._register(self.indepvariable)
     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, self.xtype[xname],
                                self.xdomain[xname], self._abseps))
     self._register(self.variables)
     self._generate_ixmaps()
     # Introduce any python-specified code to the local namespace
     self.addMethods()
     # all registration completed
     self.validateSpec()
示例#3
0
 def set(self, **kw):
     """Set ODE system parameters"""
     if remain(kw.keys(), self._validKeys) != []:
         raise KeyError("Invalid keys in argument")
     if "globalt0" in kw:
         # pass up to generic treatment for this
         ctsGen.set(self, globalt0=kw["globalt0"])
         # set this True so that can adjust the input time arrays
         # to new globalt0
         self._extInputsChanged = True
     if "checklevel" in kw:
         # pass up to generic treatment for this
         ctsGen.set(self, checklevel=kw["checklevel"])
     if "abseps" in kw:
         # pass up to generic treatment for this
         ctsGen.set(self, abseps=kw["abseps"])
     # optional keys for this call are ['pars', 'tdomain', 'ics',
     #   'algparams', 'tdata', 'xdomain', 'pdomain', 'inputs']
     if "ics" in kw:
         for k_temp, v in kw["ics"].items():
             k = self._FScompatibleNames(k_temp)
             if k in self.funcspec.vars + self.funcspec.auxvars:
                 self._xdatadict[k] = ensurefloat(v)
             else:
                 raise ValueError("Illegal variable name %s" % k)
         self.initialconditions.update(self._xdatadict)
     tchange = False
     if "tdata" in kw:
         self.tdata = kw["tdata"]
         tchange = True
     if "tdomain" in kw:
         self.tdomain = kw["tdomain"]
         self.indepvariable.indepdomain.set(self.tdomain)
         tchange = True
     if tchange:
         if self.tdomain[0] > self.tdata[0]:
             if self.indepvariable.indepdomain.contains(self.tdata[0]) == uncertain:
                 self.diagnostics.warnings.append((W_UNCERTVAL, (self.tdata[0], self.tdomain)))
             else:
                 print(
                     "tdata cannot be specified below smallest "
                     "value in tdomain\n (possibly due to uncertain bounding)."
                     " It has been automatically adjusted from %f to %f (difference of %f)\n"
                     % (self.tdata[0], self.tdomain[0], 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]:
             if self.indepvariable.indepdomain.contains(self.tdata[1]) == uncertain:
                 self.diagnostics.warnings.append((W_UNCERTVAL, (self.tdata[1], self.tdomain)))
             else:
                 print(
                     "tdata cannot be specified above largest "
                     "value in tdomain\n (possibly due to uncertain bounding)."
                     " It has been automatically adjusted from %f to %f (difference of %f)\n"
                     % (self.tdomain[1], self.tdomain[1], self.tdata[1] - self.tdomain[1])
                 )
                 if self._modeltag:
                     print("Try reducing step size in model.")
             self.tdata[1] = self.tdomain[1]
         self.indepvariable.depdomain.set(self.tdata)
     if "xdomain" in kw:
         for k_temp, v in kw["xdomain"].items():
             k = self._FScompatibleNames(k_temp)
             if k in self.funcspec.vars + self.funcspec.auxvars:
                 if isinstance(v, _seq_types):
                     assert len(v) == 2, "Invalid size of domain specification for " + k
                     if v[0] >= v[1]:
                         raise PyDSTool_ValueError("xdomain values must be" "in order of increasing " "size")
                     else:
                         self.xdomain[k] = copy(v)
                 elif isinstance(v, _num_types):
                     self.xdomain[k] = [v, v]
                 else:
                     raise PyDSTool_TypeError("Invalid type for xdomain spec" " " + k)
             else:
                 raise ValueError("Illegal variable name")
             try:
                 self.variables[k].depdomain.set(v)
             except TypeError:
                 raise TypeError(
                     "xdomain must be a dictionary of variable" " names -> valid interval 2-tuples or " "singletons"
                 )
             try:
                 evs = self.eventstruct.events.values()
             except AttributeError:
                 evs = []
             for ev in evs:
                 ev.xdomain[k] = self.xdomain[k]
     if "pdomain" in kw:
         for k_temp, v in kw["pdomain"].items():
             k = self._FScompatibleNames(k_temp)
             if k in self.funcspec.pars:
                 if isinstance(v, _seq_types):
                     assert len(v) == 2, "Invalid size of domain specification for " + k
                     if v[0] >= v[1]:
                         raise PyDSTool_ValueError("pdomain values must be" "in order of increasing " "size")
                     else:
                         self.pdomain[k] = copy(v)
                 elif isinstance(v, _num_types):
                     self.pdomain[k] = [v, v]
                 else:
                     raise PyDSTool_TypeError("Invalid type for pdomain spec" " " + k)
             else:
                 raise ValueError("Illegal parameter name")
             try:
                 self.parameterDomains[k].depdomain.set(v)
             except TypeError:
                 raise TypeError(
                     "xdomain must be a dictionary of parameter" " names -> valid interval 2-tuples or " "singletons"
                 )
             try:
                 evs = self.eventstruct.events.values()
             except AttributeError:
                 evs = []
             for ev in evs:
                 ev.pdomain[k] = self.pdomain[k]
     if "pars" in kw:
         for k_temp, v in kw["pars"].items():
             k = self._FScompatibleNames(k_temp)
             if k in self.pars:
                 cval = self.parameterDomains[k].contains(v)
                 if self.checklevel < 3:
                     if cval is not notcontained:
                         self.pars[k] = ensurefloat(v)
                         if cval is uncertain and self.checklevel == 2:
                             print("Warning: Parameter %s: value at bound" % str(k))
                     else:
                         raise PyDSTool_ValueError("Parameter %s: value out of bounds" % str(k))
                 else:
                     if cval is contained:
                         self.pars[k] = ensurefloat(v)
                     elif cval is uncertain:
                         raise PyDSTool_UncertainValueError("Parameter %s: value at bound" % str(k))
                     else:
                         raise PyDSTool_ValueError("Parameter %s: value out of bounds" % str(k))
             else:
                 raise PyDSTool_ValueError("Illegal parameter name " + str(k))
     if "algparams" in kw:
         for k, v in kw["algparams"].items():
             self.algparams[k] = v
             if k in ("eventActive", "eventTol", "eventDelay", "eventDir", "eventInt", "eventTerm", "maxbisect"):
                 raise ValueError("Use appropriate setX method in Generator.eventstruct")
     if "inputs" in kw:
         assert self.inputs, "Cannot provide inputs after " "initialization without them"
         inputs = copy(kw["inputs"])
         _inputs = {}
         if isinstance(inputs, Trajectory):
             # extract the variables
             _inputs = self._FScompatibleNames(inputs.variables)
         elif isinstance(inputs, Variable):
             _inputs = {self._FScompatibleNames(inputs.name): inputs}
         elif isinstance(inputs, Pointset):
             # turn into Variables
             for n in inputs.coordnames:
                 x_array = inputs[n]
                 nFS = self._FScompatibleNames(n)
                 _input[nFS] = Variable(
                     interp1d(inputs.indepvararray, x_array),
                     "t",
                     Interval(nFS, float, extent(x_array), abseps=self._abseps),
                     name=n,
                 )
         elif isinstance(inputs, dict):
             _inputs = self._FScompatibleNames(inputs)
             # ensure values are Variables
             for v in _inputs.values():
                 if not isinstance(v, Variable):
                     raise TypeError("Invalid specification of inputs")
         else:
             raise TypeError("Invalid specification of inputs")
         for v in _inputs.values():
             if not iscontinuous(v):
                 raise ValueError("External inputs for ODE system must be " "continously defined")
         if _inputs:
             for i in _inputs:
                 assert i in self.inputs, "Incorrect input name provided"
                 self.inputs[i] = _inputs[i]
             # re-calc inputs ixmaps
             self._generate_ixmaps("inputs")
         self._extInputsChanged = True
     if "inputs_t0" in kw:
         assert self.inputs, "Cannot provide inputs after " "initialization without them"
         inputs_t0 = self._FScompatibleNames(kw["inputs_t0"])
         for iname, t0 in inputs_t0.items():
             self.inputs[iname]._internal_t_offset = t0
         self._extInputsChanged = True
示例#4
0
 def set(self, **kw):
     """Set ODE system parameters"""
     if remain(kw.keys(), self._validKeys) != []:
         raise KeyError("Invalid keys in argument")
     if 'globalt0' in kw:
         # pass up to generic treatment for this
         ctsGen.set(self, globalt0=kw['globalt0'])
         # set this True so that can adjust the input time arrays
         # to new globalt0
         self._extInputsChanged = True
     if 'checklevel' in kw:
         # pass up to generic treatment for this
         ctsGen.set(self, checklevel=kw['checklevel'])
     if 'abseps' in kw:
         # pass up to generic treatment for this
         ctsGen.set(self, abseps=kw['abseps'])
     # optional keys for this call are ['pars', 'tdomain', 'ics',
     #   'algparams', 'tdata', 'xdomain', 'pdomain', 'inputs']
     if 'ics' in kw:
         for k_temp, v in kw['ics'].items():
             # str() ensures that Symbolic objects can be passed
             k = str(self._FScompatibleNames(k_temp))
             if k in self.funcspec.vars + self.funcspec.auxvars:
                 self._xdatadict[k] = ensurefloat(v)
             else:
                 raise ValueError('Illegal variable name %s' % k)
         self.initialconditions.update(self._xdatadict)
     tchange = False
     if 'tdata' in kw:
         self.tdata = kw['tdata']
         tchange = True
     if 'tdomain' in kw:
         self.tdomain = kw['tdomain']
         self.indepvariable.indepdomain.set(self.tdomain)
         tchange = True
     if tchange:
         if self.tdomain[0] > self.tdata[0]:
             if self.indepvariable.indepdomain.contains(
                     self.tdata[0]) == uncertain:
                 self.diagnostics.warnings.append(
                     (W_UNCERTVAL, (self.tdata[0], self.tdomain)))
             else:
                 print('tdata cannot be specified below smallest '\
                       'value in tdomain\n (possibly due to uncertain bounding).'\
                       ' It has been automatically adjusted from %f to %f (difference of %f)\n' % (
                       self.tdata[0], self.tdomain[0], 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]:
             if self.indepvariable.indepdomain.contains(
                     self.tdata[1]) == uncertain:
                 self.diagnostics.warnings.append(
                     (W_UNCERTVAL, (self.tdata[1], self.tdomain)))
             else:
                 print('tdata cannot be specified above largest '\
                       'value in tdomain\n (possibly due to uncertain bounding).'\
                       ' It has been automatically adjusted from %f to %f (difference of %f)\n' % (
                       self.tdomain[1], self.tdomain[1], self.tdata[1]-self.tdomain[1]))
                 if self._modeltag:
                     print('Try reducing step size in model.')
             self.tdata[1] = self.tdomain[1]
         self.indepvariable.depdomain.set(self.tdata)
     if 'xdomain' in kw:
         for k_temp, v in kw['xdomain'].items():
             k = str(self._FScompatibleNames(k_temp))
             if k in self.funcspec.vars + self.funcspec.auxvars:
                 if isinstance(v, _seq_types):
                     assert len(v) == 2, \
                            "Invalid size of domain specification for "+k
                     if v[0] >= v[1]:
                         raise PyDSTool_ValueError('xdomain values must be'
                                                   'in order of increasing '
                                                   'size')
                     else:
                         self.xdomain[k] = copy(v)
                 elif isinstance(v, _num_types):
                     self.xdomain[k] = [v, v]
                 else:
                     raise PyDSTool_TypeError(
                         'Invalid type for xdomain spec'
                         ' ' + k)
             else:
                 raise ValueError('Illegal variable name')
             try:
                 self.variables[k].depdomain.set(v)
             except TypeError:
                 raise TypeError('xdomain must be a dictionary of variable'
                                 ' names -> valid interval 2-tuples or '
                                 'singletons')
             try:
                 evs = self.eventstruct.events.values()
             except AttributeError:
                 evs = []
             for ev in evs:
                 ev.xdomain[k] = self.xdomain[k]
     if 'pdomain' in kw:
         for k_temp, v in kw['pdomain'].items():
             k = str(self._FScompatibleNames(k_temp))
             if k in self.funcspec.pars:
                 if isinstance(v, _seq_types):
                     assert len(v) == 2, \
                            "Invalid size of domain specification for "+k
                     if v[0] >= v[1]:
                         raise PyDSTool_ValueError('pdomain values must be'
                                                   'in order of increasing '
                                                   'size')
                     else:
                         self.pdomain[k] = copy(v)
                 elif isinstance(v, _num_types):
                     self.pdomain[k] = [v, v]
                 else:
                     raise PyDSTool_TypeError(
                         'Invalid type for pdomain spec'
                         ' ' + k)
             else:
                 raise ValueError('Illegal parameter name')
             try:
                 self.parameterDomains[k].set(v)
             except TypeError:
                 raise TypeError('xdomain must be a dictionary of parameter'
                                 ' names -> valid interval 2-tuples or '
                                 'singletons')
             try:
                 evs = self.eventstruct.events.values()
             except AttributeError:
                 evs = []
             for ev in evs:
                 ev.pdomain[k] = self.pdomain[k]
     if 'pars' in kw:
         for k_temp, v in kw['pars'].items():
             k = str(self._FScompatibleNames(k_temp))
             if k in self.pars:
                 cval = self.parameterDomains[k].contains(v)
                 if self.checklevel < 3:
                     if cval is not notcontained:
                         self.pars[k] = ensurefloat(v)
                         if cval is uncertain and self.checklevel == 2:
                             print('Warning: Parameter %s: value at bound' %
                                   str(k))
                     else:
                         raise PyDSTool_ValueError(
                             'Parameter %s: value out of bounds' % str(k))
                 else:
                     if cval is contained:
                         self.pars[k] = ensurefloat(v)
                     elif cval is uncertain:
                         raise PyDSTool_UncertainValueError(
                             'Parameter %s: value at bound' % str(k))
                     else:
                         raise PyDSTool_ValueError(
                             'Parameter %s: value out of bounds' % str(k))
             else:
                 raise PyDSTool_ValueError('Illegal parameter name ' +
                                           str(k))
     if 'algparams' in kw:
         for k, v in kw['algparams'].items():
             self.algparams[k] = v
             if k in ('eventActive', 'eventTol', 'eventDelay', 'eventDir',
                      'eventInt', 'eventTerm', 'maxbisect'):
                 raise ValueError(
                     "Use appropriate setX method in Generator.eventstruct")
     if 'inputs' in kw:
         assert self.inputs, ('Cannot provide inputs after '
                              'initialization without them')
         inputs = copy(kw['inputs'])
         _inputs = {}
         if isinstance(inputs, Trajectory):
             # extract the variables
             _inputs = self._FScompatibleNames(inputs.variables)
         elif isinstance(inputs, Variable):
             _inputs = {self._FScompatibleNames(inputs.name): inputs}
         elif isinstance(inputs, Pointset):
             # turn into Variables
             for n in inputs.coordnames:
                 x_array = inputs[n]
                 nFS = self._FScompatibleNames(n)
                 _input[nFS] = Variable(interp1d(inputs.indepvararray,
                                                 x_array),
                                        't',
                                        Interval(nFS,
                                                 float,
                                                 extent(x_array),
                                                 abseps=self._abseps),
                                        name=n)
         elif isinstance(inputs, dict):
             _inputs = self._FScompatibleNames(inputs)
             # ensure values are Variables
             for v in _inputs.values():
                 if not isinstance(v, Variable):
                     raise TypeError("Invalid specification of inputs")
         else:
             raise TypeError("Invalid specification of inputs")
         for v in _inputs.values():
             if not iscontinuous(v):
                 raise ValueError("External inputs for ODE system must be "
                                  "continously defined")
         if _inputs:
             for i in _inputs:
                 assert i in self.inputs, 'Incorrect input name provided'
                 self.inputs[i] = _inputs[i]
             # re-calc inputs ixmaps
             self._generate_ixmaps('inputs')
         self._extInputsChanged = True
     if 'inputs_t0' in kw:
         assert self.inputs, ('Cannot provide inputs after '
                              'initialization without them')
         inputs_t0 = self._FScompatibleNames(kw['inputs_t0'])
         for iname, t0 in inputs_t0.items():
             self.inputs[iname]._internal_t_offset = t0
         self._extInputsChanged = True
示例#5
0
 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()
示例#6
0
    def set(self, **kw):
        """Set ODE system parameters"""

        validKeys = ['globalt0', 'xdomain', 'tdata', 'tdomain', 'checklevel',
                     'ics', 'pars', 'algparams', 'inputs', 'pdomain']
        assert remain(kw.keys(), validKeys) == [], "Invalid keys in argument"
        if 'globalt0' in kw:
            # pass up to generic treatment for this
            ctsGen.set(self, globalt0=kw['globalt0'])
            # set this True so that can adjust the input time arrays
            # to new globalt0
            self._extInputsChanged = True
        if 'checklevel' in kw:
            # pass up to generic treatment for this
            ctsGen.set(self, checklevel=kw['checklevel'])
        # optional keys for this call are ['pars', 'tdomain', 'ics',
        #   'algparams', 'tdata', 'xdomain', 'pdomain', 'inputs']
        if 'ics' in kw:
            for k_temp, v in kw['ics'].iteritems():
                k = k_temp.replace(NAMESEP, "_")
                if k in self.funcspec.vars+self.funcspec.auxvars:
                    self._xdatadict[k] = v
                else:
                    raise ValueError, 'Illegal variable name %s'%k
            self.initialconditions.update(self._xdatadict)
        if 'tdata' in kw:
            self._tdata = kw['tdata']
        if 'tdomain' in kw:
            self._tdomain = kw['tdomain']
            self.indepvariable.indepdomain.set(self._tdomain)
        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 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 from\n ', \
                  self._tdomain[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.indepvariable.depdomain.set(self._tdata)
        if 'xdomain' in kw:
            for k_temp, v in kw['xdomain'].iteritems():
                k = k_temp.replace(NAMESEP, "_")   # use internal names
                if k in self.funcspec.vars+self.funcspec.auxvars:
                    if type(v) in [list, Array, NArray]:
                        assert len(v) == 2, \
                               "Invalid size of domain specification for "+k
                        if v[0] >= v[1]:
                            raise PyDSTool_ValueError('xdomain values must be'
                                                      'in order of increasing '
                                                      'size')
                        else:
                            self._xdomain[k] = copy(v)
                    elif type(v) in [float, int]:
                        self._xdomain[k] = [v, v]
                    else:
                        raise PyDSTool_TypeError('Invalid type for xdomain spec'
                                                 ' '+k)
                else:
                    raise ValueError, 'Illegal variable name'
                try:
                    self.variables[k].depdomain.set(v)
                except TypeError:
                    raise TypeError, ('xdomain must be a dictionary of variable'
                                      ' names -> valid interval 2-tuples or '
                                      'singletons')
                for ev in self.eventstruct.events.values():
                    ev._xdomain[k] = self._xdomain[k]
        if 'pdomain' in kw:
            for k_temp, v in kw['pdomain'].iteritems():
                k = k_temp.replace(NAMESEP, "_")   # use internal names
                if k in self.funcspec.pars:
                    if type(v) in [list, Array, NArray]:
                        assert len(v) == 2, \
                               "Invalid size of domain specification for "+k
                        if v[0] >= v[1]:
                            raise PyDSTool_ValueError('pdomain values must be'
                                                      'in order of increasing '
                                                      'size')
                        else:
                            self._pdomain[k] = copy(v)
                    elif type(v) in [float, int]:
                        self._pdomain[k] = [v, v]
                    else:
                        raise PyDSTool_TypeError('Invalid type for pdomain spec'
                                                 ' '+k)
                else:
                    raise ValueError, 'Illegal parameter name'
                try:
                    self.parameterDomains[k].depdomain.set(v)
                except TypeError:
                    raise TypeError, ('xdomain must be a dictionary of parameter'
                                      ' names -> valid interval 2-tuples or '
                                      'singletons')
                for ev in self.eventstruct.events.values():
                    ev._pdomain[k] = self._pdomain[k]
        if 'pars' in kw:
            assert self.numpars > 0, ('No pars were declared for this '
                                      'model')
            for k_temp, v in kw['pars'].iteritems():
                k = k_temp.replace(NAMESEP, "_")
                if k in self.pars:
                    cval = self.parameterDomains[k].contains(v)
                    if self.checklevel < 3:
                        if cval is not notcontained:
                            self.pars[k] = v
                            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 contained:
                            self.pars[k] = v
                        elif cval is uncertain:
                            raise PyDSTool_UncertainValueError, 'Parameter value at bound'
                        else:
                            raise PyDSTool_ValueError, 'Parameter value out of bounds'
                else:
                    raise PyDSTool_ValueError, 'Illegal parameter name'
        if 'algparams' in kw:
            for k, v in kw['algparams'].iteritems():
                self._algparams[k] = v
        if 'inputs' in kw:
            assert self.inputs, ('Cannot provide inputs after '
                                             'initialization without them')
            inputs = copy(kw['inputs'])
            _inputs = {}
            if isinstance(inputs, Trajectory):
                # extract the variables
                _inputs = inputs.variables
            elif isinstance(inputs, Variable):
                _inputs = {inputs.name: inputs}
            elif isinstance(inputs, Pointset):
                # turn into Variables
                _inputs = dict(zip(inputs.coordnames,
                            [Variable(inputs[n],name=n) for n in inputs.coordnames]))
            elif isinstance(inputs, dict):
                _inputs = inputs
                # ensure values are Variables or Pointsets
                for k, v in _inputs.iteritems():
                    if not isinstance(v, Variable):
                        try:
                            _inputs[k]=Variable(v)
                        except:
                            raise TypeError, "Invalid specification of inputs"
            else:
                raise TypeError, "Invalid specification of inputs"
            for v in _inputs.values():
                if not iscontinuous(v):
                    raise ValueError, "External inputs for ODE system must be continously defined"
            if _inputs:
                for i in _inputs:
                    assert i in self.inputs, 'Incorrect input name provided'
                    self.inputs[i] = _inputs[i]
                # re-calc inputs ixmaps
                self._generate_ixmaps('inputs')
            self._extInputsChanged = True