我正在python上实现各种数值方法,包括向后Euler。因此,我决定实现一个快速的牛顿-拉夫森方法,它将为我的计算器必须处理的变量方程提供所需的根。这是:
def Newton(y0, f, tol=1e-10):
y = Symbol('y')
df = diff(f, y)
while f.subs(y, y0) > tol:
y0 -= f.subs(y, y0)/df.subs(y, y0)
return y0
涉及Newton()
函数调用的代码摘录:
def InverseEuler(f, y0, t0, tf, h):
coords = [[t0, y0]]
t, y = symbols('t y')
while round(t0, 7) < round(tf, 7):
aux = sympify(y0 - y + h*f.subs(t, t0 + h))
print aux
y0 = utils.Newton(y0, aux)
t0 += h
coords.append([t0, y0])
return coords
其中f
是一个“sympified”字符串。在我失败的测试用例中,它是:f = sympify('(y**2 + t)/(y - t)')
如您所见,我正在打印aux
内容,以精确跟踪diff函数失败的位置。它是在y(0)=1的第一次迭代中,h=0.1,其中aux有:-y + 1 + 0.1*(y**2 + 0.1)/(y - 0.1)
。
当在{
Traceback (most recent call last):
File "C:\Users\Gabriel Vasconcelos\Documents\python\Metodos\metodos.py", line 97, in <module>
GPHandler.replot(InverseEuler(f, 1, 0, 4, 0.1))
File "C:\Users\Gabriel Vasconcelos\Documents\python\Metodos\metodos.py", line 31, in InverseEuler
y0 = utils.Newton(y0, aux)
File "C:\Users\Gabriel Vasconcelos\Documents\python\Metodos\utils.py", line 6, in Newton
df = diff(f, y)
File "C:\Python27\lib\site-packages\sympy\mpmath\calculus\differentiation.py", line 188, in diff
values, norm, workprec = hsteps(ctx, f, x, n, prec, **options)
File "C:\Python27\lib\site-packages\sympy\mpmath\calculus\differentiation.py", line 61, in hsteps
values = [f(x+k*h) for k in steps]
TypeError: 'Add' object is not callable
令人惊讶的是,当我手动“简化”同一个方程,并“区分”它时,它就工作了。牛顿的方法也适用于羽流。不过,我对什么是错的一无所知
看起来您使用的是mpmath diff而不是SymPy。在调用例程之前,请尝试“从sympy import diff”。您可以通过寻求帮助来检查您正在使用哪一个:
vs
当我用SymPy的diff运行你的程序时
相关问题 更多 >
编程相关推荐