簡體   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