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); }
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); }
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); }