-
Notifications
You must be signed in to change notification settings - Fork 0
/
power.py
executable file
·108 lines (94 loc) · 3.95 KB
/
power.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
from calcmat import *
import numpy as np
#Deux fonctions de test sont situées à la fin du fichier
#première implémentation de la méthode des puissances
#condition d'arrêt: la distance euclidienne entre les deux derniers vecteurs
# calculés est inférieure à une précision donnée par acc
def power(A,x,acc):
eprev=scale(x,norm(x))
temp = mult(A,eprev)
ecurr=scale(temp,norm(temp))
count=0
while dist(eprev,ecurr)>acc:
eprev=ecurr
temp=mult(A,temp)
ecurr=scale(temp,norm(temp))
count = count +1
print("nombre d'itérations:",count)
return ecurr
#deuxième implémentation de la méthode des puissances
#on calcule A^(2^pow) puis on l'applique à x et on renvoie un vecteur de norme 1
def power2(A,x,pow):
x=scale(x,norm(x))
for _ in range(pow):
A=mult(A,A)
e=mult(A,x)
return scale(e,norm(e))
#implémentation de la méthode de déflation: passage aux valeurs propres inférieures
def update(A,v):
dimA= dim(A)
for i in range(dimA[0]):
prodi= dotprod(v,vect2mat(A[i]))
vtemp= [prodi*v[i][0] for i in range(dimA[1])]
A[i]= sub(A[i],vtemp)
return A
#TESTS NUMERIQUES
#la matrice représentant le nuage des données est p*n, avec p grand devant n: grand nombre d'individus
#on travaille ensuite sur une matrices carrée symétrique semi-définie positive de taille n
#pour les tests, on prend une précision de 10^-4
prec=0.0001
n=10
p=100
pow = 4
#TESTS DE LA PREMIERE IMPLEMENTATION
def testpower1():
print("Première implémentation:")
#On génère le nuage de données
A=normalize(center(randomM(p,n))[0])[0]
#On calcule la matrice de variance-covariance associée
B=mult(transpose(A),A)
#on génère un vecteur aléatoire pour initialiser la méthode des puissances
x=randomV(n)
#calcul des vraies valeurs des valeurs propres avec scipy
scipyEigs = largestEig(B,2)
#premier vecteur propre renvoyé par la méthode de la puissance
e=power(B,x,prec)
#si e est une bonne approximation du vecteur propre cherché, alors le vecteur Be doit être proche de (lambda)e
#on fait apparaitre les valeurs propres empiriques calculées en divisant les coordoonées de Be par celles de e
print("premières valeurs propres empiriques", comp(mult(B,e),e))
#on fait les changements sur B pour pouvoir passer à la valeur propre suivante
B=update(B,e)
#on execute une nouvelle fois la méthode de la puissances sur la matrice modifiée
e2=power(B,x,prec)
#on fait apparaitre les valeurs propres empiriques obtenues
print("deuxièmes valeurs propres empiriques", comp(mult(B,e2),e2))
#on affiche les vraies valeurs des deux plus grandes valeurs propres de B
print('2 premières valeurs propres Scipy:', scipyEigs[::-1])
print('\n \n')
#TESTS DE LA DEUXIEME IMPLEMENTATION
def testpower2():
print("Deuxième implémentation:")
print("calcul de A^(2^"+str(pow)+')')
#On génère le nuage de données
A=normalize(center(randomM(p,n))[0])[0]
#On calcule la matrice de variance-covariance associée
B=mult(transpose(A),A)
#on génère un vecteur aléatoire pour initialiser la méthode des puissances
x=randomV(n)
#calcul des vraies valeurs des valeurs propres avec scipy
scipyEigs = largestEig(B,2)
#premier vecteur propre renvoyé par la méthode de la puissance
e=power2(B,x,pow)
#si e est une bonne approximation du vecteur propre cherché, alors le vecteur Be doit être proche de (lambda)e
#on fait apparaitre les valeurs propres empiriques calculées en divisant les coordoonées de Be par celles de e
print("premières valeurs propres empiriques", comp(mult(B,e),e))
#on fait les changements sur B pour pouvoir passer à la valeur propre suivante
B=update(B,e)
#on execute une nouvelle fois la méthode de la puissances sur la matrice modifiée
e2=power2(B,x,pow)
#on fait apparaitre les valeurs propres empiriques obtenues
print("deuxièmes valeurs propres empiriques", comp(mult(B,e2),e2))
#on affiche les vraies valeurs des deux plus grandes valeurs propres de B
print('2 premières valeurs propres Scipy:', scipyEigs[::-1])
testpower1()
testpower2()