Método de Müller - Universidad EAFIT

MÉTODO DE MULLER PARA OBTENER TODAS LAS RAÍCES DE UN
POLINOMIO
RESUMEN
Se describe en detalle el algoritmo de Muller para obtener una raíz de una
función f (x) . Se discute la forma clásica (más eficiente) de evaluar polinomios
y de realizar la división sintética, procedimientos necesarios para hallar todas
las raíces de un polinomio de coeficientes reales y grado arbitrario. Los
resultados obtenidos mediante un programa desarrollado por los autores en
la Facultad de Ingeniería Eléctrica de la Universidad Tecnológica de Pereira
se comparan, en términos de precisión y tiempo de ejecución, , con los
encontrados con el MATLAB 5.3.
Alvaro Acosta Montoya
Profesor Titular
Ingeniería Eléctrica U. T. P
e-mail: [email protected]
Carlos Galván Ceballos
Estudiante X semestre
Ingeniería Eléctrica U. T. P
e-mail: [email protected]
Mario Acosta Acosta
Ingeniero Eléctricista U. T. P.
Colombiana Kimberly Colpapel S. A.
e-mail: [email protected]
ABSTRACT
The Muller’s Method to obtain a single root of a function f(x) is described in
detail. The most efficient (classical) approach to evaluate a polynomial and
to make synthetic division are discussed, which are necesary functions to get
all the roots of a polynomial of real coefficients and arbitrary degree. The results
obtained by a program developed by the authors in the Electrical Engineering
Department at Universidad Tecnológica de Pereira, are compared to those
obtained by using MATLAB 5.3
MÉTODO DE MULLER PARA HALLAR UNA RAÍZ DE LA
ECUACIÓN f (x) ' 0
Entre las propiedades más destacadas del método se pueden
mencionar[1]:
<
Se puede usar para encontrar cualquier número prefijado
de raíces.
<
Se aplica a funciones arbitrarias.
<
Encuentra raíces reales y/o complejas.
<
En el entorno de la raíz posee convergencia casi
cuadrática.
<
<
Se basa en aproximar en la proximidad de la raíz cualquier
función mediante una parábola. Para ello se escogen tres
puntos relativamente contiguos que pertenecen a la función
y se halla la ecuación de la única parábola que pasa por ellos.
Las soluciones de la ecuación cuadrática que resulta
determinan los “puntos” por donde dicha parábola corta el
eje x, uno de los cuales se toma como mejor aproximación
a la raíz que se busca. Los detalles de la deducción de las
fórmulas se muestran a continuación:
Sean x0 , x1 y x2 tres aproximaciones diferentes para una
raíz de la ecuación f (x) ' 0 . La ecuación de la única parábola
que pasa por los puntos [x0 , f (x0 )] [x1 , f(x1 )] [x2 , f(x2 )] se
supone de la forma:
p(x) ' A x 2 % B x % C
No requiere evaluación de la derivada de la función como
en el método de Newton
Cuando la función es un polinomio,[( f (x) ' p(x) ], y se
aproxima una raíz repetida no diverge como el método
de Bairstow o el de Newton1.
entonces se debe cumplir:
2
p (x0 ) ' f0 • f ( x0 ) ' A x0 % B x0 % C
p(x1 ) ' f1 • f (x1 ) '
p (x2 ) ' f2 • f ( x2 ) '
1
No es difícil verificar que cuando f(x) es un
polinomio p(x), el método de Newton en las
proximidades de una raíz repetida xk diverge
por cuanto p´(xk)=0.
(1)
2
A x1
2
A x2
(2a)
% B x1 % C
(2b)
% B x2 % C
(2c)
Combinando (2c) con (2b) y (2b) con (2a) para eliminar la
incógnita C se obtiene:
SCIENTIA ET TECHNICA No. 12
2
ABRIL /2000 80
2
A (x2 & x1 ) % B (x2 & x1 ) ' f2 & f1
2
2
A (x1 & x0 ) % B (x1 & x0 ) ' f1 & f0
(3)
la ecuación de la parábola también se puede expresar de la
siguiente manera:
p (x ) ' f2 % g (x2, x1 ) ( x & x2 ) %
%
que se puede expresar matricialmente de la siguiente manera:
2
2
( x2 & x1 ) ( x2 & x1 ) A
2
2
( x1 & x0 ) ( x1 & x0 ) B
'
g (x2, x1 ) & g( x1, x0 )
x2 & x0
( x & x2 )( x & x1 )
que permite verificar de manera inmediata que corresponde
a la ecuación de la única parábola que pasa por los puntos
[x0 , f (x0 )] [x1 , f(x1 )] [x2 , f(x2 )]
(f2 & f1 )
(f1 & f0 )
cuya solución es la siguiente:
A '
g( x2, x1 ) & g( x1, x0 )
x2 & x0
Un enfoque alternativo supone que la ecuación de la parábola
es de la forma:
(4a)
(4)
B ' g( x2, x1 ) & A (x2 % x1 )
(4b)
g (x1, x0 ) '
f2 & f1
x2 & x1
f1 & f0
c ' f (x0)
(5)
x1 & x0
a '
Reemplazando (4) en (2c) se obtiene:
C 'f2 & x2 g( x2, x1 ) & x1 A
(9)
y en este caso mediante un procedimiento similar al descrito
se obtienen las siguientes expresiones para las constantes
a, b y c
donde
g (x2, x1 ) '
p(x) ' a( x & x0 )2 % b (x & x0 ) % c
g (x1, x0) & g (x2, x0)
x1 & x2
(10)
b ' g(x1 , x0) & a (x1 & x0)
(6)
donde
En [1] se sugiere y se justifica que para evitar pérdida de
dígitos significativos en la solución a la ecuación cuadrática
p (x ) ' A x 2 % Bx % C ' 0 se haga mediante la fórmula
alternativa:
g ( x1 , x0 ) '
g ( x2 , x0 ) '
2C
x3 '
B ±
B 2 & 4AC
(7)
donde el signo antes del radical se debe escoger de tal
manera que el valor absoluto del denominador sea el más
grande lo que da la raíz de valor absoluto más pequeño.
x1 & x0
f2 & f0
(11)
x2 & x0
y se mantienen las definiciones dadas en (2a), (2b) y (2c) para
f0 , f1 y f2 , pero en este caso se utiliza (9) para p (x)
p(x0 ) ' f0 • f (x0 ) 'c
p(x1 ) ' f1 • f (x1 ) ' a(x1 &x0)2 % b(x1 &x0) % c
Si f ( x3 ) # å donde å es una tolerancia especificada de
antemano, se ha hallado una solución. En caso contrario se
repite el proceso con las siguientes asignaciones:
x2 ' x3
x1 ' x2
x0 ' x1
f1 & f0
p(x2 ) ' f2 • f (x2 ) ' a(x2 &x0)2 % b(x1 &x0) % c
(12)
ALGORITMO DE MULLER
(8)
Reemplazando (4a) en (4b) en (6) y las expresiones resultantes
para las constantes A , B y C en (1), se puede demostrar que
Se supone que los coeficientes del polinomio se almacenan
en el vector A , y que los subíndices más bajos identifican
la posiciones de las potencias mas altas.
1.
Suponer que los tres puntos iniciales contiguos se
encuentran separados entre sí INI ' ½ unidad..
SCIENTIA ET TECHNICA No. 12
Inicialmente se busca una raíz en el intervalo
& 0.5 # x # 0.5 Es decir,
x0 ' & INI
x1 ' 0
3.
Fijar tolerancia å ' 10 & 6 y máximo número de
iteraciones MAX ' 1000 e inicializar contador de
iteraciones j ' 0
Si el grado es igual a 1 hacer
a ' 0
b ' A[0]
c ' A[1]
x3 ' & c
b
4.
b ' A[1]
c ' A[2]
5.
Aplicar secuencialmente (12), (11), (10) para obtener las
constantes a , b y c
6.
Aplicar (7) con
A = a, B = b y C = c
para obtener
Evaluación eficiente de un polinomio
p (x) ' a0 % a1 x %a2 x 2 % þþ an x n
(13)
Es ineficiente evaluar cada uno de los n % 1 términos
separadamente y sumarlos después porque el esfuerzo
n (n % 1)
computacional es de n sumas y
multiplicaciones.
2
Aún si se toma como base x k para evaluar x k % 1 se
requerirían n sumas y (2n & 1) multiplicaciones.
Observando que con excepción del primero todos los
términos de (13) contienen el factor común x (12) se puede
escribir de la siguiente manera:
Si el grado es igual a 2
a ' A[0]
ASPECTOS COMPUTACIONALES
En los métodos iterativos para encontrar las raíces de un
polinomio se requiere con demasiada frecuencia la evaluación
del polinomio de grado entero n > 0 de la forma:
x0 ' INI
2.
ABRIL /2000 81
x3 - x0 , verificar si f (x3 ) # å. Si no se
cumple esta condición incrementar en 1 el número de
iteraciones j y si se excede el máximo permitido
MAX volver a iniciar el proceso reduciendo el valor deINI
a la mitad. Si tampoco se encuentra solución en MAX
iteraciones se reduce nuevamente el valor de INI a la
mitad y se reinicia el proceso. Finalmente si tampoco se
encuentra solución con INI ' 0.125 ' c después de MAX
iteraciones se imprime mensaje de no convergencia
después de 3(MAX iteraciones.
p(x) ' a0 % x(a1 % a2 x % þþ %
% an
&1
xn
&2
% anx n
&1
)
De nuevo cada término dentro del paréntesis excepto el
primero tienen el factor común x
p(x) ' a0 % x(a1 % a2 (x % þþ %
% an
&1
xn
&3
% anx n
&2
))
Continuando con este proceso se obtiene la expresión
anidada de p (x)
p(x) ' a0 % x(a1 % x (a2 % þþ %
% x(an & 1 % x(a n ))þþ))
para evaluar la cual se necesitann sumas yn multiplicaciones.
División Sintética
7.
Cuando se haya encontrado una raíz se debe proceder
a realizar la deflación (división sintética) para reiniciar
el proceso con un polinomio de orden menor. Debe
tenerse en cuenta que, puesto que el polinomio tiene
coeficientes reales, cuando ocurre una raíz compleja
también ocurre su conjugado y en ese caso la división
sintética se debe aplicar dos veces.
Dados los n % 1 coeficientes a 0 , þþ, a n del polinomio (12)
y el número z hacer
b n ' an
Para k ' n & 1, þþ, 0 hacer
bk ' ak % z bk % 1
(14)
Entonces aplicando (14) se obtiene mediante un proceso
inductivo
SCIENTIA ET TECHNICA No. 12
b 0 ' a0 % z b 1
' a0 % z (a1
' a0 % z (a1
!
b 0 ' p (z) ' a0
%
ABRIL /2000 82
% z b 2)
% z (a2 % zb 3))
! ! ! !
% z (a 1 % z (a2 % þþ %
z (an & 1 % z (an )) þþ ))
(15)
Los autores se vieron en la necesidad de desarrollarla porque
están trabajando en un paquete para la solución analítica de
circuitos eléctricos de parámetros concentrados. Se realizaron
pruebas y se obtuvieron resultados ligeramente mejores, tanto
en tiempo de ejecución como en precisión, con los arrojados
por el MATLAB 5.3. Los lectores interesados en hacer uso
de la librería completa pueden solicitarla a cualquiera de los
autores vía e-mail
La secuencia de números b n , b n & 1 , þþ, b 1 tienen una
propiedad muy útil que se deriva a continuación:
BIBLIOGRAFÍA
De (14)
(16)
[1] CONTE, S. D. y CARL de Boor, “Elementary
Numerical Analysis”, Mc-Graw Hill, 2ª edición, New
York, 1972
Por lo tanto si q (x) es un polinomio de grado n & 1 de la
forma
[2] FADEEV, D. K. y V. N. FADEEVA, “Computational
Methods of Linear Algebra”, W. H Freeman and
Company, San Francisco, 1963
ak '
k ' n
bk
bk & bk
% 1z
k < n
k ' 0, þþ, n
q(x) ' b 1 % b 2 x % þþ % b n x n
&1
[3] JOYANES, A. Luis, “C++ A SU ALCANCE: Un
enfoque orientado a objetos”, McGraw-Hill,
México, 1995
entonces
b 0 % q(x)(x & z) ' b 0 % (b 1 % b 2 x % þþ
& (b 1 % b 2 x % þ
Apéndice A
Codificación de Evaluación de polinomios
' (b 0 & b 1 z) % (b 1 & b 2 z)x %þþ
(b n
&1
& b n z)x n
' a0 % a1 x % þþ % an
&1
&1
% b0x n
xn
&1
(17)
%
' p (x)
Es decir, b 1 , þþ, b n & 1 , b n son los coeficientes del
polinomio resultante de dividir p (x) entre el polinomio de
primer orden x & z y b 0 es el residuo. Haciendo x ' z en
(16) se obtiene nuevamente b 0 ' p (z) [ver ecuación (15)].
Sip (z) # å x ' z esunaraízylasecuenciadecoeficientesb 1 , þþ, b n & 1 , b n
son los del polinomio base para continuar hallando todas
las demás raíces.
CONCLUSIONES
Se ha descrito en detalle el algoritmo de Muller para obtener
todas las raíces de un polinomio de coeficientes reales. Esta
resulta ser una herramienta útil en el análisis de sistemas
lineales. También sirve de base para realizar expansión en
fracciones parciales.
float eval(FPoly &A,float &x)
{
float resul;
resul=A.poly[0];//coeficiente de mayor potencia
for (register unsigned char j=1;j<=A.grado;j++) //limita a un
polinomio de grado 126
{
resul=resul*x+A.poly[j];
}
return resul;
}
La clase Fpoly ha sido creada para representar un polinomio
de coeficientes reales y grado arbitrarion y se le han definido,
además de los constructores de copia y sobrecarga de
operadores binarios y de flujo, funciones para encontrar sus
raíces, evaluar el polinomio y realizar la división sintética
Apéndice B
Codificación de la División Sintética
FPoly Div(FPoly &A,const float &x)
{
SCIENTIA ET TECHNICA No. 12
float resul;
Fpoly B(char(A.grado-1));
resul=A.poly[0];//coeficiente de mayor potencia
for (register unsigned char j=1;j<=A.grado;j++)
//limita a un orden del polinomio a 126
{
B[char(j-1)]=resul;
resul=resul*x+A.poly[j];
}
return B;
}
Apéndice C
Código para encontrar raíces de un polinomio
Roots roots(FPoly A)
{
Roots raices(A.grado);
const int MAX=1000;
const float TOL=1E-6,REAL=1E-5;
//Contador de las raices encontradas
unsigned char N;
const unsigned char NRAICES=char(A.grado-1);
complex a,b,c,x0,x1,x2,h1,h12,h2,D,f10,f20;
float INI;
float var;
bool FINDROOT;
N=0;
INI=0.5;
do
{
FINDROOT=false;
x0=-INI;
x1=0;
x2=INI;
for(short i=0;i<=MAX;i++)
{
if(A.grado==2)
{
bool r1;
r1=false;
D=A[1]*A[1]-4*A[0]*A[2];
D=sqrt(D);
ABRIL /2000 83
if(abs(A[1]+D)<abs(A[1]-D))
{
raices[N]=-2*A[2]/(A[1]-D);
r1=true;
}
else raices[N]=-2*A[2]/(A[1]+D);
if(fabs(imag(raices[N]))<=REAL)
{
if(r1) raices[char(N+1)]=-2*A[2]/(A[1]+D);
else raices[char(N+1)]=-2*A[2]/(A[1]-D);
raices[N]=real(raices[N]);
raices[char(N+1)]=real(raices[char(N+1)]);
}
else raices[char(N+1)]=conj(raices[N]);
N=char(N+2);
FINDROOT=true;
break;
}
else if(A.grado==1)
{
raices[N]=-A[1]/A[0];
N++;
FINDROOT=true;
break;
}
c=eval(A,x0);
h1=x1-x0;
h2=x2-x0;
h12=x1-x2;
f10=(eval(A,x1)-eval(A,x0))/h1;
f20=(eval(A,x2)-eval(A,x0))/h2;
a=(f10-f20)/h12;
b=f10-a*h1;
D=b*b-4*a*c;
D=sqrt(D);
if(abs(b+D)<abs(b-D))
{
D*=-1;
D+=b;
}
else D+=b;
raices[N]=x0-2*c/D;
if(abs(eval(A,raices[N]))<TOL)
SCIENTIA ET TECHNICA No. 12
{
//una vez se obtenga una raiz aplicamos la deflacion
FINDROOT=true;
if(fabs(imag(raices[N]))<=REAL)
{
//si la raiz es real
var=real(raices[N]);
if(N<NRAICES) A=Div(A,var);
raices[N]=var;
}
else {
//si la raiz es compleja
if(N+1<NRAICES) A=Div(A,raices[N]);
raices[char(N+1)]=conj(raices[N]);
N++;
}
N++;
INI=0.5;
break;
}
//si no se encuentra raiz preparamos la siguiente
iteracion
else
{
x0=x1;
x1=x2;
x2=raices[N];
}
}
// si no converge en MAX iteraciones,
cambiamos el valor de INI
if(!FINDROOT)
{
INI/=2;
if(INI<0.125) {
cout<<"NO CONVERGE EN
"
<<3*MAX<<"ITERACIONES";
getch();
exit(-1);
}
}
ABRIL /2000 84
}
while(N<=NRAICES);
return raices;
}
Nótese que un objeto de la clase Fpoly no sirve para
almacenar las raíces del polinomio, ya que algunas de
estas podrían ser complejos. De ahí surge la necesidad
de crear la clase Roots que representa un polinomio de
coeficientes complejos.