/* * The mex function runs a MST problem. */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwIndex i; mwIndex mrows, ncols; mwIndex n,nz; /* sparse matrix */ mwIndex *ia, *ja; /* matching */ mwIndex *m; double *m_double; /* output */ int verify = 0; /* * The current calling pattern is * test_matching_mex(A,matching) */ const mxArray* arg_matrix; const mxArray* arg_matching; int required_arguments = 2; if (nrhs != required_arguments) { mexErrMsgIdAndTxt("matlab_bgl:invalidMexArgument", "the function requires %i arguments, not %i\n", required_arguments, nrhs); } arg_matrix = prhs[0]; arg_matching = prhs[1]; /* The first input must be a sparse matrix. */ mrows = mxGetM(arg_matrix); ncols = mxGetN(arg_matrix); if (mrows != ncols || !mxIsSparse(arg_matrix)) { mexErrMsgIdAndTxt("matlab_bgl:invalidMexArgument", "the matrix must be sparse and square"); } n = mrows; /* The second input must be of size n */ if (mxGetNumberOfElements(arg_matching) != n) { mexErrMsgIdAndTxt("matlab_bgl:invalidMexArgument", "the matching must be size %i not %i", n, mxGetNumberOfElements(arg_matching)); } m_double = mxGetPr(arg_matching); m = mxCalloc(n, sizeof(mwIndex)); for (i=0; i < n; i++) { m[i] = (mwIndex)m_double[i] ; if (m[i] == 0) { m[i] = n; } else { --m[i]; } } /* Get the sparse matrix */ /* recall that we've transposed the matrix */ ja = mxGetIr(arg_matrix); ia = mxGetJc(arg_matrix); nz = ia[n]; plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); #ifdef _DEBUG mexPrintf("test_maximum_cardinality_matching..."); #endif test_maximum_cardinality_matching(n, ja, ia, m, &verify); *mxGetPr(plhs[0]) = (double)verify; #ifdef _DEBUG mexPrintf("return\n"); #endif }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Variables */ int k,nSamples,maxIter,sparse=0,*iVals,average=0,loss; long i,j,nVars,one=1; mwIndex *jc,*ir; double *w, *Xt, *y, lambda, *stepSizes, innerProd, alpha,sig,c=1,cA=1,tau=0,*wAvg,*averageWeights,weightedAverage=0,scaling; /* Input */ if (nrhs < 6) mexErrMsgTxt("Exactly 6 arguments are needed: {w,Xy,y,lambda,stepSizes,iVals}"); w = mxGetPr(prhs[0]); Xt = mxGetPr(prhs[1]); y = mxGetPr(prhs[2]); lambda = mxGetScalar(prhs[3]); stepSizes = mxGetPr(prhs[4]); iVals = (int*)mxGetPr(prhs[5]); if (!mxIsClass(prhs[5],"int32")) mexErrMsgTxt("iVals must be int32"); /* Compute Sizes */ nVars = mxGetM(prhs[1]); nSamples = mxGetN(prhs[1]); maxIter = mxGetM(prhs[4]); if (nVars != mxGetM(prhs[0])) mexErrMsgTxt("w and Xt must have the same number of rows"); if (nSamples != mxGetM(prhs[2])) mexErrMsgTxt("number of columns of Xt must be the same as the number of rows in y"); if (maxIter != mxGetM(prhs[5])) mexErrMsgTxt("iVals and stepSizes must have the same number of rows"); if (nrhs > 7 && maxIter != mxGetM(prhs[7])) mexErrMsgTxt("iVals and averageWeights must have the same number of rows"); if (mxIsSparse(prhs[1])) { sparse = 1; jc = mxGetJc(prhs[1]); ir = mxGetIr(prhs[1]); } if (nlhs > 0) { average = 1; plhs[0] = mxCreateDoubleMatrix(nVars,1,mxREAL); wAvg = mxGetPr(plhs[0]); } for(k=0;k<maxIter;k++) { /* Select next training example */ i = iVals[k]-1; /* Compute Inner Product of Parameters with Features */ innerProd = 0; if(sparse) { for(j=jc[i];j<jc[i+1];j++) innerProd += w[ir[j]]*Xt[j]; innerProd *= c; } else innerProd = ddot(&nVars,w,&one,&Xt[nVars*i],&one); sig = -y[i]/(1+exp(y[i]*innerProd)); /* Compute step size */ alpha = stepSizes[k]; /* Update parameters */ if (sparse) { if (alpha*lambda != 1) { c *= 1-alpha*lambda; } else { c = 1; scaling = 0.0; dscal(&nVars,&scaling,w,&one); } for(j=jc[i];j<jc[i+1];j++) w[ir[j]] -= alpha*Xt[j]*sig/c; } else { scaling = 1-alpha*lambda; dscal(&nVars,&scaling,w,&one); scaling = -alpha*sig; daxpy(&nVars,&scaling,&Xt[i*nVars],&one,w,&one); } /* Average */ if(average) { if (sparse) { if (k > 0) cA *= (double)k/(double)(k+1); for(j=jc[i];j<jc[i+1];j++) wAvg[ir[j]] += tau*alpha*Xt[j]*sig/c; tau += (c/cA)/(double)(k+1); } else { scaling = 1.0; daxpy(&nVars,&scaling,w,&one,wAvg,&one); } } } if(sparse) { dscal(&nVars,&c,w,&one); } if(average) { if (sparse) { scaling = tau/c; daxpy(&nVars,&scaling,w,&one,wAvg,&one); dscal(&nVars,&cA,wAvg,&one); } else { scaling = 1.0/maxIter; dscal(&nVars,&scaling,wAvg,&one); } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ int i, j, NS, NZB, count, bdim, match, domain, bindex, sindex, nzCounts=0; int *observed, *bsubv, *ssubv, *bir, *sir, *bjc, *sjc, *mask, *ssize, *bcumprod, *scumprod; double *pDomain, *pSize, *bpr, *spr; mxArray *pTemp; pTemp = mxGetField(prhs[0], 0, "CPT"); bpr = mxGetPr(pTemp); bir = mxGetIr(pTemp); bjc = mxGetJc(pTemp); NZB = bjc[1]; pTemp = mxGetField(prhs[0], 0, "sizes"); pSize = mxGetPr(pTemp); pDomain = mxGetPr(prhs[1]); bdim = mxGetNumberOfElements(prhs[1]); mask = malloc(bdim * sizeof(int)); ssize = malloc(bdim * sizeof(int)); observed = malloc(bdim * sizeof(int)); for(i=0; i<bdim; i++){ ssize[i] = (int)pSize[i]; } count = 0; for(i=0; i<bdim; i++){ domain = (int)pDomain[i] - 1; pTemp = mxGetCell(prhs[2], domain); if(pTemp){ mask[count] = i; ssize[i] = 1; observed[count] = (int)mxGetScalar(pTemp) - 1; count++; } } if(count == 0){ pTemp = mxGetField(prhs[0], 0, "CPT"); plhs[0] = mxDuplicateArray(pTemp); free(mask); free(ssize); free(observed); return; } bsubv = malloc(bdim * sizeof(int)); ssubv = malloc(count * sizeof(int)); bcumprod = malloc(bdim * sizeof(int)); scumprod = malloc(bdim * sizeof(int)); NS = 1; for(i=0; i<bdim; i++){ NS *= ssize[i]; } plhs[0] = mxCreateSparse(NS, 1, NS, mxREAL); spr = mxGetPr(plhs[0]); sir = mxGetIr(plhs[0]); sjc = mxGetJc(plhs[0]); sjc[0] = 0; sjc[1] = NS; bcumprod[0] = 1; scumprod[0] = 1; for(i=0; i<bdim-1; i++){ bcumprod[i+1] = bcumprod[i] * (int)pSize[i]; scumprod[i+1] = scumprod[i] * ssize[i]; } nzCounts = 0; for(i=0; i<NZB; i++){ bindex = bir[i]; ind_subv(bindex, bcumprod, bdim, bsubv); for(j=0; j<count; j++){ ssubv[j] = bsubv[mask[j]]; } match = 1; for(j=0; j<count; j++){ if((ssubv[j]) != observed[j]){ match = 0; break; } } if(match){ spr[nzCounts] = bpr[i]; sindex = subv_ind(bdim, scumprod, bsubv); sir[nzCounts] = sindex; nzCounts++; } } reset_nzmax(plhs[0], NS, nzCounts); free(mask); free(ssize); free(observed); free(bsubv); free(ssubv); free(bcumprod); free(scumprod); }
/* ************************************************************ PROCEDURE mexFunction - Entry for Matlab ************************************************************ */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { jcir At; mwIndex i,j, nblk,m, L, iwsize; mwIndex *iwork, *Ablkjc, *blkstart; const mwIndex *rowj; double *AblkjcPr; const double *blkstartPr; bool *cwork; /* ------------------------------------------------------------ Check for proper number of arguments ------------------------------------------------------------ */ mxAssert(nrhs >= NPARIN, "partitA requires more input arguments."); mxAssert(nlhs <= NPAROUT, "partitA produces less output arguments."); /* -------------------------------------------------- GET inputs At, blkstart -------------------------------------------------- */ mxAssert(mxIsSparse(AT_IN), "At must be a sparse matrix."); At.jc = mxGetJc(AT_IN); At.ir = mxGetIr(AT_IN); m = mxGetN(AT_IN); nblk = mxGetM(BLKSTART_IN) * mxGetN(BLKSTART_IN); blkstartPr = mxGetPr(BLKSTART_IN); /* ------------------------------------------------------------ Allocate working array Ablkjc((nblk+2) * m), iwork(log_2(1+nblk)), blkstart(nblk) ------------------------------------------------------------ */ iwsize = (mwIndex) floor(log(1.0+nblk)/log(2.0)); iwork = (mwIndex *) mxCalloc(MAX(iwsize,1), sizeof(mwIndex)); Ablkjc = (mwIndex *) mxCalloc(MAX((nblk+2)*m,1), sizeof(mwIndex)); blkstart = (mwIndex *) mxCalloc(MAX(nblk,1), sizeof(mwIndex)); cwork = (bool *) mxCalloc(MAX(nblk,1), sizeof(bool)); /* ------------------------------------------------------------ Translate blkstart from Fortran-double to C-mwIndex ------------------------------------------------------------ */ for(i = 0; i < nblk; i++){ /* to integers */ j = (mwIndex) blkstartPr[i]; mxAssert(j>0,""); blkstart[i] = --j; } /* ------------------------------------------------------------ The real job: ------------------------------------------------------------ */ partitA(Ablkjc, At.jc,At.ir, blkstart, m,nblk, iwsize,cwork,iwork); /* ------------------------------------------------------------ Create output Ablkjc m x nblk. ------------------------------------------------------------ */ ABLKJC_OUT = mxCreateDoubleMatrix(m, nblk, mxREAL); AblkjcPr = mxGetPr(ABLKJC_OUT); rowj = Ablkjc; L = nblk+2; for(j = 0; j < nblk; j++){ ++rowj; for(i = 0; i < m; i++) AblkjcPr[i] = (double) rowj[i*L]; /* convert mwIndex to double */ AblkjcPr += m; } /* ------------------------------------------------------------ Release working arrays ------------------------------------------------------------ */ mxFree(cwork); mxFree(iwork); mxFree(Ablkjc); mxFree(blkstart); }
int flip(mxArray *X, const mxArray *DL, const mxArray *A, const mxArray *dDL, const mxArray *s, mwSize offset, mwSize T, const mxArray *h, const mxArray *wws, const mxArray *wVs) { const mwSize *sz = mxGetDimensions(dDL); mwSize D = sz[0], M = sz[1], p = sz[3], Ndt = sz[4]; mwSize N = mxGetM(DL); mwSize Tdt = ceil((double) N / (double) Ndt); mwSize lenh = mxGetM(h); mwSize pad = (lenh - 1) / 2; // find maximum double *DLpr = mxGetPr(DL); double max = 0, d; int iMax = -1, jMax = -1; for (mwSize j = 0; j != M; ++j) { for (mwSize i = offset + 1; i != offset + T + 1; ++i) { d = DLpr[N * j + i]; if (d >= max) { max = d; iMax = i; jMax = j; } } } double Xij; double *Xpr = mxGetPr(X), *Xpi = mxGetPi(X); double *hpr = mxGetPr(h), *Apr = mxGetPr(A); mwIndex *Xir = mxGetIr(X), *Xjc = mxGetJc(X); double sgn; if (max > 0) { // find location in sparse array double a = 0, r = 0; int sub; mwSize l = Xjc[jMax]; while (l != Xjc[jMax + 1] && Xir[l] <= iMax) { if (Xir[l] == iMax) { a = Xpr[l]; r = Xpi[l]; break; } else { ++l; } } if (a == 0) { // add spike - subsample // determine amplitude and subsample shift sgn = 1; max = 0; for (mwSize j = 0; j != p; ++j) { double m = 0; for (mwSize i = 0; i != lenh; ++i) { m = m + DLpr[jMax * N + iMax - pad + i] * hpr[j * lenh + i]; } if (m > max) { sub = j; max = m; } } for (mwSize i = 0; i != lenh; ++i) { a = a + Apr[N * jMax + iMax - pad + i] * hpr[sub * lenh + i]; } r = (double) (sub - (int) p / 2) / (double) p; // CHECK // grow sparse array if necessary mwSize nzmax = mxGetNzmax(X); if (Xjc[M] == nzmax) { // grow X nzmax *= 2; mxSetNzmax(X, nzmax); Xir = (mwIndex*) mxRealloc(Xir, nzmax * sizeof(*Xir)); mxSetIr(X, Xir); Xpr = (double*) mxRealloc(Xpr, nzmax * sizeof(*Xpr)); mxSetPr(X, Xpr); Xpi = (double*) mxRealloc(Xpi, nzmax * sizeof(*Xpi)); mxSetPi(X, Xpi); } // add values to sparse array // real: amplitude // imag: subsample (> 0 => shift right, < 0 => shift left) for (mwSize j = jMax; j != M; ++j) { ++Xjc[j + 1]; } for (mwSize i = Xjc[M] - 1; i > l; --i) { Xir[i] = Xir[i - 1]; Xpr[i] = Xpr[i - 1]; Xpi[i] = Xpi[i - 1]; } Xir[l] = iMax; Xpr[l] = a; Xpi[l] = r; } else { // remove spike sgn = -1; for (mwSize j = jMax + 1; j != M + 1; ++j) { --Xjc[j]; } for (; l != Xjc[M]; ++l) { Xir[l] = Xir[l + 1]; Xpr[l] = Xpr[l + 1]; Xpi[l] = Xpi[l + 1]; } } // update change in posterior double DLij = DLpr[N * jMax + iMax]; sub = (int) p / 2 - round(r * (double) p); mwSize t = iMax / Tdt; mwSize start = D * M * (jMax + M * (sub + p * t)); mwSize ii; double dA; double *dDLpr = mxGetPr(dDL), *wwspr = mxGetPr(wws), *wVspr = mxGetPr(wVs), *spr = mxGetPr(s); for (mwSize j = 0; j != M; ++j) { for (mwSize i = 0; i != D; ++i) { dA = dDLpr[start + D * j + i] * a * sgn / wwspr[Ndt * j + t]; ii = N * j + iMax + spr[i]; Apr[ii] = Apr[ii] - dA; DLpr[ii] = DLpr[ii] - dA * (wVspr[ii] + a * dDLpr[start + D * j + i]); DLpr[N * jMax + iMax] = -DLij; } } } else { iMax = -1; } return iMax; }
void mexFunction(int nlhs, Matrix **plhs, int nrhs, Matrix **prhs) { FILE *nl; char *buf1, buf[512], *what; static fint n, nc, nz; fint nerror; real *J1, *W, *c, *f, *g, *v, *t, *x; static real *J; cgrad *cg, **cgp; static size_t Jsize; Jmp_buf err_jmp0; ASL_pfgh *asl = (ASL_pfgh*)cur_ASL; static fint nhnz; static real *Hsp; real *H, *He; int *Ir, *Jc; fint *hcs, *hr, i; if (nrhs == 1 && mxIsString(prhs[0])) { if (nlhs != 6) usage(); if (mxGetString(prhs[0], buf1 = buf, sizeof(buf))) mexErrMsgTxt("Expected 'stub' as argument\n"); at_end(); mexAtExit(at_end); asl = (ASL_pfgh*)ASL_alloc(ASL_read_pfgh); return_nofile = 1; if (!(nl = jac0dim(buf1,strlen(buf)))) { sprintf(msgbuf, "Can't open %.*s\n", sizeof(msgbuf)-20, buf); mexErrMsgTxt(msgbuf); } if (n_obj <= 0) printf("Warning: objectve == 0\n"); n = n_var; nc = n_con; nz = nzc; J = (real *)M1alloc(nz*sizeof(real)); X0 = mxGetPr(plhs[0] = mxCreateFull(n, 1, REAL)); LUv = mxGetPr(plhs[1] = mxCreateFull(n, 1, REAL)); Uvx = mxGetPr(plhs[2] = mxCreateFull(n, 1, REAL)); pi0 = mxGetPr(plhs[3] = mxCreateFull(nc, 1, REAL)); LUrhs = mxGetPr(plhs[4] = mxCreateFull(nc, 1, REAL)); Urhsx = mxGetPr(plhs[5] = mxCreateFull(nc, 1, REAL)); pfgh_read(nl, ASL_findgroups); Jsize = nc*n*sizeof(real); /* Arrange to compute the whole sparese Hessian */ /* of the Lagrangian function (both triangles). */ nhnz = sphsetup(0, 0, nc > 0, 0); Hsp = (real *)M1alloc(nhnz*sizeof(real)); return; } if (!filename) mexErrMsgTxt("spamfunc(\"stub\") has not been called\n"); nerror = -1; err_jmp1 = &err_jmp0; if (nlhs == 2) { if (nrhs != 2) usage(); x = sizechk(prhs[0],"x",n); t = sizechk(prhs[1],"0 or 1", 1); if (t[0] == 0.) { f = mxGetPr(plhs[0] = mxCreateFull(1, 1, REAL)); c = mxGetPr(plhs[1] = mxCreateFull(nc, 1, REAL)); if (setjmp(err_jmp0.jb)) { sprintf(msgbuf, "Trouble evaluating %s\n", what); mexErrMsgTxt(msgbuf); } what = "f"; *f = objval(0, x, &nerror); what = "c"; conval(x, c, &nerror); return; } g = mxGetPr(plhs[0] = mxCreateFull(n, 1, REAL)); J1 = mxGetPr(plhs[1] = mxCreateSparse(nc, n, nz, REAL)); what = "g"; objgrd(0, x, g, &nerror); if (nc) { what = "J"; jacval(x, J1, &nerror); Ir = mxGetIr(plhs[1]); memcpy(mxGetJc(plhs[1]), A_colstarts, (n+1)*sizeof(int)); cgp = Cgrad; for(i = 0; i < nc; i++) for(cg = *cgp++; cg; cg = cg->next) Ir[cg->goff] = i; } return; } if (nlhs == 0 && nrhs == 3) { /* eval2('solution message', x, v): x = primal, v = dual */ if (!mxIsString(prhs[0])) usage(); x = sizechk(prhs[1],"x",n); v = sizechk(prhs[2],"v",nc); if (mxGetString(prhs[0], buf, sizeof(buf))) mexErrMsgTxt( "Expected 'solution message' as first argument\n"); write_sol(buf, x, v, 0); return; } if (nlhs != 1 || nrhs != 1) usage(); v = sizechk(prhs[0],"v",nc); W = mxGetPr(plhs[0] = mxCreateSparse(n, n, nhnz, REAL)); what = "W"; sphes(H = Hsp, 0, 0, v); /* Expand the Hessian lower triangle into the full Hessian... */ Ir = mxGetIr(plhs[0]); Jc = mxGetJc(plhs[0]); hcs = sputinfo->hcolstarts; hr = sputinfo->hrownos; for(i = 0; i <= n; i++) Jc[i] = hcs[i]; He = H + hcs[n]; while(H < He) { *W++ = *H++; *Ir++ = *hr++; } }
/* ************************************************************ PROCEDURE mexFunction - Entry for Matlab ************************************************************ */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mxArray *L_FIELD; mwIndex i,j, nsuper,m, cachesiz; const mwIndex *ljc,*lir; mwIndex *xsuper, *split; const double *xsuperPr; double *splitPr; /* ------------------------------------------------------------ Check for proper number of arguments ------------------------------------------------------------ */ mxAssert(nrhs >= NPARIN, "cholsplit requires more input arguments."); mxAssert(nlhs <= NPAROUT, "cholsplit produces less output arguments."); /* ------------------------------------------------------------ Get cachesiz, and transform from KBs into 90% of FLOATS. ------------------------------------------------------------ */ cachesiz = (mwIndex) floor(0.9 * (1024 / sizeof(double)) * mxGetScalar(CACHESIZ_IN)); /* ------------------------------------------------------------ Disassemble block Cholesky structure L ------------------------------------------------------------ */ mxAssert(mxIsStruct(L_IN), "Parameter `L' should be a structure."); L_FIELD = mxGetField(L_IN,(mwIndex)0,"L"); /* L.L */ mxAssert( L_FIELD != NULL, "Missing field L.L."); m = mxGetM(L_FIELD); mxAssert(m == mxGetN(L_FIELD), "L.L must be square."); mxAssert(mxIsSparse(L_FIELD), "L.L should be sparse."); ljc = mxGetJc(L_FIELD); lir = mxGetIr(L_FIELD); L_FIELD = mxGetField(L_IN,(mwIndex)0,"xsuper"); /* L.xsuper */ mxAssert( L_FIELD != NULL, "Missing field L.xsuper."); nsuper = mxGetM(L_FIELD) * mxGetN(L_FIELD) - 1; mxAssert( nsuper <= m, "Size L.xsuper mismatch."); xsuperPr = mxGetPr(L_FIELD); /* ------------------------------------------------------------ Allocate working arrays: ------------------------------------------------------------ */ xsuper = (mwIndex *) mxCalloc(nsuper+1,sizeof(mwIndex)); split = (mwIndex *) mxCalloc(m,sizeof(mwIndex)); /* ------------------------------------------------------------ Convert XSUPER to integer and C-Style ------------------------------------------------------------ */ for(i = 0; i <= nsuper; i++){ j = (mwIndex) xsuperPr[i]; mxAssert(j>0,""); xsuper[i] = --j; } /* ------------------------------------------------------------ The main job: compute (upper bound on) blkchol-split. ------------------------------------------------------------ */ getsplit(split, ljc,lir,xsuper,nsuper, cachesiz); /* ------------------------------------------------------------ create OUTPUT variable SPLIT(m) ------------------------------------------------------------ */ SPLIT_OUT = mxCreateDoubleMatrix(m, (mwSize)1, mxREAL); /* L.split */ splitPr = mxGetPr(SPLIT_OUT); for(i = 0; i < m; i += j){ j = split[i]; splitPr[i] = (double) j; } /* ------------------------------------------------------------ Release working arrays. ------------------------------------------------------------ */ mxFree(split); mxFree(xsuper); }
/* ************************************************************ PROCEDURE mexFunction - Entry for Matlab ************************************************************ */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { coneK cK; const mxArray *MY_FIELD; mwIndex m, i, j; const double *permPr; double *fwork; mwIndex *iwork, *perm, *invperm; jcir ada, ddota; /* ------------------------------------------------------------ Check for proper number of arguments ------------------------------------------------------------ */ mxAssert(nrhs >= NPARIN, "getADA requires more input arguments."); mxAssert(nlhs <= NPAROUT, "getADA produces less output arguments."); /* ------------------------------------------------------------ Disassemble cone K structure ------------------------------------------------------------ */ conepars(K_IN, &cK); m = mxGetM(ADA_IN); /* ------------------------------------------------------------ Allocate output matrix ADA with sparsity structure of ADA_IN, and initialize as a copy of ADA_IN. ------------------------------------------------------------ */ mxAssert(mxGetN(ADA_IN) == m, "Size mismatch ADA."); mxAssert(mxIsSparse(ADA_IN), "ADA should be sparse."); ADA_OUT = mxDuplicateArray(ADA_IN); /* ADA = ADA_IN */ if(cK.lorN <= 0) /* READY if no LORENTZ blocks !*/ return; ada.jc = mxGetJc(ADA_OUT); ada.ir = mxGetIr(ADA_OUT); ada.pr = mxGetPr(ADA_OUT); /* ------------------------------------------------------------ DISASSEMBLE DAt structure: DAt.q ------------------------------------------------------------ */ mxAssert(mxIsStruct(DAT_IN), "DAt should be a structure."); MY_FIELD = mxGetField(DAT_IN,(mwIndex)0,"q"); /* DAt.q */ mxAssert( MY_FIELD != NULL, "Missing field DAt.q."); mxAssert(mxGetM(MY_FIELD) == cK.lorN && mxGetN(MY_FIELD) == m, "Size mismatch DAt.q"); mxAssert(mxIsSparse(MY_FIELD), "DAt.q should be sparse."); ddota.jc = mxGetJc(MY_FIELD); ddota.ir = mxGetIr(MY_FIELD); ddota.pr = mxGetPr(MY_FIELD); /* ------------------------------------------------------------ DISASSEMBLE Aord structure: Aord.qperm ------------------------------------------------------------ */ mxAssert(mxIsStruct(AORD_IN), "Aord should be a structure."); MY_FIELD = mxGetField(AORD_IN,(mwIndex)0,"qperm"); /* Aord.qperm */ mxAssert( MY_FIELD != NULL, "Missing field Aord.qperm."); mxAssert(mxGetM(MY_FIELD) * mxGetN(MY_FIELD) == m, "Size mismatch Aord.qperm."); permPr = mxGetPr(MY_FIELD); /* ------------------------------------------------------------ Only work to do if ~isempty(ddota): ------------------------------------------------------------ */ if(ddota.jc[m] > 0){ /* ------------------------------------------------------------ ALLOCATE working arrays: iwork(2*m) = [perm(m), invperm(m)]. fwork[lorN] ------------------------------------------------------------ */ iwork = (mwIndex *) mxCalloc(MAX(2 * m,1), sizeof(mwIndex)); perm = iwork; invperm = perm + m; fwork = (double *) mxCalloc(MAX(cK.lorN,1), sizeof(double)); /* ------------------------------------------------------------ perm to integer C-style ------------------------------------------------------------ */ for(i = 0; i < m; i++){ j = (mwIndex) permPr[i]; mxAssert(j>0,""); perm[i] = --j; } /* ------------------------------------------------------------ Let invperm(perm) = 0:m-1. ------------------------------------------------------------ */ for(i = 0; i < m; i++) invperm[perm[i]] = i; /* ------------------------------------------------------------ ACTUAL COMPUTATION: ADA += DAt.q'*DAt.q. ------------------------------------------------------------ */ getada2(ada, ddota, perm, invperm, m, cK.lorN, fwork); /* ------------------------------------------------------------ RELEASE WORKING ARRAYS. ------------------------------------------------------------ */ mxFree(fwork); mxFree(iwork); } /* !isempty(ddota) */ }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { mxArray *A_cell_pr; double *A, *B; int *irA, *jcA, *irB, *jcB; double *Btmp, *tr; int isspA, isspB, iscellA, iscellB; int subs[2]; int nsubs=2; int mA, nA, m1, n1, m2, n2, j, index; int rowidx, colidx, r, k, kstart, kend; /* CHECK THE DIMENSIONS */ iscellA = mxIsCell(prhs[1]); mA = mxGetM(prhs[1]); if (!iscellA) { mA = 1; } if (nrhs < 2) { mexErrMsgTxt(" mexinprod: must have at least 3 inputs"); } if (nlhs>2) { mexErrMsgTxt("mexinprod: requires 1 output argument"); } if (nrhs > 4) { rowidx = (int)*mxGetPr(prhs[4]); } else { rowidx = 1; } if (rowidx > mA) { mexErrMsgTxt("mexinprod: rowidx exceeds size(Avec,1)"); } /***** assign pointers *****/ iscellB = mxIsCell(prhs[2]); isspB = mxIsSparse(prhs[2]); m2 = mxGetM(prhs[2]); n2 = mxGetN(prhs[2]); if ((n2 > 1) || (iscellB)) { mexErrMsgTxt("mexinprod: 3RD input must be a column vector"); } if (isspB) { irB = mxGetIr(prhs[2]); jcB = mxGetJc(prhs[2]); Btmp = mxGetPr(prhs[2]); /***** copy Btmp to B *****/ B = mxCalloc(m2,sizeof(double)); kstart = jcB[0]; kend = jcB[1]; for (k=kstart; k<kend; k++) { r = irB[k]; B[r] = Btmp[k]; } } else { B = mxGetPr(prhs[2]); } if (iscellA) { subs[0] = rowidx-1; /* subtract 1 to adjust for Matlab index */ subs[1] = 0; index = mxCalcSingleSubscript(prhs[1],nsubs,subs); A_cell_pr = mxGetCell(prhs[1],index); A = mxGetPr(A_cell_pr); m1 = mxGetM(A_cell_pr); n1 = mxGetN(A_cell_pr); isspA = mxIsSparse(A_cell_pr); if (isspA) { irA = mxGetIr(A_cell_pr); jcA = mxGetJc(A_cell_pr); } } else { A = mxGetPr(prhs[1]); m1 = mxGetM(prhs[1]); n1 = mxGetN(prhs[1]); isspA = mxIsSparse(prhs[1]); if (isspA) { irA = mxGetIr(prhs[1]); jcA = mxGetJc(prhs[1]); } } if (nrhs > 3) { colidx = (int)*mxGetPr(prhs[3]); } else { colidx = 1; } if (colidx > n1) { mexErrMsgTxt("mexinprod: colidx exceeds size(Avec,2)"); } if (m1 != m2) { mexErrMsgTxt("mexinprod: 2ND and 3RD input not compatible."); } /***** create return argument *****/ plhs[0] = mxCreateDoubleMatrix(colidx,1,mxREAL); tr = mxGetPr(plhs[0]); /***** compute <Aj,B> *****/ if (isspA) { for (j=0; j<colidx; j++){ tr[j] = realdot2(A,irA,jcA,j,B); } } else { for (j=0; j<colidx; j++){ tr[j] = realdot1(A,j,B,m1); } } if (isspB) { mxFree(B); } return; }
/* ************************************************************ PROCEDURE mexFunction - Entry for Matlab ************************************************************ */ void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) { const mxArray *L_FIELD; int maxnnz, i,j, nsuper,m,n; const int *ljc,*lir,*bjc,*bir; int *xjc,*xir, *snode,*snodebelow, *iwork,*xsuper; char *cwork; double *xpr; const double *xsuperPr; /* ------------------------------------------------------------ Check for proper number of arguments ------------------------------------------------------------ */ mxAssert(nrhs >= NPARIN, "symbfwblk requires more input arguments"); mxAssert(nlhs <= NPAROUT, "symbfwblk produces 1 output argument"); /* ------------------------------------------------------------ Get rhs-input B ------------------------------------------------------------ */ mxAssert(mxIsSparse(B_IN), "B must be sparse"); m = mxGetM(B_IN); n = mxGetN(B_IN); bjc = mxGetJc(B_IN); bir = mxGetIr(B_IN); /* ------------------------------------------------------------ Disassemble block Cholesky structure L ------------------------------------------------------------ */ mxAssert(mxIsStruct(L_IN), "Parameter `L' should be a structure."); L_FIELD = mxGetField(L_IN,0,"L"); mxAssert( L_FIELD != NULL, "Missing field L.L."); /* L.L */ mxAssert( m == mxGetM(L_FIELD) && m == mxGetN(L_FIELD), "Size L.L mismatch."); mxAssert(mxIsSparse(L_FIELD), "L.L should be sparse."); ljc = mxGetJc(L_FIELD); lir = mxGetIr(L_FIELD); L_FIELD = mxGetField(L_IN,0,"xsuper"); mxAssert( L_FIELD != NULL, "Missing field L.xsuper."); /* L.xsuper */ nsuper = mxGetM(L_FIELD) * mxGetN(L_FIELD) - 1; mxAssert( nsuper <= m, "Size L.xsuper mismatch."); xsuperPr = mxGetPr(L_FIELD); /* ------------------------------------------------------------ Allocate int-part of sparse output matrix X(m x n) Heuristically set nnz to nnz(B) + 4*m. ------------------------------------------------------------ */ maxnnz = bjc[n] + 4 * m; xjc = (int *) mxCalloc(n + 1, sizeof(int)); xir = (int *) mxCalloc(maxnnz, sizeof(int)); /* ------------------------------------------------------------ Allocate working arrays: int snode(m), xsuper(nsuper+1), snodebelow(nsuper), iwork(nsuper). char cwork(nsuper+1). ------------------------------------------------------------ */ snode = (int *) mxCalloc(m,sizeof(int)); xsuper = (int *) mxCalloc(nsuper+1,sizeof(int)); snodebelow = (int *) mxCalloc(nsuper,sizeof(int)); iwork = (int *) mxCalloc(nsuper, sizeof(int)); cwork = (char *) mxCalloc(nsuper+1, sizeof(char)); /* ------------------------------------------------------------ Convert XSUPER to integer and C-Style ------------------------------------------------------------ */ for(i = 0; i <= nsuper; i++){ j = xsuperPr[i]; xsuper[i] = --j; } /* ------------------------------------------------------------ Create "snode" from xsuper, and get "first-below-diag" supernodal subscript snodebelow (snodebelow[j]==nsuper means none). This is enough to determine the nz-pattern of the backward-solve. ------------------------------------------------------------ */ getSnodeBelow(snodebelow,snode, ljc,lir,xsuper,nsuper); /* ------------------------------------------------------------ Compute nz structure after backward solve ------------------------------------------------------------ */ symbbwmat(xjc, &xir, &maxnnz, bjc, bir, snode, xsuper, snodebelow, nsuper, m, n, iwork, cwork); /* ------------------------------------------------------------ Create output matrix x ------------------------------------------------------------ */ X_OUT = mxCreateSparse(m,n, 1,mxREAL); mxFree(mxGetJc(X_OUT)); /* jc */ mxFree(mxGetIr(X_OUT)); /* ir */ mxFree(mxGetPr(X_OUT)); /* pr */ xpr = (double *) mxCalloc(maxnnz,sizeof(double)); mxSetJc(X_OUT, xjc); mxSetIr(X_OUT, xir); mxSetPr(X_OUT, xpr); mxSetNzmax(X_OUT, maxnnz); for(i = 0; i < maxnnz; i++) xpr[i] = 1.0; /* ------------------------------------------------------------ Release working arrays. ------------------------------------------------------------ */ mxFree(cwork); mxFree(iwork); mxFree(snodebelow); mxFree(xsuper); mxFree(snode); }
/* ************************************************************ PROCEDURE mexFunction - Entry for Matlab ************************************************************ */ void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) { jcir At, Ablk; int i,j, nblk,m, blknnz, njc, iwsize, blk0,blk1; int *iwork, *Ajc, *blkstart; const double *blkstartPr, *AjcPr; char *cwork; /* ------------------------------------------------------------ Check for proper number of arguments ------------------------------------------------------------ */ mxAssert(nrhs >= NPARIN, "findblks requires more input arguments."); mxAssert(nlhs <= NPAROUT, "findblks produces less output arguments."); /* -------------------------------------------------- GET inputs At, blkstart, Ablkjc, blk0, blk1 -------------------------------------------------- */ mxAssert(mxIsSparse(AT_IN), "At must be a sparse matrix."); At.jc = mxGetJc(AT_IN); At.ir = mxGetIr(AT_IN); m = mxGetN(AT_IN); nblk = mxGetM(BLKSTART_IN) * mxGetN(BLKSTART_IN) - 1; blkstartPr = mxGetPr(BLKSTART_IN); AjcPr = mxGetPr(ABLKJC_IN); mxAssert(m == mxGetM(ABLKJC_IN), "Ablkjc size mismatch."); njc = mxGetN(ABLKJC_IN); blk0 = mxGetScalar(BLK0_IN); /* double to int */ --blk0; /* Fortran to C */ if(mxGetM(BLK1_IN) * mxGetN(BLK1_IN) != 1) blk1 = njc; /*default to end */ else{ blk1 = mxGetScalar(BLK1_IN); /* double to int (thus inf not allowed) */ --blk1; /* Fortran to C */ } /* ------------------------------------------------------------ Allocate working array iwork(nblk+2+log_2(1+nblk)), blkstart(2*nblk), Ajc(2*m) char cwork(nblk) ------------------------------------------------------------ */ iwsize = nblk + 2 + floor(log(1+nblk)/log(2)); iwork = (int *) mxCalloc(iwsize, sizeof(int)); blkstart = (int *) mxCalloc(MAX(2*nblk,1), sizeof(int)); Ajc = (int *) mxCalloc(MAX(2*m,1), sizeof(int)); cwork = (char *) mxCalloc(MAX(nblk,1), sizeof(char)); /* ------------------------------------------------------------ Translate blkstart from Fortran-double to C-int ------------------------------------------------------------ */ for(i = 0; i < nblk; i++){ /* to integers */ j = blkstartPr[i]; blkstart[i] = --j; blkstart[nblk+i] = --j; /* blkstart minus 1 */ } /* ------------------------------------------------------------ Convert Ajc from double to int: ------------------------------------------------------------ */ mxAssert(blk0 < njc, "Ablkjc size mismatches blk0."); if(blk0 < 0) memcpy(Ajc,At.jc,m*sizeof(int)); /* default: start of column */ else for(i = 0; i < m; i++){ /* to integers */ Ajc[i] = AjcPr[m*blk0 + i]; } mxAssert(blk1 >= 0, "blk1 must be positive."); if(blk1 >= njc) memcpy(Ajc+m,At.jc+1,m*sizeof(int)); /* default: end of column */ else for(i = 0; i < m; i++){ /* to integers */ Ajc[m+i] = AjcPr[blk1*m + i]; } /* ------------------------------------------------------------ Ablk = sparse(nblk,m,blknnz); ------------------------------------------------------------ */ blknnz = 0; for(i = 0; i < m; i++) blknnz += Ajc[m+i]-Ajc[i]; /* upper bound on nnz blocks */ blknnz = MAX(blknnz,1); ABLK_OUT = mxCreateSparse(nblk,m, blknnz,mxREAL); Ablk.jc = mxGetJc(ABLK_OUT); Ablk.ir = mxGetIr(ABLK_OUT); /* ------------------------------------------------------------ The real job: ------------------------------------------------------------ */ findblks(Ablk.ir,Ablk.jc, Ajc,Ajc+m,At.ir, blkstart,blkstart+nblk, m,nblk, iwsize,cwork,iwork); /* ------------------------------------------------------------ REALLOC (shrink) Ablk to Ablk.jc[m] nonzeros. ------------------------------------------------------------ */ mxAssert(Ablk.jc[m] <= blknnz,""); blknnz = MAX(Ablk.jc[m],1); if((Ablk.ir = (int *) mxRealloc(Ablk.ir, blknnz * sizeof(int))) == NULL) mexErrMsgTxt("Memory allocation error"); if((Ablk.pr = (double *) mxRealloc(mxGetPr(ABLK_OUT), blknnz*sizeof(double))) == NULL) mexErrMsgTxt("Memory allocation error"); mxSetPr(ABLK_OUT,Ablk.pr); mxSetIr(ABLK_OUT,Ablk.ir); mxSetNzmax(ABLK_OUT,blknnz); for(i = 0; i < blknnz; i++) Ablk.pr[i] = 1.0; /* ------------------------------------------------------------ Release working arrays ------------------------------------------------------------ */ mxFree(cwork); mxFree(iwork); mxFree(Ajc); mxFree(blkstart); }
const char *model_to_matlab_structure(mxArray *plhs[], int num_of_feature, struct svm_model *model) { int i, j, n; double *ptr; mxArray *return_model, **rhs; int out_id = 0; rhs = (mxArray **)mxMalloc(sizeof(mxArray *)*NUM_OF_RETURN_FIELD); // Parameters rhs[out_id] = mxCreateDoubleMatrix(5, 1, mxREAL); ptr = mxGetPr(rhs[out_id]); ptr[0] = model->param.svm_type; ptr[1] = model->param.kernel_type; ptr[2] = model->param.degree; ptr[3] = model->param.gamma; ptr[4] = model->param.coef0; out_id++; // nr_class rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL); ptr = mxGetPr(rhs[out_id]); ptr[0] = model->nr_class; out_id++; // total SV rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL); ptr = mxGetPr(rhs[out_id]); ptr[0] = model->l; out_id++; // rho n = model->nr_class*(model->nr_class-1)/2; rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL); ptr = mxGetPr(rhs[out_id]); for(i = 0; i < n; i++) ptr[i] = model->rho[i]; out_id++; // obj n = model->nr_class*(model->nr_class-1)/2; rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL); ptr = mxGetPr(rhs[out_id]); for(i = 0; i < n; i++) ptr[i] = model->obj[i]; out_id++; //radius rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL); ptr = mxGetPr(rhs[out_id]); ptr[0] = model->radius; out_id++; // Label if(model->label) { rhs[out_id] = mxCreateDoubleMatrix(model->nr_class, 1, mxREAL); ptr = mxGetPr(rhs[out_id]); for(i = 0; i < model->nr_class; i++) ptr[i] = model->label[i]; } else rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL); out_id++; // probA if(model->probA != NULL) { rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL); ptr = mxGetPr(rhs[out_id]); for(i = 0; i < n; i++) ptr[i] = model->probA[i]; } else rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL); out_id ++; // probB if(model->probB != NULL) { rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL); ptr = mxGetPr(rhs[out_id]); for(i = 0; i < n; i++) ptr[i] = model->probB[i]; } else rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL); out_id++; // nSV if(model->nSV) { rhs[out_id] = mxCreateDoubleMatrix(model->nr_class, 1, mxREAL); ptr = mxGetPr(rhs[out_id]); for(i = 0; i < model->nr_class; i++) ptr[i] = model->nSV[i]; } else rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL); out_id++; // sv_coef rhs[out_id] = mxCreateDoubleMatrix(model->l, model->nr_class-1, mxREAL); ptr = mxGetPr(rhs[out_id]); for(i = 0; i < model->nr_class-1; i++) for(j = 0; j < model->l; j++) ptr[(i*(model->l))+j] = model->sv_coef[i][j]; out_id++; // SVs { int ir_index, nonzero_element; mwIndex *ir, *jc; mxArray *pprhs[1], *pplhs[1]; if(model->param.kernel_type == PRECOMPUTED) { nonzero_element = model->l; num_of_feature = 1; } else { nonzero_element = 0; for(i = 0; i < model->l; i++) { j = 0; while(model->SV[i][j].index != -1) { nonzero_element++; j++; } } } // SV in column, easier accessing rhs[out_id] = mxCreateSparse(num_of_feature, model->l, nonzero_element, mxREAL); ir = mxGetIr(rhs[out_id]); jc = mxGetJc(rhs[out_id]); ptr = mxGetPr(rhs[out_id]); jc[0] = ir_index = 0; for(i = 0;i < model->l; i++) { if(model->param.kernel_type == PRECOMPUTED) { // make a (1 x model->l) matrix ir[ir_index] = 0; ptr[ir_index] = model->SV[i][0].value; ir_index++; jc[i+1] = jc[i] + 1; } else { int x_index = 0; while (model->SV[i][x_index].index != -1) { ir[ir_index] = model->SV[i][x_index].index - 1; ptr[ir_index] = model->SV[i][x_index].value; ir_index++, x_index++; } jc[i+1] = jc[i] + x_index; } } // transpose back to SV in row pprhs[0] = rhs[out_id]; if(mexCallMATLAB(1, pplhs, 1, pprhs, "transpose")) return "cannot transpose SV matrix"; rhs[out_id] = pplhs[0]; out_id++; } /* Create a struct matrix contains NUM_OF_RETURN_FIELD fields */ return_model = mxCreateStructMatrix(1, 1, NUM_OF_RETURN_FIELD, field_names); /* Fill struct matrix with input arguments */ for(i = 0; i < NUM_OF_RETURN_FIELD; i++) mxSetField(return_model,0,field_names[i],mxDuplicateArray(rhs[i])); /* return */ plhs[0] = return_model; mxFree(rhs); return NULL; }
struct svm_model *matlab_matrix_to_model(const mxArray *matlab_struct, const char **msg) { int i, j, n, num_of_fields; double *ptr; int id = 0; struct svm_node *x_space; struct svm_model *model; mxArray **rhs; num_of_fields = mxGetNumberOfFields(matlab_struct); if(num_of_fields != NUM_OF_RETURN_FIELD) { *msg = "number of return field is not correct"; return NULL; } rhs = (mxArray **) mxMalloc(sizeof(mxArray *)*num_of_fields); for(i=0;i<num_of_fields;i++) rhs[i] = mxGetFieldByNumber(matlab_struct, 0, i); model = Malloc(struct svm_model, 1); model->rho = NULL; model->obj = NULL; model->probA = NULL; model->probB = NULL; model->label = NULL; model->nSV = NULL; model->free_sv = 1; // XXX ptr = mxGetPr(rhs[id]); model->param.svm_type = (int)ptr[0]; model->param.kernel_type = (int)ptr[1]; model->param.degree = (int)ptr[2]; model->param.gamma = ptr[3]; model->param.coef0 = ptr[4]; id++; ptr = mxGetPr(rhs[id]); model->nr_class = (int)ptr[0]; id++; ptr = mxGetPr(rhs[id]); model->l = (int)ptr[0]; id++; // rho n = model->nr_class * (model->nr_class-1)/2; model->rho = (double*) malloc(n*sizeof(double)); ptr = mxGetPr(rhs[id]); for(i=0;i<n;i++) model->rho[i] = ptr[i]; id++; // obj n = model->nr_class * (model->nr_class-1)/2; model->obj = (double*) malloc(n*sizeof(double)); ptr = mxGetPr(rhs[id]); for(i=0;i<n;i++) model->obj[i] = ptr[i]; id++; //radius ptr = mxGetPr(rhs[id]); model->radius = (double)ptr[0]; id++; // label if(mxIsEmpty(rhs[id]) == 0) { model->label = (int*) malloc(model->nr_class*sizeof(int)); ptr = mxGetPr(rhs[id]); for(i=0;i<model->nr_class;i++) model->label[i] = (int)ptr[i]; } id++; // probA if(mxIsEmpty(rhs[id]) == 0) { model->probA = (double*) malloc(n*sizeof(double)); ptr = mxGetPr(rhs[id]); for(i=0;i<n;i++) model->probA[i] = ptr[i]; } id++; // probB if(mxIsEmpty(rhs[id]) == 0) { model->probB = (double*) malloc(n*sizeof(double)); ptr = mxGetPr(rhs[id]); for(i=0;i<n;i++) model->probB[i] = ptr[i]; } id++; // nSV if(mxIsEmpty(rhs[id]) == 0) { model->nSV = (int*) malloc(model->nr_class*sizeof(int)); ptr = mxGetPr(rhs[id]); for(i=0;i<model->nr_class;i++) model->nSV[i] = (int)ptr[i]; } id++; // sv_coef ptr = mxGetPr(rhs[id]); model->sv_coef = (double**) malloc((model->nr_class-1)*sizeof(double)); for( i=0 ; i< model->nr_class -1 ; i++ ) model->sv_coef[i] = (double*) malloc((model->l)*sizeof(double)); for(i = 0; i < model->nr_class - 1; i++) for(j = 0; j < model->l; j++) model->sv_coef[i][j] = ptr[i*(model->l)+j]; id++; // SV { int sr, sc, elements; int num_samples; mwIndex *ir, *jc; mxArray *pprhs[1], *pplhs[1]; // transpose SV pprhs[0] = rhs[id]; if(mexCallMATLAB(1, pplhs, 1, pprhs, "transpose")) { svm_free_and_destroy_model(&model); *msg = "cannot transpose SV matrix"; return NULL; } rhs[id] = pplhs[0]; sr = (int)mxGetN(rhs[id]); sc = (int)mxGetM(rhs[id]); ptr = mxGetPr(rhs[id]); ir = mxGetIr(rhs[id]); jc = mxGetJc(rhs[id]); num_samples = (int)mxGetNzmax(rhs[id]); elements = num_samples + sr; model->SV = (struct svm_node **) malloc(sr * sizeof(struct svm_node *)); x_space = (struct svm_node *)malloc(elements * sizeof(struct svm_node)); // SV is in column for(i=0;i<sr;i++) { int low = (int)jc[i], high = (int)jc[i+1]; int x_index = 0; model->SV[i] = &x_space[low+i]; for(j=low;j<high;j++) { model->SV[i][x_index].index = (int)ir[j] + 1; model->SV[i][x_index].value = ptr[j]; x_index++; } model->SV[i][x_index].index = -1; } id++; } mxFree(rhs); return model; }
SparseMatrix::SparseMatrix (const mxArray* ptr, bool iscomplex, bool useconjtrans) : iscomplex(iscomplex), ia(0), ja(0), ar(0), ac(0) { double* pr = mxGetPr(ptr); double* pi = mxGetPi(ptr); // Get the height and width of the sparse matrix, the number of // nonzeros, and the values of the nonzero entries. n = mxGetM(ptr); nnz = mxGetNzmax(ptr); // Allocate memory for the nonzero entries, then initialize the // complex entries to zero. if (!iscomplex) ar = new double[nnz]; else { ac = new complex[nnz]; for (int i = 0; i < nnz; i++) { ac[i].re = 0; ac[i].im = 0; } } // Copy the values of the nonzero entries. if (!mxIsComplex(ptr)) { // Copy the real matrix entries. if (!iscomplex) copymemory<double>(pr,ar,nnz); else for (int i = 0; i < nnz; i++) ac[i].re = pr[i]; } else { if (iscomplex) { // Copy the real matrix entries. for (int i = 0; i < nnz; i++) ac[i].re = pr[i]; // Copy the complex matrix entries. Note that sometimes we take // the complex conjugate of each entry. if (useconjtrans) for (int i = 0; i < nnz; i++) ac[i].im = -pi[i]; else for (int i = 0; i < nnz; i++) ac[i].im = pi[i]; } else mexErrMsgTxt("PARDISO was initialized to handle real matrices, but \ you provided a sparse matrix with complex entries"); } // Copy the row and column indices of the nonzero entries, // converting the matrix from 0-based C++ notation to Fortran // 1-based notation. Note that in the process of doing this, we // transpose the matrix. mwIndex* jc = mxGetJc(ptr); mwIndex* ir = mxGetIr(ptr); ia = new int[n+1]; ja = new int[nnz]; for (int i = 0; i < n + 1; i++) ia[i] = (int) jc[i] + 1; for (int i = 0; i < nnz; i++) ja[i] = (int) ir[i] + 1; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *srwp, *srdp, *probs, *Z, *X, *WS, *DS, *ZIN, *XIN; double ALPHA, BETA0, BETA1, BETA2, GAMMA1, GAMMA0, GAMMA2; int *irwp, *jcwp, *irdp, *jcdp; int *z,*d,*w, *x, *xcounts0, *xcounts1, *xcounts2, *order, *wp, *dp, *sumdp, *ztot; int W,T,T2,D,NN,SEED,OUTPUT, nzmax, nzmaxwp, nzmaxdp, ntokens; int i,j,c,n,nt,wi,di, startcond; /* Check for proper number of arguments. */ if (nrhs < 13) { mexErrMsgTxt("At least 13 input arguments required"); } else if (nlhs < 4) { mexErrMsgTxt("4 output arguments required"); } startcond = 0; if (nrhs >= 14) startcond = 1; /* process the input arguments */ if (mxIsDouble( prhs[ 0 ] ) != 1) mexErrMsgTxt("WS input vector must be a double precision matrix"); if (mxIsDouble( prhs[ 1 ] ) != 1) mexErrMsgTxt("DS input vector must be a double precision matrix"); // pointer to word indices WS = mxGetPr( prhs[ 0 ] ); // pointer to document indices DS = mxGetPr( prhs[ 1 ] ); // get the number of tokens ntokens = mxGetM( prhs[ 0 ] ) * mxGetN( prhs[ 0 ] ); if (ntokens == 0) mexErrMsgTxt("WS vector is empty"); if (ntokens != ( mxGetM( prhs[ 1 ] ) * mxGetN( prhs[ 1 ] ))) mexErrMsgTxt("WS and DS vectors should have same number of entries"); T = (int) mxGetScalar(prhs[2]); if (T<=0) mexErrMsgTxt("Number of topics must be greater than zero"); NN = (int) mxGetScalar(prhs[3]); if (NN<0) mexErrMsgTxt("Number of iterations must be positive"); ALPHA = (double) mxGetScalar(prhs[4]); if (ALPHA<=0) mexErrMsgTxt("ALPHA0 must be greater than zero"); BETA0 = (double) mxGetScalar(prhs[5]); if (BETA0<=0) mexErrMsgTxt("BETA0 must be greater than zero"); BETA1 = (double) mxGetScalar(prhs[6]); if (BETA1<=0) mexErrMsgTxt("BETA1 must be greater than zero"); BETA2 = (double) mxGetScalar(prhs[7]); if (BETA2<=0) mexErrMsgTxt("BETA2 must be greater than zero"); GAMMA0 = (double) mxGetScalar(prhs[8]); if (GAMMA0<=0) mexErrMsgTxt("GAMMA0 must be greater than zero"); GAMMA1 = (double) mxGetScalar(prhs[9]); if (GAMMA1<=0) mexErrMsgTxt("GAMMA1 must be greater than zero"); GAMMA2 = (double) mxGetScalar(prhs[10]); if (GAMMA2<=0) mexErrMsgTxt("GAMMA2 must be greater than zero"); SEED = (int) mxGetScalar(prhs[11]); OUTPUT = (int) mxGetScalar(prhs[12]); if (startcond == 1) { ZIN = mxGetPr( prhs[ 13 ] ); if (ntokens != ( mxGetM( prhs[ 13 ] ) * mxGetN( prhs[ 13 ] ))) mexErrMsgTxt("WS and ZIN vectors should have same number of entries"); XIN = mxGetPr( prhs[ 14 ] ); if (ntokens != ( mxGetM( prhs[ 14 ] ) * mxGetN( prhs[ 14 ] ))) mexErrMsgTxt("WS and XIN vectors should have same number of entries"); } // seeding seedMT( 1 + SEED * 2 ); // seeding only works on uneven numbers /* allocate memory */ z = (int *) mxCalloc( ntokens , sizeof( int )); x = (int *) mxCalloc( ntokens , sizeof( int )); if (startcond == 1) { for (i=0; i<ntokens; i++) z[ i ] = (int) ZIN[ i ] - 1; for (i=0; i<ntokens; i++) x[ i ] = (int) XIN[ i ]; // 0 = normal topic assignment 1 = special document topic 2 = background distribution } d = (int *) mxCalloc( ntokens , sizeof( int )); w = (int *) mxCalloc( ntokens , sizeof( int )); order = (int *) mxCalloc( ntokens , sizeof( int )); // copy over the word and document indices into internal format for (i=0; i<ntokens; i++) { w[ i ] = (int) WS[ i ] - 1; d[ i ] = (int) DS[ i ] - 1; } n = ntokens; W = 0; D = 0; for (i=0; i<n; i++) { if (w[ i ] > W) W = w[ i ]; if (d[ i ] > D) D = d[ i ]; } W = W + 1; D = D + 1; // NOTE: the wp matrix has T+D+1 topics for T regular topics, D special word topics and 1 background distribution T2 = T + D + 1; wp = (int *) mxCalloc( T2*W , sizeof( int )); // NOTE: the last two topic probabilities are for the special word topic and background topic dp = (int *) mxCalloc( (T+2)*D , sizeof( int )); sumdp = (int *) mxCalloc( D , sizeof( int )); ztot = (int *) mxCalloc( T2 , sizeof( int )); probs = (double *) mxCalloc( T+2 , sizeof( double )); xcounts0 = (int *) mxCalloc( D , sizeof( int )); xcounts1 = (int *) mxCalloc( D , sizeof( int )); xcounts2 = (int *) mxCalloc( D , sizeof( int )); //mexPrintf( "N=%d T=%d W=%d D=%d\n" , ntokens , T , W , D ); if (OUTPUT==2) { mexPrintf( "Running SWB LDA Gibbs Sampler\n" ); if (startcond==1) mexPrintf( "Starting from previous state ZIN\n" ); mexPrintf( "Arguments:\n" ); mexPrintf( "\tNumber of words W = %d\n" , W ); mexPrintf( "\tNumber of docs D = %d\n" , D ); mexPrintf( "\tNumber of topics T = %d\n" , T ); mexPrintf( "\tNumber of iterations N = %d\n" , NN ); mexPrintf( "\tHyperparameter ALPHA = %4.4f\n" , ALPHA ); mexPrintf( "\tHyperparameter BETA0 = %4.4f\n" , BETA0 ); mexPrintf( "\tHyperparameter BETA1 = %4.4f\n" , BETA1 ); mexPrintf( "\tHyperparameter BETA2 = %4.4f\n" , BETA2 ); mexPrintf( "\tHyperparameter GAMMA0 = %4.4f\n" , GAMMA0 ); mexPrintf( "\tHyperparameter GAMMA1 = %4.4f\n" , GAMMA1 ); mexPrintf( "\tHyperparameter GAMMA2 = %4.4f\n" , GAMMA2 ); mexPrintf( "\tSeed number = %d\n" , SEED ); mexPrintf( "\tNumber of tokens = %d\n" , ntokens ); } /* run the model */ GibbsSampler( ALPHA, BETA0 , BETA1, BETA2, GAMMA0, GAMMA1, GAMMA2, W, T, D, NN, OUTPUT, n, z, x, d, w, wp, dp, sumdp, ztot, xcounts0, xcounts1, xcounts2, order, probs, startcond ); /* convert the full wp matrix into a sparse matrix */ nzmaxwp = 0; for (i=0; i<W; i++) { for (j=0; j<T2; j++) nzmaxwp += (int) ( *( wp + j + i*T2 )) > 0; } /*if (OUTPUT==2) { mexPrintf( "Constructing sparse output matrix wp\n" ); mexPrintf( "Number of nonzero entries for WP = %d\n" , nzmaxwp ); }*/ // MAKE THE WP SPARSE MATRIX plhs[0] = mxCreateSparse( W,T2,nzmaxwp,mxREAL); srwp = mxGetPr(plhs[0]); irwp = mxGetIr(plhs[0]); jcwp = mxGetJc(plhs[0]); n = 0; for (j=0; j<T2; j++) { *( jcwp + j ) = n; for (i=0; i<W; i++) { c = (int) *( wp + i*T2 + j ); if (c >0) { *( srwp + n ) = c; *( irwp + n ) = i; n++; } } } *( jcwp + T2 ) = n; // MAKE THE DP SPARSE MATRIX nzmaxdp = 0; for (i=0; i<D; i++) { for (j=0; j<(T+2); j++) nzmaxdp += (int) ( *( dp + j + i*(T+2) )) > 0; } /*if (OUTPUT==2) { mexPrintf( "Constructing sparse output matrix dp\n" ); mexPrintf( "Number of nonzero entries for DP = %d\n" , nzmaxdp ); } */ plhs[1] = mxCreateSparse( D,T+2,nzmaxdp,mxREAL); srdp = mxGetPr(plhs[1]); irdp = mxGetIr(plhs[1]); jcdp = mxGetJc(plhs[1]); n = 0; for (j=0; j<T+2; j++) { *( jcdp + j ) = n; for (i=0; i<D; i++) { c = (int) *( dp + i*(T+2) + j ); if (c >0) { *( srdp + n ) = c; *( irdp + n ) = i; n++; } } } *( jcdp + (T+2) ) = n; plhs[ 2 ] = mxCreateDoubleMatrix( 1,ntokens , mxREAL ); Z = mxGetPr( plhs[ 2 ] ); for (i=0; i<ntokens; i++) Z[ i ] = (double) z[ i ] + 1; plhs[ 3 ] = mxCreateDoubleMatrix( 1,ntokens , mxREAL ); X = mxGetPr( plhs[ 3 ] ); for (i=0; i<ntokens; i++) X[ i ] = (double) x[ i ]; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize *ir, *jc, *ir_out, *jc_out; int nnz=0, M, N, D, i, j, row, column; double *U, *V, *out, *data; mxArray *Ut, *Vt, *RHS[1], *LHS[1]; if (nrhs != 3) mexErrMsgTxt("Input error: Expected sparse mask, U, V, 1 output"); if (!mxIsSparse(prhs[0])) mexErrMsgTxt("Error: Mask must be sparse\n"); if (mxIsSparse(prhs[1]) || mxIsSparse(prhs[2])) mexErrMsgTxt("Error: sparse U or V is not implemented yet"); /* load input */ ir = mxGetIr(prhs[0]); jc = mxGetJc(prhs[0]); M = mxGetM(prhs[0]); N = mxGetN(prhs[0]); nnz = jc[N]; if (mxGetM(prhs[1]) == M && mxGetM(prhs[2]) == N) { /* transpose U and V for faster memory access */ RHS[0] = prhs[1]; mexCallMATLAB(1, LHS, 1, RHS, "transpose"); Ut = LHS[0]; RHS[0] = prhs[2]; mexCallMATLAB(1, LHS, 1, RHS, "transpose"); Vt = LHS[0]; U = mxGetData(Ut); V = mxGetData(Vt); D = mxGetN(prhs[1]); } else if (mxGetN(prhs[1])==M && mxGetN(prhs[2])==N) { D = mxGetM(prhs[1]); U = mxGetPr(prhs[1]); V = mxGetPr(prhs[2]); } else mexErrMsgTxt("Error: Matrix sizes are incorrect"); /* open output */ plhs[0] = mxCreateSparse(M, N, nnz, 0); out = mxGetPr(plhs[0]); ir_out = mxGetIr(plhs[0]); jc_out = mxGetJc(plhs[0]); column=0; jc_out[0] = jc[0]; for (i=0; i<nnz; i++) { row = ir[i]; ir_out[i] = ir[i]; while (i>=jc[column+1]) { column++; } /* printf("Nonzero at %d, %d\n", row,column); */ out[i] = 0; for (j=0; j<D; j++) { out[i] += U[D*row+j]*V[D*column+j]; } if (out[i]>1e128) out[i] = 1e128; } for (i=0; i<N; i++) { jc_out[i] = jc[i]; } jc_out[N] = nnz; }
inline void callFunction(mxArray* plhs[], const mxArray*prhs[]) { if (!mexCheckType<T>(prhs[0])) mexErrMsgTxt("type of argument 1 is not consistent"); if (mxIsSparse(prhs[0])) mexErrMsgTxt("argument 1 should be full"); if (!mexCheckType<T>(prhs[1])) mexErrMsgTxt("type of argument 2 is not consistent"); if (mxIsSparse(prhs[1])) mexErrMsgTxt("argument 2 should be full"); if (mxIsSparse(prhs[2])) mexErrMsgTxt("argument 3 should be full"); if (!mexCheckType<long>(prhs[2])) mexErrMsgTxt("type of argument 3 is not consistent"); if (!mxIsStruct(prhs[3])) mexErrMsgTxt("argument 4 should be struct"); T* prX=reinterpret_cast<T*>(mxGetPr(prhs[0])); const mwSize* dims=mxGetDimensions(prhs[0]); long n=static_cast<long>(dims[0]); long M=static_cast<long>(dims[1]); T * prD = reinterpret_cast<T*>(mxGetPr(prhs[1])); const mwSize* dimsD=mxGetDimensions(prhs[1]); long nD=static_cast<long>(dimsD[0]); if (nD != n) mexErrMsgTxt("wrong size for argument 2"); long K=static_cast<long>(dimsD[1]); const mwSize* dimsList = mxGetDimensions(prhs[2]); long Ng = static_cast<long>(dimsList[0]*dimsList[1]); long* list_groups=reinterpret_cast<long*>(mxGetPr(prhs[2])); long L= getScalarStruct<long>(prhs[3],"L"); T eps= getScalarStructDef<T>(prhs[3],"eps",0); long numThreads = getScalarStructDef<long>(prhs[3],"numThreads",-1); Matrix<T> D(prD,n,K); Matrix<T>* X = new Matrix<T>[Ng]; if (list_groups[0] != 0) mexErrMsgTxt("First group index should be zero"); for (long i = 0; i<Ng-1; ++i) { if (list_groups[i] >= M) mexErrMsgTxt("Size of groups is not consistent"); if (list_groups[i] >= list_groups[i+1]) mexErrMsgTxt("Group indices should be a strictly non-decreasing sequence"); X[i].setData(prX+list_groups[i]*n,n,list_groups[i+1]-list_groups[i]); } X[Ng-1].setData(prX+list_groups[Ng-1]*n,n,M-list_groups[Ng-1]); SpMatrix<T>* spAlpha = new SpMatrix<T>[Ng]; somp(X,D,spAlpha,Ng,L,eps,numThreads); long nzmax=0; for (long i = 0; i<Ng; ++i) { nzmax += spAlpha[i].nzmax(); } plhs[0]=mxCreateSparse(K,M,nzmax,mxREAL); double* Pr = mxGetPr(plhs[0]); mwSize* Ir = mxGetIr(plhs[0]); mwSize* Jc = mxGetJc(plhs[0]); long count=0; long countcol=0; long offset=0; for (long i = 0; i<Ng; ++i) { const T* v = spAlpha[i].v(); const long* r = spAlpha[i].r(); const long* pB = spAlpha[i].pB(); long nn = spAlpha[i].n(); nzmax = spAlpha[i].nzmax(); if (nn != 0) { for (long j = 0; j<pB[nn]; ++j) { Pr[count]=static_cast<double>(v[j]); Ir[count++]=static_cast<mwSize>(r[j]); } for (long j = 0; j<=nn; ++j) Jc[countcol++]=static_cast<mwSize>(offset+pB[j]); --countcol; offset = Jc[countcol]; } } delete[](X); delete[](spAlpha); }
/** * @brief Y = predict_fastnb(model, X) performs predictions using a multinomial Naive Bayes classifier * @param model A model generated using train_fastnb * @param X MxN Matrix of observations, where columns are observations (ie. X is transposed!) * @return Y NxK Matrix of log probabilities, where K is the number of labels in the model * @note This method is about 100x faster than Matlab's NaiveBayes.predict * @see train_fastnb */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { // check inputs if(nrhs != 2) { mexErrMsgIdAndTxt("predict_fastnb:invalidNumInputs", "Two inputs required."); } else if (nlhs != 1) { mexErrMsgIdAndTxt("predict_fastnb:invalidNumOutputs", "One output required."); } else if(!mxIsStruct(prhs[0])) { mexErrMsgIdAndTxt("predict_fastnb:inputNotStruct", "First input must be struct."); } else if (!mxIsDouble(prhs[1]) || !mxIsSparse(prhs[1])) { mexErrMsgIdAndTxt("predict_fastnb:inputNotSparse", "Second input must be sparse double!"); } const mxArray * model = prhs[0]; const mxArray * X = prhs[1]; // this input should be transposed! const mxArray * featureProbs = mxGetField(model, 0, "feature_prob"); const mxArray * classProbs = mxGetField(model, 0, "class_prob"); const mxArray * classes = mxGetField(model, 0, "classes"); if (!featureProbs || !classProbs || !classes) { mexErrMsgIdAndTxt("predict_fast_nb:missingField", "One or more fields is missing from the model!"); } // TODO: Check data types and sizes here! float * wp = static_cast<float*>( mxGetData(featureProbs) ); float * cp = static_cast<float*>( mxGetData(classProbs) ); const mwSize M = mxGetM(X); const mwSize N = mxGetN(X); // check dimensions if (M == 0 || N == 0) { mexErrMsgIdAndTxt("predict_fastnb:invalidInputDimensions", "X must have non-zero dimensions"); } if (mxGetN(featureProbs) != M) { mexErrMsgIdAndTxt("predict_fastnb:invalidInputDimensions", "X does not have the same number of features as the model. Did you remember to transpose X?"); } // feature space data const mwIndex * xIR = mxGetIr(X); const mwIndex * xJC = mxGetJc(X); const double * xVals = mxGetPr(X); // label data const mwSize K = mxGetN(classes); // output is N x K, with probabilities of each class mxArray * yProbs = mxCreateNumericMatrix(N,K, mxDOUBLE_CLASS, mxREAL); mxSetM(yProbs, N); mxSetN(yProbs, K); double * yp = static_cast<double *>( mxMalloc(N * K * sizeof(double)) ); mxSetData(yProbs, yp); // iterate over observations, which are in columns now for (mwIndex n=0; n < N; n++) { mwIndex rowStart = xJC[n]; mwIndex rowEnd = xJC[n+1]; if (rowStart == rowEnd) { // observation with no features - predict class probabilies for (mwIndex k=0; k < K; k++) { yp[k*N + n] = static_cast<double>(cp[k]); } continue; } rowEnd--; std::vector<double> log_prob_n_given_k(K, 0.0); // log probability of seeing observation n, given class k std::vector<double> log_prob_n_and_k(K, 0.0); // iterate over features, which are in rows now for (mwIndex i=rowStart; i <= rowEnd; i++) { const mwIndex m = xIR[i]; // m is index of feature const double word_count = xVals[i]; // number of times word appears // get probability of word for each class for (mwIndex k=0; k < K; k++) { double log_p_word = static_cast<double>(wp[m*K + k]); // P(word) log_p_word *= word_count; // P(word)^count log_prob_n_given_k[k] += log_p_word; // P(word1)^count1 * P(word2)^count2 * ... } } // calculate probability of observation itself using handy formula for (mwIndex k=0; k < K; k++) { log_prob_n_and_k[k] = cp[k] + log_prob_n_given_k[k]; // log(P(c) * P(n|c)) } double sum=0.0f; for (mwIndex k=1; k < K; k++) { sum += exp(log_prob_n_and_k[k] - log_prob_n_and_k[0]); } sum = log_prob_n_and_k[0] + log(1.0f + sum); // calculate class probabilities for (mwIndex k=0; k < K; k++) { yp[k*N + n] = exp( static_cast<double>( cp[k] ) + log_prob_n_given_k[k] - sum ); } } // done plhs[0] = yProbs; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize sizeWm,sizeWn; mxArray * v; mwSize nzmax; mwIndex *ir, *jc, *irs, *jcs; double *weights,*sr; double * p; mwIndex currentEntryIndex,currentColumnIndex,numColumnEntries; mwIndex i; // Test number of parameters. if (nrhs != 2 || nlhs != 1) { mexWarnMsgTxt("Usage: K = computePower(W,p)"); return; } // Parse parameters if (!mxIsSparse(prhs[0])) { mexWarnMsgTxt("Error: Expects sparse matrix W."); return; } sizeWm=mxGetM(prhs[0]); sizeWn=mxGetN(prhs[0]); nzmax = mxGetNzmax(prhs[0]); // number of nonzero elements of sparse matrix ir = mxGetIr(prhs[0]); jc = mxGetJc(prhs[0]); weights = mxGetPr(prhs[0]); p = mxGetPr(prhs[1]); // Allocate memory for output (sparse real matrix) v = mxCreateSparse(sizeWm, sizeWn, nzmax, mxREAL); sr = mxGetPr(v); irs = mxGetIr(v); jcs = mxGetJc(v); currentEntryIndex=0; currentColumnIndex=0; numColumnEntries=0; jcs[0]=0; #pragma omp parallel for schedule(static) for (i=0;i<nzmax;i++) { if (i<sizeWn+1) jcs[i]=jc[i]; irs[i]=ir[i]; sr[i]=pow(fabs(weights[i]),*p); } // if we have less than sizeWn entries if (nzmax < sizeWn+1) { for (i=nzmax;i<sizeWn+1;i++) jcs[i]=jc[i]; } plhs[0]=v; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *mu, *MUIN, *phi, *theta, *sr; double ALPHA, BETA; mwIndex *ir, *jc; int W, J, D, NN, SEED, OUTPUT, nzmax, i, j, wi, di, startcond; /* Check for proper number of arguments. */ if (nrhs < 7) { mexErrMsgTxt("At least 7 input arguments required"); } else if (nlhs < 2) { mexErrMsgTxt("At least 2 output arguments required"); } startcond = 0; if (nrhs == 8) startcond = 1; /* dealing with sparse array WD */ if (mxIsDouble(prhs[0]) != 1) mexErrMsgTxt("WD must be a double precision matrix"); sr = mxGetPr(prhs[0]); ir = mxGetIr(prhs[0]); jc = mxGetJc(prhs[0]); nzmax = (int) mxGetNzmax(prhs[0]); W = (int) mxGetM(prhs[0]); D = (int) mxGetN(prhs[0]); J = (int) mxGetScalar(prhs[1]); if (J<=0) mexErrMsgTxt("Number of topics must be greater than zero"); NN = (int) mxGetScalar(prhs[2]); if (NN<0) mexErrMsgTxt("Number of iterations must be positive"); ALPHA = (double) mxGetScalar(prhs[3]); if (ALPHA<0) mexErrMsgTxt("ALPHA must be greater than zero"); BETA = (double) mxGetScalar(prhs[4]); if (BETA<0) mexErrMsgTxt("BETA must be greater than zero"); SEED = (int) mxGetScalar(prhs[5]); OUTPUT = (int) mxGetScalar(prhs[6]); if (startcond == 1) { MUIN = mxGetPr(prhs[7]); if (nzmax != (mxGetN(prhs[7]))) mexErrMsgTxt("WD and MUIN mismatch"); if (J != (mxGetM(prhs[7]))) mexErrMsgTxt("J and MUIN mismatch"); } /* seeding */ seedMT(1 + SEED*2); // seeding only works on uneven numbers /* allocate memory */ mu = dvec(J*nzmax); if (startcond == 1) { for (i=0; i<J*nzmax; i++) mu[i] = (double) MUIN[i]; } phi = dvec(J*W); theta = dvec(J*D); /* run the learning algorithm */ asiBP(ALPHA, BETA, W, J, D, NN, OUTPUT, sr, ir, jc, phi, theta, mu, startcond); /* output */ plhs[0] = mxCreateDoubleMatrix(J, W, mxREAL); mxSetPr(plhs[0], phi); plhs[1] = mxCreateDoubleMatrix(J, D, mxREAL ); mxSetPr(plhs[1], theta); plhs[2] = mxCreateDoubleMatrix(J, nzmax, mxREAL ); mxSetPr(plhs[2], mu); }
int read_problem_sparse(const mxArray *label_vec, const mxArray *instance_mat) { mwIndex *ir, *jc, low, high, k; // using size_t due to the output type of matlab functions size_t i, j, l, elements, max_index, label_vector_row_num; mwSize num_samples; double *samples, *labels; mxArray *instance_mat_col; // instance sparse matrix in column format prob.x = NULL; prob.y = NULL; x_space = NULL; if(col_format_flag) instance_mat_col = (mxArray *)instance_mat; else { // transpose instance matrix mxArray *prhs[1], *plhs[1]; prhs[0] = mxDuplicateArray(instance_mat); if(mexCallMATLAB(1, plhs, 1, prhs, "transpose")) { mexPrintf("Error: cannot transpose training instance matrix\n"); return -1; } instance_mat_col = plhs[0]; mxDestroyArray(prhs[0]); } // the number of instance l = mxGetN(instance_mat_col); label_vector_row_num = mxGetM(label_vec); prob.l = (int) l; if(label_vector_row_num!=l) { mexPrintf("Length of label vector does not match # of instances.\n"); return -1; } // each column is one instance labels = mxGetPr(label_vec); samples = mxGetPr(instance_mat_col); ir = mxGetIr(instance_mat_col); jc = mxGetJc(instance_mat_col); num_samples = mxGetNzmax(instance_mat_col); elements = num_samples + l*2; max_index = mxGetM(instance_mat_col); prob.y = Malloc(double, l); prob.x = Malloc(struct feature_node*, l); x_space = Malloc(struct feature_node, elements); prob.bias=bias; j = 0; for(i=0;i<l;i++) { prob.x[i] = &x_space[j]; prob.y[i] = labels[i]; low = jc[i], high = jc[i+1]; for(k=low;k<high;k++) { x_space[j].index = (int) ir[k]+1; x_space[j].value = samples[k]; j++; } if(prob.bias>=0) { x_space[j].index = (int) max_index+1; x_space[j].value = prob.bias; j++; } x_space[j++].index = -1; } if(prob.bias>=0) prob.n = (int) max_index+1; else prob.n = (int) max_index; return 0; }
// read in a problem (in svmlight format) void read_problem(const char *filename, mxArray *plhs[]) { int max_index, min_index, inst_max_index, i; long elements, k; FILE *fp = fopen(filename,"r"); int l = 0; char *endptr; mwIndex *ir, *jc; double *labels, *samples; if(fp == NULL) { mexPrintf("can't open input file %s\n",filename); fake_answer(plhs); return; } max_line_len = 1024; line = (char *) malloc(max_line_len*sizeof(char)); max_index = 0; min_index = 1; // our index starts from 1 elements = 0; while(readline(fp) != NULL) { char *idx, *val; // features int index = 0; inst_max_index = -1; // strtol gives 0 if wrong format, and precomputed kernel has <index> start from 0 strtok(line," \t"); // label while (1) { idx = strtok(NULL,":"); // index:value val = strtok(NULL," \t"); if(val == NULL) break; errno = 0; index = (int) strtol(idx,&endptr,10); if(endptr == idx || errno != 0 || *endptr != '\0' || index <= inst_max_index) { mexPrintf("Wrong input format at line %d\n",l+1); fake_answer(plhs); return; } else inst_max_index = index; min_index = min(min_index, index); elements++; } max_index = max(max_index, inst_max_index); l++; } rewind(fp); // y plhs[0] = mxCreateDoubleMatrix(l, 1, mxREAL); // x^T if (min_index <= 0) plhs[1] = mxCreateSparse(max_index-min_index+1, l, elements, mxREAL); else plhs[1] = mxCreateSparse(max_index, l, elements, mxREAL); labels = mxGetPr(plhs[0]); samples = mxGetPr(plhs[1]); ir = mxGetIr(plhs[1]); jc = mxGetJc(plhs[1]); k=0; for(i=0;i<l;i++) { char *idx, *val, *label; jc[i] = k; readline(fp); label = strtok(line," \t"); labels[i] = (int)strtol(label,&endptr,10); if(endptr == label) { mexPrintf("Wrong input format at line %d\n",i+1); fake_answer(plhs); return; } // features while(1) { idx = strtok(NULL,":"); val = strtok(NULL," \t"); if(val == NULL) break; ir[k] = (mwIndex) (strtol(idx,&endptr,10) - min_index); // precomputed kernel has <index> start from 0 errno = 0; samples[k] = strtod(val,&endptr); if (endptr == val || errno != 0 || (*endptr != '\0' && !isspace(*endptr))) { mexPrintf("Wrong input format at line %d\n",i+1); fake_answer(plhs); return; } ++k; } } jc[l] = k; fclose(fp); free(line); { mxArray *rhs[1], *lhs[1]; rhs[0] = plhs[1]; if(mexCallMATLAB(1, lhs, 1, rhs, "transpose")) { mexPrintf("Error: cannot transpose problem\n"); fake_answer(plhs); return; } plhs[1] = lhs[0]; } }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { mxArray *rhs[2]; mxArray *blk_cell_pr, *A_cell_pr; double *A, *B, *blksize; int *irA, *jcA, *irB, *jcB; int *cumblksize, *blknnz; int iscellA, mblk, mA, nA, m1, n1, rowidx, colidx, isspA, isspB; int subs[2]; int nsubs=2; int n, n2, k, nsub, index, numblk, NZmax; double ir2=1/sqrt(2); /* CHECK FOR PROPER NUMBER OF ARGUMENTS */ if (nrhs < 2){ mexErrMsgTxt("mexsmat: requires at least 2 input arguments."); } else if (nlhs>1){ mexErrMsgTxt("mexsmat: requires 1 output argument."); } /* CHECK THE DIMENSIONS */ iscellA = mxIsCell(prhs[1]); if (iscellA) { mA = mxGetM(prhs[1]); nA = mxGetN(prhs[1]); } else { mA = 1; nA = 1; } if (mxGetM(prhs[0]) != mA) { mexErrMsgTxt("mexsmat: blk and Avec not compatible"); } /***** main body *****/ if (nrhs > 3) {rowidx = (int)*mxGetPr(prhs[3]); } else {rowidx = 1;} if (rowidx > mA) { mexErrMsgTxt("mexsmat: rowidx exceeds size(Avec,1)."); } subs[0] = rowidx-1; /* subtract 1 to adjust for Matlab index */ subs[1] = 1; index = mxCalcSingleSubscript(prhs[0],nsubs,subs); blk_cell_pr = mxGetCell(prhs[0],index); if (blk_cell_pr == NULL) { mexErrMsgTxt("mexsmat: blk not properly specified"); } numblk = mxGetN(blk_cell_pr); blksize = mxGetPr(blk_cell_pr); cumblksize = mxCalloc(numblk+1,sizeof(int)); blknnz = mxCalloc(numblk+1,sizeof(int)); cumblksize[0] = 0; blknnz[0] = 0; n = 0; n2 = 0; for (k=0; k<numblk; ++k) { nsub = (int) blksize[k]; n += nsub; n2 += nsub*(nsub+1)/2; cumblksize[k+1] = n; blknnz[k+1] = n2; } /***** assign pointers *****/ if (iscellA) { subs[0] = rowidx-1; subs[1] = 0; index = mxCalcSingleSubscript(prhs[1],nsubs,subs); A_cell_pr = mxGetCell(prhs[1],index); A = mxGetPr(A_cell_pr); m1 = mxGetM(A_cell_pr); n1 = mxGetN(A_cell_pr); isspA = mxIsSparse(A_cell_pr); if (isspA) { irA = mxGetIr(A_cell_pr); jcA = mxGetJc(A_cell_pr); } } else { A = mxGetPr(prhs[1]); m1 = mxGetM(prhs[1]); n1 = mxGetN(prhs[1]); isspA = mxIsSparse(prhs[1]); if (isspA) { irA = mxGetIr(prhs[1]); jcA = mxGetJc(prhs[1]); } } if (numblk > 1) { isspB = 1; } else { if (nrhs > 2) {isspB = (int)*mxGetPr(prhs[2]);} else {isspB = isspA;} } if (nrhs > 4) {colidx = (int)*mxGetPr(prhs[4]) -1;} else {colidx = 0;} if (colidx > n1) { mexErrMsgTxt("mexsmat: colidx exceeds size(Avec,2)."); } /***** create return argument *****/ if (isspB) { if (isspA) { NZmax = jcA[colidx+1]-jcA[colidx]; } else { NZmax = blknnz[numblk]; } rhs[0] = mxCreateSparse(n,n,2*NZmax,mxREAL); B = mxGetPr(rhs[0]); irB = mxGetIr(rhs[0]); jcB = mxGetJc(rhs[0]); } else { plhs[0] = mxCreateDoubleMatrix(n,n,mxREAL); B = mxGetPr(plhs[0]); } /***** Do the computations in a subroutine *****/ if (numblk == 1) { smat1(n,ir2,A,irA,jcA,isspA,m1,colidx,B,irB,jcB,isspB); } else { smat2(n,numblk,cumblksize,blknnz,ir2,A,irA,jcA,isspA,m1,colidx,B,irB,jcB,isspB); } if (isspB) { /*** if isspB, (actual B) = B+B' ****/ mexCallMATLAB(1, &rhs[1], 1, &rhs[0], "transpose"); mexCallMATLAB(1, &plhs[0],2, rhs, "+"); mxDestroyArray(*rhs); } mxFree(blknnz); mxFree(cumblksize); return; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if(strcmp(glp_version(),"4.36")<0){ mexErrMsgTxt("This MEX interface is compatible only with GLPK version 4.36 or higher."); } if (nrhs != 9){ mexPrintf("MEX interface to GLPK Version %s\n",glp_version()); mexPrintf("Internal interface for the GNU GLPK library.\n"); mexPrintf("You should use the 'glpk' function instead.\n\n"); mexPrintf("SYNTAX: [xopt, fmin, status, extra] = glpk(c, a, b, lb, ub, ctype, vartype, sense, param)\n"); return; } //-- 1nd Input. A column array containing the objective function //-- coefficients. int mrowsc = mxGetM(C_IN); double *c=mxGetPr(C_IN); if (c == NULL) mexErrMsgTxt("glpk: invalid value of C"); //-- 2nd Input. A matrix containing the constraints coefficients. // If matrix A is NOT a sparse matrix double *A = mxGetPr(A_IN); // get the matrix if(A==NULL) mexErrMsgTxt("glpk: invalid value of A"); int mrowsA = mxGetM(A_IN); int *rn; int *cn; double *a; int nz = 0; if(!mxIsSparse(A_IN)){ rn=(int *)mxCalloc(mrowsA*mrowsc+1,sizeof(int)); cn=(int *)mxCalloc(mrowsA*mrowsc+1,sizeof(int)); a=(double *)mxCalloc(mrowsA*mrowsc+1,sizeof(double)); for (int i = 0; i < mrowsA; i++){ for (int j = 0; j < mrowsc; j++){ if (A[i+j*mrowsA] != 0){ nz++; rn[nz] = i + 1; cn[nz] = j + 1; a[nz] = A[i+j*mrowsA]; } } } }else{ /* NOTE: nnz is the actual number of nonzeros and is stored as the last element of the jc array where the size of the jc array is the number of columns + 1 */ nz = *(mxGetJc(A_IN) + mrowsc); mwIndex *jc = mxGetJc(A_IN); mwIndex *ir = mxGetIr(A_IN); double *pr = mxGetPr(A_IN); rn=(int *)mxCalloc(nz+1,sizeof(int)); cn=(int *)mxCalloc(nz+1,sizeof(int)); a=(double *)mxCalloc(nz+1,sizeof(double)); int nelc,count,row; count=0; row=0; for(int i=1;i<=mrowsc;i++){ nelc=jc[i]-jc[i-1]; for(int j=0;j<nelc;j++){ count++; rn[count]=ir[row]+1; cn[count]=i; a[count]=pr[row]; row++; } } } //-- 3rd Input. A column array containing the right-hand side value // for each constraint in the constraint matrix. double *b = mxGetPr(B_IN); if (b==NULL) mexErrMsgTxt("glpk: invalid value of b"); //-- 4th Input. An array of length mrowsc containing the lower //-- bound on each of the variables. double *lb = mxGetPr(LB_IN); if (lb==NULL) mexErrMsgTxt("glpk: invalid value of lb"); //-- LB argument, default: Free int *freeLB=(int *)mxCalloc(mrowsc,sizeof(int)); for (int i = 0; i < mrowsc; i++) { if (lb[i]==-mxGetInf()){ freeLB[i] = 1; }else freeLB[i] = 0; } //-- 5th Input. An array of at least length numcols containing the upper //-- bound on each of the variables. double *ub = mxGetPr(UB_IN); if (ub==NULL) mexErrMsgTxt("glpk: invalid value of ub"); int *freeUB=(int *)mxCalloc(mrowsc,sizeof(int)); for (int i = 0; i < mrowsc; i++) { if (ub[i]==mxGetInf()) { freeUB[i] = 1; }else freeUB[i] = 0; } //-- 6th Input. A column array containing the sense of each constraint //-- in the constraint matrix. int size = mxGetNumberOfElements(CTYPE_IN) + 1; if (size==0) mexErrMsgTxt("glpk: invalid value of ctype"); /* Allocate enough memory to hold the converted string. */ char *ctype =(char *)mxCalloc(size, sizeof (char)); /* Copy the string data from string_array_ptr and place it into buf. */ if (mxGetString(CTYPE_IN, ctype, size) != 0) mexErrMsgTxt("Could not convert string data."); //-- 7th Input. A column array containing the types of the variables. size = mxGetNumberOfElements(VARTYPE_IN)+1; char *vtype = (char *)mxCalloc(size, sizeof (char)); int *vartype = (int *)mxCalloc(size, sizeof (int)); if (size==0) mexErrMsgTxt("glpk: invalid value of vartype"); // Copy the string data from string_array_ptr and place it into buf. if (mxGetString(VARTYPE_IN, vtype, size) != 0) mexErrMsgTxt("Could not convert string data."); int isMIP = 0; for (int i = 0; i < mrowsc ; i++) { switch (vtype[i]){ case 'I': vartype[i] = GLP_IV; isMIP = 1; break; case 'B': vartype[i] = GLP_BV; isMIP = 1; break; default: vartype[i] = GLP_CV; } } //-- 8th Input. Sense of optimization. int sense; double *tmp = mxGetPr(SENSE_IN); if (*tmp >= 0) sense = 1; else sense = -1; //-- 9th Input. A structure containing the control parameters. //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //-- Integer parameters //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //-- Level of messages output by the solver GLPK_GET_INT_PARAM (PARAM, "msglev", glpIntParam[0]); if (glpIntParam[0] < 0 || glpIntParam[0] > 3) { mexErrMsgTxt("glpk: param.msglev must be 0 (no output [default]) or 1 (error messages only) or 2 (normal output) or 3 (full output)"); } //-- scaling option GLPK_GET_INT_PARAM (PARAM, "scale", glpIntParam[1]); if (glpIntParam[1] < 0 || glpIntParam[1] > 4) { mexErrMsgTxt("glpk: param.scale must be 0 (no scaling) or 1 (equilibration scaling [default]) or 2 (geometric mean scaling) or 3 (geometric then equilibration scaling) or 4 (rounds scale factors to nearest power of 2)"); } //-- Dual dimplex option GLPK_GET_INT_PARAM (PARAM, "dual", glpIntParam[2]); if (glpIntParam[2] < 0 || glpIntParam[2] > 2) { mexErrMsgTxt("glpk: param.dual must be 0 (do NOT use dual simplex [default]) or 1 (use dual simplex) or 2 (two phase dual simplex, switch to primal simplexi if it fails"); } //-- Pricing option GLPK_GET_INT_PARAM (PARAM, "price", glpIntParam[3]); if (glpIntParam[3] < 0 || glpIntParam[3] > 1) { mexErrMsgTxt("glpk: param.price must be 0 (textbook pricing) or 1 (steepest edge pricing [default])"); } //-- Ratio test option GLPK_GET_INT_PARAM (PARAM, "r_test", glpIntParam[20]); if (glpIntParam[20] < 0 || glpIntParam[20] > 1) { mexErrMsgTxt("glpk: param.r_test must be 0 (textbook) or 1 (Harris's Two pass ratio test)"); } //-- Solution rounding option GLPK_GET_INT_PARAM (PARAM, "round", glpIntParam[4]); if (glpIntParam[4] < 0 || glpIntParam[4] > 1) { mexErrMsgTxt("glpk: param.round must be 0 (report all primal and dual values [default]) or 1 (replace tiny primal and dual values by exact zero)"); } //-- Simplex iterations limit GLPK_GET_INT_PARAM (PARAM, "itlim", glpIntParam[5]); //-- Simplex iterations count GLPK_GET_INT_PARAM (PARAM, "itcnt", glpIntParam[6]); //-- Output frequency, in iterations GLPK_GET_INT_PARAM (PARAM, "outfrq", glpIntParam[7]); //-- Branching heuristic option GLPK_GET_INT_PARAM (PARAM, "branch", glpIntParam[14]); if (glpIntParam[14] < 0 || glpIntParam[14] > 3) { mexErrMsgTxt("glpk: param.branch must be (MIP only) 0 (branch on first variable) or 1 (branch on last variable) or 2 (most fractional variable) or 3 (branch using a heuristic by Driebeck and Tomlin [default]"); } //-- Backtracking heuristic option GLPK_GET_INT_PARAM (PARAM, "btrack", glpIntParam[15]); if (glpIntParam[15] < 0 || glpIntParam[15] > 3) { mexErrMsgTxt("glpk: param.btrack must be (MIP only) 0 (depth first search) or 1 (breadth first search) or 2 ( best local bound ) or 3 (backtrack using the best projection heuristic [default]"); } //-- Presolver option GLPK_GET_INT_PARAM (PARAM, "presol", glpIntParam[16]); if (glpIntParam[16] < 0 || glpIntParam[16] > 1) { mexErrMsgTxt("glpk: param.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])"); } //-- Generating cuts GLPK_GET_INT_PARAM (PARAM, "usecuts", glpIntParam[17]); if (glpIntParam[17] < 0 || glpIntParam[17] > 5) { mexErrMsgTxt("glpk: param.usecuts must be 0 (do NOT generate cuts), 1 (generate Gomory's cuts [default]), 2 (mir), 3 (cov) or 4 (clq cuts), 5( all cuts)"); } //-- PrePocessing GLPK_GET_INT_PARAM (PARAM, "pprocess", glpIntParam[18]); if (glpIntParam[18] < 0 || glpIntParam[18] > 2) { mexErrMsgTxt("glpk: param.pprocess must be 0 (disable preprocessing), 1 (preprocess root only) or 2 (preprocess all levels)"); } //-- Binarize GLPK_GET_INT_PARAM (PARAM, "binarize", glpIntParam[19]); if (glpIntParam[19] < 0 || glpIntParam[19] > 1) { mexErrMsgTxt("glpk: param.binarize must be 0 (do use binarization) or 1 (replace general integer variable by binary ones)"); } //-- LPsolver option int lpsolver = 1; GLPK_GET_INT_PARAM (PARAM, "lpsolver", lpsolver); if (lpsolver < 1 || lpsolver > 3) { mexErrMsgTxt("glpk: param.lpsolver must be 1 (simplex method) or 2 (interior point method) or 3 (LP in exact arithmetic)"); } //-- Save option int save_pb = 0; char *save_filename = NULL; char *filetype = NULL; GLPK_GET_INT_PARAM (PARAM, "save", save_pb); save_pb = (save_pb != 0); if (save_pb){ // -- Look for the name -- mxArray *mxtmp=mxGetField(PARAM,0,"savefilename"); if ( mxtmp != NULL ){ int nl=mxGetNumberOfElements(mxtmp)+1; nl=nl+4; // increase size to consider then extension .xxx save_filename=(char *)mxCalloc(nl,sizeof(char)); if (mxGetString(mxtmp, save_filename, nl) != 0) mexErrMsgTxt("glpk: Could not load file name to save."); }else{ // Default file name save_filename= (char *)mxCalloc(9, sizeof(char)); strcpy(save_filename,"outpb"); } // -- Look for the type -- char save_filetype[5]; mxArray *txtmp=mxGetField(PARAM,0,"savefiletype"); if ( txtmp != NULL ){ int nl=mxGetNumberOfElements(txtmp)+1; filetype=(char *)mxCalloc(nl,sizeof(char)); if (mxGetString(txtmp, filetype, nl) != 0) mexErrMsgTxt("glpk: Could not load file type."); if (!strcmp(filetype,"fixedmps") || !strcmp(filetype,"freemps")){ strcpy(save_filetype,".mps"); } else { if (!strcmp(filetype,"cplex")) strcpy(save_filetype,".lp"); else { if (!strcmp(filetype,"plain")) strcpy(save_filetype,".txt"); } } }else{ filetype= (char *)mxCalloc(5, sizeof(char)); strcpy(filetype,"cplex"); strcpy(save_filetype,".lp"); // Default file type } strcat(save_filename,save_filetype); // name.extension } // MPS parameters //-- mpsinfo GLPK_GET_INT_PARAM (PARAM, "mpsinfo", glpIntParam[8]); //-- mpsobj GLPK_GET_INT_PARAM (PARAM, "mpsobj", glpIntParam[9]); if (glpIntParam[9] < 0 || glpIntParam[9] > 2) { mexErrMsgTxt("glpk: param.mpsobj must be 0 (never output objective function row) or 1 (always output objective function row ) or 2 [default](output objective function row if the problem has no free rows)"); } //-- mpsorig GLPK_GET_INT_PARAM (PARAM, "mpsorig", glpIntParam[10]); //-- mpswide GLPK_GET_INT_PARAM (PARAM, "mpswide", glpIntParam[11]); //-- mpsfree GLPK_GET_INT_PARAM (PARAM, "mpsfree", glpIntParam[12]); //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //-- Real parameters //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //-- Ratio test option GLPK_GET_REAL_PARAM (PARAM, "relax", 0); //-- Relative tolerance used to check if the current basic solution //-- is primal feasible GLPK_GET_REAL_PARAM (PARAM, "tolbnd", 1); //-- Absolute tolerance used to check if the current basic solution //-- is dual feasible GLPK_GET_REAL_PARAM (PARAM, "toldj", 2); //-- Relative tolerance used to choose eligible pivotal elements of //-- the simplex table in the ratio test GLPK_GET_REAL_PARAM (PARAM, "tolpiv", 3); GLPK_GET_REAL_PARAM (PARAM, "objll", 4); GLPK_GET_REAL_PARAM (PARAM, "objul", 5); GLPK_GET_REAL_PARAM (PARAM, "tmlim", 6); GLPK_GET_REAL_PARAM (PARAM, "outdly", 7); GLPK_GET_REAL_PARAM (PARAM, "tolint", 8); GLPK_GET_REAL_PARAM (PARAM, "tolobj", 9); GLPK_GET_REAL_PARAM (PARAM, "mipgap", 10); //-- Assign pointers to the output parameters const char **extranames=(const char **)mxCalloc(4,sizeof(*extranames)); extranames[0]="lambda"; extranames[1]="redcosts"; extranames[2]="time"; extranames[3]="memory"; XMIN_OUT = mxCreateDoubleMatrix(mrowsc, 1, mxREAL); FMIN_OUT = mxCreateDoubleMatrix(1, 1, mxREAL); STATUS_OUT = mxCreateDoubleMatrix(1, 1, mxREAL); double *xmin = mxGetPr(XMIN_OUT); double *fmin = mxGetPr(FMIN_OUT); double *status = mxGetPr(STATUS_OUT); EXTRA_OUT = mxCreateStructMatrix(1, 1, 4, extranames); mxArray *mxlambda = mxCreateDoubleMatrix(mrowsA, 1, mxREAL); mxArray *mxredcosts = mxCreateDoubleMatrix(mrowsc, 1, mxREAL); mxArray *mxtime = mxCreateDoubleMatrix(1, 1, mxREAL); mxArray *mxmem = mxCreateDoubleMatrix(1, 1, mxREAL); double *lambda = mxGetPr(mxlambda); double *redcosts= mxGetPr(mxredcosts); double *time = mxGetPr(mxtime); double *mem = mxGetPr(mxmem); int jmpret = setjmp (mark); if (jmpret == 0) glpk (sense, mrowsc, mrowsA, c, nz, rn, cn, a, b, ctype, freeLB, lb, freeUB, ub, vartype, isMIP, lpsolver, save_pb, save_filename, filetype, xmin, fmin, status, lambda, redcosts, time, mem); if (! isMIP) { mxSetField(EXTRA_OUT,0,extranames[0],mxlambda); mxSetField(EXTRA_OUT,0,extranames[1],mxredcosts); } mxSetField(EXTRA_OUT,0,extranames[2],mxtime); mxSetField(EXTRA_OUT,0,extranames[3],mxmem); mxFree(rn); mxFree(cn); mxFree(a); mxFree(freeLB); mxFree(freeUB); mxFree(ctype); mxFree(vartype); mxFree(vtype); mxFree(extranames); mxFree(save_filename); mxFree(filetype); return; }
/* the gateway routine. */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* create a pointer to the real data in the input matrix */ int nfields = mxGetNumberOfFields(prhs[0]); // number of fields in each constraint mwSize NStructElems = mxGetNumberOfElements(prhs[0]); // number of constraints const char **fnames = (const char **)mxCalloc(nfields, sizeof(*fnames)); /* pointers to field names */ double *sw = mxGetPr(prhs[1]); /* switch vector */ double *xs = mxGetPr(prhs[2]); /* linearisation point */ long unsigned int nrow = mxGetM(prhs[2]); double *ptr = mxGetPr(prhs[3]); /* number of cameras */ int ncams = ptr[0]; /* initialise a PwgOptimiser object */ PwgOptimiser *Object; // pointer initialisation Object = new PwgOptimiser (ncams, nrow-6*ncams) ; // pointer initialisation /* get constraints from Matlab to C++ and initialise a constraint */ double *pr; mxArray *tmp; int cam, kpt; std::vector<double> p1(2), z(2), R(4,0.0);//, Y(49,0.0), y(7,0.0); std::string str1 ("cam"); std::string str2 ("kpt"); std::string str3 ("p1"); std::string str4 ("z"); std::string str5 ("R"); std::string str6 ("y"); std::string str7 ("Y"); Eigen::MatrixXd yz = Eigen::MatrixXd::Zero(7,1); Eigen::VectorXd Yz = Eigen::MatrixXd::Zero(7,7); for (mwIndex jstruct = 0; jstruct < NStructElems; jstruct++) { /* loop the constraints */ for (int ifield = 0; ifield < nfields; ifield++) { /* loop the fields */ fnames[ifield] = mxGetFieldNameByNumber(prhs[0],ifield); // get field name tmp = mxGetFieldByNumber(prhs[0], jstruct, ifield); // get field pr = (double *)mxGetData(tmp); // get the field data pointer if (str1.compare(fnames[ifield]) == 0) // cam cam = pr[0]; if (str2.compare(fnames[ifield]) == 0) // kpt kpt = pr[0]; if (str3.compare(fnames[ifield]) == 0){ // p1 p1[0] = pr[0]; p1[1] = pr[1];} if (str4.compare(fnames[ifield]) == 0){ // z z[0] = pr[0]; z[1] = pr[1];} if (str5.compare(fnames[ifield]) == 0){ // R R[0] = pr[0]; R[3] = pr[3];} } // end of nfields loop Object->initialise_a_constraint(cam, kpt, p1, z, R, Yz, yz, (int)sw[jstruct]) ; // using pointer to object } // end of NStructElems loop // optimise constraints information Object->optimise_constraints_image_inverse_depth_Mviews( xs ) ; /* get output state vector */ int ncol = (Object->xhat).size(); plhs[0] = mxCreateDoubleMatrix(ncol, 1, mxREAL); double *vec_out = mxGetPr(plhs[0]); for (int i=0; i<ncol; i++) vec_out[i] = (Object->xhat).coeffRef(i); /* get output sparse covariance matrix */ ncol = (Object->Phat).outerSize(); long unsigned int nzmax = (Object->Phat).nonZeros(); plhs[1] = mxCreateSparse(ncol, ncol, nzmax, mxREAL); double *mat_out = mxGetPr(plhs[1]); long unsigned int *ir2 = mxGetIr(plhs[1]); long unsigned int *jc2 = mxGetJc(plhs[1]); int index=0; for (int k=0; k < (Object->Phat).outerSize(); ++k) { jc2[k] = index; for (Eigen::SparseMatrix<double>::InnerIterator it(Object->Phat,k); it; ++it) { ir2[index] = it.row(); mat_out[index] = it.value(); index++; } } jc2[(Object->Phat).outerSize()] = index; /* Free memory */ mxFree((void *)fnames); delete Object; // delete class pointer //mxFree(tmp); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *srwp, *srdp, *probs, *Z, *WS, *DS, *ZIN; double ALPHA,BETA; mwIndex *irwp, *jcwp, *irdp, *jcdp; int *z,*d,*w, *order, *wp, *dp, *ztot; int W,T,D,NN,SEED,OUTPUT, nzmax, nzmaxwp, nzmaxdp, ntokens; int i,j,c,n,nt,wi,di, startcond; /* Check for proper number of arguments. */ if (nrhs < 8) { mexPrintf("1"); mexErrMsgTxt("At least 8 input arguments required"); } else if (nlhs < 3) { mexPrintf("2"); mexErrMsgTxt("3 output arguments required"); } startcond = 0; if (nrhs == 9) { mexPrintf("3"); startcond = 1; } /* process the input arguments */ if (mxIsDouble( prhs[ 0 ] ) != 1) mexErrMsgTxt("WS input vector must be a double precision matrix"); if (mxIsDouble( prhs[ 1 ] ) != 1) mexErrMsgTxt("DS input vector must be a double precision matrix"); // pointer to word indices WS = mxGetPr( prhs[ 0 ] ); // pointer to document indices DS = mxGetPr( prhs[ 1 ] ); // get the number of tokens ntokens = mxGetM( prhs[ 0 ] ) * mxGetN( prhs[ 0 ] ); if (ntokens == 0){ mexPrintf("4"); mexErrMsgTxt("WS vector is empty"); } if (ntokens != ( mxGetM( prhs[ 1 ] ) * mxGetN( prhs[ 1 ] ))) mexErrMsgTxt("WS and DS vectors should have same number of entries"); T = (int) mxGetScalar(prhs[2]); if (T<=0){ mexPrintf("5"); mexErrMsgTxt("Number of topics must be greater than zero"); } NN = (int) mxGetScalar(prhs[3]); if (NN<0) mexErrMsgTxt("Number of iterations must be positive"); ALPHA = (double) mxGetScalar(prhs[4]); if (ALPHA<=0) mexErrMsgTxt("ALPHA must be greater than zero"); BETA = (double) mxGetScalar(prhs[5]); if (BETA<=0) mexErrMsgTxt("BETA must be greater than zero"); SEED = (int) mxGetScalar(prhs[6]); OUTPUT = (int) mxGetScalar(prhs[7]); mexPrintf("ok"); if (startcond == 1) { mexPrintf("6"); ZIN = mxGetPr( prhs[ 8 ] ); if (ntokens != ( mxGetM( prhs[ 8 ] ) * mxGetN( prhs[ 8 ] ))) mexErrMsgTxt("WS and ZIN vectors should have same number of entries"); } // seeding seedMT( 1 + SEED * 2 ); // seeding only works on uneven numbers /* allocate memory */ z = (int *) mxCalloc( ntokens , sizeof( int )); if (startcond == 1) { for (i=0; i<ntokens; i++) z[ i ] = (int) ZIN[ i ] - 1; } d = (int *) mxCalloc( ntokens , sizeof( int )); w = (int *) mxCalloc( ntokens , sizeof( int )); order = (int *) mxCalloc( ntokens , sizeof( int )); ztot = (int *) mxCalloc( T , sizeof( int )); probs = (double *) mxCalloc( T , sizeof( double )); // copy over the word and document indices into internal format for (i=0; i<ntokens; i++) { w[ i ] = (int) WS[ i ] - 1; d[ i ] = (int) DS[ i ] - 1; } n = ntokens; W = 0; D = 0; for (i=0; i<n; i++) { if (w[ i ] > W) W = w[ i ]; if (d[ i ] > D) D = d[ i ]; } W = W + 1; D = D + 1; wp = (int *) mxCalloc( T*W , sizeof( int )); dp = (int *) mxCalloc( T*D , sizeof( int )); //mexPrintf( "N=%d T=%d W=%d D=%d\n" , ntokens , T , W , D ); if (OUTPUT==2) { mexPrintf("7"); mexPrintf( "Running LDA Gibbs Sampler Version 1.0\n" ); if (startcond==1) mexPrintf( "Starting from previous state ZIN\n" ); mexPrintf( "Arguments:\n" ); mexPrintf( "\tNumber of words W = %d\n" , W ); mexPrintf( "\tNumber of docs D = %d\n" , D ); mexPrintf( "\tNumber of topics T = %d\n" , T ); mexPrintf( "\tNumber of iterations N = %d\n" , NN ); mexPrintf( "\tHyperparameter ALPHA = %4.4f\n" , ALPHA ); mexPrintf( "\tHyperparameter BETA = %4.4f\n" , BETA ); mexPrintf( "\tSeed number = %d\n" , SEED ); mexPrintf( "\tNumber of tokens = %d\n" , ntokens ); mexPrintf( "Internal Memory Allocation\n" ); mexPrintf( "\tw,d,z,order indices combined = %d bytes\n" , 4 * sizeof( int) * ntokens ); mexPrintf( "\twp (full) matrix = %d bytes\n" , sizeof( int ) * W * T ); mexPrintf( "\tdp (full) matrix = %d bytes\n" , sizeof( int ) * D * T ); //mexPrintf( "Checking: sizeof(int)=%d sizeof(long)=%d sizeof(double)=%d\n" , sizeof(int) , sizeof(long) , sizeof(double)); } /* run the model */ GibbsSamplerLDA( ALPHA, BETA, W, T, D, NN, OUTPUT, n, z, d, w, wp, dp, ztot, order, probs, startcond ); /* convert the full wp matrix into a sparse matrix */ nzmaxwp = 0; for (i=0; i<W; i++) { for (j=0; j<T; j++) nzmaxwp += (int) ( *( wp + j + i*T )) > 0; } /*if (OUTPUT==2) { mexPrintf( "Constructing sparse output matrix wp\n" ); mexPrintf( "Number of nonzero entries for WP = %d\n" , nzmaxwp ); }*/ // MAKE THE WP SPARSE MATRIX plhs[0] = mxCreateSparse( W,T,nzmaxwp,mxREAL); srwp = mxGetPr(plhs[0]); irwp = mxGetIr(plhs[0]); jcwp = mxGetJc(plhs[0]); n = 0; for (j=0; j<T; j++) { *( jcwp + j ) = n; for (i=0; i<W; i++) { c = (int) *( wp + i*T + j ); if (c >0) { *( srwp + n ) = c; *( irwp + n ) = i; n++; } } } *( jcwp + T ) = n; // MAKE THE DP SPARSE MATRIX nzmaxdp = 0; for (i=0; i<D; i++) { for (j=0; j<T; j++) nzmaxdp += (int) ( *( dp + j + i*T )) > 0; } /*if (OUTPUT==2) { mexPrintf( "Constructing sparse output matrix dp\n" ); mexPrintf( "Number of nonzero entries for DP = %d\n" , nzmaxdp ); } */ plhs[1] = mxCreateSparse( D,T,nzmaxdp,mxREAL); srdp = mxGetPr(plhs[1]); irdp = mxGetIr(plhs[1]); jcdp = mxGetJc(plhs[1]); n = 0; for (j=0; j<T; j++) { *( jcdp + j ) = n; for (i=0; i<D; i++) { c = (int) *( dp + i*T + j ); if (c >0) { *( srdp + n ) = c; *( irdp + n ) = i; n++; } } } *( jcdp + T ) = n; plhs[ 2 ] = mxCreateDoubleMatrix( 1,ntokens , mxREAL ); Z = mxGetPr( plhs[ 2 ] ); for (i=0; i<ntokens; i++) Z[ i ] = (double) z[ i ] + 1; }
void mexFunction ( int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin [ ] ) { double dummy = 0, *Px, *Xsetx ; Long *Lp, *Lnz, *Xp, *Xi, xnz, *Perm, *Lprev, *Lnext, *Xsetp ; cholmod_sparse *Bset, Bmatrix, *Xset ; cholmod_dense *Bdense, *X, *Y, *E ; cholmod_factor *L ; cholmod_common Common, *cm ; Long k, j, n, head, tail, xsetlen ; int sys, kind ; /* ---------------------------------------------------------------------- */ /* start CHOLMOD and set parameters */ /* ---------------------------------------------------------------------- */ cm = &Common ; cholmod_l_start (cm) ; sputil_config (SPUMONI, cm) ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ if (nargin != 5 || nargout > 2) { mexErrMsgTxt ("usage: [x xset] = lsubsolve (L,kind,P,b,system)") ; } n = mxGetN (pargin [0]) ; if (!mxIsSparse (pargin [0]) || n != mxGetM (pargin [0])) { mexErrMsgTxt ("lsubsolve: L must be sparse and square") ; } if (mxGetNumberOfElements (pargin [1]) != 1) { mexErrMsgTxt ("lsubsolve: kind must be a scalar") ; } if (mxIsSparse (pargin [2]) || !(mxIsEmpty (pargin [2]) || mxGetNumberOfElements (pargin [2]) == n)) { mexErrMsgTxt ("lsubsolve: P must be size n, or empty") ; } if (mxGetM (pargin [3]) != n || mxGetN (pargin [3]) != 1) { mexErrMsgTxt ("lsubsolve: b wrong dimension") ; } if (!mxIsSparse (pargin [3])) { mexErrMsgTxt ("lxbpattern: b must be sparse") ; } if (mxGetNumberOfElements (pargin [4]) != 1) { mexErrMsgTxt ("lsubsolve: system must be a scalar") ; } /* ---------------------------------------------------------------------- */ /* get the inputs */ /* ---------------------------------------------------------------------- */ kind = (int) sputil_get_integer (pargin [1], FALSE, 0) ; sys = (int) sputil_get_integer (pargin [4], FALSE, 0) ; /* ---------------------------------------------------------------------- */ /* get the sparse b */ /* ---------------------------------------------------------------------- */ /* get sparse matrix B (unsymmetric) */ Bset = sputil_get_sparse (pargin [3], &Bmatrix, &dummy, 0) ; Bdense = cholmod_l_sparse_to_dense (Bset, cm) ; Bset->x = NULL ; Bset->z = NULL ; Bset->xtype = CHOLMOD_PATTERN ; /* ---------------------------------------------------------------------- */ /* construct a shallow copy of the input sparse matrix L */ /* ---------------------------------------------------------------------- */ /* the construction of the CHOLMOD takes O(n) time and memory */ /* allocate the CHOLMOD symbolic L */ L = cholmod_l_allocate_factor (n, cm) ; L->ordering = CHOLMOD_NATURAL ; /* get the MATLAB L */ L->p = mxGetJc (pargin [0]) ; L->i = mxGetIr (pargin [0]) ; L->x = mxGetPr (pargin [0]) ; L->z = mxGetPi (pargin [0]) ; /* allocate and initialize the rest of L */ L->nz = cholmod_l_malloc (n, sizeof (Long), cm) ; Lp = L->p ; Lnz = L->nz ; for (j = 0 ; j < n ; j++) { Lnz [j] = Lp [j+1] - Lp [j] ; } /* these pointers are not accessed in cholmod_solve2 */ L->prev = cholmod_l_malloc (n+2, sizeof (Long), cm) ; L->next = cholmod_l_malloc (n+2, sizeof (Long), cm) ; Lprev = L->prev ; Lnext = L->next ; head = n+1 ; tail = n ; Lnext [head] = 0 ; Lprev [head] = -1 ; Lnext [tail] = -1 ; Lprev [tail] = n-1 ; for (j = 0 ; j < n ; j++) { Lnext [j] = j+1 ; Lprev [j] = j-1 ; } Lprev [0] = head ; L->xtype = (mxIsComplex (pargin [0])) ? CHOLMOD_ZOMPLEX : CHOLMOD_REAL ; L->nzmax = Lp [n] ; /* get the permutation */ if (mxIsEmpty (pargin [2])) { L->Perm = NULL ; Perm = NULL ; } else { L->ordering = CHOLMOD_GIVEN ; L->Perm = cholmod_l_malloc (n, sizeof (Long), cm) ; Perm = L->Perm ; Px = mxGetPr (pargin [2]) ; for (k = 0 ; k < n ; k++) { Perm [k] = ((Long) Px [k]) - 1 ; } } /* set the kind, LL' or LDL' */ L->is_ll = (kind == 0) ; /* cholmod_l_print_factor (L, "L", cm) ; */ /* ---------------------------------------------------------------------- */ /* solve the system */ /* ---------------------------------------------------------------------- */ X = cholmod_l_zeros (n, 1, L->xtype, cm) ; Xset = NULL ; Y = NULL ; E = NULL ; cholmod_l_solve2 (sys, L, Bdense, Bset, &X, &Xset, &Y, &E, cm) ; cholmod_l_free_dense (&Y, cm) ; cholmod_l_free_dense (&E, cm) ; /* ---------------------------------------------------------------------- */ /* return result */ /* ---------------------------------------------------------------------- */ pargout [0] = sputil_put_dense (&X, cm) ; /* fill numerical values of Xset with one's */ Xsetp = Xset->p ; xsetlen = Xsetp [1] ; Xset->x = cholmod_l_malloc (xsetlen, sizeof (double), cm) ; Xsetx = Xset->x ; for (k = 0 ; k < xsetlen ; k++) { Xsetx [k] = 1 ; } Xset->xtype = CHOLMOD_REAL ; pargout [1] = sputil_put_sparse (&Xset, cm) ; /* ---------------------------------------------------------------------- */ /* free workspace and the CHOLMOD L, except for what is copied to MATLAB */ /* ---------------------------------------------------------------------- */ L->p = NULL ; L->i = NULL ; L->x = NULL ; L->z = NULL ; cholmod_l_free_factor (&L, cm) ; cholmod_l_finish (cm) ; cholmod_l_print_common (" ", cm) ; }
void mexFunction ( /* === Parameters ======================================================= */ int nlhs, /* number of left-hand sides */ mxArray *plhs [], /* left-hand side matrices */ int nrhs, /* number of right--hand sides */ const mxArray *prhs [] /* right-hand side matrices */ ) { /* === Local variables ================================================== */ Long *perm ; /* column ordering of M and ordering of A */ Long *A ; /* row indices of input matrix A */ Long *p ; /* column pointers of input matrix A */ Long n_col ; /* number of columns of A */ Long n_row ; /* number of rows of A */ Long full ; /* TRUE if input matrix full, FALSE if sparse */ double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */ double *out_perm ; /* output permutation vector */ double *out_stats ; /* output stats vector */ double *in_knobs ; /* input knobs vector */ Long i ; /* loop counter */ mxArray *Ainput ; /* input matrix handle */ Long spumoni ; /* verbosity variable */ Long stats2 [COLAMD_STATS] ;/* stats for symamd */ Long *cp, *cp_end, result, nnz, col, length ; Long *stats ; stats = stats2 ; /* === Check inputs ===================================================== */ if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2) { mexErrMsgTxt ( "symamd: incorrect number of input and/or output arguments.") ; } if (nrhs != 2) { mexErrMsgTxt ("symamdtest: knobs are required") ; } /* for testing we require all 3 knobs */ if (mxGetNumberOfElements (prhs [1]) != 3) { mexErrMsgTxt ("symamdtest: must have all 3 knobs for testing") ; } /* === Get knobs ======================================================== */ colamd_l_set_defaults (knobs) ; spumoni = 0 ; /* check for user-passed knobs */ if (nrhs == 2) { in_knobs = mxGetPr (prhs [1]) ; i = mxGetNumberOfElements (prhs [1]) ; if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ; if (i > 1) spumoni = (Long) in_knobs [1] ; } /* print knob settings if spumoni is set */ if (spumoni) { mexPrintf ("\nsymamd version %d.%d, %s:\n", COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ; if (knobs [COLAMD_DENSE_ROW] >= 0) { mexPrintf ("knobs(1): %g, rows/cols with > " "max(16,%g*sqrt(size(A,2))) entries removed\n", in_knobs [0], knobs [COLAMD_DENSE_ROW]) ; } else { mexPrintf ("knobs(1): %g, no dense rows removed\n", in_knobs [0]) ; } mexPrintf ("knobs(2): %g, statistics and knobs printed\n", in_knobs [1]) ; mexPrintf ("Testing %d\n", in_knobs [2]) ; } /* === If A is full, convert to a sparse matrix ========================= */ Ainput = (mxArray *) prhs [0] ; if (mxGetNumberOfDimensions (Ainput) != 2) { mexErrMsgTxt ("symamd: input matrix must be 2-dimensional.") ; } full = !mxIsSparse (Ainput) ; if (full) { mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ; } /* === Allocate workspace for symamd ==================================== */ /* get size of matrix */ n_row = mxGetM (Ainput) ; n_col = mxGetN (Ainput) ; if (n_col != n_row) { mexErrMsgTxt ("symamd: matrix must be square.") ; } /* p = mxGetJc (Ainput) ; */ p = (Long *) mxCalloc (n_col+1, sizeof (Long)) ; (void) memcpy (p, mxGetJc (Ainput), (n_col+1)*sizeof (Long)) ; nnz = p [n_col] ; if (spumoni > 0) { mexPrintf ("symamdtest: nnz %d\n", nnz) ; } /* A = mxGetIr (Ainput) ; */ A = (Long *) mxCalloc (nnz+1, sizeof (Long)) ; (void) memcpy (A, mxGetIr (Ainput), nnz*sizeof (Long)) ; perm = (Long *) mxCalloc (n_col+1, sizeof (Long)) ; /* === Jumble matrix ======================================================== */ /* knobs [2] FOR TESTING ONLY: Specifies how to jumble matrix 0 : No jumbling 1 : (no errors) 2 : Make first pointer non-zero 3 : Make column pointers not non-decreasing 4 : (no errors) 5 : Make row indices not strictly increasing 6 : Make a row index greater or equal to n_row 7 : Set A = NULL 8 : Set p = NULL 9 : Repeat row index 10: make row indices not sorted 11: jumble columns massively (note this changes the pattern of the matrix A.) 12: Set stats = NULL 13: Make n_col less than zero */ /* jumble appropriately */ switch ((Long) in_knobs [2]) { case 0 : if (spumoni > 0) { mexPrintf ("symamdtest: no errors expected\n") ; } result = 1 ; /* no errors */ break ; case 1 : if (spumoni > 0) { mexPrintf ("symamdtest: no errors expected (1)\n") ; } result = 1 ; break ; case 2 : if (spumoni > 0) { mexPrintf ("symamdtest: p [0] nonzero\n") ; } result = 0 ; /* p [0] must be zero */ p [0] = 1 ; break ; case 3 : if (spumoni > 0) { mexPrintf ("symamdtest: negative length last column\n") ; } result = (n_col == 0) ; /* p must be monotonically inc. */ p [n_col] = p [0] ; break ; case 4 : if (spumoni > 0) { mexPrintf ("symamdtest: no errors expected (4)\n") ; } result = 1 ; break ; case 5 : if (spumoni > 0) { mexPrintf ("symamdtest: row index out of range (-1)\n") ; } if (nnz > 0) /* row index out of range */ { result = 0 ; A [nnz-1] = -1 ; } else { if (spumoni > 0) { mexPrintf ("Note: no row indices to put out of range\n") ; } result = 1 ; } break ; case 6 : if (spumoni > 0) { mexPrintf ("symamdtest: row index out of range (ncol)\n") ; } if (nnz > 0) /* row index out of range */ { result = 0 ; A [nnz-1] = n_col ; } else { if (spumoni > 0) { mexPrintf ("Note: no row indices to put out of range\n") ; } result = 1 ; } break ; case 7 : if (spumoni > 0) { mexPrintf ("symamdtest: A not present\n") ; } result = 0 ; /* A not present */ A = (Long *) NULL ; break ; case 8 : if (spumoni > 0) { mexPrintf ("symamdtest: p not present\n") ; } result = 0 ; /* p not present */ p = (Long *) NULL ; break ; case 9 : if (spumoni > 0) { mexPrintf ("symamdtest: duplicate row index\n") ; } result = 1 ; /* duplicate row index */ for (col = 0 ; col < n_col ; col++) { length = p [col+1] - p [col] ; if (length > 1) { A [p [col+1]-2] = A [p [col+1] - 1] ; if (spumoni > 0) { mexPrintf ("Made duplicate row %d in col %d\n", A [p [col+1] - 1], col) ; } break ; } } if (spumoni > 1) { dump_matrix (A, p, n_row, n_col, nnz, col+2) ; } break ; case 10 : if (spumoni > 0) { mexPrintf ("symamdtest: unsorted column\n") ; } result = 1 ; /* jumbled columns */ for (col = 0 ; col < n_col ; col++) { length = p [col+1] - p [col] ; if (length > 1) { i = A[p [col]] ; A [p [col]] = A[p [col] + 1] ; A [p [col] + 1] = i ; if (spumoni > 0) { mexPrintf ("Unsorted column %d \n", col) ; } break ; } } if (spumoni > 1) { dump_matrix (A, p, n_row, n_col, nnz, col+2) ; } break ; case 11 : if (spumoni > 0) { mexPrintf ("symamdtest: massive jumbling\n") ; } result = 1 ; /* massive jumbling, but no errors */ srand (1) ; for (i = 0 ; i < n_col ; i++) { cp = &A [p [i]] ; cp_end = &A [p [i+1]] ; while (cp < cp_end) { *cp++ = rand() % n_row ; } } if (spumoni > 1) { dump_matrix (A, p, n_row, n_col, nnz, n_col) ; } break ; case 12 : if (spumoni > 0) { mexPrintf ("symamdtest: stats not present\n") ; } result = 0 ; /* stats not present */ stats = (Long *) NULL ; break ; case 13 : if (spumoni > 0) { mexPrintf ("symamdtest: ncol out of range\n") ; } result = 0 ; /* ncol out of range */ n_col = -1 ; break ; } /* === Order the rows and columns of A (does not destroy A) ============= */ if (!symamd_l (n_col, A, p, perm, knobs, stats, &mxCalloc, &mxFree)) { /* return p = -1 if colamd failed */ plhs [0] = mxCreateDoubleMatrix (1, 1, mxREAL) ; out_perm = mxGetPr (plhs [0]) ; out_perm [0] = -1 ; mxFree (p) ; mxFree (A) ; if (spumoni > 0 || result) { symamd_l_report (stats) ; } if (result) { mexErrMsgTxt ("symamd should have returned TRUE\n") ; } return ; /* mexErrMsgTxt ("symamd error!") ; */ } if (!result) { symamd_l_report (stats) ; mexErrMsgTxt ("symamd should have returned FALSE\n") ; } if (full) { mxDestroyArray (Ainput) ; } /* === Return the permutation vector ==================================== */ plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ; out_perm = mxGetPr (plhs [0]) ; for (i = 0 ; i < n_col ; i++) { /* symamd is 0-based, but MATLAB expects this to be 1-based */ out_perm [i] = perm [i] + 1 ; } mxFree (perm) ; /* === Return the stats vector ========================================== */ /* print stats if spumoni > 0 */ if (spumoni > 0) { symamd_l_report (stats) ; } if (nlhs == 2) { plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ; out_stats = mxGetPr (plhs [1]) ; for (i = 0 ; i < COLAMD_STATS ; i++) { out_stats [i] = stats [i] ; } /* fix stats (5) and (6), for 1-based information on jumbled matrix. */ /* note that this correction doesn't occur if symamd returns FALSE */ out_stats [COLAMD_INFO1] ++ ; out_stats [COLAMD_INFO2] ++ ; } }
mxArray *sfmult_AN_XN_YT // y = (A*x)' ( const mxArray *A, const mxArray *X, int ac, // if true: conj(A) if false: A. ignored if A real int xc, // if true: conj(x) if false: x. ignored if x real int yc // if true: conj(y) if false: y. ignored if y real ) { mxArray *Y ; double *Ax, *Az, *Xx, *Xz, *Yx, *Yz, *Wx, *Wz ; Int *Ap, *Ai ; Int m, n, k, k1, i ; int Acomplex, Xcomplex, Ycomplex ; //-------------------------------------------------------------------------- // get inputs //-------------------------------------------------------------------------- m = mxGetM (A) ; n = mxGetN (A) ; k = mxGetN (X) ; if (n != mxGetM (X)) sfmult_invalid ( ) ; Acomplex = mxIsComplex (A) ; Xcomplex = mxIsComplex (X) ; Ap = mxGetJc (A) ; Ai = mxGetIr (A) ; Ax = mxGetPr (A) ; Az = mxGetPi (A) ; Xx = mxGetPr (X) ; Xz = mxGetPi (X) ; //-------------------------------------------------------------------------- // allocate result //-------------------------------------------------------------------------- Ycomplex = Acomplex || Xcomplex ; Y = sfmult_yalloc (k, m, Ycomplex) ; Yx = mxGetPr (Y) ; Yz = mxGetPi (Y) ; //-------------------------------------------------------------------------- // special cases //-------------------------------------------------------------------------- if (k == 0 || m == 0 || n == 0 || Ap [n] == 0) { // Y = 0 return (sfmult_yzero (Y)) ; } if (k == 1) { // Y = A*X sfmult_AN_x_1 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc) ; return (Y) ; } if (k == 2) { // Y = (A * X)' sfmult_AN_XN_YT_2 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc) ; return (Y) ; } if (k == 4) { // Y = (A * X)' sfmult_AN_XN_YT_4 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc) ; return (Y) ; } //-------------------------------------------------------------------------- // allocate workspace //-------------------------------------------------------------------------- sfmult_walloc (4, m, &Wx, &Wz) ; //-------------------------------------------------------------------------- // Y = (A*X)', in blocks of up to 4 columns of X, using sfmult_anxnyt //-------------------------------------------------------------------------- k1 = k % 4 ; if (k1 == 1) { // W = A * X(:,1) sfmult_AN_x_1 (Wx, Wz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc) ; // Y (1,:) = W for (i = 0 ; i < m ; i++) { Yx [k*i] = Wx [i] ; } Yx += 1 ; Yz += 1 ; Xx += n ; Xz += n ; } else if (k1 == 2) { // W = (A * X(:,1:2))' sfmult_AN_XN_YT_2 (Wx, Wz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc) ; // Y (1:2,:) = W for (i = 0 ; i < m ; i++) { Yx [k*i ] = Wx [2*i ] ; Yx [k*i+1] = Wx [2*i+1] ; } Yx += 2 ; Yz += 2 ; Xx += 2*n ; Xz += 2*n ; } else if (k1 == 3) { // W = (A * X(:,1:3))' sfmult_AN_XN_YT_3 (Wx, Wz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc) ; // Y (1:3,:) = W for (i = 0 ; i < m ; i++) { Yx [k*i ] = Wx [4*i ] ; Yx [k*i+1] = Wx [4*i+1] ; Yx [k*i+2] = Wx [4*i+2] ; } Yx += 3 ; Yz += 3 ; Xx += 3*n ; Xz += 3*n ; } for ( ; k1 < k ; k1 += 4) { // W = (A*X(:,1:4))' sfmult_AN_XN_YT_4 (Wx, Wz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc) ; // Y (k1+(1:4),:) = W for (i = 0 ; i < m ; i++) { Yx [k*i ] = Wx [4*i ] ; Yx [k*i+1] = Wx [4*i+1] ; Yx [k*i+2] = Wx [4*i+2] ; Yx [k*i+3] = Wx [4*i+3] ; } Yx += 4 ; Yz += 4 ; Xx += 4*n ; Xz += 4*n ; } //-------------------------------------------------------------------------- // free workspace and return result //-------------------------------------------------------------------------- mxFree (Wx) ; return (Y) ; }
mxArray *sfmult_AT_XT_YT // y = (A'*x')' ( const mxArray *A, const mxArray *X, int ac, // if true: conj(A) if false: A. ignored if A real int xc, // if true: conj(x) if false: x. ignored if x real int yc // if true: conj(y) if false: y. ignored if y real ) { mxArray *Y ; double *Ax, *Az, *Xx, *Xz, *Yx, *Yz, *Wx, *Wz ; Int *Ap, *Ai ; Int m, n, k, k1, i ; int Acomplex, Xcomplex, Ycomplex ; //-------------------------------------------------------------------------- // get inputs //-------------------------------------------------------------------------- m = mxGetM (A) ; n = mxGetN (A) ; k = mxGetM (X) ; if (m != mxGetN (X)) sfmult_invalid ( ) ; Acomplex = mxIsComplex (A) ; Xcomplex = mxIsComplex (X) ; Ap = mxGetJc (A) ; Ai = mxGetIr (A) ; Ax = mxGetPr (A) ; Az = mxGetPi (A) ; Xx = mxGetPr (X) ; Xz = mxGetPi (X) ; //-------------------------------------------------------------------------- // allocate result //-------------------------------------------------------------------------- Ycomplex = Acomplex || Xcomplex ; Y = sfmult_yalloc (k, n, Ycomplex) ; Yx = mxGetPr (Y) ; Yz = mxGetPi (Y) ; //-------------------------------------------------------------------------- // special cases //-------------------------------------------------------------------------- if (k == 0 || m == 0 || n == 0 || Ap [n] == 0) { // Y = 0 return (sfmult_yzero (Y)) ; } if (k == 1) { // Y = A' * X sfmult_AT_x_1 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc) ; return (Y) ; } if (k == 2) { // Y = (A' * X')' sfmult_AT_XT_YT_2 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc, k); return (Y) ; } if (k == 4) { // Y = (A' * X')' sfmult_AT_XT_YT_4 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc, k); return (Y) ; } if (k > 8 && Ap [n] < 8 * MAX (m,n)) { // Y = (A' * X')' when A is moderately sparse and X is large sfmult_xA (Yx, Yz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc, k) ; return (Y) ; } //-------------------------------------------------------------------------- // allocate workspace //-------------------------------------------------------------------------- sfmult_walloc (4, m, &Wx, &Wz) ; //-------------------------------------------------------------------------- // Y = (A'*X')', in blocks of up to 4 columns of X, using sfmult_atxtyt //-------------------------------------------------------------------------- k1 = k % 4 ; if (k1 == 1) { // W = X (1,:)' for (i = 0 ; i < m ; i++) { Wx [i] = Xx [k*i] ; } // Y (1,:) = (A' * W)' sfmult_AT_xk_1 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Wx, Wz, ac, xc, yc, k) ; Yx += 1 ; Yz += 1 ; Xx += 1 ; Xz += 1 ; } else if (k1 == 2) { // W = X (1:2,:) for (i = 0 ; i < m ; i++) { Wx [2*i ] = Xx [k*i ] ; Wx [2*i+1] = Xx [k*i+1] ; } // Y (1:2,:) = (A' * W')' sfmult_AT_XT_YT_2 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Wx, Wz, ac, xc, yc, k); Yx += 2 ; Yz += 2 ; Xx += 2 ; Xz += 2 ; } else if (k1 == 3) { // W = X (1:3,:) for (i = 0 ; i < m ; i++) { Wx [4*i ] = Xx [k*i ] ; Wx [4*i+1] = Xx [k*i+1] ; Wx [4*i+2] = Xx [k*i+2] ; } // Y (1:3,:) = (A' * W')' sfmult_AT_XT_YT_3 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Wx, Wz, ac, xc, yc, k); Yx += 3 ; Yz += 3 ; Xx += 3 ; Xz += 3 ; } for ( ; k1 < k ; k1 += 4) { // W = X (1:4,:) for (i = 0 ; i < m ; i++) { Wx [4*i ] = Xx [k*i ] ; Wx [4*i+1] = Xx [k*i+1] ; Wx [4*i+2] = Xx [k*i+2] ; Wx [4*i+3] = Xx [k*i+3] ; } // Y (k1+(1:4),:) = (A' * W')' sfmult_AT_XT_YT_4 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Wx, Wz, ac, xc, yc, k); Yx += 4 ; Yz += 4 ; Xx += 4 ; Xz += 4 ; } //-------------------------------------------------------------------------- // free workspace and return result //-------------------------------------------------------------------------- mxFree (Wx) ; return (Y) ; }