SymPy diff () function problem

I am working on implementing various numeric methods in python including reverse Euler. Thus, I decided to implement the fast Newton-Raphson method, which would give me the desired root for the variables of the equations that I would have to deal with with the calculator. Here he is:

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

      

A code excerpt that includes a function call 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

      

Where f

is the "sympified" symbol. In my failed test case, it was:f = sympify('(y**2 + t)/(y - t)')

As you can see, I am printing aux

content to keep track of exactly where the diff function is not working. This was the first iteration for y (0) = 1 for h = 0,1, where aux: -y + 1 + 0.1*(y**2 + 0.1)/(y - 0.1)

. Going through aux

both f

in Newton()

and then running diff(f, y)

it gives me:

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

      

Surprisingly, when I manually 'simpify' the same equation and 'diff' it, it works. Newton's method also works like a plume. However, I don't know what might be wrong.

+3


source to share


1 answer


It looks like you are using mpmath diff instead of SymPy. Try "from sympy import diff" before you call your routine. You can check which one you are using by asking for help:

>>> help(diff)
Help on method diff in module sympy.mpmath.calculus.differentiation:

      

against



>>> from sympy import diff
>>> help(diff)
Help on function diff in module sympy.core.function:

      

When I run your program with SymPy diff, I get

>>> InverseEuler(f,1, 0, 1, 0.1)[-1]
-y + 1 + 0.1*(y**2 + 0.1)/(y - 0.1)
-y + 1.13404207225556 + 0.1*(y**2 + 0.2)/(y - 0.2)
-y + 1.30637177730098 + 0.1*(y**2 + 0.3)/(y - 0.3)
-y + 1.52036600337727 + 0.1*(y**2 + 0.4)/(y - 0.4)
-y + 1.77886566311632 + 0.1*(y**2 + 0.5)/(y - 0.5)
-y + 2.08466045990054 + 0.1*(y**2 + 0.6)/(y - 0.6)
-y + 2.44089877798719 + 0.1*(y**2 + 0.7)/(y - 0.7)
-y + 2.85134771320082 + 0.1*(y**2 + 0.8)/(y - 0.8)
-y + 3.32053168504081 + 0.1*(y**2 + 0.9)/(y - 0.9)
-y + 3.85380349564978 + 0.1*(y**2 + 1.0)/(y - 1.0)
[0.99999999999999989, 4.45738956363267]

      

+4


source







All Articles