Commit | Line | Data |
---|---|---|
1d3c1faa BA |
1 | #include "EMGrank.h" |
2 | #include "constructionModelesLassoRank.h" | |
3 | #include <gsl/gsl_linalg.h> | |
4 | #include <omp.h> | |
5 | #include "omp_num_threads.h" | |
6 | ||
7 | // TODO: comment on constructionModelesLassoRank purpose | |
8 | void constructionModelesLassoRank( | |
9 | // IN parameters | |
10 | const Real* Pi, // parametre initial des proportions | |
11 | const Real* Rho, // parametre initial de variance renormalisé | |
12 | Int mini, // nombre minimal d'itérations dans l'algorithme EM | |
13 | Int maxi, // nombre maximal d'itérations dans l'algorithme EM | |
14 | const Real* X, // régresseurs | |
15 | const Real* Y, // réponse | |
16 | Real tau, // seuil pour accepter la convergence | |
17 | const Int* A1, // matrice des coefficients des parametres selectionnes | |
18 | Int rangmin, //rang minimum autorisé | |
19 | Int rangmax, //rang maximum autorisé | |
20 | // OUT parameters (all pointers, to be modified) | |
21 | Real* phi, // estimateur ainsi calculé par le Lasso | |
22 | Real* lvraisemblance, // estimateur ainsi calculé par le Lasso | |
23 | // additional size parameters | |
24 | mwSize n, // taille de l'echantillon | |
25 | mwSize p, // nombre de covariables | |
26 | mwSize m, // taille de Y (multivarié) | |
27 | mwSize k, // nombre de composantes | |
28 | mwSize L) // taille de glambda | |
29 | { | |
30 | //On cherche les rangs possiblement intéressants | |
31 | Int deltaRank = rangmax-rangmin+1; | |
32 | mwSize Size = (mwSize)pow(deltaRank,k); | |
33 | Int* Rank = (Int*)malloc(Size*k*sizeof(Int)); | |
34 | for (mwSize r=0; r<k; r++) | |
35 | { | |
36 | //On veut le tableau de toutes les combinaisons de rangs possibles | |
37 | //Dans la première colonne : on répète (rangmax-rangmin)^(k-1) chaque chiffre : ca remplit la colonne | |
38 | //Dans la deuxieme : on répète (rangmax-rangmin)^(k-2) chaque chiffre, et on fait ca (rangmax-rangmin)^2 fois | |
39 | //... | |
40 | //Dans la dernière, on répète chaque chiffre une fois, et on fait ca (rangmin-rangmax)^(k-1) fois. | |
41 | Int indexInRank = 0; | |
42 | Int value = 0; | |
43 | while (indexInRank < Size) | |
44 | { | |
45 | for (Int u=0; u<pow(deltaRank,k-r-1); u++) | |
46 | Rank[(indexInRank++)*k+r] = rangmin + value; | |
47 | value = (value+1) % deltaRank; | |
48 | } | |
49 | } | |
50 | ||
51 | //Initialize phi to zero, because unactive variables won't be assigned | |
52 | for (mwSize i=0; i<p*m*k*L*Size; i++) | |
53 | phi[i] = 0.0; | |
54 | ||
55 | //initiate parallel section | |
56 | mwSize lambdaIndex; | |
57 | omp_set_num_threads(OMP_NUM_THREADS); | |
58 | #pragma omp parallel default(shared) private(lambdaIndex) | |
59 | { | |
60 | #pragma omp for schedule(dynamic,CHUNK_SIZE) nowait | |
61 | for (lambdaIndex=0; lambdaIndex<L; lambdaIndex++) | |
62 | { | |
63 | //On ne garde que les colonnes actives : active sera l'ensemble des variables informatives | |
64 | Int* active = (Int*)malloc(p*sizeof(Int)); | |
65 | mwSize longueurActive = 0; | |
66 | for (Int j=0; j<p; j++) | |
67 | { | |
68 | if (A1[j*L+lambdaIndex] != 0) | |
69 | active[longueurActive++] = A1[j*L+lambdaIndex] - 1; | |
70 | } | |
71 | ||
72 | if (longueurActive == 0) | |
73 | continue; | |
74 | ||
75 | //from now on, longueurActive > 0 | |
76 | Real* phiLambda = (Real*)malloc(longueurActive*m*k*sizeof(Real)); | |
77 | Real LLF; | |
78 | for (Int j=0; j<Size; j++) | |
79 | { | |
80 | //[phiLambda,LLF] = EMGrank(Pi(:,lambdaIndex),Rho(:,:,:,lambdaIndex),mini,maxi,X(:,active),Y,tau,Rank(j,:)); | |
81 | Int* rank = (Int*)malloc(k*sizeof(Int)); | |
82 | for (mwSize r=0; r<k; r++) | |
83 | rank[r] = Rank[j*k+r]; | |
84 | Real* Xactive = (Real*)malloc(n*longueurActive*sizeof(Real)); | |
85 | for (mwSize i=0; i<n; i++) | |
86 | { | |
87 | for (mwSize jj=0; jj<longueurActive; jj++) | |
88 | Xactive[i*longueurActive+jj] = X[i*p+active[jj]]; | |
89 | } | |
90 | Real* PiLambda = (Real*)malloc(k*sizeof(Real)); | |
91 | for (mwSize r=0; r<k; r++) | |
92 | PiLambda[r] = Pi[r*L+lambdaIndex]; | |
93 | Real* RhoLambda = (Real*)malloc(m*m*k*sizeof(Real)); | |
94 | for (mwSize u=0; u<m; u++) | |
95 | { | |
96 | for (mwSize v=0; v<m; v++) | |
97 | { | |
98 | for (mwSize r=0; r<k; r++) | |
99 | RhoLambda[u*m*k+v*k+r] = Rho[u*m*k*L+v*k*L+r*L+lambdaIndex]; | |
100 | } | |
101 | } | |
102 | EMGrank(PiLambda,RhoLambda,mini,maxi,Xactive,Y,tau,rank, | |
103 | phiLambda,&LLF, | |
104 | n,longueurActive,m,k); | |
105 | free(rank); | |
106 | free(Xactive); | |
107 | free(PiLambda); | |
108 | free(RhoLambda); | |
109 | //lvraisemblance((lambdaIndex-1)*Size+j,:) = [LLF, dot(Rank(j,:), length(active)-Rank(j,:)+m)]; | |
110 | lvraisemblance[(lambdaIndex*Size+j)*2] = LLF; | |
111 | //dot(Rank(j,:), length(active)-Rank(j,:)+m) | |
112 | Real dotProduct = 0.0; | |
113 | for (mwSize r=0; r<k; r++) | |
114 | dotProduct += Rank[j*k+r] * (longueurActive-Rank[j*k+r]+m); | |
115 | lvraisemblance[(lambdaIndex*Size+j)*2+1] = dotProduct; | |
116 | //phi(active,:,:,(lambdaIndex-1)*Size+j) = phiLambda; | |
117 | for (mwSize jj=0; jj<longueurActive; jj++) | |
118 | { | |
119 | for (mwSize mm=0; mm<m; mm++) | |
120 | { | |
121 | for (mwSize r=0; r<k; r++) | |
122 | phi[active[jj]*m*k*L*Size+mm*k*L*Size+r*L*Size+(lambdaIndex*Size+j)] = phiLambda[jj*m*k+mm*k+r]; | |
123 | } | |
124 | } | |
125 | } | |
126 | free(active); | |
127 | free(phiLambda); | |
128 | } | |
129 | } | |
130 | free(Rank); | |
131 | } |