“添加"对象没有属性"sinh";数字和符号表达中的错误? [英] "Add" object has no attribute "sinh" error in numerical and symbolic expression?

查看:165
本文介绍了“添加"对象没有属性"sinh";数字和符号表达中的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Ultimately, my goal is to numerically differentiate the expression 'u' (see code) with respect to t, with respect to X and three times with respect to X.

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

First idea was to just write the expression down numerically, providing arrays (linspaces) for X and t. This resulted in the error "'Add' object has no attribute 'cosh'". The only thing I know about this error is that it indicates I should use sympy-functions instead of numpy-functions or the other way around. But, using a symbpolic expression (sympy-functions) and then trying to lambdify gave the same error, this time with no attribute 'sinh'.

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

I don't know where I'm going wrong with this. The symbolic expression is defined just fine, the error only occurs when I add the first lambdify into the code.

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进行数值区分的方法?

Does anybody know how to fix my code to prevent this error, or know another method to numerically differentiate u as I described above?

推荐答案

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

SymPy and NumPy are completely separate libraries. SymPy flourishes in the world of symbolic math and works with its own symbols for every part of mathematical expressions.

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

The only place where SymPy and NumPy touch, is lambdify where everything is converted to NumPy symbols, ready to go number crunching.

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

The function u doesn't need a symbol: it gets its SymPy representation via its definition based on t and X.

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

The differentiation happens completely inside SymPy, e.g. diff(u, X, 3) calculates the third derivative of u with respect to X. simplify helps to reduce the size of the expression. However, the expression for du_dddX seems so long that simplification takes a huge amount of time. If you don't need to call the function millions of times, you can leave it without simplification.

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, X, 3)
#du_dddX = sp.simplify(du_dddX)

U = sp.lambdify((X,t), u, "numpy")
U1 = sp.lambdify((X,t), du_dt, "numpy")
U2 = sp.lambdify((X,t), du_dX, "numpy")
U3 = sp.lambdify((X,t), 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() .网格在两个方向上可以具有不同数量的划分.函数示例:

Note that the linspace for Y and for T need to have the same size if you want to call the lambdified functions directly on them. You probably want to extend the 1D linspaces to a 2D mesh using np.meshgrid(). The mesh can have a different number of divisions in the two directions. An example with your function:

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

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

PS: To convert the expressions to LaTeX, although the are quite long:

print(sp.latex(du_dt))
print(sp.latex(du_dX))

这篇关于“添加"对象没有属性"sinh";数字和符号表达中的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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