Esempio n. 1
0
/* Multiply columns of m by v */
void mat_mul_cols(Matrix m, double *v)
{
	int xi,yi;
	double *p=m.dat;

	for (yi=0; yi<m.ny; yi++,p+=m.nx)
		vec_mul_scalar(p,m.nx,v[yi]);
}
Esempio n. 2
0
void next_position(int *steps)
{
	double newp[MAX_DIM];
	double err[MAX_DIM];
	int i;

	tim += 1.0;
	vec_mul_scalar(newp, incvec, tim);
	vec_sum(newp, newp, origin);
	vec_diff(err, newp, position);
	for (i = 0; i < MAX_DIM; i++) {
		steps[i] = (int)err[i];
		position[i] += (double)steps[i];
	}
}
Esempio n. 3
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  double M;
  double log_thr;
  int Xs,D,Ys,i,j,ep=0;
  int maxentep;
  int pxy_size;
  double mx;
  Matrix phi,psi,phi_tr,psi_tr,phi_exp_d,psi_exp_d,psi_exp_m,phi_exp_m,grad_phi,grad_psi;
  double *px0,*py0,*px,*py,*pa,*pb,*grad_a,*grad_b;
  double Z,loglik;
  int xi,yi,di;
  int b_cond; /* Says if the model is conditioned on x, or joint */
  double *p0_i,*p0_j,*p0_val;
  int Np0;
  
  MatFromMLab(prhs[0],&phi);   /* Size NX,D */ 
  MatFromMLab(prhs[1],&psi);   /* Size NX,D */	
  MatFromMLab(prhs[2],&phi_tr);   /* Size D,NX */ 
  MatFromMLab(prhs[3],&psi_tr);   /* Size D,NY */	
  px0		  = mxGetPr(prhs[4]);
  py0		  = mxGetPr(prhs[5]);
  MatFromMLab(prhs[6],&phi_exp_d);
  MatFromMLab(prhs[7],&psi_exp_d);
  
  pa = mxGetPr(prhs[8]);
  pb = mxGetPr(prhs[9]);
  b_cond = *mxGetPr(prhs[10]);

  p0_i = mxGetPr(prhs[11]);
  p0_j = mxGetPr(prhs[12]);
  p0_val = mxGetPr(prhs[13]);
  
  
  Xs = mxGetM(prhs[0]);
  D = mxGetN(prhs[0]);
  Ys = mxGetM(prhs[1]);
  Np0 = mxGetNumberOfElements(prhs[13]);
    
  pxy_size = Xs*Ys;
  
  plhs[0] = mxCreateDoubleMatrix(D,Xs,mxREAL); 
  plhs[1] = mxCreateDoubleMatrix(D,Ys,mxREAL);
  plhs[2] =  mxCreateDoubleMatrix(1,Xs,mxREAL);
  plhs[3] =  mxCreateDoubleMatrix(1,Ys,mxREAL);
  plhs[4] =  mxCreateDoubleMatrix(1,1,mxREAL);
  
  grad_phi.dat = mxGetPr(plhs[0]);
  grad_psi.dat = mxGetPr(plhs[1]);
  grad_phi.nx = D;
  grad_phi.ny = Xs;
  grad_phi.nall = Xs*D;
  
  grad_psi.nx = D;
  grad_psi.ny = Ys;
  grad_psi.nall = Ys*D;
  
 
  grad_a = mxGetPr(plhs[2]);
  grad_b = mxGetPr(plhs[3]);
  
  
  AllocMat(D,Ys,&phi_exp_m);
  AllocMat(D,Xs,&psi_exp_m);
  
  px  = malloc(Xs*sizeof(double)); 
  py  = malloc(Ys*sizeof(double)); 

  if (px==NULL || py==NULL)
    printf("Error in allocation\n");
	   
  if (!b_cond)
    mat_logemb_model(phi_tr, psi_tr, pa, pb, phi_exp_m, psi_exp_m, px, py, p0_i, p0_j, p0_val, Np0, mxGetPr(plhs[4]),b_cond) ;
  else
  {
    /* Run logemb model one time to get the x partition function in px */
    mat_logemb_model(phi_tr, psi_tr, pa, pb, phi_exp_m, psi_exp_m, px, py, p0_i, p0_j, p0_val, Np0, mxGetPr(plhs[4]),b_cond) ;
    /* Create new x factor */
    for (xi=0; xi<Xs; xi++)
        grad_a[xi] =   pa[xi]-log(px[xi])+log(px0[xi]);
    mat_logemb_model(phi_tr, psi_tr, grad_a, pb, phi_exp_m, psi_exp_m, px, py, p0_i, p0_j, p0_val, Np0, mxGetPr(plhs[4]),0) ;
  }


  /* Matlab line: diag(px)*phi-pxy*psi - (diag(px0)*phi-pxy0*psi);
     /* equivalent to  diag(px-px0)*phi+psi_expect_d - psi_expect_m */
  vec_subtract(px,px0,Xs);
  mat_set(grad_phi,phi_tr);
  /*  printf("\n Phi1 Max=%g MaxPx=%g\n",mat_max_abs(grad_phi.dat,grad_phi.nall),mat_max_abs(px,Xs));    */
  mat_mul_cols(grad_phi,px);
  /*  printf("\n Phi2 Max=%g MaxPx=%g\n",mat_max_abs(grad_phi.dat,grad_phi.nall),mat_max_abs(px,Xs)); */
  mat_subtract(psi_exp_d.dat,psi_exp_m.dat,psi_exp_d.nall);
  /* printf("\n Phi3 Max=%g\n",mat_max_abs(grad_phi.dat,grad_phi.nall));      */
  mat_add(grad_phi.dat,psi_exp_d.dat,psi_exp_d.nall);
  /* printf("\n Phi4 Max=%g\n",mat_max_abs(grad_phi.dat,grad_phi.nall)); */
  
  vec_subtract(py,py0,Ys);
  mat_set(grad_psi,psi_tr);
  mat_mul_cols(grad_psi,py);
  mat_subtract(phi_exp_d.dat,phi_exp_m.dat,phi_exp_d.nall);
  mat_add(grad_psi.dat,phi_exp_d.dat,phi_exp_d.nall);

  /* Generate gradient for a and b. Remember px already has px  subtracted. Just need to flip sign */
  memcpy(grad_a,px,Xs*sizeof(double));
  vec_mul_scalar(grad_a,-1,Xs);
  
  memcpy(grad_b,py,Ys*sizeof(double));
  vec_mul_scalar(grad_b,-1,Ys);
  
  free(psi_exp_m.dat);
  free(phi_exp_m.dat);
  free(px);
  free(py);
  
}
Esempio n. 4
0
void mat_logemb_model(Matrix phi, Matrix psi, double *a, double *b, Matrix phi_expect, Matrix psi_expect,  double *px, double *py
		      ,double *p0_i, double *p0_j, double *p0_val, int n_p0, double *loglik, int b_cond)

