对包含 UndefinedFunction 的导数的 sympy 表达式进行lambdify [英] lambdify a sympy expression that contains a Derivative of UndefinedFunction

查看:26
本文介绍了对包含 UndefinedFunction 的导数的 sympy 表达式进行lambdify的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个未定义函数的表达式,其中一些包含该函数的相应(未定义)导数.函数及其导数都仅作为数值数据存在.我想从我的表达式中创建函数,然后使用相应的数值数据调用该函数以数值计算表达式.不幸的是,我遇到了 Lambdify 的问题.

I have several expressions of an undefined function some of which contain the corresponding (undefined) derivatives of that function. Both the function and its derivatives exist only as numerical data. I want to make functions out of my expressions and then call that function with the corresponding numerical data to numerically compute the expression. Unfortunately I have run into a problem with lambdify.

考虑以下简化示例:

import sympy
import numpy

# define a parameter and an unknown function on said parameter
t = sympy.Symbol('t')
s = sympy.Function('s')(t)

# a "normal" expression
a = t*s**2
print(a)
#OUT: t*s(t)**2

# an expression which contains a derivative
b = a.diff(t)
print(b)
#OUT: 2*t*s(t)*Derivative(s(t), t) + s(t)**2

# generate an arbitrary numerical input
# for demo purposes lets assume that s(t):=sin(t)
t0 = 0
s0 = numpy.sin(t0)
sd0 = numpy.cos(t0)

# labdify a
fa = sympy.lambdify([t, s], a)
va = fa(t0, s0)
print (va)
#OUT: 0

# try to lambdify b
fb = sympy.lambdify([t, s, s.diff(t)], b)  # this fails with syntax error
vb = fb(t0, s0, sd0)
print (vb)

错误信息:

  File "<string>", line 1
    lambda _Dummy_142,_Dummy_143,Derivative(s(t), t): (2*_Dummy_142*_Dummy_143*Derivative(_Dummy_143, _Dummy_142) + _Dummy_143**2)
                                           ^
SyntaxError: invalid syntax

显然 Derivative 对象没有正确解析,我该如何解决?

Apparently the Derivative object is not resolved correctly, how can I work around that?

作为 Lambdify 的替代方案,我也愿意使用基于 theano 或 cython 的解决方案,但我在使用相应的打印机时遇到了类似的问题.

As an alternative to lambdify I'm also open to using theano or cython based solutions, but I have encountered similar problems with the corresponding printers.

感谢任何帮助.

推荐答案

据我所知,问题源于 lambdify 函数中不正确/不幸的虚拟化过程.在将参数和表达式传递给lambdifying 之前,我已经编写了自己的dummification 函数.

As far as I can tell, the problem originates from an incorrect/unfortunate dummification process within the lambdify function. I have written my own dummification function that I apply to the parameters as well as the expression before passing them to lambdifying.

def dummify_undefined_functions(expr):
    mapping = {}    

    # replace all Derivative terms
    for der in expr.atoms(sympy.Derivative):
        f_name = der.expr.func.__name__
        var_names = [var.name for var in der.variables]
        name = "d%s_d%s" % (f_name, 'd'.join(var_names))
        mapping[der] = sympy.Symbol(name)

    # replace undefined functions
    from sympy.core.function import AppliedUndef
    for f in expr.atoms(AppliedUndef):
        f_name = f.func.__name__
        mapping[f] = sympy.Symbol(f_name)

    return expr.subs(mapping)

像这样使用:

params = [dummify_undefined_functions(x) for x in [t, s, s.diff(t)]]
expr = dummify_undefined_functions(b)
fb = sympy.lambdify(params, expr)

显然这有点脆弱:

  • 没有防止名称冲突
  • 也许不是最好的名称方案:df_dxdy for Derivative(f(x,y), x, y)
  • 假设所有导数都具有以下形式:Derivative(s(t), t, ...) 其中 s(t)UndefinedFunctiont> 符号.如果 Derivative 的任何参数是更复杂的表达式,我不知道会发生什么.我有点认为/希望(自动)简化过程将任何更复杂的导数减少为由基本"导数组成的表达式.但我当然不防备.
  • 基本上未经测试(除了我的特定用例)
  • no guard against name-collisions
  • perhaps not the best possible name-scheme: df_dxdy for Derivative(f(x,y), x, y)
  • it is assumed that all derivatives are of the form: Derivative(s(t), t, ...) with s(t) being an UndefinedFunction and t a Symbol. I have no idea what will happen if any argument to Derivative is a more complex expression. I kind of think/hope that the (automatic) simplification process will reduce any more complex derivative into an expression consisting of 'basic' derivatives. But I certainly do not guard against it.
  • largely untested (except for my specific use-cases)

除此之外,它工作得很好.

Other than that it works quite well.

这篇关于对包含 UndefinedFunction 的导数的 sympy 表达式进行lambdify的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