Bisección

Método de Bisección

El método de bisección se basa en el Teorema del Valor Intermedio. Se elige un intervalo cerrado \((a, b)\) tal que la función es continua y \(f(a) \cdot f(b) < 0\), lo que garantiza que existe al menos una raíz dentro de ese intervalo.

La fórmula principal del método de bisección es:

\[ X_r = \frac{a + b}{2} \]

Algoritmo

  1. Escoger un intervalo inicial [a, b] tal que la función sea continua y que se cumpla \(f(a) \cdot f(b) < 0\). Esta condición garantiza que existe al menos una raíz en el intervalo.
    Comprobación:
    • Si \(f(a) \cdot f(b) > 0\): se debe cambiar el intervalo.
  2. Calcular el punto medio del intervalo:
    \[ X_r = \frac{a + b}{2} \] Este valor es la nueva aproximación a la raíz.
  3. Evaluar la función en el punto medio: Calcular \(f(X_r)\) y el producto \(f(a) \cdot f(X_r)\), y actuar según su signo:
    • Si \(f(a) \cdot f(X_r) < 0\), la raíz está entre a y \(X_r\) → se actualiza \(b = X_r\).
    • Si \(f(a) \cdot f(X_r) > 0\), la raíz está entre \(X_r\) y b → se actualiza \(a = X_r\).
    • Si \(f(a) \cdot f(X_r) = 0\), entonces se ha encontrado la raíz exacta.
  4. Calcular el error relativo porcentual:
    Desde la segunda iteración en adelante, se evalúa: \[ E_a = \left| \frac{X_{r_{\text{actual}}} - X_{r_{\text{anterior}}}}{X_{r_{\text{actual}}}} \right| \times 100 \] Esto indica cuán cerca están las dos últimas aproximaciones.
  5. Verificar si el error calculado es menor que la tolerancia deseada.
    Si se cumple, se detiene el proceso y se considera la raíz encontrada. En caso contrario, regresar al paso 2 con los nuevos valores de a y b.

Ejemplo 1: f(x) = cos(x) - x

Esta función tiene una raíz en el intervalo (0, 1). El método de bisección reduce el intervalo hasta converger a la raíz con precisión.


Ejemplo 2: f(x) = x³ - x - 2

La raíz se encuentra entre 1 y 2. La animación muestra la reducción del intervalo en cada paso hasta encontrar la raíz.


Ejemplo 3: f(x) = ex - 2

La raíz real es \(\ln(2) \approx 0.693\). Esta animación muestra cómo el método de bisección converge a la raíz desde el intervalo [0, 1].


Explicación en video del código en Python

Método de Bisección en Python


import numpy as np

# Definición de la función a evaluar: f(x) = e^x - 3x
def f(x):
    return np.exp(x) - 3 * x

# Parámetros iniciales para el método de bisección
a = 0             # Límite inferior del intervalo
b = 1             # Límite superior del intervalo
tol = 0.05        # Tolerancia en porcentaje para el criterio de finalización
max_iter = 1000   # Número máximo de iteraciones permitidas

# Encabezado de la tabla de resultados
print("Iteración\t   a\t\t  f(a)\t\t   b\t\t  f(b)\t\t   Xr\t\t  f(Xr)\t\t f(a)*f(Xr)\t   Error (%)")
print("-" * 145)

# Variables auxiliares para el cálculo
iteracion = 0
error = 100.0            # Error inicial alto para entrar al ciclo
xr_anterior = None       # Almacena el valor anterior de Xr para calcular el error

# Bucle principal del método de bisección
while error > tol and iteracion < max_iter:
    xr = (a + b) / 2.0   # Punto medio del intervalo
    f_a = f(a)           # Evaluación de la función en el extremo inferior
    f_b = f(b)           # Evaluación en el extremo superior
    fxr = f(xr)          # Evaluación de la función en el punto medio
    signo = f_a * fxr    # Producto para verificar el cambio de signo
    
    # Cálculo del error a partir de la segunda iteración
    if iteracion == 0:
        error_str = "   -----  "  # No se calcula error en la primera iteración
    else:
        error = abs((xr - xr_anterior) / xr) * 100
        error_str = f"{error:10.6f}"

    # Imprimir fila de resultados de la iteración actual
    print(f"{iteracion+1:>10d}\t{a:>10.6f}\t{f_a:>10.6f}\t{b:>10.6f}\t{f_b:>10.6f}"
          f"\t{xr:>10.6f}\t{fxr:>10.6f}\t{signo:>13.6f}\t{error_str}")

    # Actualización del intervalo según el signo del producto f(a)*f(Xr)
    if signo < 0:
        b = xr  # La raíz está en [a, Xr]
    else:
        a = xr  # La raíz está en [Xr, b]
    
    # Preparar para siguiente iteración
    xr_anterior = xr
    iteracion += 1

# Imprimir resumen final de resultados
print("\nResultados finales:")
print("Raíz encontrada:", xr)
print("Número de iteraciones:", iteracion)
print("Error final:", error, "%")