X-Git-Url: https://git.auder.net/?p=valse.git;a=blobdiff_plain;f=pkg%2Fsrc%2Fsources%2FEMGLLF.c;h=d2f5a8e54c6e84fcfdb58a630b8f011d6ea79b84;hp=86b606053076242cb6a623861990a4f7517089c4;hb=9a73b9662b16a990370ac5142bf4cf1f782d801f;hpb=1c45d8e4f6fd4209d26709f17a58920218ee828d diff --git a/pkg/src/sources/EMGLLF.c b/pkg/src/sources/EMGLLF.c index 86b6060..d2f5a8e 100644 --- a/pkg/src/sources/EMGLLF.c +++ b/pkg/src/sources/EMGLLF.c @@ -1,8 +1,9 @@ #include "utils.h" #include +#include #include -// TODO: don't recompute indexes every time...... +// TODO: don't recompute indexes ai(...) and mi(...) when possible void EMGLLF_core( // IN parameters const Real* phiInit, // parametre initial de moyenne renormalisé @@ -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,39 +35,33 @@ 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 + //Other local variables: same as in R 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* 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)); + 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)); 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.); + 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)); - 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; u1) sum(phi[1:(j-1),mm,r] * Gram2[j,1:(j-1),r]) else 0) + - // (if(j n*lambda*pow_pir_gamma) + //sum(phi[-j,mm,r] * Gram2[j,-j,r]) + Real phiDotGram2 = 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*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)]; } } @@ -270,137 +260,146 @@ void EMGLLF_core( // Etape E // ///////////// + // Precompute det(rho[,,r]) for r in 1...k 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); + 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); - - //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)]; + gam[mi(i,r,n,k)] = pi[r] * exp(-.5*sqNorm2[r]) * detRho[r]; + sumGamI += gam[mi(i,r,n,k)]; } - sumLogLLF2 += log(sumLLF1); - for (int r=0; r EPS) //else: gam[i,] is already ~=0 { - //gam[i,] = Gam[i,] / sumGamI - gam[mi(i,r,n,k)] = sumGamI > EPS ? Gam[mi(i,r,n,k)] / sumGamI : 0.; + for (int r=0; r Dist1) Dist1 = tmpDist; } } } //Dist2 = max( (abs(rho-Rho)) / (1+abs(rho)) ) - Real Dist2 = 0.0; + Real Dist2 = 0.; for (int u=0; u Dist2) Dist2 = tmpDist; } } } //Dist3 = max( (abs(pi-Pi)) / (1+abs(Pi))) - Real Dist3 = 0.0; + Real Dist3 = 0.; for (int u=0; u Dist3) Dist3 = tmpDist; } } //dist2=max([max(Dist1),max(Dist2),max(Dist3)]); - dist2 = Dist1; + Real dist2 = Dist1; if (Dist2 > dist2) dist2 = Dist2; if (Dist3 > dist2) dist2 = Dist3; - ite++; + if (ite >= mini && (dist >= tau || dist2 >= sqrt(tau))) + 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(Gam); free(Phi); free(Rho); free(Pi); - free(ps); - free(nY2); - free(ps1); - free(nY21); free(Gram2); free(ps2); + free(detRho); gsl_matrix_free(matrix); gsl_permutation_free(permutation); free(XiPhiR);