“添加”对象在数字和符号表达式中没有属性“ sinh”错误?

最终,我的目标是相对于t,相对于X和相对于X,对表达式'u'(请参见代码)进行数值区分。

第一个想法是只将表达式数字记下来,为X和t提供数组(线性空间)。这导致错误“'添加'对象没有属性'cosh'”。关于此错误,我唯一了解的是它指示我应该使用sympy-functions而不是numpy-functions或其他方式。但是,使用符号表达(sympy函数)然后尝试进行lambdify会产生相同的错误,这次没有属性“ sinh”。

我不知道我要怎么做。符号表达式定义得很好,仅当我将第一个lambdify添加到代码中时,才会发生错误。

import numpy as np
import sympy as sp
c_1=1.35
c_2=0.7
X = sp.Symbol('X')
t = sp.Symbol('t')
u = sp.Function('u')(X,t)
u = 2*(c_1-c_2)*(c_1*(sp.cosh(sp.sqrt(c_2)*(X-c_2*t)/2))**2 + c_2*(sp.sinh(sp.sqrt(c_1)*(-X-c_1*t)/2))**2)/((sp.sqrt(c_1)-sp.sqrt(c_2))*sp.cosh((sp.sqrt(c_1)*(-X-c_1*t) + sp.sqrt(c_2)*(X-c_2*t))/2)+ (sp.sqrt(c_1)+sp.sqrt(c_2))*sp.cosh((sp.sqrt(c_1)*(-X-c_1*t)-sp.sqrt(c_2)*(X-c_2*t))/2))**2
Y= np.linspace(-20,20,100)
T = np.linspace(-35,35,300)
U = sp.lambdify(X,u,"numpy")
U2 = sp.lambdify(t,U(Y),"numpy")(T)

有人知道如何修复我的代码以防止出现此错误,还是知道另一种如上所述对u进行数值区分的方法?

whtorry 回答:“添加”对象在数字和符号表达式中没有属性“ sinh”错误?

usympy表达式。 python / numpy中的Usp.sinh等被翻译为np.sinh等。

U(Y)使用numpy数组对此求值,但是t仍然是一个符号。生成numpy对象dtype数组,其中包含数字和符号的某种混合。 np.sinh(x)被评估为[z.sinh() for z in x]。由于大多数对象(包括符号)都没有sinh方法,因此会引发错误。

对此我不确定,但是我怀疑您需要同时lambdifyX同时t(Y,T)一起进行评估,而不是在两步。

(稍后我可能会尝试通过isympy会话进行演示。)

,

SymPy和NumPy是完全独立的库。 SymPy在符号数学领域蓬勃发展,并在数学表达式的每个部分都使用自己的符号。

SymPy和NumPy唯一接触的地方是lambdify,在那里所有内容都转换为NumPy符号,可以进行数字运算了。

函数u不需要符号:它通过基于tX的定义来获取SymPy表示形式。

差异完全发生在SymPy内部,例如diff(u,X,3)计算u相对于X的三阶导数。 simplify有助于减小表达式的大小。但是,du_dddX的表达式似乎很长,以至于简化需要大量时间。如果您不需要数百万次调用该函数,则可以不做任何简化。

import numpy as np
import sympy as sp
c_1 = 1.35
c_2 = 0.7
X = sp.Symbol('X',real=True)
t = sp.Symbol('t',real=True)
u = 2*(c_1-c_2)*(c_1*(sp.cosh(sp.sqrt(c_2)*(X-c_2*t)/2))**2 + c_2*(sp.sinh(sp.sqrt(c_1)*(-X-c_1*t)/2))**2)/((sp.sqrt(c_1)-sp.sqrt(c_2))*sp.cosh((sp.sqrt(c_1)*(-X-c_1*t) + sp.sqrt(c_2)*(X-c_2*t))/2)+ (sp.sqrt(c_1)+sp.sqrt(c_2))*sp.cosh((sp.sqrt(c_1)*(-X-c_1*t)-sp.sqrt(c_2)*(X-c_2*t))/2))**2
du_dt = sp.simplify(sp.diff(u,t))
du_dX = sp.simplify(sp.diff(u,X))
du_dddX = sp.diff(u,3)
#du_dddX = sp.simplify(du_dddX)

U = sp.lambdify((X,t),u,"numpy")
U1 = sp.lambdify((X,du_dt,"numpy")
U2 = sp.lambdify((X,du_dX,"numpy")
U3 = sp.lambdify((X,du_dddX,"numpy")

# before this line,everything happened in SymPy
# now the NumPy part starts

Y = np.linspace(-20,20,20)
T = np.linspace(-35,35,20)

print(U(Y,T))
print(U1(Y,T))
print(U2(Y,T))
print(U3(Y,T))

请注意,如果要直接在它们上调用lambdified函数,则Y和T的linspace必须具有相同的大小。您可能想使用np.meshgrid()将1D线性空间扩展到2D网格。网格在两个方向上可以具有不同数量的划分。函数示例:

import matplotlib.pyplot as plt
Y = np.linspace(-20,100)
T = np.linspace(-35,300)
YY,TT = np.meshgrid(Y,T)
z = U1(YY,TT)
h = plt.contourf(Y,T,z)
plt.show()

PS:尽管表达式很长,但要将表达式转换为LaTeX:

print(sp.latex(du_dt))
print(sp.latex(du_dX))
本文链接:https://www.f2er.com/3149114.html

大家都在问