Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Método de BAIRSTOW
Ing Yamil Armando Cerquera Rojas – yacerque@gmail.com
Especialista en Sistemas Universidad Nacional
Docente Universidad Surcolombiana
Neiva - Huila
Preámbulo
En análisis numérico, el método de Bairstow es un algoritmo eficiente de
búsqueda de las raíces de un polinomio real de grado arbitrario. El
algoritmo apareció por primera vez en el apéndice del libro
"Aerodinámica Aplicada", escrito por Leonard Bairstow y publicado en
1920. El algoritmo se diferencia de otros métodos en que encuentra
tanto las raíces reales como las imaginarias (en parejas complejas
conjugadas), utilizando únicamente aritmética real.
Leonard Bairstow
Sir Leonard Bairstow (1880-1963), fue miembro de la Orden del
Imperio Británico y nació en 1880 en Halifax, West
Yorkshire. Es recordado principalmente por sus trabajos en
aviación y por el Método de Bairstow, mediante el cual se
pueden encontrar las raíces enteras e imaginarias de un
polinomio de grado arbitrario.
p ( x) = ( x 2 − rx − s ) p1 ( x )
p ( x) = ( x 2 − rx − s ) p1 ( x ) + Ax + B
A = A(r , s ) = 0
(1)
B = B(r , s ) = 0
As = A1 , Bs = B1
Ar = rA1 + B1 , Br = sA1
Sean
p ( x) = a 0 x n + a1 x n − 1 + ... + a n − 1 x + a n = ( x 2 − rx − s) p1 ( x) + Ax + B
p1 ( x ) = b0 x n − 2 + b1 x n − 3 + ... + bn − 3 x + bn − 2 = ( x 2 − rx − s ) p 2 ( x) + A1 x + B1
p 2 ( x ) = c0 x n − 4 + c1 x n − 5 + ... + c n − 5 x + c n − 4 , donde
b0 = a 0
b1 = a1 + rb0
b2 = a 2 + rb1 + sb0
bk = a k + rbk − 1 + sbk − 2 , k = 2,3,..., n − 2
A = a n − 1 + rbn − 2 + sbn − 3
B = a n + + sbn − 2
c 0 = b0
c1 = b1 + rc 0
c 2 = b2 + rc1 + sc 0
c k = bk + rc k − 1 + sc k − 2 , k = 2,3,..., n − 4
A1 = bn − 3 + rc n − 4 + sc n − 5
B1 = bn − 2 + + sc n − 4
Resumiendo
1. Dado f n (x) y r0 y s 0
2. Utilizando el método de Newton Raphson se calcula f 2 ( x) = x 2 − r0 x − s 0
y f n− 2 ( x) , tal que, el residuo de f n ( x) / f 2 ( x) sea igual a cero.
3. Se determinan la raíces f 2 ( x) , utilizando la formula general.
4. Se calcula f n − 2 ( x) = f n ( x) / f 2 ( x)
5. Se hace f n ( x) = f n− 2 ( x)
6. Si el grado del polinomio es mayor que tres se regresa al paso 2
7. Si no se termina
f n ( x) = a0 + a1 x + a 2 x 2 + ... + a n x n
n− 3 n− 2
Resultando: f n − 2 ( x) = b2 + b3 x + b4 x + ... + bn − 1 x + bn x
2
Con residuo:
R = b1 ( x − r ) + b0 Ec.3
Esto para que los valores de inicio al evaluar r y s conduzcan a este resultado,
se debe de aplicar un camino para los valores iniciales o de inicio de manera
que b1 y b0 tiendan a cero para ello se utiliza una técnica similar a la de
Newton Raphson.
Para dar un valor inicial que se acerque a las raíces es el colocar la Ec. 5 igual
a cero y que resulte:
∂ b1 ∂ b1
∆r+ ∆ s = − b1 Ec.6
∂r ∂s
∂ b0 ∂ b0
∆r+ ∆ s = − b0 Ec.7
∂r ∂s
Si las variables ∆ r y ∆ s forman un sistema de ecuaciones de dos incógnitas
y el método de Bairstow muestra que las derivadas parciales pueden
resolverse por división sintética de las b en forma similar al camino en que
las b en sí mismas fueron derivadas:
c n = bn
c n− 1 = bn− 1 + rc n Para i = n − 2 a 0
ci = bi + rci + 1 + sci + 2
∆s
ε a,s = 100%
s
Cuando los dos valores fallan bajo un criterio especificado las raíces pueden
determinarse con la siguiente ecuación:
r± r 2 + 4s
x=
2
Aquí pueden caber tres posibilidades:
Iteración 1 con:
∆ r = − 0.04728019113442016
∆ s = − 3.469106187802152
De donde
Iteración 3.
De donde
clear all;clc;j=1;
%r(1)=input('Digite valor para r');
r(1)=-1;
%s(1)=input ('Digite valor para s');
s(1)=2;
while j<=8
a=[1 -3.5 2.75 2.125 -3.875 1.25];
n=length(a);
b(1)=a(1);
c(1)=b(1);
b(2)=a(2)+r(j)*b(1);
c(2)=b(2)+r(j)*c(1);
i=3;
while (i<=n)
b(i)=a(i)+r(j)*b(i-1)+s(j)*b(i-2);
c(i)=b(i)+r(j)*c(i-1)+s(j)*c(i-2);
i=i+1;
end
m=[c(4) c(3); c(5) c(4)];
B=[-b(5); -b(6)];
v=inv(m)*B;
dr=v(1); ds=v(2);
j=j+1;
r(j)=r(j-1)+dr; s(j)=s(j-1)+ds;
end
disp([r' s'])
En resumen
k r s Residuo
0 -1.000000 2.000000 30.750000 -61.75000
1 1.763680 7.403374 51.756406 105.68578
2 1.716400 3.934260 12.654710 28.188140
3 1.599731 2.450680 2.8995800 8.154670
4 1.333540 2.186660 0.7601220 2.522228
5 1.118260 2.113020 0.2719400 0.607688
6 1.027050 2.023170 0.0431300 0.111850
7 1.001650 2.001530 0.0027700 0.006340
8 1.000000 2.000000 1.13930E-5 2.67534E-5
La solución es:
x1 = 2
x2 = -1
Formulas apropiadas:
bn = an
bn − 1 = a n − 1 + rbn
bi = ai + rbi + 1 + sbi + 2 , para i = n − 2 hasta 0
Cálculos:
b5 = a5 = 1
b4 = a 4 + rb5 = − 3.5 + ( − 1)1 = − 4.5
b3 = a3 + rb4 + sb5 = 2.75 + (− 1)(− 4.5) + (− 1)(1) = 6.25
b2 = a 2 + rb3 + sb4 = 2.125 + (− 1)(6.25) + (− 1)(− 4.5) = 0.375
b1 = a1 + rb2 + sb3 = − 3.875 + ( − 1)(0.375) + (− 1)(6.25) = − 10.5
b0 = a 0 + rb1 + sb2 = 1.25 + (− 1)(− 10.5) + (− 1)(0.375) = 11.375
c5 = b5 = 1
c 4 = b4 + rc5 = − 4.5 + (− 1)1 = − 5.5
c3 = b3 + rc 4 + sc5 = 6.25 + (− 1)(− 5.5) + (− 1)(1) = 10.75
c 2 = b2 + rc3 + sc 4 = 0.375 + (− 1)(10.75) + (− 1)(− 5.5) = − 4.875
c1 = b1 + rc 2 + sc3 = − 10.5 + (− 1)(− 4.875) + (− 1)(10.75) = − 16.375
s=solve('-4.875*dr+10.75*ds=10.5','-16.375*dr-4.875*ds=-11.375')
» s.dr
ans =0.35583013998592320325330413701416
» s.ds
ans =1.1381090169703605224055681551576
r = -1 + 0.3558 = -0.6442
s = -1 + 1.1381 = 0.1381
0.3558
ε a ,r = 100% = 55.23%
− 0.6442
y
1.1381
ε a ,s = 100% = 824.1%
0.1381
Y luego:
c5 = 1
c4 = − 4.7884
c3 = 8.7806
c2 = − 8.3454
c1 = 4.7874
Para ∆ r = 0.1331 y ∆ s = 0.3316 , los cuales pueden usarse para estimar la raíz
correcta como
ε a ,r = 26.0%
y
ε a ,s = 70.6%
El cálculo debe continuar, por los valores tan altos en el error que se calcula.
Con los resultados después de cuatro iteraciones, el método converge a los
valores de r = -0.5 ( ε a ,r = 0.063% ) y s = 0.5 ( ε a ,s = 0.040% ). La fórmula
general puede emplearse para evaluar las raíces como
f ( x) = x 3 − 4 x 2 + 5.25 x − 2.5
El método de Bairstow puede aplicarse a este polinomio usando resultados del
paso anterior, r = -0.5 y s = 0.5, como valores iniciales. Cinco iteraciones dan
un estimado de r = 2 y s = -1.249, el cual puede usarse para calcular
f 5(x) = ( x 3 − 4 x 2 + 5.25 x − 2.5 )*( x 2 + 0.5 x − 0.5 ) Pol Resultado * Pol Factor
Las raíces del polinomio factor del Paso 1, dado por x 2 + 0.5 x − 0.5 = 0 son:
x1 = 0.5 y x 2 = − 1.0
x3 = 1 + 0.5 j
x 4 = − 1 − 0.5 j
f 1 ( x) = ( x − 2)
x5 = 2 ;
Todas la raíces de f 5 ( x) son x = [0.5, 1.0, (1.0 + j0.5), (1 - j0.5), 2]
Código en lenguaje C
Aquí el código de una función que saca los factores cuadráticos y lineales en
los que se debe dividir el polinomio:
void find_poly_roots(int n)
{ double r,s,dn,dr,ds,drn,dsn,eps;
int i,iter;
r = s = 0;
dr = 1.0;
ds = 0;
eps = 1e-14;
iter = 1;
while ((fabs(dr)+fabs(ds)) > eps)
{ if ((iter % 200) == 0)
{ r=(double)rand()/16000.;
}
if ((iter % 500) == 0)
{ eps*=10.0;
precision_error_flag=1;
printf("Perdida de Precisión \n");
}
b[1] = a[1] - r;
c[1] = b[1] - r;
for (i=2;i<=n;i++)
{ b[i] = a[i] - r * b[i-1] - s * b[i-2];
c[i] = b[i] - r * c[i-1] - s * c[i-2];
}
dn=c[n-1] * c[n-3] - c[n-2] * c[n-2];
drn=b[n] * c[n-3] - b[n-1] * c[n-2];
dsn=b[n-1] * c[n-1] - b[n] * c[n-2];
if (fabs(dn) < 1e-16)
{ dn = 1;
drn = 1;
dsn = 1;
}
dr = drn / dn;
ds = dsn / dn;
r += dr;
s += ds;
iter++;
}
for (i=0;i<n-1;i++)
a[i] = b[i];
a[n] = s;
a[n-1] = r;
}
Codigo en MatLAb
clear
clc
z=input ('TECLEE LOS COEFICIENTES DEL POLINOMIO ENTRE CORCHETES:\n');
%z=[1 -3.5 2.75 2.125 -3.875 1.25];
n=length(z); % Se define la longitud de la ecuación
it=0; % Se inicia el contador de iteraciones
limit_it=1000; % Se define el limite en el numero de iteraciones
tol=0.0001; % Se define la tolerancia de la estimación
raiz(1:n-1)=0;
ri=0;
r=2; % Se supone el valor de r que es el coeficiente de primer grado
s=2; % Se supone el valor de s que es el termino independiente
err=1; % Se inicializa el valor del error en r igual a 1
ers=1; % Se inicializa el valor del error en s igual a 1
if z(1)==0
fprintf('EL PRIMER COEFICIENTE NO DEBE SER CERO:\n\n')
break
end
while 1 % Ciclo que nos permitirá ir evaluando las raíces del polinomio
if (n-1>=3);
else break,end % Condición si el grado de la raíz es mayor a 3
t=[1 r s]; % Esta es el polinomio cuadrático de inicio
it=it+1; % Se incrementa en 1 la iteración
[x,y]=deconv(z,t); % Se divide la ecuación entre el polinomio de inicio
length(x); % Se define la longitud del polinomio resultante
length(y); % Se define la longitud del residuo resultante
x=[x,0,0]; % Se ajusta la variable x para poder sumarla al residuo
x=[x+y]; % Suma del cociente mas residuo
c(1)=z(1); % Valor de los coeficientes de la función a
c(2)=z(2)+(-r*c(1)); % Evaluar, en virtud de que el coeficiente de mayor
for i=3:n % Grado será equivalente al coeficiente de menor grado
m=n-i; % Y en este ciclo se realiza la inversión de ellos
c(n-m)=z(i)+(-r*x(n-m-1))+(-s*x(n-m-2));%algoritmo de inversión
end
d(1)=c(1); %valor de los coeficientes de las derivadas parciales
d(2)=c(2)+(-r*d(1)); %valor de los coeficientes de las derivadas parciales
for i=3:(n-1); %se realizan los cálculos de los coeficientes
m=n-i; %hasta el grado máximo del polinomio
d(n-m)=c(i)+(-r*d(n-m-1))+(-s*d(n-m-2));%algoritmo de calculo
end
e=[d(n-2),d(n-3);d(n-1),d(n-2)]\[-c(n-1);-c(n)];%calculo del
d_r=e(1); %nuevo valor del coeficientes de primer grado
d_s=e(2); %nuevo valor del termino independiente
if r==0
else
err=d_r/r; %calculo del error para coeficiente de primer grado
end
if s==0
else
ers=d_s/s; %calculo del error para termino independiente
end
r=r-d_r; %valor del coeficiente de primer grado
s=s-d_s; %valor del termino independiente
if ((abs (err))&(abs(ers))<=tol) %si se cumple la condición de
ri=ri+1;
x1=(-r+sqrt(r^2-4*s))/2; % tolerancia entonces se calcula el valor del
raiz(ri)=x1;
ri=ri+1;
x2=(-r-sqrt(r^2-4*s))/2; % polinomio cuadrático.
raiz(ri)=x2;
xx=[x1,x2]'; %valor del polinomio que divide exactamente a la ecuación
tt=poly(xx); %cambio de variable para efectuar nuevamente la división
[x3,y]=deconv(z,tt); %se efectúa la división
z=x3; %se hace cambio de variable
n=length(x3-1); %se determina el grado del polinomio
r=tt(1);
s=tt(2);
end
if (it>limit_it) %condición de iteraciones
fprintf ('Exceso en el limite de iteraciones. \n');break
end %si hay exceso en el numero de iteraciones se termina el programa
end
if (n-1)==2 %si la ecuación que se introduce es de segundo grado
ri=ri+1;
x1=(-z(2)+sqrt(z(2).^2-4*z(1)*z(3)))/(2*z(1));%se calcula normalmente por
raiz(ri)=x1;
x2=(-z(2)-sqrt(z(2).^2-4*z(1)*z(3)))/(2*z(1));%medio de la formula tradicional
ri=ri+1;
raiz(ri)=x2;
end
if (n-1)==1 %si el valor de la ecuación que se introduce es de primer
if (abs(z(2))>=tol)
ri=ri+1;
x1=-z(2)/z(1); %grado solamente se hace la sustitución.
else
x1=0;
end
raiz(ri)=x1;
x1;
end
if (n-1)==0 %si el valor de la ecuación que se introduce es una constante
fprintf('El valor que introdujo es una constante igual a:\n\n')
constante=z
end
raices=raiz';
sort raices;
raices