def init_eval(method, name): if (name not in method.inits_evals.keys() or method.inits_evals[name] is None): if VERBOSE >= 2: print(' Init value for {}'.format(name)) if name in method.ops_names: obj = copy.copy(getattr(method, name+'_op')) sobj = eval_op(method, obj) elif name == 'y': obj = copy.copy(geteval(method, 'output')) sobj = substitute(obj, method.subscpp) sobj = numpy.asarray(sobj, dtype=float) else: obj = copy.copy(geteval(method, name)) sobj = substitute(obj, method.subscpp) while not len(free_symbols(sobj)) == 0: sobjpre = copy.copy(sobj) sobj = substitute(sobj, method.subscpp) if sobj == sobjpre: freesymbs = free_symbols(sobj) text = 'Missing substitution symbols: {}'.format(freesymbs) raise AttributeError(text) if not isinstance(sobj, (float, list)): sobj = numpy.asarray(sobj.tolist(), dtype=float) else: sobj = numpy.asarray(sobj, dtype=float) method.inits_evals[name] = sobj
def explicit_implicit(self): v = geteval(self, 'v') jacF = geteval(self, 'jactempF') args = (v, ) * 2 mats = (jacF[:, :self.dims.x()], jacF[:, self.dims.x():]) * 2 criterion = list(zip(mats, args)) self.linear_nonlinear(criterion=criterion)
def func(): Fa = geteval(method, 'tempF' + a) vl = geteval(method, 'vl') JacFal = geteval( method, 'jactempF' + a + 'l', ) return sumvecs(Fa, [-e for e in matvecprod(JacFal, vl)])
def inds(): """ get indices deb and end of a block""" deb = 0 for current_name in names: if current_name != name: deb += geteval(core.dims, current_name) else: end = deb + geteval(core.dims, current_name) break return (deb, end)
def inds(): """ get indices deb and end of a block""" deb = 0 for current_name in names: if current_name != name: deb += geteval(core.dims, current_name) else: end = deb + geteval(core.dims, current_name) break return (deb, end)
def _load(self): if not self.methodWidget.status: self.methodWidget._build() options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog dialog = QFileDialog() filename = os.path.join(self.methodWidget.folder, self.methodWidget.label + '.init') dialog.selectFile(filename) fname, _ = dialog.getOpenFileName(self, 'Load initial values', filename, "All Files (*);;PyPHS initial values (*.init)", "PyPHS initial values (*.init)", options=options) if not fname == '': with open(fname, 'r') as f: for name in self._names: line = f.readline() if len(line) > 0: values = list(map(float, line.split(' '))) if not len(values) == len(geteval(self.method, name)): text = 'Initial values shape error: ' + name raise ValueError(text) else: values = [] self.inits[name] = values self.modifSig.sig.emit()
def symb2ref(self, symb): symb = self.method.symbols(str(symb)) for name in self._names: symbs = geteval(self.method, name) if symb in symbs: index = symbs.index(symb) return (name, index)
def _str_vectors(simu): vectors = str() for name in simu.data.names: dim = len(geteval(simu.method, name)) if dim > 0: temp = name, dim, CONFIG_CPP['float'] vectors += "\n {2} {0}[{1}];".format(*temp) return indent(vectors)
def _str_vectors(simu): vectors = str() for name in simu.data.names: dim = len(geteval(simu.method, name)) if dim > 0: temp = name, dim, CONFIG_CPP['float'] vectors += "\n {2} {0}[{1}];".format(*temp) return indent(vectors)
def _str_updateInputs(simu, objlabel): updateInputs = str() for name in ['u', 'p']: dim = len(geteval(simu.method, name)) if dim > 0: temp = objlabel.lower(), name, CONFIG_CPP['float'], dim updateInputs += "\n{0}.set_{1}((Matrix<double, {3}, 1> &)mystruct.{1});".format(*temp) return indent(indent(updateInputs))
def init_funcs(self): needed = self.update_actions_deps() for name in list(self.exprs_names) + list(self.struc_names): if name in needed: self.setfunc(name) if 'y' in needed: self.setfunc('y', geteval(self, 'output')) if 'fs' in needed: self.setfunc('fs', self.fs)
def initUI(self): font = QFont() font.setBold(True) vbox = QVBoxLayout() self.grids = [] # ------------------------------- for i, name in enumerate(self.initWidget._names): h = QHBoxLayout() l = QLabel(name) l.setFont(font) h.addWidget(l) self.grids.append(QGridLayout()) for j, s in enumerate(geteval(self.initWidget.method, name)): pos = (0, j) content = { 'desc': '', 'label': str(s), 'value': self.initWidget.inits[name][j], 'type': 'float' } self.grids[i].addWidget(ElementWidget(**content), *pos) w = self.grids[i].itemAtPosition(*pos).widget() onchange = self.build_onchange(i, j) w.modifiedSig.sig.connect(onchange) h.addLayout(self.grids[i]) h.addStretch() scroll = QScrollArea() widget = QWidget() widget.setLayout(h) scroll.setWidget(widget) scroll.setFixedHeight(80) scroll.setWidgetResizable(True) vbox.addWidget(scroll) # ------------------------------- # OK and Cancel buttons buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) # ------------------------------- vbox.addStretch(1) vbox.addWidget(buttons) self.setLayout(vbox) self.setWindowTitle('Edit component')
def _str_updateResults(simu, objlabel): updateResults = str() for name in simu.data.names[2:]: dim = len(geteval(simu.method, name)) if dim > 0: temp = {'dim': dim, 'obj': objlabel.lower(), 'name': name} updateResults += """ for (unsigned int ind=0; ind<{dim}; ind++)""".format(**temp) + "{" + """ mystruct.{name}[ind] = {obj}.{name}_vector()[ind]; """.format(**temp) + "}" return indent(indent(updateResults))
def setfunc(self, name, expr=None): if VERBOSE >= 3: print(' Build {}'.format(name)) if expr is None: expr = geteval(self, name) symbs = free_symbols(expr) args, inds = find(symbs, self.args()) setattr(self, name + '_expr', expr) setattr(self, name + '_args', args) setattr(self, name + '_inds', inds) self.funcs_names.append(name)
def setarg(self, name): if VERBOSE >= 3: print(' Build {}'.format(name)) expr = geteval(self, name) # retrieve expr symbols symbs = free_symbols(expr) # retrieve ordered symbols (args) and indices in self.args args, inds = find(symbs, self.args()) setattr(self, name + '_expr', expr) setattr(self, name + '_args', args) setattr(self, name + '_inds', inds) self.args_names.append(name)
def symbol_names(core): sn = {} for var in [r'x', 'dx', r'w', r'u', r'y', r'cy', r'p', r'o', r'g', r'z_symbols']: for symb in geteval(core, var): string = str(symb) lab = string[1:] sn.update({symb: string[0]+r'_{\mathrm{'+lab+r'}}'}) for symb in core.subs.keys(): string = str(symb) lab = string[1:] sn.update({symb: string[0]+r'_{\mathrm{'+lab+r'}}'}) return sn
def symbol_names(core): sn = {} for var in [r'x', 'dx', r'w', r'u', r'y', r'cy', r'p', r'o', r'g', r'z_symbols']: for symb in geteval(core, var): string = str(symb) lab = string[1:] sn.update({symb: string[0]+r'_{\mathrm{'+lab+r'}}'}) for symb in core.subs.keys(): string = str(symb) lab = string[1:] sn.update({symb: string[0]+r'_{\mathrm{'+lab+r'}}'}) return sn
def nice_label(core, tup): var, ind = tup if var in ['x', 'w', 'u', 'y']: label = str(geteval(core, var)[ind]) content = label[0] + '_{\mathrm{' + label[1:] + '}}' return r'$' + content + r'$' if var in ['dx']: label = str(geteval(core, 'x')[ind]) content = label[0] + '_{\mathrm{' + label[1:] + '}}' return r'$\mathrm{d} ' + content + r'$' elif var == 'dxH': label = str(geteval(core, 'x')[ind]) content = label[0] + '_{\mathrm{' + label[1:] + '}}' return r'$\frac{\mathrm{d} \mathtt{H}}{\mathrm{d} ' + content + r'}$' elif var == 'dtx': label = str(geteval(core, 'x')[ind]) content = label[0] + '_{\mathrm{' + label[1:] + '}}' return r'$\frac{\mathrm{d}' + content + r'}{\mathrm{d} t}$' elif var == 'z': label = str(geteval(core, 'w')[ind]) content = '_{\mathrm{' + label[1:] + '}}' return r'$z' + content + r'$'
def nice_label(core, tup): var, ind = tup if var in ['x', 'w', 'u', 'y']: label = str(geteval(core, var)[ind]) content = label[0] + '_{\mathrm{' + label[1:] + '}}' return r'$' + content + r'$' if var in ['dx']: label = str(geteval(core, 'x')[ind]) content = label[0] + '_{\mathrm{' + label[1:] + '}}' return r'$\mathrm{d} ' + content + r'$' elif var == 'dxH': label = str(geteval(core, 'x')[ind]) content = label[0] + '_{\mathrm{' + label[1:] + '}}' return r'$\frac{\mathrm{d} \mathtt{H}}{\mathrm{d} ' + content+r'}$' elif var == 'dtx': label = str(geteval(core, 'x')[ind]) content = label[0] + '_{\mathrm{' + label[1:] + '}}' return r'$\frac{\mathrm{d}' + content + r'}{\mathrm{d} t}$' elif var == 'z': label = str(geteval(core, 'w')[ind]) content = '_{\mathrm{' + label[1:] + '}}' return r'$z' + content+r'$'
def expr_to_numeric(core, name, allargs, theano=False, vectorize=True): """ Return an evaluator of the function :code:`getarg(nums.method, names + '_expr')`, with a mapping to some of the arguments in :code:`nums.args`, using sympy or theano lambdification. Parameters ---------- core : Core name : str theano : bool vectorize : bool Return ------ func : function Evaluator """ expr = geteval(core, name) if expr is not None: symbs = free_symbols(expr) args, inds = find(symbs, allargs) # args are symbs reorganized func = lambdify(args, expr, subs=core.subs, theano=theano) func = numpy.vectorize(func) func.func_doc = """ Evaluate `{0}`. Parameters ---------- """.format(name) + ''.join( [""" {} : float """.format(str(a)) for a in args]) + """ Return ------ {0} : numpy array The numerical valuation of {0}. """.format(name) else: func, args, inds = None, None, None return func, args, inds
def _str_updateResults(simu, objlabel): updateResults = str() for name in simu.data.names[2:]: dim = len(geteval(simu.method, name)) if dim > 0: temp = {'dim':dim, 'obj': objlabel.lower(), 'name': name } updateResults += """ for (unsigned int ind=0; ind<{dim}; ind++)""".format(**temp) + "{" + """ mystruct.{name}[ind] = {obj}.{name}_vector()[ind]; """.format(**temp) + "}" return indent(indent(updateResults))
def func(): v = geteval(method, 'v' + suffix) Mvvl = geteval(method, 'Mv' + suffix + 'vl') Mvvnl = geteval(method, 'Mv' + suffix + 'vnl') Mvy = geteval(method, 'Mv' + suffix + 'y') fl = geteval(method, 'fl') fnl = geteval(method, 'fnl') u = geteval(method, 'u') temp = [ sp.sympify(0), ] * len(geteval(method, 'v' + suffix)) temp = sumvecs(temp, matvecprod(method.I(suffix), v), [-e for e in matvecprod(Mvvl, fl)], [-e for e in matvecprod(Mvvnl, fnl)], [-e for e in matvecprod(Mvy, u)]) return temp
def simplify_core(core): """ substitute_core *************** Apply simplifications to every expressions of a Core. """ # substitutions in core's list of expressions and symbols attrs_to_sub = set( list(core.exprs_names) + list(core.symbs_names) + ['M', '_dxH', 'observers']) for name in attrs_to_sub: expr = geteval(core, name) if expr is not None: setattr(core, name, simplify(expr))
def faust_vector(name, expr, argsnames, subs, method): joinListArgsNames = ', '.join(map(lambda s: s[-1], argsnames)) methodargs = [] for namea in argsnames: methodargs.extend(geteval(method, namea)) argsnames = list(map(str, methodargs)) code = str() for i, e in enumerate(expr): code += faust_expr(name + str(i), argsnames, e, subs) code += '\n' + name + " = " if len(expr) > 0: code += joinListArgsNames code += " <: " + ''.join( [name + str(i) + ', ' for i in range(len(expr))])[:-2] else: code += '0. : ! ' code += ';' return code
def func(): v = geteval(method, 'v') Mvv = geteval(method, 'Mvv') Mvy = geteval(method, 'Mvy') f = geteval(method, 'f') u = geteval(method, 'u') temp = [ sp.sympify(0), ] * len(geteval(method, 'v')) temp = sumvecs(temp, matvecprod(method.I(''), v), [-e for e in matvecprod(Mvv, f)], [-e for e in matvecprod(Mvy, u)]) return temp
def _process_py(self): # get values for u and p data = self.data tslice = slice(0, None, 1) data.h5open() seq_u = data.u(tslice=tslice) seq_p = data.p(tslice=tslice) names = list(self.config['dnames']) # progressbar if self.config['pbar'] and VERBOSE >= 1: self._init_pb() # init time step self.n = 0 # process for i, (u, p) in enumerate(zip(seq_u, seq_p)): # update numerics self.nums.update(u=u, p=p) vecs = dict(zip(names, [geteval(self.nums, name) for name in names])) # write to files data.h5dump_vecs(self.n, vecs) self.n += 1 # update progressbar if self.config['pbar'] and VERBOSE >= 1: self._update_pb() # progressbar if self.config['pbar'] and VERBOSE >= 1: self._close_pb() time.sleep(1e-3) data.h5close()
def _process_py(self): # get values for u and p data = self.data tslice = slice(0, None, 1) data.h5open() seq_u = data.u(tslice=tslice) seq_p = data.p(tslice=tslice) names = list(self.config['dnames']) # progressbar if self.config['pbar']: self._init_pb() # init time step self.n = 0 # process for i, (u, p) in enumerate(zip(seq_u, seq_p)): # update numerics self.nums.update(u=u, p=p) vecs = dict(zip(names, [geteval(self.nums, name) for name in names])) # write to files data.h5dump_vecs(self.n, vecs) self.n += 1 # update progressbar if self.config['pbar']: self._update_pb() # progressbar if self.config['pbar']: self._close_pb() time.sleep(1e-3) data.h5close()
def _method_dims(self): """ return the dimensions of method attributes in self.names """ dims = list() for name in self.names: if name in ('x', 'dx', 'dxH'): dim = self.method.dims.x() elif name in ('u', 'y'): dim = self.method.dims.y() elif name in ('w', 'z'): dim = self.method.dims.w() else: dim = geteval(self.method.dims, name) dims.append((name, dim)) return dims
def _method_dims(self): """ return the dimensions of method attributes in self.names """ dims = list() for name in self.names: if name in ('x', 'dx', 'dxH'): dim = self.method.dims.x() elif name in ('u', 'y'): dim = self.method.dims.y() elif name in ('w', 'z'): dim = self.method.dims.w() else: dim = geteval(self.method.dims, name) dims.append((name, dim)) return dims
def initUI(self): # define vbox vbox = QVBoxLayout() self.checkboxes = {} self.hboxes = [] self.labels = {} for name in ['x', 'dx', 'dxH', 'w', 'z', 'u', 'y', 'p', 'o']: if name == 'dxH': labels = tuple( map(lambda x: 'dHd' + str(x), self.simu.method.x)) elif name == 'z': labels = tuple( map(lambda w: 'z' + str(w)[1:], self.simu.method.w)) else: labels = tuple(map(str, geteval(self.simu.method, name))) self.labels[name] = labels self.checkboxes[name] = tuple( map(lambda l: QCheckBox(l, self), labels)) hbox = QHBoxLayout() for qcb in self.checkboxes[name]: hbox.addWidget(qcb) hbox.addStretch() vbox.addLayout(hbox) # OK and Cancel buttons hbox_but = QHBoxLayout() hbox_but.addStretch() buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) hbox_but.addWidget(buttons) hbox_but.addStretch() vbox.addLayout(hbox_but) # set layout and show self.setLayout(vbox) self.setWindowTitle('Select Signals to Plot')
def reduce_z(core): """ Incorporate the linear dissipative elements in the interconnection by \ redefining the structure matrix \ :math:`\\mathbf{M}_{\\mathrm{new}}\\in\\mathbb{R}^{N\\times N}` \ with \ :math:`N=\\mathrm{dim}(\\mathbf{x})+\\mathrm{dim}(\\mathbf{w}_{\\mathtt{nl}})+\\mathrm{dim}(\\mathbf{y})+\\mathrm{dim}(\\mathbf{c_y})`: .. math:: \\mathbf{M}_{\\mathrm{new}} = \\mathbf{M}_{\\mathtt{nlwl}}\\cdot\\mathbf{Z}_{\\mathtt{l}}\\cdot\\mathbf{D}_{\\mathtt{l}}\\cdot\\mathbf{M}_{\\mathtt{wlnl}} +\\mathbf{M}_{\\mathtt{nl}} where * :math:`\\mathbf{z}_{\\mathtt{l}}(\\mathbf{w}_{\\mathtt{l}})=\\mathbf{Z}_{\\mathtt{l}}\\cdot\\mathbf{w}_{\\mathtt{l}}`; * :math:`\\mathbf{D}_{\\mathtt{l}} = \\left(\\mathbf{I_d}-\ \\mathbf{M}_{\\mathtt{wlwl}}\\cdot\\mathbf{Z}_{\\mathtt{l}}\\right)^{-1}`, * :math:`\\mathbf{M}_{\\mathtt{wlnl}} = \\left(\\mathbf{M}_{\\mathtt{wlxl}}, \ \\mathbf{M}_{\\mathtt{wlxnl}}, \\mathbf{M}_{\\mathtt{wlwnl}}, \ \\mathbf{M}_{\\mathtt{wly}}, \\mathbf{M}_{\\mathtt{wlcy}}\\right)`, * :math:`\\mathbf{M}_{\\mathtt{nlwl}} = \\left(\\begin{array}{c}\ \\mathbf{M}_{\\mathtt{xlwl}} \\\\ \\mathbf{M}_{\\mathtt{xnlwl}}\\\\ \ \\mathbf{M}_{\\mathtt{wnlwl}}\\\\ \\mathbf{M}_{\\mathtt{ywl}}\\\\ \ \\mathbf{M}_{\\mathtt{cywl}}\\end{array}\\right)`. Warning ------- The linear dissipative variables :code:`core.wl()` are not accessible \ after this operation, and :code:`core.z()=core.znl()`. """ # identify the linear components core.linear_nonlinear() # identify the number of components excluded from the linear part nforced = len(core.force_wnl) # move linear and excluded components at the top of linear components list if not nforced == 0: i = 0 for _ in range(core.dims.wl()): if core.w[i] in core.force_wnl: core.move_dissipative(i, core.dims.wl()) else: i += 1 # reduce number of linear components core.dims._wl -= nforced # reduce Zl core.Zl = core.Zl[:-nforced, :-nforced] # build inverse of Dl iDl = types.matrix_types[0](sympy.eye(core.dims.wl())-core.Mwlwl()*core.Zl) # build Dl Dl = inverse(iDl) # build Mwlnl Mwlnl = types.matrix_types[0].hstack(core.Mwlxl(), core.Mwlxnl(), core.Mwlwnl(), core.Mwly(), core.Mwlcy()) # build Mnlwl Mnlwl = types.matrix_types[0].vstack(core.Mxlwl(), core.Mxnlwl(), core.Mwnlwl(), core.Mywl(), core.Mcywl()) # build Mnl names = ('xl', 'xnl', 'wnl', 'y', 'cy') mat = [] for namei in names: mati = [] for namej in names: Mij = geteval(core, 'M'+namei+namej) mati.append(Mij) Mi = types.matrix_types[0].hstack(*mati) mat.append(Mi) Mnl = types.matrix_types[0].vstack(*mat) # Set M to Mnew core.M = Mnlwl*core.Zl*Dl*Mwlnl + Mnl # Reduce w core.w = core.w[core.dims.wl():] # Reduce z core.z = core.z[core.dims.wl():] # Set dim(wl) to 0 core.dims._wl = 0
def func(): F = geteval(method, 'tempF') vl = geteval(method, 'vl') JacFl = jacobian(F, vl) G = sumvecs(F, [-e for e in matvecprod(JacFl, vl)]) return list(G)
def func(): F, v = geteval(method, 'tempF' + n1), geteval(method, 'v' + n2) return jacobian(F, v)
def __init__(self, core): self.dims = {} for name in ['', 'x', 'w', 'y', 'p', 'o', 'cy']: for dim in ['', 'l', 'nl']: key = name+dim try: self.dims[key] = geteval(core.dims, key) except AttributeError: pass self.core = core self.sn = symbol_names(core) self.x = obj2tex(self.core.x, r'\mathbf{x}', '', self.sn) self.dx = obj2tex(self.core.dx(), r'\mathbf{d_x}', '', self.sn) self.H = obj2tex(self.core.H, r'\mathrm H(\mathbf{x})', '', self.sn, toMatrix=False) self.dxH = obj2tex(self.core.g(), r'\nabla\mathrm H(\mathbf{x})', '', self.sn) self.dxH_elements = list(map(lambda a: obj2tex(a[0], sympy2latex(a[1], self.sn), '', self.sn, toMatrix=False), zip(core.dxH(), self.core.g()))) self.Q = obj2tex(self.core.Q, r'\mathbf{Q}', '', self.sn) self.Zl = obj2tex(self.core.Zl, r'\mathbf{Z_l}', '', self.sn) self.w = obj2tex(self.core.w, r'\mathbf{w}', '', self.sn) self.z = obj2tex(core.z_symbols(), r'\mathbf z(\mathbf{w})', '', self.sn) self.z_elements = list(map(lambda a: obj2tex(a[0], sympy2latex(a[1], self.sn), '', self.sn, toMatrix=False), zip(core.z, core.z_symbols()))) self.u = obj2tex(self.core.u, r'\mathbf{u}', '', self.sn) self.y = obj2tex(self.core.y, r'\mathbf y', '', self.sn) self.cy = obj2tex(self.core.cy, r'\mathbf y_c', '', self.sn) self.cu = obj2tex(self.core.cu, r'\mathbf u_c', '', self.sn) l = [] for i, c in enumerate(self.core.connectors): alpha = c['alpha'] u1, y1 = c['u'][0], c['y'][0] s = obj2tex(alpha*y1, str(u1), '', self.sn) u2, y2 = c['u'][1], c['y'][1] s += obj2tex(-alpha*y2, str(u2), '', self.sn) l.append(s) self.connectors_elements = l self.y_elements = list(map(lambda a: obj2tex(a[0], sympy2latex(a[1], self.sn), '', self.sn, toMatrix=False), zip(core.output(), core.y))) self.o = obj2tex(self.core.o(), r'\mathbf o', '', self.sn) self.o_elements = list(map(lambda a: obj2tex(a[0], sympy2latex(a[1], self.sn), '', self.sn, toMatrix=False), zip(core.observers.values(), core.observers.keys()))) self.p = obj2tex(self.core.p, r'\mathbf p', '', self.sn) for mat in 'MJR': M = obj2tex(geteval(core, mat), r'\mathbf{%s}' % mat, '', self.sn) setattr(self, mat, M) for i in ['x', 'w', 'y', 'cy']: for j in ['x', 'w', 'y', 'cy']: M = obj2tex(geteval(core, mat + i + j), r'\mathbf{' + mat + '_{' + i + j + '}}', '', self.sn) setattr(self, mat + i + j, M) self.subs = dic2table(['parameter', 'value (SI)'], core.subs, self.sn, centering=True) self.jacz = obj2tex(self.core.jacz(), r'\mathcal J_{\mathbf z}(\mathbf w)', '', self.sn) self.hessH = obj2tex(self.core.hessH(), r'\triangle\mathrm H(\mathbf x)', '', self.sn)
def func(): output = geteval(method, 'dxH' + suffix) + geteval( method, 'z' + suffix) return output
def substitute_core(core, subs=None, selfall=False, selfexprs=False, simplify=False): """ substitute_core *************** Apply substitutions to every expressions of a Core. Parameters ----------- subs : dictionary or None A dictionary with entries in the format :code:`{s: v}` with :code:`s` the sympy symbol to substitute by value :code:`v`, which value can be a numerical value (:code:`float, int`), a new sympy symbol or a sympy expression. Default is None. selfall : bool If True, every substitutions in the dictionary :code:`Core.subs` are applied and the dictionary is reinitialized to :code:`{}`. Default is False. selfexprs : bool If True, only substitutions in the dictionary :code:`Core.subs` that are not numerical values are applied to the core's expressions. simplify : bool If True, every expressions are simplified after substitution (default). """ # init substitution dic if subs is None: subs = {} # append self subs dic if selfall: substitute_core(core, selfexprs=True) subs.update(core.subs) # append only exprs in core subs dic elif selfexprs: for k in core.subs.keys(): if not isinstance(core.subs[k], (int, float)): subs[k] = core.subs[k] # substitutions in core's own subsitution dictionary core.subs = substitute_dict(core.subs, subs) # substitutions in core's list of expressions and symbols attrs_to_sub = set(list(core.exprs_names) + list(core.symbs_names) + ['M', '_dxH', 'observers']) for name in attrs_to_sub: expr = geteval(core, name) keys = free_symbols(expr).intersection(set(subs.keys())) # recast the elements of the substitution dictionary as sympy objects subs_e = dict(map(lambda k, v: (k, v), keys, [subs[k] for k in keys])) if expr is None or callable(expr): pass else: setattr(core, name, substitute(expr, subs_e)) if simplify: expr = simplify_func(expr) # remove entries in core.subs for k in subs.keys(): try: core.subs.pop(k) except KeyError: pass
def method2cpp(method, objlabel=None, path=None, inits=None, config=None, subs=None): """ Writes all files that define the c++ class associated with a given pyphs.Method. Parameters ---------- method : pyphs.Method The object that will be converted to c++. objlabel : string (default is None) Name of the c++ class. path : string (default is None) Path to the folder where the source files will be generated. inits : dictionary (default is None) Dictionary of initialization values `{name: array}` with `name` in ('x', 'dx', 'w', 'u', 'p', 'o') and `array` an vector of floats with appropriate shape. config : dictionary (default is None) Dictionary of configuration options (see pyphs.config.CONFIG_NUMERIC). subs : dictionary or list (default is None) Dictionary or list of dictionaries of substitution parameters. """ if VERBOSE >= 1: print('Prepare method {} for C++ generation...'.format(method.label)) if inits is None: inits = {} if config is None: config = {} method.configcpp = CONFIG_NUMERIC.copy() method.configcpp.update(config) args_names = ['x', 'dx', 'w', 'u', 'p', 'o'] for name in args_names: if name not in inits.keys() or inits[name] is None: inits[name] = list(sympy.zeros(len(geteval(method, name)), 1)) method.inits = inits method.inits_evals = {} method.subscpp = method.subs.copy() method.subscpp[method.fs] = method.configcpp['fs'] for name in args_names: for i, a in enumerate(geteval(method, name)): method.subscpp[a] = method.inits[name][i] for name in method.update_actions_deps(): init_eval(method, name) if VERBOSE >= 1: print('Generate core C++ object {}...'.format(method.label)) if objlabel is None: objlabel = 'phscore'.upper() else: objlabel = objlabel.upper() if path is None: path = os.getcwd() + os.sep + objlabel if not os.path.exists(path): os.makedirs(path) files = {} exts = ['cpp', 'h'] for name in exts: files.update({name: {'public': '', 'private': '', 'init': '', 'data': '', 'starting': str_preamble(objlabel), 'closing': ''}}) files['h']['starting'] += '\n' files['h']['starting'] += "\n#ifndef {0}_H".format(objlabel) files['h']['starting'] += "\n#define {0}_H".format(objlabel) h, cpp = _str_includes() files['h']['starting'] += h files['cpp']['starting'] += cpp files['h']['starting'] += _str_namespaces() files['h']['starting'] += "\n\nclass {0} ".format(objlabel) + "{" files['h']['closing'] += "\n}"+";\n\n#endif /* {0}_H */\n".format(objlabel) files['h']['private'] += '\nprivate:' files['h']['public'] += '\npublic:' if VERBOSE >= 2: print(' Build parameters...') append_parameters(method, files, objlabel) if VERBOSE >= 2: print(' Build update...') append_update(method, files, objlabel) if VERBOSE >= 2: print(' Build arguments...') append_args(method, files, objlabel) if VERBOSE >= 2: print(' Build functions...') append_funcs(method, files, objlabel) if VERBOSE >= 2: print(' Build operations...') append_ops(method, files, objlabel) if VERBOSE >= 2: print(' Build initialisation...') append_init(objlabel, files) if VERBOSE >= 2: print(' Build constructors...') append_constructor(method, objlabel, files) # append_constructor_init_vector(objlabel, files) # append_constructor_init_matrix(nums.method, objlabel, files) if VERBOSE >= 2: print(' Build destructor...') append_destructuor(objlabel, files) for e in exts: filename = path + os.sep + 'core.{0}'.format(e) if VERBOSE >= 1: print(' Write {}...'.format(filename)) string = files[e]['starting'] string += linesplit + '\n// PUBLIC' string += indent(files[e]['public']) string += '\n' + linesplit + '\n// PRIVATE' string += indent(files[e]['private']) string += files[e]['closing'] _file = open(filename, 'w') _file.write(string) _file.close() if subs is None: subs = method.subs parameters_files = parameters(subs, objlabel) for e in exts: filename = path + os.sep + 'parameters.{0}'.format(e) if VERBOSE >= 1: print(' Write {}'.format(filename)) string = parameters_files[e] _file = open(filename, 'w') _file.write(string) _file.close()
def func(): G, v = geteval(method, 'G' + a), geteval(method, 'v' + b) return jacobian(G, v)
def expr_to_numeric(core, name, allargs, theano=False, vectorize=True): """ Return an evaluator of the function :code:`getarg(nums.method, names + '_expr')`, with a mapping to some of the arguments in :code:`nums.args`, using sympy or theano lambdification. Parameters ---------- core : Core name : str theano : bool vectorize : bool Return ------ func : function Evaluator """ expr = geteval(core, name) if expr is not None: symbs = free_symbols(expr) args, inds = find(symbs, allargs) # args are symbs reorganized f = lambdify(args, expr, subs=core.subs, theano=theano) # Cope with vector evaluation of functions with arguments if vectorize and len(args) > 0: func = numpy.vectorize(f) # Cope with vector evaluation of functions with no arguments elif vectorize and len(args) == 0: def func(*args): if len(args) == 0: return numpy.array(f()) elif isinstance(args[0], list): return numpy.array([f(), ]*len(args[0])) elif isinstance(args[0], numpy.ndarray): return numpy.array([f(), ]*args[0].shape[0]) else: return numpy.array(f()) # No vectorization else: func = f func.func_doc = """ Evaluate `{0}`. Parameters ---------- """.format(name) + ''.join([""" {} : float """.format(str(a)) for a in args]) + """ Return ------ {0} : numpy array The numerical valuation of {0}. """.format(name) else: print('Expression {0} is None'.format(name)) func, args, inds = None, None, None return func, args, inds
def expr_to_numeric(core, name, allargs, theano=False, vectorize=True): """ Return an evaluator of the function :code:`getarg(nums.method, names + '_expr')`, with a mapping to some of the arguments in :code:`nums.args`, using sympy or theano lambdification. Parameters ---------- core : Core name : str theano : bool vectorize : bool Return ------ func : function Evaluator """ expr = geteval(core, name) if expr is not None: symbs = free_symbols(expr) args, inds = find(symbs, allargs) # args are symbs reorganized f = lambdify(args, expr, subs=core.subs, theano=theano) # Cope with vector evaluation of functions with arguments if vectorize and len(args) > 0: func = numpy.vectorize(f) # Cope with vector evaluation of functions with no arguments elif vectorize and len(args) == 0: def func(*args): if len(args) == 0: return numpy.array(f()) elif isinstance(args[0], list): return numpy.array([ f(), ] * len(args[0])) elif isinstance(args[0], numpy.ndarray): return numpy.array([ f(), ] * args[0].shape[0]) else: return numpy.array(f()) # No vectorization else: func = f func.func_doc = """ Evaluate `{0}`. Parameters ---------- """.format(name) + ''.join( [""" {} : float """.format(str(a)) for a in args]) + """ Return ------ {0} : numpy array The numerical valuation of {0}. """.format(name) else: print('Expression {0} is None'.format(name)) func, args, inds = None, None, None return func, args, inds
def expr_to_numeric(core, name, allargs, theano=None, vectorize=True): """ Return an evaluator of the function :code:`getarg(nums.method, names + '_expr')`, with a mapping to some of the arguments in :code:`nums.args`, using sympy or theano lambdification. Parameters ---------- core : Core name : str theano : bool vectorize : bool Return ------ func : function Evaluator """ # set theano if theano is None: theano = THEANO # recover func from core expr = geteval(core, name) if expr is not None: # recover symbols from expr symbs = free_symbols(expr) # args are symbs reorganized args, inds = find(symbs, allargs) if isinstance(expr, types.vector_types): func = vector_expr_to_numeric(args, expr, subs=core.subs, theano=theano, vectorize=vectorize) else: func = scalar_expr_to_numeric(args, expr, subs=core.subs, theano=theano, vectorize=vectorize) func.__doc__ = """ Evaluate `{0}`. Parameters ---------- """.format(name) + ''.join( [""" {} : float """.format(str(a)) for a in args]) + """ Return ------ {0} : numpy array The numerical valuation of {0}. """.format(name) else: print('Expression {0} is None'.format(name)) func, args, inds = None, None, None return func, args, inds
def func(): "Getter" output = geteval(method, 'dx' + suffix) + geteval( method, 'w' + suffix) return output
def tot(self): """ Total dimension ntot = dim(x)+dim(w)+dim(y)+dim(cy) """ return sum(geteval(self, var) for var in self.names)
def dimvar(): return len(geteval(core, var))