X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=pkg%2Fsrc%2Fsources%2FEMGLLF.c;h=d9f92c049745c1304b1852df9f509c18a841a308;hb=23b9fb13bc6e82d7ca43bfb83aa85b6cd69c52c0;hp=7ce6ded7cdcf0bff99786370f9e61dc778a3b608;hpb=5a190d9d42b0313eace2e85b145b19f74542840f;p=valse.git diff --git a/pkg/src/sources/EMGLLF.c b/pkg/src/sources/EMGLLF.c index 7ce6ded..d9f92c0 100644 --- a/pkg/src/sources/EMGLLF.c +++ b/pkg/src/sources/EMGLLF.c @@ -1,5 +1,6 @@ #include "utils.h" #include +#include #include // TODO: don't recompute indexes ai(...) and mi(...) when possible @@ -20,8 +21,10 @@ void EMGLLF_core( 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* 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 @@ -32,29 +35,23 @@ void EMGLLF_core( 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: 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)); - Real dist = 0.; - Real dist2 = 0.; - int ite = 0; + *llh = -INFINITY; Real* pi2 = (Real*)malloc(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* Gam = (Real*)malloc(n*k*sizeof(Real)); - const Real EPS = 1e-15; // 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)); @@ -64,7 +61,7 @@ void EMGLLF_core( Real* Rho = (Real*)malloc(m*m*k*sizeof(Real)); Real* Pi = (Real*)malloc(k*sizeof(Real)); - while (ite < mini || (ite < maxi && (dist >= tau || dist2 >= sqrt(tau)))) + for (int ite=1; ite<=maxi; ite++) { copyArray(phi, Phi, p*m*k); copyArray(rho, Rho, m*m*k); @@ -77,7 +74,7 @@ void EMGLLF_core( { //Y2[,mm,r] = sqrt(gam[,r]) * Y[,mm] for (int u=0; u + //< X2[i,,r] , phi[,mm,r] > Real dotProduct = 0.; for (int u=0; u n*lambda*pow_pir_gamma) + //S[j,mm,r] = -rho[mm,mm,r]*ps2[j,mm,r] + sum(phi[-j,mm,r] * Gram2[j,-j,r]) + S[ai(j,mm,r,p,m,k)] = -rho[ai(mm,mm,r,m,m,k)] * ps2[ai(j,mm,r,p,m,k)] + + phiDotGram2; + Real pirPowGamma = pow(pi[r],gamma); + if (fabs(S[ai(j,mm,r,p,m,k)]) <= n*lambda*pirPowGamma) + phi[ai(j,mm,r,p,m,k)] = 0.; + else if (S[ai(j,mm,r,p,m,k)] > n*lambda*pirPowGamma) { - phi[ai(j,mm,r,p,m,k)] = (n*lambda*pow_pir_gamma - S[ai(j,mm,r,p,m,k)]) + 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*pow_pir_gamma + S[ai(j,mm,r,p,m,k)]) + 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)]; } } @@ -267,8 +260,20 @@ void EMGLLF_core( // Etape E // ///////////// + // Precompute det(rho[,,r]) for r in 1...k int signum; - Real sumLogLLF2 = 0.; + 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; 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); - Gam[mi(i,r,n,k)] = pi[r] * exp(-.5*sqNorm2[r]) * detRhoR; - sumLLF1 += Gam[mi(i,r,n,k)] / gaussConstM; - sumGamI += Gam[mi(i,r,n,k)]; + logGam[r] = log(pi[r]) - .5 * sqNorm2[r] + log(detRho[r]); + if (maxLogGam < logGam[r]) + maxLogGam = logGam[r]; } - sumLogLLF2 += log(sumLLF1); + Real norm_fact = 0.; for (int r=0; r EPS ? Gam[mi(i,r,n,k)] / sumGamI : 0.; + logGam[r] = logGam[r] - maxLogGam; //adjust without changing proportions + gam[mi(i,r,n,k)] = exp(logGam[r]); //gam[i, ] <- exp(logGam) + norm_fact += gam[mi(i,r,n,k)]; //norm_fact <- sum(gam[i, ]) } + // gam[i, ] <- gam[i, ] / norm_fact + for (int r=0; r dist2) dist2 = Dist2; if (Dist3 > dist2) dist2 = Dist3; - ite++; + if (ite >= mini && (dist >= tau || dist2 >= sqrt(tau))) + break; } - //TODO: affec = apply(gam, 1,which.max) à traduire, et retourner affec aussi. + //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(Gam); + free(logGam); free(Phi); free(Rho); free(Pi); - free(ps); - free(nY2); - free(ps1); free(Gram2); free(ps2); + free(detRho); gsl_matrix_free(matrix); gsl_permutation_free(permutation); free(XiPhiR); @@ -401,4 +417,4 @@ void EMGLLF_core( free(X2); free(Y2); free(sqNorm2); -} +}