예제 #1
0
파일: gmm.c 프로젝트: Erotemic/yael
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);
}
예제 #2
0
파일: gmm.c 프로젝트: czxxjtu/videosearch
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);

}