{
  int i1,i2,k,di;
  double *p1,*p2,*res_ptr;
  double *p_phiexp,*p_psiexp;
  double tmp,df;
  double Z=0;
  int D = phi_expect.nx;
  double *ap,*bp,*p_phie,*p_psie;  
  int NX = phi.ny;
  int NY = psi.ny;
  int p0ind = 0;
  double *aend;

  (*loglik) = 0;
  p2 = psi.dat;
  p_phiexp = phi_expect.dat;
  p_psiexp = psi_expect.dat;
  
  /* Reset everything */
  
  memset(phi_expect.dat,0,phi_expect.nall*sizeof(double));
  memset(psi_expect.dat,0,psi_expect.nall*sizeof(double));
  memset(px,0,NX*sizeof(double));
  memset(py,0,NY*sizeof(double));

  for (i2=0; i2< psi.ny; i2++)    {
    p1 = phi.dat;
    p_psiexp = psi_expect.dat;
    
    for (i1=0; i1< phi.ny; i1++)     {
      /* Inlining of l2_dist */
      tmp=0;
      {
	aend=&p1[phi.nx];
	double d=0;
	
	for (ap=&p1[0],bp=&p2[0]; ap<aend; ap++, bp++)	  {
	  d = *ap-*bp;
	  tmp+=(d*d);
	}
      }
      tmp = -tmp+a[i1]+b[i2];
      
      if ((i1==p0_i[p0ind]-1) && (i2==p0_j[p0ind]-1))
      {
	(*loglik)+= p0_val[p0ind]*tmp;
	p0ind++;
      }
      
      tmp = exp(tmp);
      
      if (!b_cond)
      {
	/* This can be speeded up by avoiding called to GetMatInd */
	aend=&p1[D];
	for (di=0,ap=&p1[0],bp=&p2[0],p_phie=&p_phiexp[0],p_psie=&p_psiexp[0]; di<D; di++,ap++,bp++,p_phie++,p_psie++)
        {
	  /*
	    phi_expect.dat[GetMatInd(phi_expect,di,i2)]+=tmp*(*ap);
	    psi_expect.dat[GetMatInd(psi_expect,i1,di)]+=tmp*(*bp);
	  */
	  /*	
	    phi_expect.dat[GetMatInd(phi_expect,di,i2)]+=tmp*phi.dat[GetMatInd(phi,di,i1)];
	    psi_expect.dat[GetMatInd(psi_expect,i1,di)]+=tmp*psi.dat[GetMatInd(psi,di,i2)];
	  */
	  (*p_phie)+=tmp*(*ap);
	  (*p_psie)+=tmp*(*bp);
	}
      }
      px[i1]+=tmp;
      py[i2]+=tmp;

      Z+= tmp;

      p1+= phi.nx;
      p_psiexp += D;      
    }
    /* Advance to next column */
    p2 += phi.nx;
    p_phiexp += D;          
  }

  if (!b_cond)
  {
     vec_mul_scalar(px,NX,1/Z);
     vec_mul_scalar(py,NY,1/Z);
     mat_el_mul_scalar(phi_expect.dat, 1/Z, phi_expect.nall);
     mat_el_mul_scalar(psi_expect.dat, 1/Z, psi_expect.nall);
     (*loglik)-= log(Z);
  }
 
}
Esempio n. 5
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    double M;
	double log_thr;
	int Xs,D,Ys,i,j,ep=0;
	int maxentep;
	int pxy_size;
	double mx;
	Matrix pxy,phi,psi,phi_tr,psi_tr,phi_exp_d,psi_exp_d,psi_exp_m,phi_exp_m,grad_phi,grad_psi;
	double *px0,*py0,*px,*py,*pa,*pb,*grad_a,*grad_b;
	double Z;
	int xi,yi,di;
	


	MatFromMLab(prhs[0],&phi);   /* Size NX,D */ 
	MatFromMLab(prhs[1],&psi);   /* Size NX,D */	
	MatFromMLab(prhs[2],&phi_tr);   /* Size D,NX */ 
	MatFromMLab(prhs[3],&psi_tr);   /* Size D,NY */	
	px0		  = mxGetPr(prhs[4]);
	py0		  = mxGetPr(prhs[5]);
	MatFromMLab(prhs[6],&phi_exp_d);
	MatFromMLab(prhs[7],&psi_exp_d);

	pa = mxGetPr(prhs[8]);
	pb = mxGetPr(prhs[9]);
 

	Xs = mxGetM(prhs[0]);
	D = mxGetN(prhs[0]);
	Ys = mxGetM(prhs[1]);
	pxy_size = Xs*Ys;

	plhs[0] = mxCreateDoubleMatrix(Xs,D,mxREAL); 
	plhs[1] = mxCreateDoubleMatrix(D,Ys,mxREAL);
	plhs[2] = mxCreateDoubleMatrix(Xs,Ys,mxREAL);
	plhs[3] =  mxCreateDoubleMatrix(1,Xs,mxREAL);
	plhs[4] =  mxCreateDoubleMatrix(1,Ys,mxREAL);

	grad_phi.dat = mxGetPr(plhs[0]);
	grad_psi.dat = mxGetPr(plhs[1]);
	grad_phi.nx = Xs;
	grad_phi.ny = D;
	grad_phi.nall = Xs*D;

	grad_psi.nx = D;
	grad_psi.ny = Ys;
	grad_psi.nall = Ys*D;

	/* Will hold the models distribution */
	pxy.dat = mxGetPr(plhs[2]);
	pxy.nx = Xs;
	pxy.ny = Ys;
	pxy.nall = Xs*Ys;

	grad_a = mxGetPr(plhs[3]);
	grad_b = mxGetPr(plhs[4]);

	AllocMat(D,Ys,&phi_exp_m);
	AllocMat(Xs,D,&psi_exp_m);

	px  = malloc(Xs*sizeof(double)); 
	py  = malloc(Ys*sizeof(double)); 

	mat_logemb_model(phi_tr,psi_tr,pa,pb,pxy);

	Z = mat_el_exp_sum(pxy.dat, pxy_size);
	mat_el_mul_scalar(pxy.dat, 1/Z, pxy_size);

	mat_sum_rows(pxy,px);
	mat_sum_cols(pxy,py);

	
	mat_mul_a_tr_b(phi,pxy,phi_exp_m);
	mat_mul(pxy,psi,psi_exp_m);

	/* Matlab line: diag(px)*phi-pxy*psi - (diag(px0)*phi-pxy0*psi);
	/* equivalent to  diag(px-px0)*phi+psi_expect_d - psi_expect_m */
	vec_subtract(px,px0,Xs);
	mat_set(grad_phi,phi);
	mat_mul_rows(grad_phi,px);
	mat_subtract(psi_exp_d.dat,psi_exp_m.dat,psi_exp_d.nall);
	mat_add(grad_phi.dat,psi_exp_d.dat,psi_exp_d.nall);

	vec_subtract(py,py0,Ys);
	mat_set(grad_psi,psi_tr);
	mat_mul_cols(grad_psi,py);
	mat_subtract(phi_exp_d.dat,phi_exp_m.dat,phi_exp_d.nall);
	mat_add(grad_psi.dat,phi_exp_d.dat,phi_exp_d.nall);

	mat_el_log(pxy.dat,pxy.nall);

        /* Generate gradient for a and b. Remember px already has px  subtracted. Just need to flip sign */
	memcpy(grad_a,px,Xs*sizeof(double));
	vec_mul_scalar(grad_a,-1,Xs);

	memcpy(grad_b,py,Ys*sizeof(double));
	vec_mul_scalar(grad_b,-1,Ys);

	free(psi_exp_m.dat);
	free(phi_exp_m.dat);
	free(px);
	free(py);

}