def make_system(M, ics, pars=None): n = len(M) xvarlist = ["x%i" % i for i in range(1, n + 1)] xvars = [Var(x) for x in xvarlist] varspecs = {} jac_str_list = [] for i, xv in enumerate(xvars): M_row = M[i] varspecs[str(xv)] = pt.QuantSpec( str(xv) + "_DE", "+".join([str(M_row[j] * xvars[j]) for j in range(n)])) jac_str_list.append("[" + ",".join([str(M_row[j]) for j in range(n)]) + "]") jac_str = "[" + ",".join(jac_str_list) + "]" print(jac_str) DSargs = args(name="linear_net") DSargs.varspecs = varspecs DSargs.ics = dict(zip(xvars, ics)) DSargs.pars = pars DSargs.tdata = [0, 1000] DSargs.fnspecs = {"Jacobian": (["t"] + xvarlist, jac_str)} return Generator.Vode_ODEsystem(DSargs)
def make_measure(fn_name, fn_spec, **defs): """Dynamically create a python function for use with calculation context. """ all_defs = defs.copy() q = dst.QuantSpec('_dummy_', fn_spec, treatMultiRefs=False) import PyDSTool.parseUtils as pu mapping = pu.symbolMapClass() assumed_modules = [] tokens = q.parser.tokenized for sym in q.freeSymbols: # Hack, for now: if first (therefore, assumed all) # occurrences of symbol are in quotes, then don't convert. # Better solution would be to make parser create "x" as a single # symbol, at least with a detect quote option first_ix = tokens.index(sym) if first_ix == 0 or (first_ix > 0 and tokens[first_ix-1] not in ['"', "'"]): if pu.isHierarchicalName(sym): parts = sym.split('.') if parts[0] == 'sim': mapping[sym] = 'con.'+sym ## elif parts[0] == 'bombardier': ## # special case as this factory function is defined in that ## # module so that reference will fail at runtime: remove ## # 'bombardier' prefix ## rest_sym = '.'.join(parts[1:]) ## mapping[sym] = rest_sym ## scope = globals() ## # locals override ## scope.update(locals()) ## if parts[1] in scope: ## all_defs[parts[1]] = scope[parts[1]] ## else: ## raise ValueError("Cannot resolve scope of symbol '%s'"%sym) else: # assume module reference assumed_modules.append(parts[0]) # record here to ensure inclusion in dyn_dummy mapping[sym] = 'self.'+sym else: mapping[sym] = 'con.workspace.'+sym elif first_ix > 0 and tokens[first_ix-1] in ['"', "'"]: # put this symbol in the mapping values to ensure not included # as an argument to the function mapping[sym] = sym q.mapNames(mapping) import types for module_name in assumed_modules: global_scope = globals() # test if module name in scope if module_name in global_scope: _mod = global_scope[module_name] if isinstance(_mod, types.ModuleType): all_defs[module_name] = _mod # dyn_dummy contains dummy mappings but declares symbols to leave # evaluating until runtime dyn_dummy = dict(zip(mapping.values(), ['']*len(mapping))) funq = dst.expr2fun(q, ensure_args=['con'], ensure_dynamic=dyn_dummy, for_funcspec=False, fn_name=fn_name, **all_defs) # decorate output funq.attr_name = fn_name return funq