void gmm_compute_p (int n, const float * v, const gmm_t * g, float * p, int flags) { if(n==0) return; /* sgemm doesn't like empty matrices */ long i, j, l; double dtmp; long d=g->d, k=g->k; /* p_i(x|\lambda)'s denominator, eq (7) */ float * logdetnr = fvec_new(k); for (j = 0 ; j < k ; j++) { logdetnr[j] = -d / 2.0 * log (2 * M_PI); for (i = 0 ; i < d ; i++) logdetnr[j] -= 0.5 * log (g->sigma[j * d + i]); } /* compute all probabilities in log domain */ /* compute squared Mahalanobis distances (result in p), log of numerator eq (7) */ if(0) { /* simple & slow */ for (i = 0 ; i < n ; i++) { for (j = 0 ; j < k ; j++) { dtmp = 0; for (l = 0 ; l < d ; l++) { dtmp += sqr (v[i * d + l] - g->mu[j * d + l]) / g->sigma[j * d + l]; } p[i * k + j] = dtmp; } } } else { /* complicated & fast */ compute_mahalanobis_sqr(n,k,d,g->mu,g->sigma,v,p); } float *lg = (float*)malloc(sizeof(float) * k); if(flags & GMM_FLAGS_W) { for (j = 0 ; j < k ; j++) lg[j] = log(g->w[j]); } else memset(lg, 0, sizeof(float) * k); for (i = 0 ; i < n ; i++) { /* p contains log(p_j(x|\lambda)) eq (7) */ for (j = 0 ; j < k ; j++) { p[i * k + j] = logdetnr[j] - 0.5 * p[i * k + j] + lg[j]; } } free(lg); softmax_ref(k, n, p, p, NULL); free(logdetnr); }
void gmm_compute_p (int n, const float * v, const gmm_t * g, float * p, int flags) { if(n==0) return; /* sgemm doesn't like empty matrices */ long i, j, l; double dtmp; long d=g->d, k=g->k; float * logdetnr = fvec_new(k); for (j = 0 ; j < k ; j++) { logdetnr[j] = -d / 2.0 * log (2 * M_PI); for (i = 0 ; i < d ; i++) logdetnr[j] -= 0.5 * log (g->sigma[j * d + i]); } /* compute all probabilities in log domain */ /* compute squared Mahalanobis distances (result in p) */ if(0) { /* simple & slow */ for (i = 0 ; i < n ; i++) { for (j = 0 ; j < k ; j++) { dtmp = 0; for (l = 0 ; l < d ; l++) { dtmp += sqr (v[i * d + l] - g->mu[j * d + l]) / g->sigma[j * d + l]; } p[i * k + j] = dtmp; } } } else { /* complicated & fast */ compute_mahalanobis_sqr(n,k,d,g->mu,g->sigma,v,p); } /* convert distances to probabilities, staying in the log domain until the very end */ for (i = 0 ; i < n ; i++) { for (j = 0 ; j < k ; j++) { p[i * k + j] = logdetnr[j] - 0.5 * p[i * k + j]; CHECKFINITE(p[i * k + j]); } /* at this point, we have p(x|ci) -> we want p(ci|x) */ if(flags & GMM_FLAGS_NO_NORM) { /* compute the normalization factor */ dtmp=0; } else { dtmp = p[i * k + 0]; if(flags & GMM_FLAGS_W) dtmp+=log(g->w[0]); for (j = 1 ; j < k ; j++) { double log_p=p[i * k + j]; if(flags & GMM_FLAGS_W) log_p+=log(g->w[j]); dtmp = log_sum (dtmp, log_p); } /* now dtmp contains the log of sums */ } for (j = 0 ; j < k ; j++) { double log_norm=0; if(flags & GMM_FLAGS_W) log_norm=log(g->w[j])-dtmp; else log_norm=-dtmp; p[i * k + j] = exp (p[i * k + j] + log_norm); CHECKFINITE(p[i * k + j]); } // printf ("p[%d] = ", i); // fvec_print (p + i * k, k); } free(logdetnr); }