El método de bisección es un algoritmo numérico utilizado para encontrar raíces de ecuaciones de la forma f(x)=0f(x). Se basa en el Teorema del Valor Intermedio, que establece que si una función f(x)f(x)f(x) es continua en un intervalo [a,b] y f(a) y f(b) tienen signos opuestos (f(a)⋅f(b)<0f(a) \ f(b) , entonces existe al menos una raíz r en [a,b].
Elegir un intervalo [a,b] tal que f(a)⋅f(b)<0
Calcular el punto medio del intervalo:
c=a+b2c = \{a + b}{2}
Evaluar f(c):
Si f(c)=0) entonces ccc es la raíz exacta.
Si f(c) tiene el mismo signo que f(a), se reemplaza a por c (a=c).
Si f(c) tiene el mismo signo que f(b) se reemplaza b por c (b=c)
Repetir el proceso hasta que el intervalo sea lo suficientemente pequeño o hasta alcanzar una precisión deseada.
Ejercicio clase
function [c, yc, err, P] = bisect(a, b, delta)
function [c,yc,err,P] = bisect(a,b,delta)
f = input('Ingrese f(x) entre comillas en términos de x: ');
f = inline(f, 'x');
err = 0;
P = [a b err];
ya = feval(f,a);
yb = feval(f,b);
if ya*yb > 0
disp('No hay cambio de signo. No se puede aplicar bisección.');
return
end
max1 = 1 + round((log(b - a) - log(delta)) / log(2));
for k = 1:max1
c = (a + b)/2;
yc = feval(f,c);
if ya*yc < 0
b = c;
yb = yc;
else
a = c;
ya = yc;
end
err = abs(b - a)/2;
P = [P; a b err];
if err < delta
break
end
end
disp('c (raíz aproximada):'), disp(c)
disp('f(c):'), disp(yc)
disp('Error estimado:'), disp(err)
disp(' X0 X1 ERROR')
disp(P)
end
octave:2> [c,yc,err,P] = bisect(0, 2, 1e-3)
Ingrese f(x) entre comillas en términos de x: > 'x*sin(x)-1'
warning: inline is obsolete; use anonymous functions instead
c (raíz aproximada):
1.1152
f(c):
1.4960e-03
Error estimado:
9.7656e-04
X0 X1 ERROR
0 2.0000 0
1.0000 2.0000 0.5000
1.0000 1.5000 0.2500
1.0000 1.2500 0.1250
1.0000 1.1250 0.0625
1.0625 1.1250 0.0312
1.0938 1.1250 0.0156
1.1094 1.1250 0.0078
1.1094 1.1172 0.0039
1.1133 1.1172 0.0020
1.1133 1.1152 0.0010
c = 1.1152
yc = 1.4960e-03
err = 9.7656e-04
P =
0 2.0000 0
1.0000 2.0000 0.5000
1.0000 1.5000 0.2500
1.0000 1.2500 0.1250
1.0000 1.1250 0.0625
1.0625 1.1250 0.0312
1.0938 1.1250 0.0156
1.1094 1.1250 0.0078
1.1094 1.1172 0.0039
1.1133 1.1172 0.0020
1.1133 1.1152 0.0010
Tarea
function raiz = biseccion(f, a, b, tol)
#Verifica si el intervalo dado contiene una raíz
if f(a) * f(b) > 0
error('El intervalo no garantiza la existencia de una raíz.');
end
iter = 0; % Contador de iteraciones
while (b - a) / 2 > tol
c = (a + b) / 2;
#Punto medio
if f(c) == 0 % Si encontramos la raíz exacta
break;
elseif f(a) * f(c) < 0
b = c;
else
a = c;
end
iter = iter + 1;
end
raiz = (a + b) / 2;
fprintf('Raíz encontrada en x = %.6f después de %d iteraciones\n', raiz, iter);
end
#Definimos las funciones dadas
f1 = @(x) x * sin(x) - 1;
f2 = @(x) x^3 + 4*x^2 - 10;
#Aplicamos el método de la bisección a cada función
fprintf('\nResolviendo x*sin(x) - 1 en [0,2] con tol=10^-3:\n');
raiz1 = biseccion(f1, 0, 2, 1e-3);
fprintf('Resultado: x ≈ 1.114257 después de 10 iteraciones\n');
fprintf('\nResolviendo x^3 + 4x^2 - 10 en [1,2] con tol=10^-4:\n');
raiz2 = biseccion(f2, 1, 2, 1e-4);
fprintf('Resultado: x ≈ 1.365173 después de 13 iteraciones\n');
Graficas
x1 = linspace(0, 2, 100);
y1 = arrayfun(f1, x1);
x2 = linspace(1, 2, 100);
y2 = arrayfun(f2, x2);
figure;
subplot(2,1,1);
plot(x1, y1, 'b', raiz1, f1(raiz1), 'ro');
grid on;
title('Gráfico de f_1(x) = x*sin(x) - 1');
xlabel('x'); ylabel('f_1(x)');
legend('f_1(x)', 'Raíz aproximada');
subplot(2,1,2);
plot(x2, y2, 'r', raiz2, f2(raiz2), 'bo');
grid on;
title('Gráfico de f_2(x) = x^3 + 4x^2 - 10');
xlabel('x'); ylabel('f_2(x)');
legend('f_2(x)', 'Raíz aproximada');