Métodos Numéricos Tema 7: Valores y vectores propios Practica Prof: Francisco Palacios EPSEM-UPC Curso 2006/2007 Versión. Contenido Polinomio característco. Cálculo de valores propios con solve y fsolve. Cálculo de valores propios con el comando eigenvals. Comando eigenvects. Diagonalización. Programa para método de la potencia. Programa para método de la potencia. Parada por error estimado sobre el valor propio. Mètodo de la potencia inversa. Mètodo de la potencia desplazada. > restart;. Polinomio característico Cálculo "manual" del polinomio caracterísco. p(t)=det(a-t*i). Warning, new definition for norm Warning, new definition for trace > a:=matrix(3,3,[,2,,0,,2,,3,2]); Construimos la matriz unitaria de orden 3. > id3:=diag(,,); 0 0 id3 := 0 0 0 0 > b:=evalm(a-t*id3); t 2 b := 0 t 2 3 2 t > p:=det(b); p := + 2 t + 4 t 2 t 3 Cálculo directo del polinomio característico usando charpoly. > p:=charpoly(a,t); p := 2 t 4 t 2 + t 3 + p y p pueden ser distintos en un cambio de signo, Maple calcula el polinomio característico de una matriz de orden n como p(t)=(-)^n det(a-ti). 2. Cálculo de vaps con solve y fsolve C alculamos las raíces del polinomio característico con solve. > vaps:=solve(p); vaps + + 6 % / 3 44 4 3 % / 3 3 2 % / 3 22 3 + 4 % + / 3 3 2 I 3 6 % / 3 44 :=,, 3 % / 3 + 2 % / 3 22 4 3 % / 3 3 2 I 3 6 % / 3 44 3 % / 3 % := 692 + 2 I 407 > evalf(vaps); 4.402678830,.787096905 Page.9 0-9 I,.360308605 +.9 0-9 I
En la evaluació float aparecen partes complejas "residuales". Es preferible usar fsolve si sabemos que los valores propios son reales. > vaps:=fsolve(p); vaps :=,.360308609, 4.402678830 3. Comando eigenvals El comando eigenvals proporciona directamente los valores propios. > a:=matrix(3,3,[,2,,0,,2,,3,2]); > vaps:=eigenvals(a); vaps + + 6 % / 3 44 4 3 % / 3 3 2 % / 3 22 3 + 4 % + / 3 3 2 I 3 6 % / 3 44 :=,, 3 % / 3 + 2 % / 3 22 4 3 % / 3 3 2 I 3 6 % / 3 44 3 % / 3 % := 692 + 2 I 407 > evalf(vaps);.360308609, 4.402678830, Si usamos una matriz "float", se obtienen valores aproximados para los valores propios. > af:=evalf(evalm(a)); > vaps:=eigenvals(af); 4. Comando eigenvects vaps :=.360308609, 4.402678830, El comando eigenvects proporciona los valores propios, multipliciad y vectores propios asociados. > a:=matrix(3,3,[,2,,0,,2,,3,2]); af:=evalf(evalm(a)); > veps:=eigenvects(af); veps := [ 4.402678829,, {[-.520207449, -.478522694, -.834993026 ]} ], [-.787096906,, { [-.6779459756,.0252049, -.877848599 ]} ], [.360308632,, { [-.96668609,.378466858, -.29320336 ]} ] Podemos acceder al contenido de la estructura compleja veps usando ínices. veps[,3] es el tercer elemento del primer objeto en veps. > veps[,3]; {[-.520207449, -.478522694, -.834993026 ]} > veps[,3,]; [-.520207449, -.478522694, -.834993026 ] Construcción de una matriz que tiene en columnas los vectores propios. > v:=veps[,3,]; v := [-.520207449, -.478522694, -.834993026 ] > v2:=veps[2,3,]; v2 := [-.6779459756,.0252049, -.877848599 ] > v3:=veps[3,3,]; v3 := [-.96668609 Page,.378466858 2, -.29320336 ]
> v:=transpose(matrix([v,v2,v3])); 5. Diagonalización v := -.520207449 -.6779459756 -.96668609 -.478522694.0252049.378466858 -.834993026 -.877848599 -.29320336 Si las columnas de V son una base de vectores propios de la matriz A, entonces el producto D=inv(V) A V es una matriz diagonal. > d:=evalm(inverse(v)&*a&*v); 4.402678827 -.5 0-8 -.8 0-9 d :=.9 0-8 -.787096905 -.36 0-9 -.02 0-7.33 0-8.360308607 Observa que hay elementos residuales que no son exactamente cero. el sugiente programa sirve para filtrar los elementos casi nulos. > filt0:=x->if abs(x)<0^(-6) then 0 else x fi; filt0 := proc( x) option operator, arrow; if abs( x ) < / 000000 then 0 else x fi end Aplicamos el programa a la matriz usando el comando map > df:=map(filt0,d); df := 6. Progama para método de la potencia 4.402678827 0 0 0 -.787096905 0 0 0.360308607 El método de la potencia permite determinar el valor propio de módulo máximo y un vector propio asociado. a:=matrix(3,3,[,2,,0,,2,,3,2]); x0:=[,,];# vector inicial n:=3; for i from 0 to n do `********** iteración`,i+,`**********`; y.(i+):=evalf(evalm(a&*x.i)); ny:=norm(y.(i+), infinity); for j from to vectdim(x0) do if abs(y.(i+)[j])=ny then cdom:=y.(i+)[j];break;fi; c.(i+):=cdom; x.(i+):=evalm(y.(i+)/c.(i+)); x0 := [,, ] n := 3 ********** iteración,, ********** y := [ 4., 3., 6. ] ny := 6. c := 6. x := [.6666666668,.500000000, ********** iteración, 2, ********** y2 := [ 2.666666667, 2.500000000, 4.66666667 ] ny := 4.66666667 c2 := 4.66666667 x2 := [.640000000,.6000000000, ********** iteración, 3, ********** y3 := [ 2.840000000, 2.600000000, 4.440000000 ] ny := 4.440000000 := c3 4.440000000 Page 3
x3 := [.6396396396,.5855855855,.9999999999 ] ********** iteración, 4, ********** y4 := [ 2.80808, 2.585585586, 4.396396397 ] ny := 4.396396397 c4 := 4.396396397 x4 := [.6393442624,.58847542, 7. Programa con parada por error estimado sobre el valor propio a:=matrix(3,3,[,2,,0,,2,,3,2]); x0:=[,,]; t:=3; n:=4; c0:=0^(0); for i from 0 to n do `********** iteración`,i+,`**********`; y.(i+):=evalf(evalm(a&*x.i)); ny:=norm(y.(i+), infinity); for j from to vectdim(x0) do if abs(y.(i+)[j])=ny then cdom:=y.(i+)[j];break;fi; c.(i+):=cdom; x.(i+):=evalm(y.(i+)/c.(i+)); er.(i+):=c.(i+)-c.i; if abs(er.(i+))<0.5*0^(-t) then print(`*** precisión alcazada ***`);break; fi; x0 := [,, ] t := 3 n := 4 c0 := 0000000000 ********** iteración,, ********** y := [ 4., 3., 6. ] ny := 6. c := 6. x := [.6666666668,.500000000, er := -.9999999994 0 0 ********** iteración, 2, ********** y2 := [ 2.666666667, 2.500000000, 4.66666667 ] ny := 4.66666667 c2 := 4.66666667 x2 := [.640000000,.6000000000, er2 := -.833333333 ********** iteración, 3, ********** y3 := [ 2.840000000, 2.600000000, 4.440000000 ] ny := 4.440000000 c3 := 4.440000000 x3 := [.6396396396,.5855855855,.9999999999 ] er3 :=.273333333 ********** iteración, 4, ********** y4 := [ 2.80808, 2.585585586, 4.396396397 ] Page 4
> af:=evalf(evalm(a)); eigenvals(af); 8. Método de la potencia inversa ny := 4.396396397 c4 := 4.396396397 x4 := [.6393442624,.58847542, er4 := -.043603603 ********** iteración, 5, ********** y5 := [ 2.85573770, 2.5884754, 4.403688525 ] ny := 4.403688525 c5 := 4.403688525 x5 := [.639367474,.58775264, er5 :=.00729228 ********** iteración, 6, ********** y6 := [ 2.84797580, 2.5877526, 4.40252796 ] ny := 4.40252796 c6 := 4.40252796 x6 := [.639365898,.58778485, er6 := -.0075729 ********** iteración, 7, ********** y7 := [ 2.84924427, 2.5877849, 4.402705846 ] ny := 4.402705846 c7 := 4.402705846 x7 := [.639362366,.5877706823, er7 :=.00093050 *** precisión alcazada ***.360308609, 4.402678830, Calcula el valor propio de módulo mínimo. a:=matrix(3,3,[,2,,0,,2,,3,2]); af:=evalf(evalm(a)); a:=inverse(af); x0:=[,2,]; t:=3; n:=24; c0:=0^(0); for i from 0 to n do `********** iteración`,i+,`**********`; y.(i+):=evalf(evalm(a&*x.i)); ny:=norm(y.(i+), infinity); for j from to vectdim(x0) do if abs(y.(i+)[j])=ny then cdom:=y.(i+)[j];break;fi; c.(i+):=cdom; x.(i+):=evalm(y.(i+)/c.(i+)); er.(i+):=c.(i+)-c.i; if abs(er.(i+))<0.5*0^(-t) then print(`*** precisión alcazada ***`); vapdom_a:=c.(i+); break; fi; vap_min:=/vapdom_a; Page 5
4.000000000.000000000-3.000000000 a := -2.000000000 -.000000000 2.000000000.000000000.000000000 -.000000000 x0 := [, 2, ] t := 3 n := 24 c0 := 0000000000 ********** iteración,, ********** y := [ 3.000000000, -2.000000000, 2.000000000 ] ny := 3.000000000 c := 3.000000000 x := [.9999999999, -.6666666666,.6666666666 ] er := -.9999999997 0 0 ********** iteración, 2, ********** y2 := [.333333333, 0, -.3333333333 ] ny :=.333333333 c2 :=.333333333 x2 := [.000000000, 0, -.2500000000 ] er2 := -.666666667 ********** iteración, 3, ********** y3 := [ 4.750000000, -2.500000000,.250000000 ] ny := 4.750000000 c3 := 4.750000000 x3 := [.000000000, -.526357895,.263578948 ] er3 := 3.46666667 ********** iteración, 4, ********** y4 := [ 2.68420527, -.947368424,.20526357 ] ny := 2.68420527 c4 := 2.68420527 x4 := [.000000000, -.35294765,.0784337249 ] er4 := -2.065789473 ********** iteración, 5, ********** y5 := [ 3.4764707, -.49096079,.568627450 ] ny := 3.4764707 c5 := 3.4764707 x5 := [.000000000, -.436786092,.666666666 ] er5 :=.72755480 ********** iteración, 6, ********** y6 := [ 3.0632839, -.229885058,.396557242 ] ny := 3.0632839 c6 := 3.0632839 x6 := [.000000000, -.405009383,.29455900 ] er6 := -.34854636 ********** iteración, 7, ********** y7 := [ 3.203332, -.339587242,.46904357 ] ny := 3.203332 := c7 3.203332 Page 6
> eigenvals(af); 9. Método de la potencia desplazada x7 := [.000000000, -.472998247,.4633839 ] er7 :=.469294 ********** iteración, 8, ********** y8 := [ 3.44360023, -.290473407,.436586794 ] ny := 3.44360023 c8 := 3.44360023 x8 := [.000000000, -.40408928,.388475837 ] er8 := -.06577309 ********** iteración, 9, ********** y9 := [ 3.73048327, -.38959,.4507434945 ] ny := 3.73048327 c9 := 3.73048327 x9 := [.000000000, -.43449702,.420537755 ] er9 :=.028688304 ********** iteración, 0, ********** y0 := [ 3.60388964, -.302442739,.444496543 ] ny := 3.60388964 c0 := 3.60388964 x0 := [.000000000, -.4246966,.4064648 ] er0 := -.02659363 ********** iteración,, ********** y := [ 3.65946878, -.30659309,.44723966 ] ny := 3.65946878 c := 3.65946878 x := [.000000000, -.42702297,.42655294 ] er :=.00555794 ********** iteración, 2, ********** y2 := [ 3.6350282, -.3047668,.4460323409 ] ny := 3.6350282 c2 := 3.6350282 x2 := [.000000000, -.42443905,.409932544 ] er2 := -.002445596 ********** iteración, 3, ********** y3 := [ 3.64576336, -.305569590,.446562844 ] ny := 3.64576336 c3 := 3.64576336 x3 := [.000000000, -.425574647,.429948 ] er3 :=.00075054 ********** iteración, 4, ********** y4 := [ 3.640355, -.30526545,.4463295405 ] ny := 3.640355 c4 := 3.640355 x4 := [.000000000, -.42507534,.40603456 ] er4 := -.000472785 *** precisión alcazada *** vap_min :=.360452823.360308609, 4.402678830, Calcula un valor propio próximo a un valor dado. Page 7
a:=matrix(3,3,[,2,,0,,2,,3,2]); af:=evalf(evalm(a)); vapest:=-0.5;# Estimacion del valor propio id3:=diag(,,); b:=evalm(af-vapest*id3); b:=inverse(b); x0:=[,2,]; t:=3; n:=4; c0:=0^(0); for i from 0 to n do `********** iteración`,i+,`**********`; y.(i+):=evalf(evalm(b&*x.i)); ny:=norm(y.(i+), infinity); for j from to vectdim(x0) do if abs(y.(i+)[j])=ny then cdom:=y.(i+)[j];break;fi; c.(i+):=cdom; x.(i+):=evalm(y.(i+)/c.(i+)); er.(i+):=c.(i+)-c.i; if abs(er.(i+))<0.5*0^(-t) then print(`*** precisión alcazada ***`); vap_dom_desp:=c.(i+); break; fi; vap:=/c.(i+)+vapest; b := b := vapest := -.5.5 2.. 0.5 2.. 3. 2.5 2.5742857 2.28574286-2.85742857-2.28574286-3.4285743 3.42857429.7428574 2.85742857-2.5742857 x0 := [, 2, ] t := 3 n := 4 c0 := 0000000000 ********** iteración,, ********** y := [ 4.28574286, -5.4285743, 4.85742857 ] ny := 5.4285743 c := -5.4285743 x := [-.8333333332,.9999999998, -.9444444442 ] er := -.00000000 0 ********** iteración, 2, ********** y2 := [ 2.84269842, -4.47690475, 3.85742856 ] ny := 4.47690475 c2 := -4.47690475 x2 := [-.634757734,.000000000, -.86702277 ] er2 :=.666666668 ********** iteración, 3, ********** y3 := [ 3.55059Page, -4.64640324 8, 3.98480243 ]
> eigenvals(af); > ny := 4.64640324 c3 := -4.64640324 x3 := [-.670589709,.000000000, -.8576080 ] er3 := -.7022766 ********** iteración, 4, ********** y4 := [ 3.0837270, -4.55069900, 3.92964924 ] ny := 4.55069900 c4 := -4.55069900 x4 := [-.668520852,.9999999999, -.859875400 ] er4 :=.09578334 ********** iteración, 5, ********** y5 := [ 3.040595038, -4.5789575, 3.933646785 ] ny := 4.5789575 c5 := -4.5789575 x5 := [-.66447095,.000000000, -.859233300 ] er5 := -.02757585 ********** iteración, 6, ********** y6 := [ 3.032802893, -4.57068088, 3.9280084 ] ny := 4.57068088 c6 := -4.57068088 x6 := [-.663534286,.000000000, -.8593928866 ] er6 :=.00754627 ********** iteración, 7, ********** y7 := [ 3.0348997, -4.572697603, 3.929523202 ] ny := 4.572697603 c7 := -4.572697603 x7 := [-.6636983637,.000000000, -.8593446458 ] er7 := -.0020655 ********** iteración, 8, ********** y8 := [ 3.03433767, -4.572568, 3.9297609 ] ny := 4.572568 c8 := -4.572568 x8 := [-.663654352,.9999999998, -.8593575790 ] er8 :=.000540792 ********** iteración, 9, ********** y9 := [ 3.03448892, -4.5723075, 3.92922632 ] ny := 4.5723075 c9 := -4.5723075 x9 := [-.663666484,.000000000, -.85935423 ] er9 := -.00044940 *** precisión alcazada *** vap := -.787082250.360308609, 4.402678830, Page 9