← Volver al blog

Newton-Raphson Symbolic Method with Python

Implementar el método de Newton-Raphson usando sympy para derivar la función analíticamente — sin aproximar la derivada por diferencias finitas. Envuelto en una clase reutilizable.

La recurrencia clásica:

\[x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}\]
import sympy as sp

class NewtonRaphsonSymbolic:
    def __init__(self, f, x0):
        """
        Args:
            x: Symbolic variable
            x0: Point to start iterations
            f: Symbolic function
            df: Symbolic derivative
        """
        x = sp.symbols('x')
        self.x0 = x0
        self.f = sp.sympify(f)
        self.df = sp.diff(f, x)

    def NewtonRaphsonSolve(self, tol = 1e-10, max_iteration = 100):
        """
        Returns:
            x: Root of the function
        """
        x_previous = self.x0
        iteration = 0
        while 1:
            x = x_previous - self.f.evalf(subs = {'x': x_previous}) / self.df.evalf(subs = {'x': x_previous})

            if abs(x - x_previous) < tol or iteration >= max_iteration:
                break
            x_previous = x
            iteration = iteration + 1

        return x

function_value = NewtonRaphsonSymbolic("x**3 - 5*x**2 + 7*x - 1", 4)
root = function_value.NewtonRaphsonSolve()
print(f"The root of the function is: {root:.4f}")

Ejecutándolo sobre \(f(x) = x^3 - 5x^2 + 7x - 1\) con \(x_0 = 4\):

The root of the function is: 0.1607

Newton-Raphson convergence

Aunque partimos desde \(x_0 = 4\) (lejos de la única raíz real, que está cerca de \(0.16\)), el método termina convergiendo después de varias iteraciones. El comportamiento depende fuertemente de la curvatura local: con puntos iniciales cercanos a extremos (\(f'(x) \approx 0\)) la división explota y las iteraciones divergen.

Ventajas de la variante simbólica:

  • La derivada es exacta, no una aproximación numérica — útil cuando f involucra exponenciales, logaritmos o funciones trigonométricas anidadas.
  • El código no depende de la aritmética de punto flotante hasta el paso de evaluación, por lo que mantiene alta precisión.
  • Se puede reutilizar con cualquier función: basta pasar la expresión como string.

Consideraciones:

  • sympy es más lento que una implementación puramente numérica (por ejemplo scipy.optimize.newton), así que para problemas de alto rendimiento conviene diferenciar una vez simbólicamente y luego compilar con sp.lambdify.
  • Siempre verificar el dominio de definición antes de iterar: si \(f'(x_n) = 0\), el método falla.

Instalación:

pip install sympy
← Volver al blog