polinomios horner

36
Raices de polinomios Programación Numérica

Upload: luis-alfonso-hidalgo-tamayo

Post on 01-Nov-2014

194 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Polinomios Horner

Raices de polinomios

Programación Numérica

Page 2: Polinomios Horner

Definición

Un polinomio de grado n es una expresión de la forma:

P(x) = anxn + an-1xn-1 + ... +a1x + a0

Donde an <> 0

Teorema (teorema fundamental del álgebra): Si P(x) es un polinomio de grado n >= 1, entonces P(x) = 0 tiene al menos una raíz (posiblemente compleja).

Page 3: Polinomios Horner

Corolario

Si P(x) es un polinomio de grado n >= 1, entonces existen constantes únicas x1, x2, ... xk, posiblemente complejas, y enteros positivos m1, m2, ..., mk, tales que:

k

ii nm

1

kmk

mmn xxxxxxaxP ...)( 21

21

y

Page 4: Polinomios Horner

Método de HornerSea

P(x) = anxn + an-1xn-1 + ... +a1x + a0

Si bn = an y

bk = ak + bk+1x0 para k = n – 1, n – 2, ..., 1, 0

Por tanto b0 = P(x0). Más aún, si

Q(x) = bnxn–1 + bn-1xn-2 + ... +b2x + b1

Entonces

P(x) = (x – x0) Q(x) + b0

Page 5: Polinomios Horner

Ejercicios

Evaluar:

P(x) = 2x4 – 3x2 + 3x – 4 en x0 = –2

P(x) = 7x5 + 6x4 – 6x3 + 3x – 4 en x0 = 3

P(x) = – 5x6 + 3x4 + 2x2 – 4x en x0 = –1

Page 6: Polinomios Horner

Método de Horner en Cdouble horner(double p[],int n, double x){ double y = p[0]; int i; for(i = 1; i<n; i++){ y = x*y + p[i]; } return y; }

double eval(double p[],int n, double x){ double s = 0; int i; for(i = 0; i<n; i++){ s = s + p[i]*pow(x,n-i-1); } return s; }

Page 7: Polinomios Horner

Evaluación de la derivada

Dado que:

P(x) = (x – x0) Q(x) + b0

donde

Q(x) = bnxn–1 + bn-1xn-2 + ... +b2x + b1

Derivando

P’(x) = Q(x)+(x – x0)Q’(x)

En x = x0,

P’(x0) = Q(x0)

Page 8: Polinomios Horner

Evaluación de la derivada en C

void hornerDer(double p[],int n, double x,double &y,double &z){ y = p[0]; z = p[0]; int i; for(i = 1; i<n-1; i++){ y = x*y + p[i]; z = x*z + y; } y = x*y + p[n-1];}

Page 9: Polinomios Horner

Método horner

Entrada: grado n, a0, a1, ..., an, x0

Salida: y =P(x0), z = P’(x0)

1. y = an //calcule bn para P2. z = an //calcule bn-1 para Q3. Para j = n –1, n – 2, .... , 14. y = x0*y + aj 5. z = x0*z + y6. y = x0*y + a07. regresar y, z

Page 10: Polinomios Horner

Método de Horner en Matlabfunction [y,z]=Horner(x,x0)%x es un vector con los coeficientes%de P(x)%regresa en y el polinomio y en z%la derivada evaluados en x0[muda n] = size(x);y = x(1); %calcule bn para P. z = x(1); %calcule bn-1 para Qfor j = 2:n-1, y = x0*y + x(j); z = x0*z + y;endy = x0*y + x(n);

Page 11: Polinomios Horner

Método de Newton para polinomios

Se puede aplicar el método de Newton para polinomios evaluando el polinomio y su derivada mediante el método de Horner.

El esquema sería

n

nn

n

nnn xQ

xPx

xPxP

xx '1

Page 12: Polinomios Horner

Newton para polinomios en C

double NewtonPol(double p[],int n,double x0,double ee, int ni){ int i=0; double f,df,x = x0,error; while(i<ni){ hornerDer(p,n,x,f,df); x = x0 - f/df; error = fabs((x-x0)/x); if(error<=ee) return x; i++; x0 = x; } std::cout << "No solución en " << i << " pasos\n"; return x;}

Page 13: Polinomios Horner

La Clase Hornerclass Horner{

int n;double a[],y,z;Horner(double[] a1){

n = a1.length;a = a1;

}public double val(){return y;}public double der(){return z;}public void evalua(double x0){

y = a[n-1];z = a[n-1];for(int j = n-2; j>0; j--){

y = x0*y + a[j];z = x0*z + y;

}y = x0*y + a[0];

}}

Page 14: Polinomios Horner

Ejemplo de llamadaclass HornerMain{ static public void main(String[] args){ double pol[] = new double[5];// P(x)=2*x^4-3*x^2+3*x-4 pol[0]=-4; pol[1]=3; pol[2]=-3; pol[3]=0; pol[4]=2; Horner h = new Horner(pol); h.evalua(-2); System.out.println(“P(-2) = "+h.val()); System.out.println("P’(-2) = "+h.der()); }}

Page 15: Polinomios Horner

Método de Newtonclass NewtonPol{ double p,tol; double a[]; NewtonPol(double[] a1, double x0_1,double tol_1){ p = x0_1; a = a1; tol = tol_1; } public double resuelve(){ Horner h=new Horner(a); double f=1, d; while(f>tol){ h.evalua(p); f = h.val(); d = h.der(); p = p - f/d; } return p; }}

Page 16: Polinomios Horner

Ejemploclass NewtonHornerMain{ static public void main(String[] args){ double pol[] = new double[5]; pol[0]=-4; pol[1]=3; pol[2]=-3; pol[3]=0; pol[4]=2; NewtonPol h = new NewtonPol(pol,-2,1e-5); System.out.println("raiz = "+h.resuelve()); }}

Page 17: Polinomios Horner

Método de Müller

Utiliza tres aproximaciones: x0, x1, x2.

Determina la siguiente aproximación x3 encontrando la intersección con el eje x de la parábola definida por los puntos (x0,f(x0)), (x1,f(x1)), (x2,f(x2)).

x0 x1 x2 x3

f

Page 18: Polinomios Horner

Método de Müller

Se considera el polinomio

P(x) = a(x – x2)2 + b(x – x2) + c

Se puede encontrar a, b y c resolviendo

f(x0) = a(x0 – x2)2 + b(x0 – x2) + c

f(x1) = a(x1 – x2)2 + b(x1 – x2) + c

f(x2) = a(x2 – x2)2 + b(x2 – x2) + c

Page 19: Polinomios Horner

Método de Müller

Se llega a

)( 2xfc

102120

202

21212

20 )()()()(xxxxxx

xfxfxxxfxfxxb

102120

21202021 )()()()(xxxxxx

xfxfxxxfxfxxa

Page 20: Polinomios Horner

Método de Müller

Para minimizar el error al resolver la cuadrática P(x) = 0, se calcula x3 con

acbbsignob

cxx

4)(

2223

El proceso se reinicia tomando ahora x1, x2, y x3.

Page 21: Polinomios Horner

Müller en Ccomplex<double> muller(double p[], int n, complex<double> x0,complex<double>x1,complex<double>x2,double tol,int ni){ complex<double> q,h,h1,h2,d1,d2,d,b,D,E; int i; h1 = x1 - x0; h2 = x2 - x1; d1 = (horner(p,n,x1) - horner(p,n,x0))/h1; d2 = (horner(p,n,x2) - horner(p,n,x1))/h2; d = (d2 - d1)/(h2 + h1); i = 3; while(i <= ni){ b = d2 + h2*d; D = pow((b*b - 4.0*horner(p,n,x2)*d),0.5); if(abs(b - D) < abs(b + D)) E = b + D; else E = b - D; h = -2.0*horner(p,n,x2)/E; q = x2 + h; if( abs(h) < tol) return q;

Page 22: Polinomios Horner

Müller en C x0 = x1; x1 = x2; x2 = q; h1 = x1 - x0; h2 = x2 - x1; d1 = (horner(p,n,x1) - horner(p,n,x0))/h1; d2 = (horner(p,n,x2) - horner(p,n,x1))/h2; d = (d2 - d1)/(h2 + h1); i++; } std:cout <<"Fallo después de “<< ni <<“ iteraciones\n";}

int main() { double pol[]={16,-40,5,20,6}; complex<double> x0(0.5,0.0),x1(-0.5,0.0),x2(0.0,0.0); complex<double> raiz = muller(pol,5,x0,x1,x2,0.0001,20); cout << raiz << "\n"; system("PAUSE"); return 0; }

Page 23: Polinomios Horner

Horner complejo

complex<double> horner(double p[],int n, complex<double> x){ complex<double> y = p[0]; int i; for(i = 1; i<n; i++){ y = x*y + p[i]; } return y; }

Page 24: Polinomios Horner

Método de Müller en Matlab% metodo de Muller para obtener una solución para f(x)=0function p = muller(f,x0,x1,x2,tol,ni)h1 = x1 - x0;h2 = x2 - x1;d1 = (polyval(f,x1) - polyval(f,x0))/h1;d2 = (polyval(f,x2) - polyval(f,x1))/h2;d = (d2 - d1)/(h2 + h1);i = 3;while i <= ni b = d2 + h2*d; D = (b*b - 4*polyval(f,x2)*d)^0.5; if abs(b - D) < abs(b + D) E = b + D; else E = b - D; end h = -2*polyval(f,x2)/E; p = x2 + h; if abs(h) < tol return; end

Page 25: Polinomios Horner

Método de Müller en Matlab

x0 = x1; x1 = x2; x2 = p; h1 = x1 - x0; h2 = x2 - x1; d1 = (polyval(f,x1) - polyval(f,x0))/h1; d2 = (polyval(f,x2) - polyval(f,x1))/h2; d = (d2 - d1)/(h2 + h1); i = i + 1;endfprintf('Fallo después de %d iteraciones',ni);

Page 26: Polinomios Horner

EjemploP(x) = 16x4 – 40x3 + 5x2 + 20x + 6

x0 = 0.5 x1 = -0.5 x2 = 0.0

i xi P(xi)

3 -0.555556 + ( -0.598352)i -29.400701 + ( 3.898725)i

4 -0.435450 + ( -0.102101)i 1.332225 + ( 1.193097)i

5 -0.390631 + ( -0.141852)i 0.375058 + ( 0.670168)i

6 -0.357698 + ( -0.169926)i -0.146750 + ( 0.007446)i

7 -0.356051 + ( -0.162856)i -0.001840 + ( -0.000538)i

8 -0.356062 + ( -0.162758)i 0.000002 + ( -0.000001)i

Page 27: Polinomios Horner

Ejemplox0 = 2.5 x1 = 2.0 x2 = 2.3

i xi P(xi)

3 1.960592 + ( 0.000000)i -0.611310 + ( 0.000000)i

4 1.970564 + ( 0.000000)i 0.007455 + ( 0.000000)i

5 1.970447 + ( 0.000000)i 0.000029 + ( 0.000000)i

x0 = 0.5 x1 = 1.0 x2 = 1.5

i xi P(xi)

3 1.287855 + ( 0.000000)i -1.376275 + ( 0.000000)i

4 1.237459 + ( 0.000000)i 0.126945 + ( 0.000000)i

5 1.241605 + ( 0.000000)i 0.002193 + ( 0.000000)i

6 1.241677 + ( 0.000000)i -0.000001 + ( 0.000000)i

Page 28: Polinomios Horner

Raíces de no lineales en Matlabfzero(FUN, x0) – encuentra la raíz de FUN cerca al punto x0. Ejemplos: FUN puede especificarse usando @: X = fzero(@sin,3)regresa pi. X = fzero(@sin,3,optimset('disp','iter')) regresa pi, usa la tolerancia por omisión y despliega información de las iteraciones. FUN puede ser una función en línea: X = fzero(inline('sin(3*x)'),2);

Page 29: Polinomios Horner

Polinomios con Matlab

polyval(P, x) – evalua el polinomio P en el punto x. El polinomio se especifica como un vector donde P(1) es el coeficiente de la potencia más alta y P(length(P)) es el término independiente.

polyder(P) – obtiene la derivada delpolinomio P.

con(A, B) – multiplica el polinomio A por el polinomio B.

[Q R] = deconv(A, B) – divide los dos polinomios A y B y almacena el cociente en Q y el residuo en R.

roots(P) – encuentra todas las raices reales y complejas del polinomio P.

Page 30: Polinomios Horner

Método de BairstowEl enfoque de Bairstow es el de utilizar el Método de Newton para ajustar los coeficientes r y s en la cuadrática x2 – rx + s hasta que sus raíces sean también raíces del polinomio que se quiere resolver.

Con estos coeficientes se determina la cuadrática correspondiente que se utiliza para simplificar la expresión, eliminando estas raíces del conjunto buscado.

El proceso se repite hasta que el polinomio se convierta en uno cuadrático o lineal, momento en que todas las raíces quedan determinadas.

Page 31: Polinomios Horner

La División Larga de un polinomio

n

i

ii xaxP

0

por x2 – rx – s resulta en un cociente de la forma

n

i

ii xbxQ

0

y un residuo b1(x – r) + b0 tal que

01

2

2

2 brxbxbsrxxxPn

i

ii

Page 32: Polinomios Horner

Se utiliza la división sintética para obtener la división entre el factor cuadrático:

bn = an

bn–1 = an–1 + rbn

bi = ai + rbi+1 + sbi+2 (i = n – 2,…, 0)

El método se reduce a determinar los valores de r y s que hacen que el factor cuadrático sea un divisor exacto.

Se utiliza el método de Newton-Raphson. Se calculan incrementos r y s para acercarse a la solución.

200

111

bssb

rrb

bssb

rrb

Las derivadas parciales se calculan por un proceso de división sintética similar al utilizado para calcular las b’s.

Page 33: Polinomios Horner

cn = bn

cn–1 = bn–1 + rcn

ci = bi + rci+1 + sci+2 (i = n – 2,…, 1)

Donde:

sb

crb

c

sb

crb

c

02

01

13

11

,

,

Se resuelven las ecuaciones para r y s y se emplean para mejorar r y s.

Page 34: Polinomios Horner

Bairstow en Cvoid bairstow(double a[],int nn,double es, double rr, double ss,int maxit, double re[],double im[],int &ier){ double b[nn],c[nn]; double r=rr,s=ss,det,dr,ds,ea1,ea2,r1,r2,i1,i2; int n=nn,i,iter; ier = 0; ea1 = 1; ea2 = 1; do{ if(n<3 || iter>=maxit)break; iter = 0; do{ iter++; b[n] = a[n]; b[n-1] = a[n-1]+r*b[n]; c[n] = b[n]; c[n-1] = b[n-1]+r*c[n]; for(i = n-2; i>=0; 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]; } det = c[2]*c[2]-c[3]*c[1];

Page 35: Polinomios Horner

if(det!=0){ dr = (-b[1]*c[2]+b[0]*c[3])/det; ds = (-b[0]*c[2]+b[1]*c[1])/det; r = r+dr; s = s+ds; if(r!=0) ea1 = fabs(dr/r)*100; if(s!=0) ea2 = fabs(ds/s)*100; }else{ r++; s++; iter = 0; } if(ea1<=es && ea2<=es || iter>maxit) break; }while(true); Quadroot(r,s,r1,i1,r2,i2); re[n] = r1; im[n] = i1; re[n-1] = r2; im[n-1] = i2; n = n-2; for(i=0; i<=n; i++) a[i] = b[i+2]; }while(1); if(iter<maxit) if(n==2){ r = -a[1]/a[2]; s = -a[0]/a[2];

Quadroot(r,s,r1,i1,r2,i2); re[n] = r1; im[n] = i1; re[n-1] = r2; im[n-1] = i2; }else{ re[n] = -a[0]/a[1]; im[n] = 0; } else ier = 1;}void Quadroot(double r,double s,double &r1,double &i1,double &r2,double &i2){ double disc = r*r+4*s; if(disc>0){ r1 = (r+sqrt(disc))/2.0; r2 = (r-sqrt(disc))/2.0; i1 = 0; i2 = 0; }else{ r1 = r/2.0; r2 = r1; i1 = sqrt(fabs(disc))/2.0; i2 = -i1; }}

Page 36: Polinomios Horner

Tarea

Escriba un programa en C amigable para el usuario que utilice la función bairstow() para encontrar las raíces de un polinomio.

Deberá pedir el grado del polinomio, los coeficientes, los valores iniciales para la función bairstow, el error esperado y el número de iteraciones máximo.

Deberá dar como salida una lista de las raíces del polinomio y/o una indicación de error.