BhallaLab / moose-core

C++ basecode and python scripting interface
https://moose.ncbs.res.in
GNU General Public License v3.0
15 stars 27 forks source link

Named variables in Function expression #390

Closed dilawar closed 4 years ago

dilawar commented 4 years ago

moose.Function now supports named variables

Support arbitrarily named variable in the expression.

Currenty expression set on moose.Function can have variables named xi, yi etc. Using indices is supported by by default since it is straightforward to keep track of variables in memory. This PR enable support of arbitrary names in expr.

Here is an example of moose.Function. Also not the prettyprint of function expression. This is enabled by default if sympy is installed. Else normal text is printed.

>>> k1, k2 = 1.0, 2.0
>>> demo = moose.Neutral('/model')
>>> function = moose.Function('/model/function')
>>> function.c['c0'] = k1
>>> function.c['c1'] = k2
>>> function.x.num = 1
>>> function.expr = 'c0*exp(c1*x0)*cos(y0)+sin(t)'
>>> function.printUsingSympy()
    c₁⋅x₀
c₀⋅ℯ     ⋅cos(y₀) + sin(t)

Alternative, one can use this syntax.

>>> k0, k1 = 1.0, 2.0
>>> demo = moose.Neutral('/model')
>>> function = moose.Function('/model/function')
>>> function.compile('k1*exp(k2*Ca)*cos(y0)+sin(t)', constants={'k1': k0, 'k2': k1}, variables=['Ca'], independent='y0', mode=0)
root        : WARNING  Expression has been changed to MOOSE's form.
 ﹅ From,
 ﹅     Ca⋅k₂
 ﹅ k₁⋅ℯ     ⋅cos(y₀) + sin(t)
 ﹅ to,
 ﹅     Ca⋅c₁
 ﹅ c₀⋅ℯ     ⋅cos(y₀) + sin(t)
>>> function.printUsingSympy()
    Ca⋅c₁
c₀⋅ℯ     ⋅cos(y₀) + sin(t)

moose.connect is also wrapped

# moose.connect(x0, 'output', fn1['A'], 'input')   # old style.
x0.connect('output', fn1['A'], 'input')
# moose.connect(x1, 'output', fn1['B'], 'input')   # old style
x1.connect('output', fn1['B'], 'nput')    # typo.
moose       : ERROR    Could not find 'nput' on <moose.Variable: id=449, dataIndex=0, path=/fn1[0]/x[1]>.
Did you mean input?

Pretty print

If sympy >= 1.15, is already installed, a function's expression is printed using sympy. For example:

root : WARNING Expression has been changed to MOOSE's form. ﹅ From, ﹅ Ca⋅k₂
﹅ k₁⋅ℯ ⋅cos(y₀) + sin(t) ﹅ to, ﹅ Ca⋅c₁
﹅ c₀⋅ℯ ⋅cos(y₀) + sin(t)

One can do so manually:

>>> f = moose.Function('f')
>>> f.compile('x^2+sqrt(y)+exp(x^y)')
>>> f.printUsingSympy()
           ⎛ y⎞
 2         ⎝x ⎠
x  + √ y + ℯ
>>>