O zero de uma função é qualquer valor tal que . É a raiz da equação. É onde a curva cruza o eixo .
Para polinômios de segundo grau, existe fórmula fechada. Para grau 3 ou 4, existem fórmulas mas são complicadas. Para grau 5 em diante, não existe fórmula geral.
É exatamente nesses casos que o cálculo numérico entra.
Todo método de busca de raízes funciona em duas etapas:
Fase I - Isolamento: encontrar um intervalo que com certeza contém uma raiz.
Fase II - Refinamento: a partir desse intervalo, ir melhorando a aproximação até atingir a precisão que você quer.
O isolamento se apoia no Teorema do Valor Intermediário (TVI): se é contínua em e os sinais nos extremos são opostos,
então existe pelo menos um entre e onde . É intuitivo, se a função começa positiva e termina negativa, ela teve que cruzar o zero em algum ponto.
Método da Bissecção: dividir para conquistar
Você tem um intervalo com uma raiz dentro. Calcula o ponto do meio
e avalia .
Aí três coisas podem acontecer:
- -> achou a raiz, acabou
- -> a raiz está em , descarta a metade direita
- -> a raiz está em , descarta a metade esquerda
Repete até o intervalo ser menor que a precisão que você definiu.
1# Pseudo-código do método da Bissecção2
3dado f, a, b, ε:4 enquanto (b - a) > ε:5 x = (a + b) / 26 se f(a) * f(x) < 0:7 b = x8 senão:9 a = x10 retorna xQuantas iterações vai precisar?
Dá para calcular antes de rodar. O intervalo encolhe pela metade a cada iteração, então depois de passos o tamanho é . Para garantir precisão :
Com e , precisamos de menos de 17 iterações. O método é convergente, vai sempre chegar lá, só não é o mais rápido.
Implementando em Python
1import math2
3def f(x):4 return x * math.log10(x) - 15
6def bisseccao(f, a, b, eps=1e-5):7 if f(a) * f(b) >= 0:8 raise ValueError("f(a) e f(b) precisam ter sinais opostos")9
10 k = 011 while (b - a) > eps:12 x = (a + b) / 213 if f(a) * f(x) < 0:14 b = x15 else:16 a = x17 k += 118 print(f"Iteração {k:2d}: x = {x:.8f}, f(x) = {f(x):.2e}")19
20 return (a + b) / 221
22raiz = bisseccao(f, 2, 3)23print(f"\nRaiz encontrada: {raiz:.6f}")Rodando para no intervalo :
1Iteração 1: x = 2.50000000, f(x) = -5.15e-032Iteração 2: x = 2.75000000, f(x) = 2.08e-013Iteração 3: x = 2.62500000, f(x) = 1.00e-014Iteração 4: x = 2.56250000, f(x) = 4.72e-025Iteração 5: x = 2.53125000, f(x) = 2.09e-026Iteração 6: x = 2.51562500, f(x) = 7.87e-037Iteração 7: x = 2.50781250, f(x) = 1.36e-038Iteração 8: x = 2.50390625, f(x) = -1.90e-039Iteração 9: x = 2.50585938, f(x) = -2.71e-0410Iteração 10: x = 2.50683594, f(x) = 5.43e-0411Iteração 11: x = 2.50634766, f(x) = 1.36e-0412Iteração 12: x = 2.50610352, f(x) = -6.72e-0513Iteração 13: x = 2.50622559, f(x) = 3.45e-0514Iteração 14: x = 2.50616455, f(x) = -1.63e-0515Iteração 15: x = 2.50619507, f(x) = 9.10e-0616Iteração 16: x = 2.50617981, f(x) = -3.61e-0617Iteração 17: x = 2.50618744, f(x) = 2.74e-0618
19Raiz encontrada: 2.506184Vantagens e limitações
O método da Bissecção é robusto: desde que seja contínua e os sinais sejam opostos, ele sempre converge.
A desvantagem é a velocidade, outros métodos como Newton-Raphson têm convergência mais rápida, mas exigem calcular derivadas e podem divergir se o chute inicial for ruim.
Para muitas aplicações práticas, a bissecção já resolve muito bem. É o método que você usa quando quer garantia, não velocidade.