Revista Informática

El método de Muller e implementación en Python

Publicado el 24 marzo 2023 por Daniel Rodríguez @analyticslane
El método de Muller e implementación en Python

Uno de los métodos numéricos más sencillos para obtener las raíces de una función es el método de la secante. Existe una modificación de este método en el que se usa una aproximación cuadrática en lugar de una línea llamado método de Muller. Este cambio permite una convergencia más rápida hacia el resultado y una mayor estabilidad.

El método de Muller

Al igual que el método de las aproximaciones sucesivas, el de Newton o el de Steffensen, el método de Muller es un método numérico iterativo para encontrar las raíces de una función. El método combina el método de interpolación cuadrática inversa y el método de la secante para obtener una fórmula que converge rápidamente a la raíz de la función.

El algoritmo del método de Muller es el siguiente:

  1. Seleccionar tres puntos iniciales (x_0, x_1, x_2) cercanos a la raíz de la función f(x).
  2. Usando los tres puntos iniciales, calcular los coeficientes a, b y c de la interpolación cuadrática inversa:f(x) = a(x - x_2)^2 + b(x - x_2) + c donde: a = \frac{f(x_0) - f(x_1)}{(x_0 - x_1)(x_0 - x_2)} - \frac{f(x_1) - f(x_2)}{(x_1 - x_2)(x_0 - x_2)} b = \frac{f(x_0) - f(x_1)}{(x_0 - x_1)} - a(x_0 - x_1) c = f(x_2)
  3. Calcular las raíces de la ecuación cuadrática f(x) = 0: x_3 = x_2 - \frac{2c}{b + sign(b) \sqrt{b^2 - 4ac}} donde sign(b) es la función signo de b (1 si b es positivo, -1 si b es negativo).
  4. Si la diferencia entre x_3 y x_2 es menor que una tolerancia predefinida, entonces x_3 es la raíz buscada. De lo contrario, actualizar los valores de x_0, x_1 y x_2 con x_1 = x_2, x_2 = x_3 y x_0 = x_1.
  5. Repetir los pasos 2 a 4 hasta que la diferencia entre x3 y x2 sea menor que la tolerancia predefinida.

Ventajas del método de Muller

Este método puede ser útil para encontrar raíces de funciones no lineales donde otros métodos pueden ser ineficientes o fallar. Sin embargo, puede requerir más iteraciones que otros métodos para converger a la solución. Entre las ventajas del método de Muller se pueden destacar las siguientes:

  1. Es un método rápido de convergencia: combina el método de interpolación cuadrática inversa y el método de la secante para acelerar la convergencia a la raíz de la función.
  2. No requiere conocimiento previo de la función: no necesita que la función sea diferenciable o que se conozca su derivada. Por lo tanto, es aplicable a una amplia variedad de funciones.
  3. Puede encontrar múltiples raíces: puede encontrar múltiples raíces de una función no lineal, siempre y cuando se inicien los puntos iniciales cercanos a cada raíz.

Implementación en Python

La implementación del método de Muller es algo más complicada que otras como pueden ser el método de la secante, el método de Newton o el método de Steffensen. En cada una de las iteraciones requiere calcular bastantes puntos intermedios, pero, si se siguen los pasos de la sección anterior se puede crear una función como la siguiente.

import math

def muller(f, x0, x1, x2, epsilon=1e-10, max_iter=100):
    h1 = x1 - x0
    h2 = x2 - x1
    y1 = (f(x1) - f(x0)) / h1
    y2 = (f(x2) - f(x1)) / h2
    d = (y2 - y1) / (h2 + h1)
    n_iter = 3
    x = None

    while n_iter <= max_iter:
        b = y2 + h2*d
        D = math.sqrt(b**2 - 4*f(x2)*d)

        if abs(b-D) < abs(b+D):
            E = b + D
        else:
            E = b - D

        h = -2*f(x2)/E
        p = x2 + h

        if abs(h) < epsilon:
            x = p
            break

        x0, x1, x2 = x1, x2, p
        h1 = x1 - x0
        h2 = x2 - x1
        y1 = (f(x1) - f(x0)) / h1
        y2 = (f(x2) - f(x1)) / h2
        d = (y2 - y1) / (h2 + h1)
        n_iter += 1

    if x is None:
        raise ValueError("El método no converge")

    return x

Validación de la implementación

Para validar la implementación de la sección anterior se puede usar la misma función que se empleó en anteriormente en métodos como el de la secante, el de Newton o el de Steffensen. Comprobando si la función puede encontrar las dos raíces de f(x) = x^2 + 2x -8.

fun = lambda x: x**2 + 2*x - 8

muller(fun, 0, 4, 8)     # 2.0
muller(fun, -10, -6, -1) # -4.0

Observándose que, en función de los puntos de inicio, se puede obtener cada una de las dos raíces de la función: 2 o -4.

Conclusiones

En esta ocasión se ha visto un nuevo método numérico para obtener la raíz de una función. Aunque es un poco más complicado de implementar que otros anteriores, ofrece mejores resultados en funciones complejas.

Image by Alicja from Pixabay


Volver a la Portada de Logo Paperblog