#include "utils.h" #include #include // TODO: don't recompute indexes every time...... void EMGLLF_core( // IN parameters const Real* phiInit, // parametre initial de moyenne renormalisé const Real* rhoInit, // parametre initial de variance renormalisé const Real* piInit, // parametre initial des proportions const Real* gamInit, // paramètre initial des probabilités a posteriori de chaque échantillon int mini, // nombre minimal d'itérations dans l'algorithme EM int maxi, // nombre maximal d'itérations dans l'algorithme EM Real gamma, // puissance des proportions dans la pénalisation pour un Lasso adaptatif Real lambda, // valeur du paramètre de régularisation du Lasso const Real* X, // régresseurs const Real* Y, // réponse Real tau, // seuil pour accepter la convergence // OUT parameters (all pointers, to be modified) Real* phi, // parametre de moyenne renormalisé, calculé par l'EM Real* rho, // parametre de variance renormalisé, calculé par l'EM Real* pi, // parametre des proportions renormalisé, calculé par l'EM Real* LLF, // log vraisemblance associée à cet échantillon, pour les valeurs estimées des paramètres Real* S, // additional size parameters int n, // nombre d'echantillons int p, // nombre de covariables int m, // taille de Y (multivarié) int k) // nombre de composantes dans le mélange { //Initialize outputs copyArray(phiInit, phi, p*m*k); copyArray(rhoInit, rho, m*m*k); copyArray(piInit, pi, k); zeroArray(LLF, maxi); //S is already allocated, and doesn't need to be 'zeroed' //Other local variables Real* gam = (Real*)malloc(n*k*sizeof(Real)); copyArray(gamInit, gam, n*k); Real* b = (Real*)malloc(k*sizeof(Real)); Real* Phi = (Real*)malloc(p*m*k*sizeof(Real)); Real* Rho = (Real*)malloc(m*m*k*sizeof(Real)); Real* Pi = (Real*)malloc(k*sizeof(Real)); Real* gam2 = (Real*)malloc(k*sizeof(Real)); Real* pi2 = (Real*)malloc(k*sizeof(Real)); Real* Gram2 = (Real*)malloc(p*p*k*sizeof(Real)); Real* ps = (Real*)malloc(m*k*sizeof(Real)); Real* nY2 = (Real*)malloc(m*k*sizeof(Real)); Real* ps1 = (Real*)malloc(n*m*k*sizeof(Real)); Real* ps2 = (Real*)malloc(p*m*k*sizeof(Real)); Real* nY21 = (Real*)malloc(n*m*k*sizeof(Real)); Real* Gam = (Real*)malloc(n*k*sizeof(Real)); Real* X2 = (Real*)malloc(n*p*k*sizeof(Real)); Real* Y2 = (Real*)malloc(n*m*k*sizeof(Real)); Real* sqNorm2 = (Real*)malloc(k*sizeof(Real)); gsl_matrix* matrix = gsl_matrix_alloc(m, m); gsl_permutation* permutation = gsl_permutation_alloc(m); Real* YiRhoR = (Real*)malloc(m*sizeof(Real)); Real* XiPhiR = (Real*)malloc(m*sizeof(Real)); Real dist = 0.; Real dist2 = 0.; int ite = 0; const Real EPS = 1e-15; const Real gaussConstM = pow(2.*M_PI,m/2.); while (ite < mini || (ite < maxi && (dist >= tau || dist2 >= sqrt(tau)))) { copyArray(phi, Phi, p*m*k); copyArray(rho, Rho, m*m*k); copyArray(pi, Pi, k); // Calculs associés a Y et X for (int r=0; r= 0) pi2AllPositive = 1; for (int r=0; r Real dotProduct = 0.; for (int u=0; u1) sum(phi[1:(j-1),mm,r] * Gram2[j,1:(j-1),r]) else 0) + // (if(j n*lambda*pow_pir_gamma) { phi[ai(j,mm,r,p,m,k)] = (n*lambda*pow_pir_gamma - S[ai(j,mm,r,p,m,k)]) / Gram2[ai(j,j,r,p,p,k)]; } else { phi[ai(j,mm,r,p,m,k)] = -(n*lambda*pow_pir_gamma + S[ai(j,mm,r,p,m,k)]) / Gram2[ai(j,j,r,p,p,k)]; } } } } ///////////// // Etape E // ///////////// int signum; Real sumLogLLF2 = 0.0; for (int i=0; idata[u*m+v] = rho[ai(u,v,r,m,m,k)]; } gsl_linalg_LU_decomp(matrix, permutation, &signum); Real detRhoR = gsl_linalg_LU_det(matrix, signum); //FIXME: det(rho[,,r]) too small(?!). See EMGLLF.R Gam[mi(i,r,n,k)] = pi[r] * exp(-0.5*sqNorm2[r] + shift) ; //* detRhoR; sumLLF1 += Gam[mi(i,r,n,k)] / gaussConstM; sumGamI += Gam[mi(i,r,n,k)]; } sumLogLLF2 += log(sumLLF1); for (int r=0; r EPS ? Gam[mi(i,r,n,k)] / sumGamI : 0.; } } //sumPen = sum(pi^gamma * b) Real sumPen = 0.0; for (int r=0; r Dist1) Dist1 = tmpDist; } } } //Dist2 = max( (abs(rho-Rho)) / (1+abs(rho)) ) Real Dist2 = 0.0; for (int u=0; u Dist2) Dist2 = tmpDist; } } } //Dist3 = max( (abs(pi-Pi)) / (1+abs(Pi))) Real Dist3 = 0.0; for (int u=0; u Dist3) Dist3 = tmpDist; } } //dist2=max([max(Dist1),max(Dist2),max(Dist3)]); dist2 = Dist1; if (Dist2 > dist2) dist2 = Dist2; if (Dist3 > dist2) dist2 = Dist3; ite++; } //free memory free(b); free(gam); free(Gam); free(Phi); free(Rho); free(Pi); free(ps); free(nY2); free(ps1); free(nY21); free(Gram2); free(ps2); gsl_matrix_free(matrix); gsl_permutation_free(permutation); free(XiPhiR); free(YiRhoR); free(gam2); free(pi2); free(X2); free(Y2); free(sqNorm2); }