✨ Método de Leverrier-Faddeev

Autor: Prof. Doherty Andrade | www.metodosnumericos.com.br

📚 Fundamentos Teóricos

Referência: D. K. Faddeev & V. N. Faddeeva. Computational Methods of Linear Algebra. Freeman, 1963.

O Algoritmo de Leverrier-Faddeev calcula o polinômio característico $p(\lambda)=\det(\lambda I-A)$ sem determinantes, usando recursão baseada em traços:

$$F_1(A)= A,\quad p_1= -\frac{1}{1}\operatorname{tr}(F_1(A))$$ $$F_k(A)= A(F_{k-1}(A)+p_{k-1}I), \quad p_k= -\frac{1}{k}\operatorname{tr}(F_k(A))$$

Ao final da $n$-ésima iteração, temos $p(\lambda) = \lambda^n + p_1\lambda^{n-1} + \dots + p_n$.

🐍 Implementação em Python

Implementação com numpy e renderização LaTeX via IPython:

import numpy as np
from IPython.display import display, Math

def _poly_to_latex(coeffs):
    n = len(coeffs) - 1
    terms = []
    for i, c in enumerate(coeffs):
        if abs(c) < 1e-12: continue
        exp, sign, val = n - i, '+' if c > 0 else '-', abs(c)
        val_str = f'{val:g}' if val != 1 or exp == 0 else ''
        var_str = '' if exp == 0 else ('\\lambda' if exp == 1 else f'\\lambda^{exp}')
        terms.append(f' {sign} {val_str}{var_str}')
    poly = ''.join(terms).strip()
    if poly.startswith('+'): poly = poly[1:].strip()
    return f'p(\\lambda) = {poly}'

def leverrier_faddeev(A, render=True):
    A = np.asarray(A, dtype=float)
    if A.ndim != 2 or A.shape[0] != A.shape[1]:
        raise ValueError("Matriz deve ser quadrada.")
    n = A.shape[0]
    p = np.zeros(n + 1); p[0] = 1.0
    Fk = A.copy()
    for k in range(1, n + 1):
        pk = -Fk.trace() / k
        p[k] = pk
        if k < n:
            Fk = Fk + np.eye(n) * pk
            Fk = A @ Fk
    latex_expr = _poly_to_latex(p)
    if render:
        try: display(Math(latex_expr))
        except: print(f"[LaTeX] {latex_expr}")
    return p
    # Matriz de exemplo
A = np.array([[ 2., -1.,  3.],
              [-1.,  1.,  2.],
              [ 3.,  2., -1.]])

# Executa e renderiza automaticamente
coefs = leverrier_faddeev(A)