#include "utils.h" #include #include #include // TODO: don't recompute indexes ai(...) and mi(...) when possible 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 eps, // 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* llh, // (derniere) log vraisemblance associée à cet échantillon, // pour les valeurs estimées des paramètres Real* S, int* affec, // 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); //S is already allocated, and doesn't need to be 'zeroed' //Other local variables: same as in R Real* gam = (Real*)malloc(n*k*sizeof(Real)); Real* logGam = (Real*)malloc(k*sizeof(Real)); copyArray(gamInit, gam, n*k); Real* Gram2 = (Real*)malloc(p*p*k*sizeof(Real)); Real* ps2 = (Real*)malloc(p*m*k*sizeof(Real)); Real* b = (Real*)malloc(k*sizeof(Real)); Real* X2 = (Real*)malloc(n*p*k*sizeof(Real)); Real* Y2 = (Real*)malloc(n*m*k*sizeof(Real)); *llh = -INFINITY; Real* pi2 = (Real*)malloc(k*sizeof(Real)); // Additional (not at this place, in R file) Real* gam2 = (Real*)malloc(k*sizeof(Real)); Real* sqNorm2 = (Real*)malloc(k*sizeof(Real)); Real* detRho = (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)); const Real gaussConstM = pow(2.*M_PI,m/2.); 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)); for (int ite=1; ite<=maxi; ite++) { 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; u n*lambda*pirPowGamma) { phi[ai(j,mm,r,p,m,k)] = (n*lambda*pirPowGamma - 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*pirPowGamma + S[ai(j,mm,r,p,m,k)]) / Gram2[ai(j,j,r,p,p,k)]; } } } } ///////////// // Etape E // ///////////// // Precompute det(rho[,,r]) for r in 1...k int signum; for (int r=0; rdata[u*m+v] = rho[ai(u,v,r,m,m,k)]; } gsl_linalg_LU_decomp(matrix, permutation, &signum); detRho[r] = gsl_linalg_LU_det(matrix, signum); } Real sumLogLLH = 0.; for (int i=0; i Dist1) Dist1 = tmpDist; } } } //Dist2 = max( (abs(rho-Rho)) / (1+abs(rho)) ) Real Dist2 = 0.; for (int u=0; u Dist2) Dist2 = tmpDist; } } } //Dist3 = max( (abs(pi-Pi)) / (1+abs(Pi))) Real Dist3 = 0.; for (int u=0; u Dist3) Dist3 = tmpDist; } } //dist2=max([max(Dist1),max(Dist2),max(Dist3)]); Real dist2 = Dist1; if (Dist2 > dist2) dist2 = Dist2; if (Dist3 > dist2) dist2 = Dist3; if (ite >= mini && (dist >= eps || dist2 >= sqrt(eps))) break; } //affec = apply(gam, 1, which.max) for (int i=0; i rowMax) { affec[i] = j+1; //R indices start at 1 rowMax = gam[mi(i,j,n,k)]; } } } //free memory free(b); free(gam); free(logGam); free(Phi); free(Rho); free(Pi); free(Gram2); free(ps2); free(detRho); gsl_matrix_free(matrix); gsl_permutation_free(permutation); free(XiPhiR); free(YiRhoR); free(gam2); free(pi2); free(X2); free(Y2); free(sqNorm2); }