![](/img/trans.png)
[英]Difference in numpy and sympy lambdify results for basic optimization
[英]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]]))
如果x
和y
是數組,則 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
值,但其形狀反映了其他項中x
和y
上的廣播操作。 我認為這對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.