1. Polinomio característico 2. Cálculo de vaps con solve y fsolve

Anuncio
Métodos Numéricos
Tema 7: Valores y vectores propios
Practica 1
Prof: Francisco Palacios
EPSEM-UPC
Curso 2006/2007 Versión 1.1
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;
1. Polinomio característico
Cálculo "manual" del polinomio caracterísco. p(t)=det(A-t*I).
> with(linalg):
Warning, new definition for norm
Warning, new definition for trace
> a:=matrix(3,3,[1,2,1,0,1,2,1,3,2]);
⎡1
⎢
a := ⎢ 0
⎢
⎣1
2
1
3
1⎤
⎥
2⎥
⎥
2⎦
Construimos la matriz unitaria de orden 3.
> id3:=diag(1,1,1);
⎡1
⎢
id3 := ⎢ 0
⎢
⎣0
0
1
0
0⎤
⎥
0⎥
⎥
1⎦
> b:=evalm(a-t*id3);
⎡1 − t
⎢
b := ⎢ 0
⎢
⎣ 1
2
1−t
3
1 ⎤
⎥
2 ⎥
⎥
2 − t⎦
> p:=det(b);
p := −1 + 2 t + 4 t2 − t3
Cálculo directo del polinomio característico usando charpoly.
> p1:=charpoly(a,t);
p1 := −2 t − 4 t2 + t3 + 1
p y p1 pueden ser distintos en un cambio de signo, Maple calcula el polinomio característico de una matriz de orden n como
p(t)=(-1)^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 :=
−
1
6
%11 / 3 +
1
12
44
%11 / 3 −
1
3 %1
1/3
22
1
3 %1
%1 := 692 + 12 I
> evalf(vaps);
4
1
22 1
4 1
%11 / 3 −
+ + I
+ ,−
1/3
3 12
3 %1
3 2
1/3
+
4
3
−
1
2
I
44 1 ⎞
⎛1
⎟,
3 ⎜⎜ %11 / 3 −
3 %11 / 3 ⎟⎠
⎝6
44 1 ⎞
⎛1
⎟
3 ⎜⎜ %11 / 3 −
3 %11 / 3 ⎟⎠
⎝6
1407
-9
-9
4.402678830, −.7187096905
− .9 10
Page
1 I, .3160308605 + .9 10 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 := -.7187096904, .3160308609, 4.402678830
3. Comando eigenvals
El comando eigenvals proporciona directamente los valores propios.
> a:=matrix(3,3,[1,2,1,0,1,2,1,3,2]);
⎡1
⎢
a := ⎢ 0
⎢
⎣1
2
1
3
1⎤
⎥
2⎥
⎥
2⎦
> vaps:=eigenvals(a);
vaps :=
−
1
6
%11 / 3 +
1
12
44
%11 / 3 −
1
3 %1
1/3
22
1
4
1
22 1
4 1
+ ,−
%11 / 3 −
+ + I
1
/
3
3 12
3 %1
3 2
3 %11 / 3
%1 := 692 + 12 I
> evalf(vaps);
+
4
3
−
1
2
I
44 1 ⎞
⎛1
⎟,
3 ⎜⎜ %11 / 3 −
3 %11 / 3 ⎟⎠
⎝6
44 1 ⎞
⎛1
⎟
3 ⎜⎜ %11 / 3 −
3 %11 / 3 ⎟⎠
⎝6
1407
.3160308609, 4.402678830, -.7187096904
Si usamos una matriz "float", se obtienen valores aproximados para los valores propios.
> af:=evalf(evalm(a));
⎡1.
⎢
af := ⎢ 0
⎢
⎣1.
2.
1.
3.
1.⎤
⎥
2.⎥
⎥
2.⎦
> vaps:=eigenvals(af);
vaps := .3160308609, 4.402678830, -.7187096904
4. Comando eigenvects
El comando eigenvects proporciona los valores propios, multipliciad y vectores propios asociados.
> a:=matrix(3,3,[1,2,1,0,1,2,1,3,2]);
af:=evalf(evalm(a));
⎡1
⎢
a := ⎢ 0
⎢
⎣1
2
1
3
1⎤
⎥
2⎥
⎥
2⎦
⎡1.
⎢
af := ⎢ 0
⎢
⎣1.
2.
1.
3.
1.⎤
⎥
2.⎥
⎥
2.⎦
> veps:=eigenvects(af);
veps := [ 4.402678829, 1, { [ -.5201207449, -.4781522694, -.8134993026 ] } ],
[ -.7187096906, 1, { [ -.6779459756, 1.021520419, -.8778485199 ] } ],
[ .3160308632, 1, { [ -.916668609, .3781466858, -.1293203316 ] } ]
Podemos acceder al contenido de la estructura compleja veps usando ínices. veps[1,3] es el tercer elemento del primer objeto
en veps.
> veps[1,3];
{ [ -.5201207449, -.4781522694, -.8134993026 ] }
> veps[1,3,1];
[ -.5201207449, -.4781522694, -.8134993026 ]
Construcción de una matriz que tiene en columnas los vectores propios.
> v1:=veps[1,3,1];
v1 := [ -.5201207449, -.4781522694, -.8134993026 ]
> v2:=veps[2,3,1];
v2 := [ -.6779459756, 1.021520419, -.8778485199 ]
> v3:=veps[3,3,1];
v3 := [ -.916668609Page
, .3781466858
, -.1293203316 ]
2
> v:=transpose(matrix([v1,v2,v3]));
⎡-.5201207449
⎢
v := ⎢-.4781522694
⎢
⎣-.8134993026
-.6779459756
1.021520419
-.8778485199
-.916668609 ⎤
⎥
.3781466858 ⎥
⎥
-.1293203316⎦
5. Diagonalización
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
-.8 10-9 ⎤⎥
-.5 10-8
⎢
-8
⎢
d := ⎢ .19 10
-.7187096905
-.36 10-9 ⎥⎥
⎢
⎥
-7
-8
.33 10
.3160308607⎦
⎣ -.102 10
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)<10^(-6) then 0 else x fi;
filt0 := proc(x) option operator, arrow; if abs( x ) < 1 / 1000000 then 0 else x fi end
Aplicamos el programa a la matriz usando el comando map
> df:=map(filt0,d);
⎡4.402678827
⎢
df := ⎢
0
⎢
⎣
0
0
-.7187096905
0
0
⎤
⎥
⎥
0
⎥
.3160308607⎦
6. Progama para método de la potencia
El método de la potencia permite determinar el valor propio de módulo máximo y un vector propio asociado.
> with(linalg):
a:=matrix(3,3,[1,2,1,0,1,2,1,3,2]);
x0:=[1,1,1];# vector inicial
n:=3;
for i from 0 to n do
`********** iteración`,i+1,`**********`;
y.(i+1):=evalf(evalm(a&*x.i));
ny:=norm(y.(i+1), infinity);
for j from 1 to vectdim(x0) do
if abs(y.(i+1)[j])=ny then cdom:=y.(i+1)[j];break;fi;
od;
c.(i+1):=cdom;
x.(i+1):=evalm(y.(i+1)/c.(i+1));
od;
⎡1
⎢
a := ⎢ 0
⎢
⎣1
2
1
3
1⎤
⎥
2⎥
⎥
2⎦
x0 := [ 1, 1, 1 ]
n := 3
********** iteración, 1, **********
y1 := [ 4., 3., 6. ]
ny := 6.
c1 := 6.
x1 := [ .6666666668, .5000000001, 1.000000000 ]
********** iteración, 2, **********
y2 := [ 2.666666667, 2.500000000, 4.166666667 ]
ny := 4.166666667
c2 := 4.166666667
x2 := [ .6400000001, .6000000000, 1.000000000 ]
********** 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.810810811, 2.585585586, 4.396396397 ]
ny := 4.396396397
c4 := 4.396396397
x4 := [ .6393442624, .5881147542, 1.000000000 ]
7. Programa con parada por error estimado sobre el valor propio
> with(linalg):
a:=matrix(3,3,[1,2,1,0,1,2,1,3,2]);
x0:=[1,1,1];
t:=3;
n:=14;
c0:=10^(10);
for i from 0 to n do
`********** iteración`,i+1,`**********`;
y.(i+1):=evalf(evalm(a&*x.i));
ny:=norm(y.(i+1), infinity);
for j from 1 to vectdim(x0) do
if abs(y.(i+1)[j])=ny then cdom:=y.(i+1)[j];break;fi;
od;
c.(i+1):=cdom;
x.(i+1):=evalm(y.(i+1)/c.(i+1));
er.(i+1):=c.(i+1)-c.i;
if abs(er.(i+1))<0.5*10^(-t)
then print(`*** precisión alcazada ***`);break;
fi;
od;
⎡1
⎢
a := ⎢ 0
⎢
⎣1
2
1
3
1⎤
⎥
2⎥
⎥
2⎦
x0 := [ 1, 1, 1 ]
t := 3
n := 14
c0 := 10000000000
********** iteración, 1, **********
y1 := [ 4., 3., 6. ]
ny := 6.
c1 := 6.
x1 := [ .6666666668, .5000000001, 1.000000000 ]
er1 := -.9999999994 1010
********** iteración, 2, **********
y2 := [ 2.666666667, 2.500000000, 4.166666667 ]
ny := 4.166666667
c2 := 4.166666667
x2 := [ .6400000001, .6000000000, 1.000000000 ]
er2 := -1.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.810810811, 2.585585586, 4.396396397 ]
Page 4
ny := 4.396396397
c4 := 4.396396397
x4 := [ .6393442624, .5881147542, 1.000000000 ]
er4 := -.043603603
********** iteración, 5, **********
y5 := [ 2.815573770, 2.588114754, 4.403688525 ]
ny := 4.403688525
c5 := 4.403688525
x5 := [ .6393671474, .5877152164, 1.000000000 ]
er5 := .007292128
********** iteración, 6, **********
y6 := [ 2.814797580, 2.587715216, 4.402512796 ]
ny := 4.402512796
c6 := 4.402512796
x6 := [ .6393615898, .5877814185, 1.000000000 ]
er6 := -.001175729
********** iteración, 7, **********
y7 := [ 2.814924427, 2.587781419, 4.402705846 ]
ny := 4.402705846
c7 := 4.402705846
x7 := [ .6393623661, .5877706823, 1.000000000 ]
er7 := .000193050
*** precisión alcazada ***
> af:=evalf(evalm(a));
eigenvals(af);
⎡1.
⎢
af := ⎢ 0
⎢
⎣1.
2.
1.
3.
1.⎤
⎥
2.⎥
⎥
2.⎦
.3160308609, 4.402678830, -.7187096904
8. Método de la potencia inversa
Calcula el valor propio de módulo mínimo.
> with(linalg):
a:=matrix(3,3,[1,2,1,0,1,2,1,3,2]);
af:=evalf(evalm(a));
a1:=inverse(af);
x0:=[1,2,1];
t:=3;
n:=24;
c0:=10^(10);
for i from 0 to n do
`********** iteración`,i+1,`**********`;
y.(i+1):=evalf(evalm(a1&*x.i));
ny:=norm(y.(i+1), infinity);
for j from 1 to vectdim(x0) do
if abs(y.(i+1)[j])=ny then cdom:=y.(i+1)[j];break;fi;
od;
c.(i+1):=cdom;
x.(i+1):=evalm(y.(i+1)/c.(i+1));
er.(i+1):=c.(i+1)-c.i;
if abs(er.(i+1))<0.5*10^(-t)
then print(`*** precisión alcazada ***`);
vapdom_a1:=c.(i+1);
break;
fi;
od;
vap_min:=1/vapdom_a1;
Page 5
⎡1
⎢
a := ⎢ 0
⎢
⎣1
2
1
3
1⎤
⎥
2⎥
⎥
2⎦
⎡1.
⎢
af := ⎢ 0
⎢
⎣1.
2.
1.
3.
1.⎤
⎥
2.⎥
⎥
2.⎦
⎡ 4.000000000
⎢
a1 := ⎢-2.000000000
⎢
⎣ 1.000000000
1.000000000
-1.000000000
1.000000000
-3.000000000⎤
⎥
2.000000000 ⎥
⎥
-1.000000000⎦
x0 := [ 1, 2, 1 ]
t := 3
n := 24
c0 := 10000000000
********** iteración, 1, **********
y1 := [ 3.000000000, -2.000000000, 2.000000000 ]
ny := 3.000000000
c1 := 3.000000000
x1 := [ .9999999999, -.6666666666, .6666666666 ]
er1 := -.9999999997 1010
********** iteración, 2, **********
y2 := [ 1.333333333, 0, -.3333333333 ]
ny := 1.333333333
c2 := 1.333333333
x2 := [ 1.000000000, 0, -.2500000000 ]
er2 := -1.666666667
********** iteración, 3, **********
y3 := [ 4.750000000, -2.500000000, 1.250000000 ]
ny := 4.750000000
c3 := 4.750000000
x3 := [ 1.000000000, -.5263157895, .2631578948 ]
er3 := 3.416666667
********** iteración, 4, **********
y4 := [ 2.684210527, -.9473684214, .2105263157 ]
ny := 2.684210527
c4 := 2.684210527
x4 := [ 1.000000000, -.3529411765, .07843137249 ]
er4 := -2.065789473
********** iteración, 5, **********
y5 := [ 3.411764707, -1.490196079, .5686274510 ]
ny := 3.411764707
c5 := 3.411764707
x5 := [ 1.000000000, -.4367816092, .1666666666 ]
er5 := .727554180
********** iteración, 6, **********
y6 := [ 3.063218391, -1.229885058, .3965517242 ]
ny := 3.063218391
c6 := 3.063218391
x6 := [ 1.000000000, -.4015009383, .1294559100 ]
er6 := -.348546316
********** iteración, 7, **********
y7 := [ 3.210131332, -1.339587242, .4690431517 ]
ny := 3.210131332
c7 := 3.210131332
Page 6
x7 := [ 1.000000000, -.4172998247, .1461133839 ]
er7 := .146912941
********** iteración, 8, **********
y8 := [ 3.144360023, -1.290473407, .4365867914 ]
ny := 3.144360023
c8 := 3.144360023
x8 := [ 1.000000000, -.4104089218, .1388475837 ]
er8 := -.065771309
********** iteración, 9, **********
y9 := [ 3.173048327, -1.311895911, .4507434945 ]
ny := 3.173048327
c9 := 3.173048327
x9 := [ 1.000000000, -.4134497102, .1420537755 ]
er9 := .028688304
********** iteración, 10, **********
y10 := [ 3.160388964, -1.302442739, .4444965143 ]
ny := 3.160388964
c10 := 3.160388964
x10 := [ 1.000000000, -.4121146966, .1406461418 ]
er10 := -.012659363
********** iteración, 11, **********
y11 := [ 3.165946878, -1.306593019, .4472391616 ]
ny := 3.165946878
c11 := 3.165946878
x11 := [ 1.000000000, -.4127021297, .1412655294 ]
er11 := .005557914
********** iteración, 12, **********
y12 := [ 3.163501282, -1.304766811, .4460323409 ]
ny := 3.163501282
c12 := 3.163501282
x12 := [ 1.000000000, -.4124439015, .1409932544 ]
er12 := -.002445596
********** iteración, 13, **********
y13 := [ 3.164576336, -1.305569590, .4465628441 ]
ny := 3.164576336
c13 := 3.164576336
x13 := [ 1.000000000, -.4125574647, .1411129948 ]
er13 := .001075054
********** iteración, 14, **********
y14 := [ 3.164103551, -1.305216545, .4463295405 ]
ny := 3.164103551
c14 := 3.164103551
x14 := [ 1.000000000, -.4125075314, .1410603456 ]
er14 := -.000472785
*** precisión alcazada ***
vap_min := .3160452823
> eigenvals(af);
.3160308609, 4.402678830, -.7187096904
9. Método de la potencia desplazada
Calcula un valor propio próximo a un valor dado.
> with(linalg):
Page 7
a:=matrix(3,3,[1,2,1,0,1,2,1,3,2]);
af:=evalf(evalm(a));
vapest:=-0.5;# Estimacion del valor propio
id3:=diag(1,1,1);
b:=evalm(af-vapest*id3);
b1:=inverse(b);
x0:=[1,2,1];
t:=3;
n:=14;
c0:=10^(10);
for i from 0 to n do
`********** iteración`,i+1,`**********`;
y.(i+1):=evalf(evalm(b1&*x.i));
ny:=norm(y.(i+1), infinity);
for j from 1 to vectdim(x0) do
if abs(y.(i+1)[j])=ny then cdom:=y.(i+1)[j];break;fi;
od;
c.(i+1):=cdom;
x.(i+1):=evalm(y.(i+1)/c.(i+1));
er.(i+1):=c.(i+1)-c.i;
if abs(er.(i+1))<0.5*10^(-t)
then print(`*** precisión alcazada ***`);
vap_dom_desp:=c.(i+1);
break;
fi;
od;
vap:=1/c.(i+1)+vapest;
⎡1
⎢
a := ⎢ 0
⎢
⎣1
2
1
3
1⎤
⎥
2⎥
⎥
2⎦
⎡1.
⎢
af := ⎢ 0
⎢
⎣1.
2.
1.
3.
1.⎤
⎥
2.⎥
⎥
2.⎦
vapest := -.5
⎡1.5
⎢
b := ⎢ 0
⎢
⎣ 1.
⎡ 2.571428571
⎢
b1 := ⎢-2.285714286
⎢
⎣ 1.714285714
2.
1.5
3.
1. ⎤
⎥
2. ⎥
⎥
2.5⎦
2.285714286
-3.142857143
2.857142857
-2.857142857⎤
⎥
3.428571429 ⎥
⎥
-2.571428571⎦
x0 := [ 1, 2, 1 ]
t := 3
n := 14
c0 := 10000000000
********** iteración, 1, **********
y1 := [ 4.285714286, -5.142857143, 4.857142857 ]
ny := 5.142857143
c1 := -5.142857143
x1 := [ -.8333333332, .9999999998, -.9444444442 ]
er1 := -.1000000001 1011
********** iteración, 2, **********
y2 := [ 2.841269842, -4.476190475, 3.857142856 ]
ny := 4.476190475
c2 := -4.476190475
x2 := [ -.6347517734, 1.000000000, -.8617021277 ]
er2 := .666666668
********** iteración, 3, **********
y3 := [ 3.115501519Page
, -4.646403241
, 3.984802431 ]
8
ny := 4.646403241
c3 := -4.646403241
x3 := [ -.6705189709, 1.000000000, -.8576101180 ]
er3 := -.170212766
********** iteración, 4, **********
y4 := [ 3.011837270, -4.550619900, 3.912964924 ]
ny := 4.550619900
c4 := -4.550619900
x4 := [ -.6618520852, .9999999999, -.8598751400 ]
er4 := .095783341
********** iteración, 5, **********
y5 := [ 3.040595038, -4.578195715, 3.933646785 ]
ny := 4.578195715
c5 := -4.578195715
x5 := [ -.6641470195, 1.000000000, -.8592133300 ]
er5 := -.027575815
********** iteración, 6, **********
y6 := [ 3.032802893, -4.570681088, 3.928010814 ]
ny := 4.570681088
c6 := -4.570681088
x6 := [ -.6635341286, 1.000000000, -.8593928866 ]
er6 := .007514627
********** iteración, 7, **********
y7 := [ 3.034891917, -4.572697603, 3.929523202 ]
ny := 4.572697603
c7 := -4.572697603
x7 := [ -.6636983637, 1.000000000, -.8593446458 ]
er7 := -.002016515
********** iteración, 8, **********
y8 := [ 3.034331767, -4.572156811, 3.929117609 ]
ny := 4.572156811
c8 := -4.572156811
x8 := [ -.6636543521, .9999999998, -.8593575790 ]
er8 := .000540792
********** iteración, 9, **********
y9 := [ 3.034481892, -4.572301751, 3.929226312 ]
ny := 4.572301751
c9 := -4.572301751
x9 := [ -.6636661484, 1.000000000, -.8593541123 ]
er9 := -.000144940
*** precisión alcazada ***
vap := -.7187082250
> eigenvals(af);
.3160308609, 4.402678830, -.7187096904
>
Page 9
Descargar