TP MAO 5

> restart: with(linalg): with(pldx):

`pldx v6-20  ;  author : <douillet@ensait.fr>  ;  l...

>

Cas où l'algorithme converge

> ma:= randmatrix(4,4);
# les coefficients vont de -99 à +99

ma := matrix([[-85, -55, -37, -35], [97, 50, 79, 56...

> ma := matrix([[-53, 85, 49, 78], [17, 72, -99, -85], [-86, 30, 80, 72], [66, -29, -91, -53]]);

ma := matrix([[-53, 85, 49, 78], [17, 72, -99, -85]...

> v0:= evalf(randvector(4));
# on se place sur les réels et pas dans le corps des fractions

v0 := vector([43., -62., 77., 66.])

> itera:= proc(v1); evalm(ma &* v1): evalm(%/norm(%) ); end;

itera := proc (v1) evalm(`&*`(ma,v1)); evalm(%/norm...

> (itera@@30)(v0); itera(%); vp1:= norm(evalm(ma &* %));
# la direction ne change plus beaucoup

vector([-.6503047452, -.9999999998, .3362540319, -....

vector([-.6481619418, -1.000000000, .3386454681, -....

vp1 := 90.03184028

> Digits:=20: (itera@@190)(v0); itera(%); vp1:= norm(evalm(ma &* %)); Digits:=10:
# on augmente la précision

vector([-.64879950917570258300, -.99999999999999999...

vector([-.64879950917570258252, -.99999999999999999...

vp1 := 89.969586403616302244

190 étapes pour gagner 18 décimales, cela fait un taux de convergence égal à :

> (10.^18)^(1/190);

1.243760735

Et cela se vérifie...

> [eigenvals(map(evalf, ma))]; sort(map(abs,%)); %[-1]/%[-2];

[-44.75593994+56.25306788*I, -44.75593994-56.253067...

[45.54229347, 71.88533791, 71.88533791, 89.96958640...

1.251570752

Cas où le premier algorithme ne converge pas

> ma:= randmatrix(4,4):

> ma := matrix([[-11, 38, -7, 58], [-94, -68, 14, -35], [-14, -9, -51, -73], [-73, -91, 1, 5]]);

ma := matrix([[-11, 38, -7, 58], [-94, -68, 14, -35...

> v0:= evalf(randvector(4));

v0 := vector([-58., -90., 53., -1.])

> itera:= proc(v1) global ma ; evalm(ma &* v1): return evalm(%/norm(%) ); end;

itera := proc (v1) global ma; evalm(`&*`(ma,v1)); r...

> (itera@@90)(v0); itera(%); vp1:= norm(evalm(ma &* %));
# la direction ne se stabilise pas

vector([-.9999999998, .1871558364, .8864130832, .29...

vector([.3486664364, 1.000000000, -.6536957700, .69...

vp1 := 134.4261017

Il y a donc plusieurs valeurs propres dominantes.
La matrice étant réelle, il y a des valeurs propres conjuguées.

Diviser par la norme (qui est un réel) ne permet plus d'identifier la direction (colinéarité avec coefficient complexe). On selectionne la composante dominante

> cpodom:= proc(w) local modmx, jx, j, tmp;
modmx:= 0; jx:=1;
for j from 1 to 4 do
tmp:= evalf(abs(w[j])); if tmp > modmx then modmx:=tmp; jx:=j; fi;
od; return w[jx];
end :

On teste

> evalm(randvector(4)+randvector(4)*I); cpodom(%);

vector([94-84*I, 83+19*I, -86-50*I, 23+88*I])

94-84*I

Réécriture de l'itérateur

> iterb:= subs(ma=mb, norm=cpodom, eval(itera));

iterb := proc (v1) global mb; evalm(`&*`(mb,v1)); r...

Décalage de la matrice initiale

> tr:=100*I; mb:= evalm(ma+tr);

tr := 100*I

mb := matrix([[-11+100*I, 38, -7, 58], [-94, -68+10...

Convergence : la direction se stabilise

> (iterb@@30)(v0); iterb(%); vp1:= cpodom(evalm(mb &* %));

vector([-.4201321949-.8050817993*I, 1.000000000-.45...

vector([-.4201322003-.8050817856*I, .9999999999+.42...

vp1 := -56.12606754+181.9953743*I

Augmentation de la précision et du nombre d'étapes

> Digits:=20: vn:= (iterb@@50)(v0); vn1:= iterb(%); vp1:= cpodom(evalm(mb &* %));
evalm(vn1-vn); norm(%,2); Digits:=10:

vn := vector([-.42013219235420657971-.8050817751088...
vn := vector([-.42013219235420657971-.8050817751088...

vn1 := vector([-.42013219235395226927-.805081775108...
vn1 := vector([-.42013219235395226927-.805081775108...

vp1 := -56.126068101048541837+181.99537256631103057...

vector([.25431044e-12+.1613695e-13*I, 0.+.334824605...

.81330083242471979362e-12

Vitesse : 11 décimales en 50 étapes

> (10.^11)^(1/50);

1.659586907

Vérification

> [eigenvals(map(evalf, mb))]; sort(map(abs,%)); %[-1]/%[-2];

[-56.12606804+181.9953725*I, -56.12606811+18.004627...

[58.94321099, 109.0858619, 114.7758069, 190.4532781...

1.659350374

Les valeurs propres dominantes de ma sont donc

> mu1:= evalf(vp1-tr, 20); mu2:= conjugate(%);

mu1 := -56.126068101048541837+81.99537256631103057*...

mu2 := -56.126068101048541837-81.99537256631103057*...

Et les vecteurs propres

> wp1:= pldx[xpurge](vn): Vector[column](wp1);
ma &* wp1 - 'mu1'*wp1; evalf(evalm(%), 20): norm(%,2);
# remarque sur les arrondis de calcul : on perd deux décimales sur le résultat

_rtable[11908104]

`&*`(ma,wp1)-mu1*wp1

.1550140048e-9

Calcul de la valeur propre de plus petit module

Réécriture de l'itérateur

> iterc:= subs(ma=mc, norm=cpodom, eval(itera));

iterc := proc (v1) global mc; evalm(`&*`(mc,v1)); r...

Décalage de la matrice initiale

> mc:= inverse( ma);

mc := matrix([[-268758/24242611, -323432/24242611, ...

Convergence : la direction se stabilise

> (iterc@@30)(v0); iterc(%); vp3:= cpodom(evalm(mc &* %));

vector([.5519685694, -.8752831063, -.7703655487, 1....

vector([.5519980839, -.8752869598, -.7700759114, 1....

vp3 := .2294296321e-1

Augmentation de la précision

> Digits:=20: vm:= (iterc@@100)(v0); vm1:= iterc(%); vq1:= cpodom(evalm(mc &* %));
evalm(vm1-vm); norm(%,2); Digits:=10:

vm := vector([.55198520972396517245, -.875285279327...

vm1 := vector([.55198520972443338841, -.87528527932...

vq1 := .22943232233064801887e-1

vector([.46821596e-12, -.6113527e-13, .459464387e-1...

.46188435780577448994e-11

Vitesse : 11 décimales en 100 étapes

> (10.^11)^(1/100);

1.288249552

Vérification

> [eigenvals(map(evalf, mc))]; sort(map(abs,%)); %[-1]/%[-2];

[-.1775136322e-1, -.5684586956e-2+.8304694081e-2*I,...

[.1006391935e-1, .1006391935e-1, .1775136322e-1, .2...

1.292477200

La dernière valeurs propre de ma est donc

> mu4:= evalf(1/vq1, 20);

mu4 := 43.585837855872936082

Et le vecteurs propres

> wp4:= pldx[xpurge](vm): Vector[column](wp4);
ma &* wp4 - 'mu4'*wp4; evalf(evalm(%), 20): norm(%,2);
# remarque sur les arrondis de calcul : on perd deux décimales sur le résultat

_rtable[11657576]

`&*`(ma,wp4)-mu4*wp4

.2565242167e-9

>

Calcul de la dernière valeur propre

On pourrait se contenter d'une soustraction...

Réécriture de l'itérateur

> iterd:= subs(ma=md, norm=cpodom, eval(itera));

iterd := proc (v1) global md; evalm(`&*`(md,v1)); r...

Décalage de la matrice initiale

> ts:= -30: md:= inverse( ma-ts);

md := matrix([[-189768/14350891, -185222/14350891, ...

Convergence

> (iterd@@30)(v0); iterd(%); vp3:= cpodom(evalm(md &* %));

vector([.1362790583, -.6158640987e-1, 1.000000000, ...

vector([.1362790583, -.6158640987e-1, 1.000000000, ...

vp3 := -.3797415241e-1

Augmentation de la précision

> Digits:=20: vm:= (iterd@@30)(v0); vm1:= iterd(%); vq2:= cpodom(evalm(md &* %));
evalm(vm1-vm); norm(%,2); Digits:=10:

vm := vector([.13627905830555132907, -.615864098779...

vm1 := vector([.13627905830565487479, -.61586409878...

vq2 := -.37974152405532003317e-1

vector([.10354572e-12, -.150684089e-12, 0., .166037...

.24697373395443168462e-12

Vitesse : 12 décimales en 30 étapes

> (10.^12)^(1/30);

2.511886432

Vérification

> [eigenvals(map(evalf, md))]; sort(map(abs,%)); %[-1]/%[-2];

[-.3797415241e-1, -.3527778742e-2+.1107175910e-1*I,...

[.1162020105e-1, .1162020105e-1, .1358957143e-1, .3...

2.794359823

La dernière valeurs propre de ma est donc

> mu3:= evalf(ts+1/vq2, 20);

mu3 := -56.333701653715432898

Et le vecteurs propres

> wp3:= pldx[xpurge](vm): Vector[column](%);
ma &* wp3 - 'mu3'*wp3; evalf(evalm(%), 20): norm(%,2);
# remarque sur les arrondis de calcul : on perd deux décimales sur le résultat

_rtable[11896008]

`&*`(ma,wp3)-mu3*wp3

.1881034906e-10

>

Test général

> conj:= z-> map(conjugate,z);

conj := proc (z) options operator, arrow; map(conju...

> Digits:=20 : evalm(wp1), conj(wp1), evalm(wp3), evalm(wp4):
pas:= transpose(matrix([%])): 'pas' = evalf(%,8);

pas = matrix([[-.42013219-.80508178*I, -.42013219+....

> inverse(pas): sap:=pldx[xpurge](%): 'sap'= evalf(%, 8);

sap = matrix([[.38932624e-1+.55839825*I, .31096316+...

Et la matrice se diagonalise

> evalm(sap &* ma &* pas): evalf(pldx[xpurge](%,9), 10); Digits:=10:

matrix([[-56.12606810+81.99537257*I, 0., 0., 0.], [...

>

>