繁体   English   中英

sympy lamdify 与 sympy 矩阵和 numpy 向量输入

[英]sympy lambdify with sympy matrix and numpy vector inputs

我想用 sympy 计算一个符号梯度,例如,

import sympy as sym
x, y, z  = sym.symbols("x y z", real=True)

T = sym.cos(x**2+y**2)

gradT = sym.Matrix([sym.diff(T, x), sym.diff(T,y), sym.diff(T,z)])

现在我想用这个表达式创建一个 lamddify 函数:

func = lambdify((x,y,z), gradT,'numpy')

要使用我有的功能:

gradT_exact = func(np.linspace(0,2,100), np.linspace(0,2,100), np.linspace(0,2,100))

我收到以下错误:

<lambdifygenerated-3>:2: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  return (array([[-2*x*sin(x**2 + y**2)], [-2*y*sin(x**2 + y**2)], [0]]))

如果我将 T 更改为 x,y,z 的函数,它不会给我带来任何问题......当 T 仅取决于 x 和 y 并且 z 设置为零时,为什么它会发出警告。

提前致谢!

gradT表达式:

In [84]: gradT
Out[84]: 
⎡        ⎛ 2    2⎞⎤
⎢-2⋅x⋅sin⎝x  + y ⎠⎥
⎢                 ⎥
⎢        ⎛ 2    2⎞⎥
⎢-2⋅y⋅sin⎝x  + y ⎠⎥
⎢                 ⎥
⎣        0        ⎦

并将其转换为numpy

In [87]: print(func.__doc__)
Created with lambdify. Signature:

func(x, y, z)

Expression:

Matrix([[-2*x*sin(x**2 + y**2)], [-2*y*sin(x**2 + y**2)], [0]])

Source code:

def _lambdifygenerated(x, y, z):
    return (array([[-2*x*sin(x**2 + y**2)], [-2*y*sin(x**2 + y**2)], [0]]))

如果xy是数组,则 2 项将反映它们的维度,但最后一项是[0] 这就是为什么你的ragged警告。

lambdify做了一个相当简单的词法翻译。 它没有实现对numpy数组的任何深入理解。 在某种程度上,您有责任检查 numpy 代码是否合理。

使用标量输入:

In [88]: func(1,2,3)
Out[88]: 
array([[1.91784855],
       [3.8356971 ],
       [0.        ]])

但如果一个输入是一个数组:

In [90]: func(np.array([1,2]),2,3)
<lambdifygenerated-1>:2: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
  return (array([[-2*x*sin(x**2 + y**2)], [-2*y*sin(x**2 + y**2)], [0]]))
Out[90]: 
array([[array([ 1.91784855, -3.95743299])],
       [array([ 3.8356971 , -3.95743299])],
       [0]], dtype=object)

结果是包含 2 个数组和[0]列表的对象 dtype。

为了避免这个问题, lambdify必须产生一个函数,如:

In [95]: def f(x,y,z):
    ...:     temp = 0*x*y
    ...:     return np.array([-2*x*np.sin(x**2 + y**2), -2*y*np.sin(x**2 + y**2)
    ...: , temp])

其中temp旨在给出0值,但其形状反映了其他项中xy上的广播操作。 我认为这对lambdify要求过高。

In [96]: 

In [96]: f(np.array([1,2]),2,3)
Out[96]: 
array([[ 1.91784855, -3.95743299],
       [ 3.8356971 , -3.95743299],
       [ 0.        ,  0.        ]])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM