示例#1
0
lebool InverseMatrix (Matrix * InvM, Matrix * M)
{

   Matrix Temp;
   int j, rang;
   if (M->nblignes != M->l) {
      printf ("Matrix M is not square!\n");
      exit (1);
   }
   AllocMat (&Temp, M->nblignes, M->l, 2);
   for (j = 0; j < M->l; j++)
      CopyBV (&(Temp.lignes[j][0]), &(M->lignes[j][0]));
   for (j = 0; j < M->l; j++) {
      BVCanonic (&(Temp.lignes[j][1]), j);
   }
   /* DispMat(&Temp,2,M->l,M->nblignes,0); */
   rang = CompleteElimination (&Temp, M->nblignes, M->l, 2);
   /* DispMat(&Temp,2,M->l,M->nblignes,0); */
   /* printf("rang=%d",rang); */
   for (j = 0; j < M->l; j++)
      CopyBV (&(InvM->lignes[j][0]), &(Temp.lignes[j][1]));
   return (rang == M->l);
   FreeMat (&Temp);
}
示例#2
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);
  
}
示例#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 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);

}