/* The gateway routine. */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { int mxVLoc, mxSVLoc, da, db = 0, len; double *vr, *vi, sv[min(da,db)], *svr; complex v[da*db],ia[da*min(da,db)],ib[db*min(da,db)]; register int i,j; /* check for the proper number of arguments */ switch(nrhs){ case 3: mxVLoc = 2; if(!mxIsInt(prhs[0])) { mexErrMsgTxt("First input must be an integer if there are three inputs");} da = mxGetScalar(prhs[0]); if(!mxIsInt(prhs[1])) { mexErrMsgTxt("Second input must be an integer if there are three inputs");} db = mxGetScalar(prhs[1]); break; case 2: mxVLoc = 1; if(!mxIsInt(prhs[0])) { mexErrMsgTxt("First input must be an integer if there are two inputs");} da = mxGetScalar(prhs[0]); break; case 1: mxVLoc = 0; da = db = 2; break; default: mexPrintf("\nnrhs:%d\n", nrhs); mexErrMsgTxt("One or three inputs required."); break; } switch(nlhs){ case 1: mxSVLoc = 0; break; case 3: mxSVLoc = 0; break; default:mexErrMsgTxt("One or three outputs required."); break; } /*Check the input is a column vector*/ if(mxGetN(prhs[mxVLoc]) != 1 ){ mexErrMsgTxt("Inputs must be a column vector.");} /* Check that both inputs are complex*/ switch(mxGetClassID(prhs[mxVLoc])){ case mxDOUBLE_CLASS: case mxSINGLE_CLASS: break; case mxINT8_CLASS: case mxUINT8_CLASS: case mxINT16_CLASS: case mxUINT16_CLASS: case mxINT32_CLASS: case mxUINT32_CLASS: case mxINT64_CLASS: case mxUINT64_CLASS: break; default:mexErrMsgTxt("Illegal input type; must be float or int\n"); break; } /* get the length of the input vector */ len = mxGetM(prhs[mxVLoc]); if(len != da*db){ if(mxVLoc == 2){ db = len / da; }else{ mexErrMsgTxt("The length of the array doesn't equal the product of the two dimensions\n"); } } /* get pointers to the real and imaginary parts of the inputs */ vr = mxGetPr(prhs[mxVLoc]); if(mxIsComplex(prhs[mxVLoc])){ register int i,j; vi = mxGetPi(prhs[mxVLoc]); for(i=0;i<da;i++){ for(j=0;j<db;j++){ v[i*da+j]=vr[i*da+j]+I*vi[i*da+j];}} }else{ register int i,j; for(i=0;i<da;i++){ for(j=0;j<db;j++){ v[i*da+j]=vr[i*da+j];}} } schmidt_decomposition(da,db,v,sv,ia,ib); plhs[0] = mxCreateDoubleMatrix(min(da,db), min(da,db), mxREAL); svr = mxGetPr(plhs[mxSVLoc]); for(i=0;i<min(da,db);i++){ svr[i*da+i] = sv[i];} /* zr = mxGetPr(plhs[0]); zi = mxGetPi(plhs[0]); */ /* create a new array and set the output pointer to it */ /* cols = nx + ny - 1; */ /* call the C subroutine */ /* convec(xr, xi, nx, yr, yi, ny, zr, zi);*/ return; }
static mxArray *makeMxFromNumeric(const PyArrayObject *pSrc) { npy_intp lRows, lCols; bool lIsComplex; bool lIsNotAMatrix = false; double *lR = NULL; double *lI = NULL; mxArray *lRetval = NULL; switch (pSrc->nd) { case 0: // XXX the evil 0D lRows = 1; lCols = 1; lIsNotAMatrix = true; break; case 1: lRows = pSrc->dimensions[0]; lCols = min(1, lRows); // for array([]): to avoid zeros((0,1)) ! lIsNotAMatrix = true; break; case 2: lCols = pSrc->dimensions[1]; lRows = pSrc->dimensions[0]; break; default: char strbuff[1024]; sprintf(strbuff, "Only arrays with up to 2D are currently supported (not %dD)", pSrc->nd); PyErr_SetString(PyExc_TypeError, strbuff); goto error_return; } switch (pSrc->descr->type_num) { case PyArray_OBJECT: PyErr_SetString(PyExc_TypeError, "Non-numeric array types not supported"); return NULL; case PyArray_CFLOAT: case PyArray_CDOUBLE: lIsComplex = true; break; default: lIsComplex = false; } lRetval = mxCreateDoubleMatrix(lRows, lCols, lIsComplex ? mxCOMPLEX : mxREAL); if (lRetval == NULL) return NULL; lR = mxGetPr(lRetval); lI = mxGetPi(lRetval); if (lIsNotAMatrix) { switch (pSrc->descr->type_num) { case PyArray_CHAR: copyNumericVector2Mx((char *)(pSrc->data), lRows, lR, pSrc->strides); break; case PyArray_UBYTE: copyNumericVector2Mx((unsigned char *)(pSrc->data), lRows, lR, pSrc->strides); break; case PyArray_SBYTE: copyNumericVector2Mx((signed char *)(pSrc->data), lRows, lR, pSrc->strides); break; case PyArray_SHORT: copyNumericVector2Mx((short *)(pSrc->data), lRows, lR, pSrc->strides); break; case PyArray_INT: copyNumericVector2Mx((int *)(pSrc->data), lRows, lR, pSrc->strides); break; case PyArray_LONG: copyNumericVector2Mx((long *)(pSrc->data), lRows, lR, pSrc->strides); break; case PyArray_FLOAT: copyNumericVector2Mx((float *)(pSrc->data), lRows, lR, pSrc->strides); break; case PyArray_DOUBLE: copyNumericVector2Mx((double *)(pSrc->data), lRows, lR, pSrc->strides); break; case PyArray_CFLOAT: copyCplxNumericVector2Mx((float *)(pSrc->data), lRows, lR, lI, pSrc->strides); break; case PyArray_CDOUBLE: copyCplxNumericVector2Mx((double *)(pSrc->data), lRows, lR, lI, pSrc->strides); break; } } else { switch (pSrc->descr->type_num) { case PyArray_CHAR: copyNumeric2Mx((char *)(pSrc->data), lRows, lCols, lR, pSrc->strides); break; case PyArray_UBYTE: copyNumeric2Mx((unsigned char *)(pSrc->data), lRows, lCols, lR, pSrc->strides); break; case PyArray_SBYTE: copyNumeric2Mx((signed char *)(pSrc->data), lRows, lCols, lR, pSrc->strides); break; case PyArray_SHORT: copyNumeric2Mx((short *)(pSrc->data), lRows, lCols, lR, pSrc->strides); break; case PyArray_INT: copyNumeric2Mx((int *)(pSrc->data), lRows, lCols, lR, pSrc->strides); break; case PyArray_LONG: copyNumeric2Mx((long *)(pSrc->data), lRows, lCols, lR, pSrc->strides); break; case PyArray_FLOAT: copyNumeric2Mx((float *)(pSrc->data), lRows, lCols, lR, pSrc->strides); break; case PyArray_DOUBLE: copyNumeric2Mx((double *)(pSrc->data), lRows, lCols, lR, pSrc->strides); break; case PyArray_CFLOAT: copyCplxNumeric2Mx((float *)(pSrc->data), lRows, lCols, lR, lI, pSrc->strides); break; case PyArray_CDOUBLE: copyCplxNumeric2Mx((double *)(pSrc->data), lRows, lCols, lR, lI, pSrc->strides); break; } } return lRetval; error_return: return NULL; }
void mexFunction ( int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin [ ] ) { Long *Ap, *Ai, *Zp, *Zi ; double *Ax, *Az, *Zx ; Long p, j, build_upper, zero_handling, nrow, ncol, mkind, skind, asize, znz, status ; char filename [LEN+1], title [73], key [9], mtype [4] ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ if (nargin != 1 || nargout > 5 || !mxIsChar (pargin [0])) { mexErrMsgTxt ("Usage: [A Z title key mtype] = RBread (filename)") ; } /* ---------------------------------------------------------------------- */ /* get filename */ /* ---------------------------------------------------------------------- */ if (mxGetString (pargin [0], filename, LEN) != 0) { mexErrMsgTxt ("filename too long") ; } /* ---------------------------------------------------------------------- */ /* read the matrix */ /* ---------------------------------------------------------------------- */ build_upper = TRUE ; /* always build upper tri. part */ zero_handling = (nargout > 1) ? 2 : 1 ; /* prune or extract zeros */ status = RBread (filename, build_upper, zero_handling, title, key, mtype, &nrow, &ncol, &mkind, &skind, &asize, &znz, &Ap, &Ai, &Ax, &Az, &Zp, &Zi) ; if (status != RBIO_OK) { RBerror (status) ; mexErrMsgTxt ("error reading file") ; } /* ---------------------------------------------------------------------- */ /* return A to MATLAB */ /* ---------------------------------------------------------------------- */ pargout [0] = mxCreateSparse (0, 0, 0, (mkind == 2) ? mxCOMPLEX : mxREAL) ; mxFree (mxGetJc (pargout [0])) ; mxFree (mxGetIr (pargout [0])) ; mxFree (mxGetPr (pargout [0])) ; if (mkind == 2) mxFree (mxGetPi (pargout [0])) ; mxSetM (pargout [0], nrow) ; mxSetN (pargout [0], ncol) ; mxSetNzmax (pargout [0], asize) ; mxSetJc (pargout [0], (mwIndex *) Ap) ; mxSetIr (pargout [0], (mwIndex *) Ai) ; mxSetPr (pargout [0], Ax) ; if (mkind == 2) mxSetPi (pargout [0], Az) ; /* ---------------------------------------------------------------------- */ /* return Z to MATLAB */ /* ---------------------------------------------------------------------- */ if (nargout > 1) { Zx = (double *) SuiteSparse_malloc (znz, sizeof (double)) ; for (p = 0 ; p < znz ; p++) { Zx [p] = 1 ; } pargout [1] = mxCreateSparse (0, 0, 0, mxREAL) ; mxFree (mxGetJc (pargout [1])) ; mxFree (mxGetIr (pargout [1])) ; mxFree (mxGetPr (pargout [1])) ; mxSetM (pargout [1], nrow) ; mxSetN (pargout [1], ncol) ; mxSetNzmax (pargout [1], MAX (znz,1)) ; mxSetJc (pargout [1], (mwIndex *) Zp) ; mxSetIr (pargout [1], (mwIndex *) Zi) ; mxSetPr (pargout [1], Zx) ; } /* ---------------------------------------------------------------------- */ /* return title */ /* ---------------------------------------------------------------------- */ if (nargout > 2) { pargout [2] = mxCreateString (title) ; } /* ---------------------------------------------------------------------- */ /* return key */ /* ---------------------------------------------------------------------- */ if (nargout > 3) { pargout [3] = mxCreateString (key) ; } /* ---------------------------------------------------------------------- */ /* return mtype */ /* ---------------------------------------------------------------------- */ if (nargout > 4) { pargout [4] = mxCreateString (mtype) ; } }
/** * L1 solver. * * Usage: * xsol = sopt_solver_l1_mex(y, xsol, ny, nx, nr, A, At, Psi, Psit, ... * Weights, Analysis, ... * ParamMaxIter, ParamGamma, ParamRelObj, ... * ParamEpsilon, ParamRealOut, ParamRealMeas, ... * ParamL1ProxMaxIter, ParamL1ProxRelObj, ParamL1ProxNu, ... * ParamL1ProxTight, ParamL1ProxPositivity, ... * ParamL2BallMaxIter, ParamL2BallTol, ParamL2BallNu, ... * ParamL2BallTight, ParamL2BallPositivity, ... * ParamL2BallReality); */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i, j, iin, iout; int y_is_complex; double *y_real = NULL, *y_imag = NULL; double *yr = NULL; complex double *yc = NULL; int y_m, y_n; int xsol_is_complex; double *xsol_real = NULL, *xsol_imag = NULL; double *xsolr = NULL; complex double *xsolc = NULL; int xsol_m, xsol_n; // Check number of arguments. if (nrhs != 28) { mexErrMsgIdAndTxt("sopt_solver_l1_mex:InvalidInput:nrhs", "Require 28 inputs."); } if (nlhs != 1) { mexErrMsgIdAndTxt("sopt_solver_l1_mex:InvalidOutput:nlhs", "Require one output."); } // Parse y. iin = 0; y_m = mxGetM(prhs[iin]); y_n = mxGetN(prhs[iin]); if (!mxIsDouble(prhs[iin]) || (y_m != 1 && y_n != 1)) mexErrMsgIdAndTxt("sopt_solver_l1_mex:InvalidInput:y", "y must be double array."); y_real = mxGetPr(prhs[iin]); y_is_complex = mxIsComplex(prhs[iin]); y_imag = y_is_complex ? mxGetPi(prhs[iin]) : NULL; if (!y_is_complex) { yr = (double*)malloc(y_m * y_n * sizeof(double)); for(i=0; i<y_m; i++) for(j=0; j<y_n; j++) yr[i*y_n + j] = y_real[i*y_n + j]; } else { yc = (complex double*)malloc(y_m * y_n * sizeof(complex double)); for(i=0; i<y_m; i++) for(j=0; j<y_n; j++) yc[i*y_n + j] = y_real[i*y_n + j] + I * (y_is_complex ? y_imag[i*y_n + j] : 0.0); } // Parse xsol. iin = 1; xsol_m = mxGetM(prhs[iin]); xsol_n = mxGetN(prhs[iin]); if (!mxIsDouble(prhs[iin]) || (xsol_m != 1 && xsol_n != 1)) mexErrMsgIdAndTxt("sopt_solver_l1_mex:InvalidInput:xsol", "xsol must be double array."); xsol_real = mxGetPr(prhs[iin]); xsol_is_complex = mxIsComplex(prhs[iin]); xsol_imag = xsol_is_complex ? mxGetPi(prhs[iin]) : NULL; if (!xsol_is_complex) { xsolr = (double*)malloc(xsol_m * xsol_n * sizeof(double)); for(i=0; i<xsol_m; i++) for(j=0; j<xsol_n; j++) xsolr[i*xsol_n + j] = xsol_real[i*xsol_n + j]; } else { xsolc = (complex double*)malloc(xsol_m * xsol_n * sizeof(complex double)); for(i=0; i<xsol_m; i++) for(j=0; j<xsol_n; j++) xsolc[i*xsol_n + j] = xsol_real[i*xsol_n + j] + I * (xsol_is_complex ? xsol_imag[i*xsol_n + j] : 0.0); } // if (f_is_complex && reality) // mexWarnMsgTxt("Running real transform but input appears to be complex (ignoring imaginary component)."); // if (!f_is_complex && !reality) // mexWarnMsgTxt("Running complex transform on real signal (set reality flag to improve performance)."); double *xout; double *error; double *y0; double *y; double *noise; double *w; void *datam[1]; void *datas[1]; int flag; double sigma; double a; double mse; double snr; int Nx, Ny, Nr; int seedn=54; int seedmat; Nx=256*256; Ny=(int)(0.5*Nx); Nr=1*Nx; xout = (double*)malloc((Nx) * sizeof(double)); SOPT_ERROR_MEM_ALLOC_CHECK(xout); error = (double*)malloc((Nx) * sizeof(double)); SOPT_ERROR_MEM_ALLOC_CHECK(error); y = (double*)malloc((Ny) * sizeof(double)); SOPT_ERROR_MEM_ALLOC_CHECK(y); y0 = (double*)malloc((Ny) * sizeof(double)); SOPT_ERROR_MEM_ALLOC_CHECK(y0); noise = (double*)malloc((Ny) * sizeof(double)); SOPT_ERROR_MEM_ALLOC_CHECK(noise); w = (double*)malloc((Nr) * sizeof(double)); SOPT_ERROR_MEM_ALLOC_CHECK(w); //Measurement operator initialization //Structure for the measurement operator sopt_meas_usparam param1; param1.nmeas = Ny; param1.nx = Nx; param1.real_flag = 1; seedmat = 234; param1.perm = (int*)malloc( param1.nmeas * sizeof(int)); SOPT_ERROR_MEM_ALLOC_CHECK(param1.perm); flag = sopt_ran_knuthshuffle(param1.perm, param1.nmeas, param1.nx, seedmat); //Check random permutation. if (flag!=0) { SOPT_ERROR_GENERIC("Could not generate the permutation"); } //Data cast for the measurement operator datam[0] = (void*)¶m1; //Measurement operator sopt_meas_urandsamp((void*)y0, (void*)yr, datam); //Noise realization //Input snr snr = 30.0; a = cblas_dnrm2(Ny, y0, 1)/sqrt(Ny); sigma = a*pow(10.0,-(snr/20.0)); for (i=0; i < Ny; i++) { noise[i] = sigma*sopt_ran_gasdev2(seedn); y[i] = y0[i] + noise[i]; } //Backprojected image sopt_meas_urandsampadj((void*)xsolr, (void*)y, datam); // sopt_prox_tvparam param2; sopt_prox_l2bparam param3; // sopt_tv_param param4; // //Structure for the TV prox // param2.verbose = 1; // param2.max_iter = 50; // param2.rel_obj = 0.0001; //Structure for the l2 ball prox param3.verbose = 1; param3.max_iter = 50; param3.tol = 0.001; param3.nu = 1; param3.tight = 1; param3.pos = 1; param3.real = 0; // //Structure for the TV solver // param4.verbose = 2; // param4.max_iter = 200; // param4.gamma = 0.1; // param4.rel_obj = 0.0005; // param4.epsilon = sqrt(Ny + 2*sqrt(Ny))*sigma; // param4.real_out = 1; // param4.real_meas = 1; // param4.paramtv = param2; // param4.paraml2b = param3; // //Initial solution for TV reconstruction // for (i=0; i < Nx; i++) { // xsolr[i] = 0.0; // } // sopt_tv_solver((void*)xsolr, 256, 256, // &sopt_meas_urandsamp, // datam, // &sopt_meas_urandsampadj, // datam, // (void*)y, Ny, param4); sopt_wavelet_type *dict_types; sopt_sara_param param5; sopt_prox_l1param param6; sopt_l1_param param7; param5.ndict = 1; param5.real = 1; dict_types = malloc(param5.ndict * sizeof(sopt_wavelet_type)); SOPT_ERROR_MEM_ALLOC_CHECK(dict_types); dict_types[0] = SOPT_WAVELET_DB8; sopt_sara_initop(¶m5, 256, 256, 4, dict_types); datas[0] = (void*)¶m5; //Structure for the L1 prox param6.verbose = 1; param6.max_iter = 50; param6.rel_obj = 0.01; param6.nu = 1; param6.tight = 1; param6.pos = 0; //Structure for the L1 solver param7.verbose = 2; param7.max_iter = 200; param7.gamma = 0.1; param7.rel_obj = 0.0005; param7.epsilon = sqrt(Ny + 2*sqrt(Ny))*sigma; param7.real_out = 1; param7.real_meas = 1; param7.paraml1 = param6; param7.paraml2b = param3; //Weights for (i=0; i < Nr; i++) { w[i] = 1.0; } //Initial solution for L1 recosntruction for (i=0; i < Nx; i++) { xsolr[i] = 0.0; } sopt_l1_solver((void*)xsolr, Nx, &sopt_meas_urandsamp, datam, &sopt_meas_urandsampadj, datam, &sopt_sara_synthesisop, datas, &sopt_sara_analysisop, datas, Nr, (void*)y, Ny, w, param7); // Copy xsol to output. iout = 0; if (!xsol_is_complex) { plhs[iout] = mxCreateDoubleMatrix(xsol_m * xsol_n, 1, mxREAL); xsol_real = mxGetPr(plhs[iout]); for(i=0; i<xsol_m; i++) for(j=0; j<xsol_n; j++) xsol_real[i*xsol_n + j] = xsolr[i*xsol_n + j]; } else { plhs[iout] = mxCreateDoubleMatrix(xsol_m * xsol_n, 1, mxCOMPLEX); xsol_real = mxGetPr(plhs[iout]); xsol_imag = mxGetPi(plhs[iout]); for(i=0; i<xsol_m; i++) for(j=0; j<xsol_n; j++) { xsol_real[i*xsol_n + j] = creal(xsolc[i*xsol_n + j]); xsol_imag[i*xsol_n + j] = cimag(xsolc[i*xsol_n + j]); } } // Free memory. if (!y_is_complex) free(yr); else free(yc); if (!xsol_is_complex) free(xsolr); else free(xsolc); free(xout); free(y); free(y0); free(noise); free(error); free(w); free(param1.perm); free(dict_types); sopt_sara_free(¶m5); }
void mexFunction(int nlhs, mxArray *plhs[ ], int nrhs, const mxArray *prhs[ ]) { int i,j,pos; int *ptr_int; double *ptr_double; double *ptr_matlab; #if MUMPS_ARITH == MUMPS_ARITH_z double *ptri_matlab; #endif mwSize tmp_m,tmp_n; /* C pointer for input parameters */ size_t inst_address; mwSize n,m,ne, netrue ; int inst,job; mwIndex *irn_in,*jcn_in; /* variable for multiple and sparse rhs */ int posrhs; mwSize nbrhs,ldrhs, nz_rhs; mwIndex *irhs_ptr, *irhs_sparse; double *rhs_sparse; #if MUMPS_ARITH == MUMPS_ARITH_z double *im_rhs_sparse; #endif DMUMPS_STRUC_C *dmumps_par; int dosolve = 0; int donullspace = 0; int doanal = 0; if(nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString("4.10.0"); return; } EXTRACT_FROM_MATLAB_TOVAL(JOB,job); dosolve = (job == 3 || job == 5 || job == 6); doanal = (job == 1 || job == 4 || job == 6); if(job == -1){ DMUMPS_alloc(&dmumps_par); EXTRACT_FROM_MATLAB_TOVAL(SYM,dmumps_par->sym); dmumps_par->job = -1; dmumps_par->par = 1; dmumps_c(dmumps_par); dmumps_par->nz = -1; dmumps_par->nz_alloc = -1; }else{ EXTRACT_FROM_MATLAB_TOVAL(INST,inst_address); ptr_int = (int *) inst_address; dmumps_par = (DMUMPS_STRUC_C *) ptr_int; if(job == -2){ dmumps_par->job = -2; dmumps_c(dmumps_par); DMUMPS_free(&dmumps_par); }else{ /* check of input arguments */ n = mxGetN(A_IN); m = mxGetM(A_IN); if (!mxIsSparse(A_IN) || n != m ) mexErrMsgTxt("Input matrix must be a sparse square matrix"); jcn_in = mxGetJc(A_IN); ne = jcn_in[n]; irn_in = mxGetIr(A_IN); dmumps_par->n = (int)n; if(dmumps_par->n != n) mexErrMsgTxt("Input is too big; will not work...barfing out\n"); if(dmumps_par->sym != 0) netrue = (n+ne)/2; else netrue = ne; if(dmumps_par->nz_alloc < netrue || dmumps_par->nz_alloc >= 2*netrue){ MYFREE(dmumps_par->jcn); MYFREE(dmumps_par->irn); MYFREE(dmumps_par->a); MYMALLOC((dmumps_par->jcn),(int)netrue,int); MYMALLOC((dmumps_par->irn),(int)netrue,int); MYMALLOC((dmumps_par->a),(int)netrue,double2); dmumps_par->nz_alloc = (int)netrue; if (dmumps_par->nz_alloc != netrue) mexErrMsgTxt("Input is too big; will not work...barfing out\n"); } if(dmumps_par->sym == 0){ /* if analysis already performed then we only need to read numerical values Note that we suppose that matlab did not change the internal format of the matrix between the 2 calls */ if(doanal){ /* || dmumps_par->info[22] == 0 */ for(i=0;i<dmumps_par->n;i++){ for(j=jcn_in[i];j<jcn_in[i+1];j++){ (dmumps_par->jcn)[j] = i+1; (dmumps_par->irn)[j] = ((int)irn_in[j])+1; } } } dmumps_par->nz = (int)ne; if( dmumps_par->nz != ne) mexErrMsgTxt("Input is too big; will not work...barfing out\n"); #if MUMPS_ARITH == MUMPS_ARITH_z ptr_matlab = mxGetPr(A_IN); for(i=0;i<dmumps_par->nz;i++){ ((dmumps_par->a)[i]).r = ptr_matlab[i]; } ptr_matlab = mxGetPi(A_IN); if(ptr_matlab){ for(i=0;i<dmumps_par->nz;i++){ ((dmumps_par->a)[i]).i = ptr_matlab[i]; } }else{ for(i=0;i<dmumps_par->nz;i++){ ((dmumps_par->a)[i]).i = 0.0; } } #else ptr_matlab = mxGetPr(A_IN); for(i=0;i<dmumps_par->nz;i++){ (dmumps_par->a)[i] = ptr_matlab[i]; } #endif }else{ /* in the symmetric case we do not need to check doanal */ pos = 0; ptr_matlab = mxGetPr(A_IN); #if MUMPS_ARITH == MUMPS_ARITH_z ptri_matlab = mxGetPi(A_IN); #endif for(i=0;i<dmumps_par->n;i++){ for(j=jcn_in[i];j<jcn_in[i+1];j++){ if(irn_in[j] >= i){ if(pos >= netrue) mexErrMsgTxt("Input matrix must be symmetric"); (dmumps_par->jcn)[pos] = i+1; (dmumps_par->irn)[pos] = (int)irn_in[j]+1; #if MUMPS_ARITH == MUMPS_ARITH_z ((dmumps_par->a)[pos]).r = ptr_matlab[j]; if(ptri_matlab){ ((dmumps_par->a)[pos]).i = ptri_matlab[j]; }else{ ((dmumps_par->a)[pos]).i = 0.0; } #else (dmumps_par->a)[pos] = ptr_matlab[j]; #endif pos++; } } } dmumps_par->nz = pos; } EXTRACT_FROM_MATLAB_TOVAL(JOB,dmumps_par->job); EXTRACT_FROM_MATLAB_TOARR(ICNTL,dmumps_par->icntl,int,40); EXTRACT_FROM_MATLAB_TOARR(CNTL,dmumps_par->cntl,double,15); EXTRACT_FROM_MATLAB_TOPTR(PERM_IN,(dmumps_par->perm_in),int,((int)n)); EXTRACT_FROM_MATLAB_TOPTR(COLSCA,(dmumps_par->colsca),double,((int)n)); EXTRACT_FROM_MATLAB_TOPTR(ROWSCA,(dmumps_par->rowsca),double,((int)n)); dmumps_par->size_schur = (int)mxGetN(VAR_SCHUR); EXTRACT_FROM_MATLAB_TOPTR(VAR_SCHUR,(dmumps_par->listvar_schur),int,dmumps_par->size_schur); if(!dmumps_par->listvar_schur) dmumps_par->size_schur = 0; ptr_matlab = mxGetPr (RHS); /* * To follow the "spirit" of the matlab/scilab interfaces, treat case of null * space separately. In that case, we initialize lrhs and nrhs automatically * allocate the space needed, and do not rely on what is provided by the user * in component RHS, that is not touched. * * Note that at the moment the user should not call the solution step combined * with the factorization step when he/she sets icntl[25-1] to a non-zero value. * Hence we suppose infog[28-1] is available and we can use it. * * For users of scilab/matlab, it would still be nice to be able to set ICNTL(25)=-1, * and use JOB=6. If we want to make this functionality available, we should * call separately job=2 and job=3 even if job=5 or 6 and set nbrhs (and allocate * space correctly) between job=2 and job=3 calls to MUMPS. * */ if ( dmumps_par->icntl[25-1] == -1 && dmumps_par->infog[28-1] > 0 ) { dmumps_par->nrhs=dmumps_par->infog[28-1]; donullspace = dosolve; } else if ( dmumps_par->icntl[25-1] > 0 && dmumps_par->icntl[25-1] <= dmumps_par->infog[28-1] ) { dmumps_par->nrhs=1; donullspace = dosolve; } else { donullspace=0; } if (donullspace) { nbrhs=dmumps_par->nrhs; ldrhs=n; dmumps_par->lrhs=(int)n; MYMALLOC((dmumps_par->rhs),((dmumps_par->n)*(dmumps_par->nrhs)),double2); } else if((!dosolve) || ptr_matlab[0] == -9999 ) { /* rhs not already provided, or not used */ /*JY: Case where dosolve is true and ptr_matlab[0]=-9999, this could cause problems: * 1/ RHS was not initialized while it should have been * 2/ RHS was explicitely initialized to -9999 but is not allocated of the right size */ EXTRACT_CMPLX_FROM_MATLAB_TOPTR(RHS,(dmumps_par->rhs),double,1); }else{
void mexFunction ( int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin [ ] ) { double dummy = 0 ; double *Lx, *Lx2, *Lz, *Lz2 ; Long *Li, *Lp, *Lnz2, *Li2, *Lp2, *ColCount ; cholmod_sparse *A, Amatrix, *Lsparse, *S ; cholmod_factor *L ; cholmod_common Common, *cm ; Long j, s, n, lnz, is_complex ; /* ---------------------------------------------------------------------- */ /* start CHOLMOD and set parameters */ /* ---------------------------------------------------------------------- */ cm = &Common ; cholmod_l_start (cm) ; sputil_config (SPUMONI, cm) ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ if (nargout > 1 || nargin != 2) { mexErrMsgTxt ("usage: L = resymbol (L, A)\n") ; } n = mxGetN (pargin [0]) ; if (!mxIsSparse (pargin [0]) || n != mxGetM (pargin [0])) { mexErrMsgTxt ("resymbol: L must be sparse and square") ; } if (n != mxGetM (pargin [1]) || n != mxGetN (pargin [1])) { mexErrMsgTxt ("resymbol: A and L must have same dimensions") ; } /* ---------------------------------------------------------------------- */ /* get the sparse matrix A */ /* ---------------------------------------------------------------------- */ A = sputil_get_sparse_pattern (pargin [1], &Amatrix, &dummy, cm) ; S = (A == &Amatrix) ? NULL : A ; A->stype = -1 ; /* A = sputil_get_sparse (pargin [1], &Amatrix, &dummy, -1) ; */ /* ---------------------------------------------------------------------- */ /* construct a copy of the input sparse matrix L */ /* ---------------------------------------------------------------------- */ /* get the MATLAB L */ Lp = (Long *) mxGetJc (pargin [0]) ; Li = (Long *) mxGetIr (pargin [0]) ; Lx = mxGetPr (pargin [0]) ; Lz = mxGetPi (pargin [0]) ; is_complex = mxIsComplex (pargin [0]) ; /* allocate the CHOLMOD symbolic L */ L = cholmod_l_allocate_factor (n, cm) ; L->ordering = CHOLMOD_NATURAL ; ColCount = L->ColCount ; for (j = 0 ; j < n ; j++) { ColCount [j] = Lp [j+1] - Lp [j] ; } /* allocate space for a CHOLMOD LDL' packed factor */ /* (LL' and LDL' are treated identically) */ cholmod_l_change_factor (is_complex ? CHOLMOD_ZOMPLEX : CHOLMOD_REAL, FALSE, FALSE, TRUE, TRUE, L, cm) ; /* copy MATLAB L into CHOLMOD L */ Lp2 = L->p ; Li2 = L->i ; Lx2 = L->x ; Lz2 = L->z ; Lnz2 = L->nz ; lnz = L->nzmax ; for (j = 0 ; j <= n ; j++) { Lp2 [j] = Lp [j] ; } for (j = 0 ; j < n ; j++) { Lnz2 [j] = Lp [j+1] - Lp [j] ; } for (s = 0 ; s < lnz ; s++) { Li2 [s] = Li [s] ; } for (s = 0 ; s < lnz ; s++) { Lx2 [s] = Lx [s] ; } if (is_complex) { for (s = 0 ; s < lnz ; s++) { Lz2 [s] = Lz [s] ; } } /* ---------------------------------------------------------------------- */ /* resymbolic factorization */ /* ---------------------------------------------------------------------- */ cholmod_l_resymbol (A, NULL, 0, TRUE, L, cm) ; /* ---------------------------------------------------------------------- */ /* copy the results back to MATLAB */ /* ---------------------------------------------------------------------- */ Lsparse = cholmod_l_factor_to_sparse (L, cm) ; /* return L as a sparse matrix */ pargout [0] = sputil_put_sparse (&Lsparse, cm) ; /* ---------------------------------------------------------------------- */ /* free workspace and the CHOLMOD L, except for what is copied to MATLAB */ /* ---------------------------------------------------------------------- */ cholmod_l_free_factor (&L, cm) ; cholmod_l_free_sparse (&S, cm) ; cholmod_l_finish (cm) ; cholmod_l_print_common (" ", cm) ; /* if (cm->malloc_count != 3 + mxIsComplex (pargout[0])) mexErrMsgTxt ("!") ; */ }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) /* left hand side right hand side /* function [z,kz] = mandelbrot_step(z,kz,z0,d); * Take one step of the Mandelbrot iteration. * Complex arithmetic: * z = z.^2 + z0 * kz(abs(z) < 2) == d * Real arithmetic: * x <-> real(z); * y <-> imag(z); * u <-> real(z0); * v <-> imag(z0); * [x,y] = [x.^2-y.^2+u, 2*x.*y+v]; * kz(x.^2+y.^2 < 4) = d; */ { double *x,*y,*u,*v,t; unsigned short *kz, *num, d; int j ,n, m; int dim[] = {1, 1}; x = mxGetPr(prhs[0]); y = mxGetPi(prhs[0]); kz = (unsigned short *) mxGetData(prhs[1]); u = mxGetPr(prhs[2]); v = mxGetPi(prhs[2]); d = (unsigned short) mxGetScalar(prhs[3]); plhs[0] = prhs[0]; plhs[1] = prhs[1]; plhs[2] = mxCreateNumericArray(2,dim,mxUINT32_CLASS,mxREAL); num = mxGetData(plhs[2]); *num = 0; n = mxGetN(prhs[0]); m = mxGetM(prhs[0]); if(1){ for (j=n*m; j--; ) { if (kz[j] == d-1) { t = x[j]; x[j] = x[j]*x[j] - y[j]*y[j] + u[j]; y[j] = (t+t)*y[j] + v[j]; if (x[j]*x[j] + y[j]*y[j] < 4) { kz[j] = d; } else { *num = *num+1; } } } } else { for (j=0; j<n*m; j++) { if (kz[j] == d-1) { t = x[j]; x[j] = x[j]*x[j] - y[j]*y[j] + u[j]; y[j] = 2*t*y[j] + v[j]; if (x[j]*x[j] + y[j]*y[j] < 4) { kz[j] = d; } } } } return; }
void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] ) { // Register exit function only once #ifdef LTFAT_DOUBLE if(p_old==0) { mexAtExit(fftrealAtExit); } #endif mwIndex L, W, N, type; LTFAT_REAL *f_r, *f_i; LTFAT_FFTW(iodim) dims[1], howmanydims[1]; LTFAT_FFTW(plan) p; LTFAT_FFTW(r2r_kind) kind[1]; L = mxGetM(prhs[0]); W = mxGetN(prhs[0]); N = 2*L; type = (mwIndex) mxGetScalar(prhs[1]); // Copy inputs and get pointers if( mxIsComplex(prhs[0])) { plhs[0] = ltfatCreateMatrix(L, W, LTFAT_MX_CLASSID, mxCOMPLEX); f_i = (LTFAT_REAL*) mxGetPi(plhs[0]); memcpy(f_i,mxGetPi(prhs[0]),W*L*sizeof(LTFAT_REAL)); } else { plhs[0] = ltfatCreateMatrix(L, W, LTFAT_MX_CLASSID, mxREAL); } f_r = (LTFAT_REAL*) mxGetPr(plhs[0]); memcpy(f_r,mxGetPr(prhs[0]),W*L*sizeof(LTFAT_REAL)); // Create plan. Copy data from f to cout. dims[0].n = L; dims[0].is = 1; dims[0].os = 1; howmanydims[0].n = W; howmanydims[0].is = L; howmanydims[0].os = L; LTFAT_REAL sqrt2 = (LTFAT_REAL) sqrt(2.0); LTFAT_REAL postScale = (LTFAT_REAL) 1.0/sqrt2; LTFAT_REAL scale = (LTFAT_REAL) sqrt2*(1.0/(double)N)*sqrt((double)L); // Re-allocate and prescale input if(type==1||type==3) { for(mwIndex ii=0; ii<W; ii++) { f_r[ii*L] *= sqrt2; } if(mxIsComplex(prhs[0])) { for(mwIndex ii=0; ii<W; ii++) { f_i[ii*L] *= sqrt2; } } } switch(type) { case 1: N -= 2; for(mwIndex ii=0; ii<W; ii++) { f_r[(ii+1)*L-1] *= sqrt2; } if(mxIsComplex(prhs[0])) { for(mwIndex ii=0; ii<W; ii++) { f_i[(ii+1)*L-1] *= sqrt2; } } scale = (LTFAT_REAL) sqrt2*(1.0/((double)N))*sqrt((double)L-1); kind[0] = FFTW_REDFT00; break; case 2: kind[0] = FFTW_REDFT10; break; case 3: kind[0] = FFTW_REDFT01; break; case 4: kind[0] = FFTW_REDFT11; break; default: mexErrMsgTxt("Unknown type."); } // The calling prototype //fftw_plan fftw_plan_guru_split_dft_r2c( // int rank, const fftw_iodim *dims, // int howmany_rank, const fftw_iodim *howmany_dims, // double *in, double *ro, double *io, // unsigned flags); p = LTFAT_FFTW(plan_guru_r2r)(1, dims, 1, howmanydims, f_r, f_r, kind, FFTW_OPTITYPE); /* FFTW documentation qote http://www.fftw.org/fftw3_doc/New_002darray-Execute-Functions.html#New_002darray-Execute-Functions: ... creating a new plan is quick once one exists for a given size ... so why not to store the old plan.. */ if(p_old!=0) { fftw_destroy_plan(*p_old); free(p_old); } p_old = malloc(sizeof(p)); memcpy(p_old,&p,sizeof(p)); // Real FFT. LTFAT_FFTW(execute)(p); // Do the normalization for(int ii=0; ii<L*W; ii++) { f_r[ii] *= scale; } if(type==1||type==2) { // Scale DC component for(int ii=0; ii<W; ii++) { f_r[ii*L] *= postScale; } } if(type==1) { // Scale AC component for(int ii=0; ii<W; ii++) { f_r[(ii+1)*L-1] *= postScale; } } // If the input is complex, process the imaginary part if(mxIsComplex(prhs[0])) { LTFAT_FFTW(execute_r2r)(p,f_i,f_i); // Do the normalization for(int ii=0; ii<L*W; ii++) { f_i[ii] *= scale; } if(type==1||type==2) { // Scale DC component for(int ii=0; ii<W; ii++) { f_i[ii*L] *= postScale; } } if(type==1) { // Scale AC component for(int ii=0; ii<W; ii++) { f_i[(ii+1)*L-1] *= postScale; } } } // LTFAT_FFTW(destroy_plan)(p); return; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { mxArray *blk_cell_pr, *A_cell_pr; double *A, *B, *AI, *BI, *blksize, *Atmp, *AItmp; int *irA, *jcA, *irB, *jcB; int *cumblksize, *blknnz; int iscellA, mblk, mA, nA, m1, n1, rowidx, colidx, isspA, isspB; int iscmpA, iscmpB; int subs[2]; int nsubs=2; int n, n2, k, nsub, index, numblk, NZmax, r, kstart, kend; /* 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); 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; 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); iscmpA = mxIsComplex(A_cell_pr); if (isspA) { irA = mxGetIr(A_cell_pr); jcA = mxGetJc(A_cell_pr); } if (iscmpA) { AI = mxGetPi(A_cell_pr); } } else { A = mxGetPr(prhs[1]); m1 = mxGetM(prhs[1]); n1 = mxGetN(prhs[1]); isspA = mxIsSparse(prhs[1]); iscmpA = mxIsComplex(prhs[1]); if (isspA) { irA = mxGetIr(prhs[1]); jcA = mxGetJc(prhs[1]); } if (iscmpA) { AI = mxGetPi(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 (numblk == 1 & isspA) { NZmax = jcA[colidx+1]-jcA[colidx]; } else { NZmax = blknnz[numblk]; } if (iscmpA) { plhs[0] = mxCreateSparse(n,n,NZmax,mxCOMPLEX); } else { plhs[0] = mxCreateSparse(n,n,NZmax,mxREAL); } B = mxGetPr(plhs[0]); irB = mxGetIr(plhs[0]); jcB = mxGetJc(plhs[0]); if (iscmpA) { BI = mxGetPi(plhs[0]); } } else { if (iscmpA) { plhs[0] = mxCreateDoubleMatrix(n,n,mxCOMPLEX); } else { plhs[0] = mxCreateDoubleMatrix(n,n,mxREAL); } B = mxGetPr(plhs[0]); if (iscmpA) { BI = mxGetPi(plhs[0]); } } /***** Do the computations in a subroutine *****/ if (numblk == 1) { if (iscmpA) { mat1cmp(n,A,irA,jcA,isspA,m1,colidx,B,irB,jcB,isspB,AI,BI); } else { mat1(n,A,irA,jcA,isspA,m1,colidx,B,irB,jcB,isspB); } } else { if (isspA) { Atmp = mxCalloc(blknnz[numblk],sizeof(double)); kstart = jcA[colidx]; kend = jcA[colidx+1]; for (k=kstart; k<kend; k++) { r = irA[k]; Atmp[r] = A[k]; } if (iscmpA) { AItmp = mxCalloc(blknnz[numblk],sizeof(double)); for (k=kstart; k<kend; k++) { r = irA[k]; AItmp[r] = AI[k]; } mat2cmp(n,numblk,cumblksize,blknnz,Atmp,m1,0,B,irB,jcB,isspB,AItmp,BI); } else { mat2(n,numblk,cumblksize,blknnz,Atmp,m1,0,B,irB,jcB,isspB); } } else { if (iscmpA) { mat2cmp(n,numblk,cumblksize,blknnz,A,m1,colidx,B,irB,jcB,isspB,AI,BI); } else { mat2(n,numblk,cumblksize,blknnz,A,m1,colidx,B,irB,jcB,isspB); } } } if ((isspA) & (numblk>1)) { mxFree(Atmp); if (iscmpA) { mxFree(AItmp); } } return; }
static mxArray* matlab_create_value(gld_property *prop) { mxArray *value=NULL; switch ( prop->get_type() ) { case PT_double: case PT_random: case PT_enduse: case PT_loadshape: value = mxCreateDoubleScalar(*(double*)prop->get_addr()); break; case PT_complex: { value = mxCreateDoubleMatrix(1,1,mxCOMPLEX); complex *v = (complex*)prop->get_addr(); *mxGetPr(value) = v->Re(); *mxGetPi(value) = v->Im(); } break; case PT_int16: value = mxCreateDoubleScalar((double)*(int16*)prop->get_addr()); break; case PT_enumeration: case PT_int32: value = mxCreateDoubleScalar((double)*(int32*)prop->get_addr()); break; case PT_set: case PT_int64: value = mxCreateDoubleScalar((double)*(int64*)prop->get_addr()); break; case PT_timestamp: value = mxCreateDoubleScalar((double)*(TIMESTAMP*)prop->get_addr()); break; case PT_bool: value = mxCreateDoubleScalar((double)*(bool*)prop->get_addr()); break; case PT_char8: case PT_char32: case PT_char256: case PT_char1024: { const char *str[] = {(char*)prop->get_addr()}; value = mxCreateCharMatrixFromStrings(mwSize(1),str); } break; case PT_double_array: { double_array *data = (double_array*)prop->get_addr(); size_t n=data->get_rows(), m=data->get_cols(); value = mxCreateDoubleMatrix(0,0,mxREAL); double *copy = (double*)mxMalloc(m*n); for ( int c=0 ; c<m ; c++ ) { for ( int r=0 ; r<n ; r++ ) { copy[c*m+r] = data->get_at(r,c); } } mxSetPr(value,copy); mxSetM(value,m); mxSetN(value,n); } break; case PT_complex_array: // TODO break; default: value = NULL; break; } return value; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //----------------------- // Input pointers double *h_fMRI_Volumes_double, *h_Quadrature_Filter_1_Real_double, *h_Quadrature_Filter_2_Real_double, *h_Quadrature_Filter_3_Real_double, *h_Quadrature_Filter_1_Imag_double, *h_Quadrature_Filter_2_Imag_double, *h_Quadrature_Filter_3_Imag_double; float *h_fMRI_Volumes, *h_Quadrature_Filter_1_Real, *h_Quadrature_Filter_2_Real, *h_Quadrature_Filter_3_Real, *h_Quadrature_Filter_1_Imag, *h_Quadrature_Filter_2_Imag, *h_Quadrature_Filter_3_Imag; int MOTION_CORRECTION_FILTER_SIZE, NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION; int OPENCL_PLATFORM,OPENCL_DEVICE; //----------------------- // Output pointers double *h_Motion_Corrected_fMRI_Volumes_double, *h_Motion_Parameters_double; double *h_Quadrature_Filter_Response_1_Real_double, *h_Quadrature_Filter_Response_1_Imag_double; double *h_Quadrature_Filter_Response_2_Real_double, *h_Quadrature_Filter_Response_2_Imag_double; double *h_Quadrature_Filter_Response_3_Real_double, *h_Quadrature_Filter_Response_3_Imag_double; double *h_Phase_Differences_double, *h_Phase_Certainties_double, *h_Phase_Gradients_double; float *h_Quadrature_Filter_Response_1_Real, *h_Quadrature_Filter_Response_1_Imag; float *h_Quadrature_Filter_Response_2_Real, *h_Quadrature_Filter_Response_2_Imag; float *h_Quadrature_Filter_Response_3_Real, *h_Quadrature_Filter_Response_3_Imag; float *h_Phase_Differences, *h_Phase_Certainties, *h_Phase_Gradients; float *h_Motion_Corrected_fMRI_Volumes, *h_Motion_Parameters; //--------------------- /* Check the number of input and output arguments. */ if(nrhs<7) { mexErrMsgTxt("Too few input arguments."); } if(nrhs>7) { mexErrMsgTxt("Too many input arguments."); } if(nlhs<8) { mexErrMsgTxt("Too few output arguments."); } if(nlhs>8) { mexErrMsgTxt("Too many output arguments."); } /* Input arguments */ // The data h_fMRI_Volumes_double = (double*)mxGetData(prhs[0]); h_Quadrature_Filter_1_Real_double = (double*)mxGetPr(prhs[1]); h_Quadrature_Filter_1_Imag_double = (double*)mxGetPi(prhs[1]); h_Quadrature_Filter_2_Real_double = (double*)mxGetPr(prhs[2]); h_Quadrature_Filter_2_Imag_double = (double*)mxGetPi(prhs[2]); h_Quadrature_Filter_3_Real_double = (double*)mxGetPr(prhs[3]); h_Quadrature_Filter_3_Imag_double = (double*)mxGetPi(prhs[3]); NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION = (int)mxGetScalar(prhs[4]); OPENCL_PLATFORM = (int)mxGetScalar(prhs[5]); OPENCL_DEVICE = (int)mxGetScalar(prhs[6]); int NUMBER_OF_DIMENSIONS = mxGetNumberOfDimensions(prhs[0]); const int *ARRAY_DIMENSIONS_DATA = mxGetDimensions(prhs[0]); const int *ARRAY_DIMENSIONS_FILTER = mxGetDimensions(prhs[1]); int DATA_H, DATA_W, DATA_D, DATA_T, NUMBER_OF_MOTION_CORRECTION_PARAMETERS; NUMBER_OF_MOTION_CORRECTION_PARAMETERS = 6; DATA_H = ARRAY_DIMENSIONS_DATA[0]; DATA_W = ARRAY_DIMENSIONS_DATA[1]; DATA_D = ARRAY_DIMENSIONS_DATA[2]; DATA_T = ARRAY_DIMENSIONS_DATA[3]; MOTION_CORRECTION_FILTER_SIZE = ARRAY_DIMENSIONS_FILTER[0]; int DATA_SIZE = DATA_W * DATA_H * DATA_D * DATA_T * sizeof(float); int MOTION_PARAMETERS_SIZE = NUMBER_OF_MOTION_CORRECTION_PARAMETERS * DATA_T * sizeof(float); int FILTER_SIZE = MOTION_CORRECTION_FILTER_SIZE * MOTION_CORRECTION_FILTER_SIZE * MOTION_CORRECTION_FILTER_SIZE * sizeof(float); int VOLUME_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float); mexPrintf("Data size : %i x %i x %i x %i \n", DATA_W, DATA_H, DATA_D, DATA_T); mexPrintf("Filter size : %i x %i x %i \n", MOTION_CORRECTION_FILTER_SIZE,MOTION_CORRECTION_FILTER_SIZE,MOTION_CORRECTION_FILTER_SIZE); mexPrintf("Number of iterations : %i \n", NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION); //------------------------------------------------- // Output to Matlab // Create pointer for volumes to Matlab NUMBER_OF_DIMENSIONS = 4; int ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[4]; ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[0] = DATA_H; ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[1] = DATA_W; ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[2] = DATA_D; ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES[3] = DATA_T; plhs[0] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_MOTION_CORRECTED_FMRI_VOLUMES,mxDOUBLE_CLASS, mxREAL); h_Motion_Corrected_fMRI_Volumes_double = mxGetPr(plhs[0]); NUMBER_OF_DIMENSIONS = 2; int ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS[2]; ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS[0] = DATA_T; ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS[1] = NUMBER_OF_MOTION_CORRECTION_PARAMETERS; plhs[1] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_MOTION_PARAMETERS,mxDOUBLE_CLASS, mxREAL); h_Motion_Parameters_double = mxGetPr(plhs[1]); NUMBER_OF_DIMENSIONS = 3; int ARRAY_DIMENSIONS_OUT_FILTER_RESPONSE[3]; ARRAY_DIMENSIONS_OUT_FILTER_RESPONSE[0] = DATA_H; ARRAY_DIMENSIONS_OUT_FILTER_RESPONSE[1] = DATA_W; ARRAY_DIMENSIONS_OUT_FILTER_RESPONSE[2] = DATA_D; plhs[2] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_FILTER_RESPONSE,mxDOUBLE_CLASS, mxCOMPLEX); h_Quadrature_Filter_Response_1_Real_double = mxGetPr(plhs[2]); h_Quadrature_Filter_Response_1_Imag_double = mxGetPi(plhs[2]); plhs[3] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_FILTER_RESPONSE,mxDOUBLE_CLASS, mxCOMPLEX); h_Quadrature_Filter_Response_2_Real_double = mxGetPr(plhs[3]); h_Quadrature_Filter_Response_2_Imag_double = mxGetPi(plhs[3]); plhs[4] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_FILTER_RESPONSE,mxDOUBLE_CLASS, mxCOMPLEX); h_Quadrature_Filter_Response_3_Real_double = mxGetPr(plhs[4]); h_Quadrature_Filter_Response_3_Imag_double = mxGetPi(plhs[4]); plhs[5] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_FILTER_RESPONSE,mxDOUBLE_CLASS, mxREAL); h_Phase_Differences_double = mxGetPr(plhs[5]); plhs[6] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_FILTER_RESPONSE,mxDOUBLE_CLASS, mxREAL); h_Phase_Certainties_double = mxGetPr(plhs[6]); plhs[7] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_FILTER_RESPONSE,mxDOUBLE_CLASS, mxREAL); h_Phase_Gradients_double = mxGetPr(plhs[7]); // ------------------------------------------------ // Allocate memory on the host h_fMRI_Volumes = (float *)mxMalloc(DATA_SIZE); h_Quadrature_Filter_1_Real = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_1_Imag = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_2_Real = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_2_Imag = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_3_Real = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_3_Imag = (float *)mxMalloc(FILTER_SIZE); h_Quadrature_Filter_Response_1_Real = (float *)mxMalloc(VOLUME_SIZE); h_Quadrature_Filter_Response_1_Imag = (float *)mxMalloc(VOLUME_SIZE); h_Quadrature_Filter_Response_2_Real = (float *)mxMalloc(VOLUME_SIZE); h_Quadrature_Filter_Response_2_Imag = (float *)mxMalloc(VOLUME_SIZE); h_Quadrature_Filter_Response_3_Real = (float *)mxMalloc(VOLUME_SIZE); h_Quadrature_Filter_Response_3_Imag = (float *)mxMalloc(VOLUME_SIZE); h_Phase_Differences = (float *)mxMalloc(VOLUME_SIZE); h_Phase_Certainties = (float *)mxMalloc(VOLUME_SIZE); h_Phase_Gradients = (float *)mxMalloc(VOLUME_SIZE); h_Motion_Corrected_fMRI_Volumes = (float *)mxMalloc(DATA_SIZE); h_Motion_Parameters = (float *)mxMalloc(MOTION_PARAMETERS_SIZE); // Pack data (reorder from y,x,z to x,y,z and cast from double to float) pack_double2float_volumes(h_fMRI_Volumes, h_fMRI_Volumes_double, DATA_W, DATA_H, DATA_D, DATA_T); pack_double2float_volume(h_Quadrature_Filter_1_Real, h_Quadrature_Filter_1_Real_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); pack_double2float_volume(h_Quadrature_Filter_1_Imag, h_Quadrature_Filter_1_Imag_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); pack_double2float_volume(h_Quadrature_Filter_2_Real, h_Quadrature_Filter_2_Real_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); pack_double2float_volume(h_Quadrature_Filter_2_Imag, h_Quadrature_Filter_2_Imag_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); pack_double2float_volume(h_Quadrature_Filter_3_Real, h_Quadrature_Filter_3_Real_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); pack_double2float_volume(h_Quadrature_Filter_3_Imag, h_Quadrature_Filter_3_Imag_double, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE, MOTION_CORRECTION_FILTER_SIZE); //------------------------ BROCCOLI_LIB BROCCOLI(OPENCL_PLATFORM,OPENCL_DEVICE); // Something went wrong... if (BROCCOLI.GetOpenCLInitiated() == 0) { int getPlatformIDsError = BROCCOLI.GetOpenCLPlatformIDsError(); int getDeviceIDsError = BROCCOLI.GetOpenCLDeviceIDsError(); int createContextError = BROCCOLI.GetOpenCLCreateContextError(); int getContextInfoError = BROCCOLI.GetOpenCLContextInfoError(); int createCommandQueueError = BROCCOLI.GetOpenCLCreateCommandQueueError(); int createProgramError = BROCCOLI.GetOpenCLCreateProgramError(); int buildProgramError = BROCCOLI.GetOpenCLBuildProgramError(); int getProgramBuildInfoError = BROCCOLI.GetOpenCLProgramBuildInfoError(); mexPrintf("Get platform IDs error is %d \n",getPlatformIDsError); mexPrintf("Get device IDs error is %d \n",getDeviceIDsError); mexPrintf("Create context error is %d \n",createContextError); mexPrintf("Get create context info error is %d \n",getContextInfoError); mexPrintf("Create command queue error is %d \n",createCommandQueueError); mexPrintf("Create program error is %d \n",createProgramError); mexPrintf("Build program error is %d \n",buildProgramError); mexPrintf("Get program build info error is %d \n",getProgramBuildInfoError); // Print create kernel errors int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors(); for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++) { if (createKernelErrors[i] != 0) { mexPrintf("Create kernel error %i is %d \n",i,createKernelErrors[i]); } } mexPrintf("OPENCL initialization failed, aborting \n"); } else if (BROCCOLI.GetOpenCLInitiated() == 1) { BROCCOLI.SetEPIWidth(DATA_W); BROCCOLI.SetEPIHeight(DATA_H); BROCCOLI.SetEPIDepth(DATA_D); BROCCOLI.SetEPITimepoints(DATA_T); BROCCOLI.SetInputfMRIVolumes(h_fMRI_Volumes); BROCCOLI.SetImageRegistrationFilterSize(MOTION_CORRECTION_FILTER_SIZE); BROCCOLI.SetParametricImageRegistrationFilters(h_Quadrature_Filter_1_Real, h_Quadrature_Filter_1_Imag, h_Quadrature_Filter_2_Real, h_Quadrature_Filter_2_Imag, h_Quadrature_Filter_3_Real, h_Quadrature_Filter_3_Imag); BROCCOLI.SetNumberOfIterationsForMotionCorrection(NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION); BROCCOLI.SetOutputMotionCorrectedfMRIVolumes(h_Motion_Corrected_fMRI_Volumes); BROCCOLI.SetOutputMotionParameters(h_Motion_Parameters); //BROCCOLI.SetOutputQuadratureFilterResponses(h_Quadrature_Filter_Response_1_Real, h_Quadrature_Filter_Response_1_Imag, h_Quadrature_Filter_Response_2_Real, h_Quadrature_Filter_Response_2_Imag, h_Quadrature_Filter_Response_3_Real, h_Quadrature_Filter_Response_3_Imag); BROCCOLI.SetOutputPhaseDifferences(h_Phase_Differences); BROCCOLI.SetOutputPhaseCertainties(h_Phase_Certainties); BROCCOLI.SetOutputPhaseGradients(h_Phase_Gradients); BROCCOLI.PerformMotionCorrectionWrapper(); // Print create buffer errors int* createBufferErrors = BROCCOLI.GetOpenCLCreateBufferErrors(); for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++) { if (createBufferErrors[i] != 0) { mexPrintf("Create buffer error %i is %d \n",i,createBufferErrors[i]); } } // Print run kernel errors int* runKernelErrors = BROCCOLI.GetOpenCLRunKernelErrors(); for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++) { if (runKernelErrors[i] != 0) { mexPrintf("Run kernel error %i is %d \n",i,runKernelErrors[i]); } } } // Print build info mexPrintf("Build info \n \n %s \n", BROCCOLI.GetOpenCLBuildInfoChar()); // Unpack results to Matlab unpack_float2double_volumes(h_Motion_Corrected_fMRI_Volumes_double, h_Motion_Corrected_fMRI_Volumes, DATA_W, DATA_H, DATA_D, DATA_T); unpack_float2double(h_Motion_Parameters_double, h_Motion_Parameters, NUMBER_OF_MOTION_CORRECTION_PARAMETERS * DATA_T); unpack_float2double_volume(h_Quadrature_Filter_Response_1_Real_double, h_Quadrature_Filter_Response_1_Real, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_Quadrature_Filter_Response_1_Imag_double, h_Quadrature_Filter_Response_1_Imag, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_Quadrature_Filter_Response_2_Real_double, h_Quadrature_Filter_Response_2_Real, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_Quadrature_Filter_Response_2_Imag_double, h_Quadrature_Filter_Response_2_Imag, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_Quadrature_Filter_Response_3_Real_double, h_Quadrature_Filter_Response_3_Real, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_Quadrature_Filter_Response_3_Imag_double, h_Quadrature_Filter_Response_3_Imag, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_Phase_Differences_double, h_Phase_Differences, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_Phase_Certainties_double, h_Phase_Certainties, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_Phase_Gradients_double, h_Phase_Gradients, DATA_W, DATA_H, DATA_D); // Free all the allocated memory on the host mxFree(h_fMRI_Volumes); mxFree(h_Quadrature_Filter_1_Real); mxFree(h_Quadrature_Filter_1_Imag); mxFree(h_Quadrature_Filter_2_Real); mxFree(h_Quadrature_Filter_2_Imag); mxFree(h_Quadrature_Filter_3_Real); mxFree(h_Quadrature_Filter_3_Imag); mxFree(h_Quadrature_Filter_Response_1_Real); mxFree(h_Quadrature_Filter_Response_1_Imag); mxFree(h_Quadrature_Filter_Response_2_Real); mxFree(h_Quadrature_Filter_Response_2_Imag); mxFree(h_Quadrature_Filter_Response_3_Real); mxFree(h_Quadrature_Filter_Response_3_Imag); mxFree(h_Phase_Differences); mxFree(h_Phase_Certainties); mxFree(h_Phase_Gradients); mxFree(h_Motion_Corrected_fMRI_Volumes); mxFree(h_Motion_Parameters); return; }
static mxArray* matlab_get_value(mxArray *value, gld_property *prop) { switch ( prop->get_type() ) { case PT_double: case PT_random: case PT_enduse: case PT_loadshape: { double *ptr = mxGetPr(value); *(double*)prop->get_addr() = *ptr; } break; case PT_complex: { double *r = mxGetPr(value); double *i = mxGetPi(value); complex *v = (complex*)prop->get_addr(); if (r) v->Re() = *r; if (i) v->Im() = *i; } break; case PT_int16: { double *ptr = mxGetPr(value); if (ptr) *(int16*)prop->get_addr() = (int16)*ptr; } break; case PT_enumeration: case PT_int32: { double *ptr = mxGetPr(value); if (ptr) *(int32*)prop->get_addr() = (int32)*ptr; } break; case PT_set: case PT_int64: { double *ptr = mxGetPr(value); if (ptr) *(int64*)prop->get_addr() = (int64)*ptr; } break; case PT_timestamp: { double *ptr = mxGetPr(value); if (ptr) *(TIMESTAMP*)prop->get_addr() = (TIMESTAMP)*ptr; } break; case PT_bool: { double *ptr = mxGetPr(value); if (ptr) *(bool*)prop->get_addr() = (bool)*ptr; } break; case PT_char8: case PT_char32: case PT_char256: case PT_char1024: // TODO break; default: value = NULL; break; } return value; }
/*============================================================================ */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mxArray *T, *D; double *R; double *basisopts, *allocationOptions; int N, idxS, idxB, idxD; if (nrhs==1) { double *jm = mxGetPr(prhs[0]); /*mexPrintf("%0.10f\n",jjj(jm[0],jm[1],jm[2],jm[3],jm[4],jm[5])); */ return; } if (nrhs!=4) mexErrMsgTxt("4 input arguments expected!"); if (nlhs!=5) mexErrMsgTxt("3 output arguments expected!"); if (Display) mexPrintf("Parsing system...\n"); idxS = 0; Sys.I = mxGetScalar(mxGetField(prhs[idxS],0,"I")); Sys.EZI0 = mxGetScalar(mxGetField(prhs[idxS],0,"EZ0")); Sys.NZI0 = mxGetScalar(mxGetField(prhs[idxS],0,"NZ0")); Sys.HFI0 = mxGetScalar(mxGetField(prhs[idxS],0,"HF0")); Sys.DirTilt = mxGetScalar(mxGetField(prhs[idxS],0,"DirTilt")); Sys.d2psi = mxGetPr(mxGetField(prhs[idxS],0,"d2psi")); T = mxGetField(prhs[idxS],0,"EZ2"); Sys.ReEZI2 = mxGetPr(T); Sys.ImEZI2 = mxGetPi(T); T = mxGetField(prhs[idxS],0,"HF2"); Sys.ReHFI2 = mxGetPr(T); Sys.ImHFI2 = mxGetPi(T); /*mexPrintf("Parsing basis structure...\n"); */ idxB = 1; /*Lemax = (int)mxGetScalar(mxGetField(prhs[idxB],0,"evenLmax")); Lomax = (int)mxGetScalar(mxGetField(prhs[idxB],0,"oddLmax")); Kmax = (int)mxGetScalar(mxGetField(prhs[idxB],0,"Kmax")); Mmax = (int)mxGetScalar(mxGetField(prhs[idxB],0,"Mmax")); jKmin = (int)mxGetScalar(mxGetField(prhs[idxB],0,"jKmin")); pSmin = (int)mxGetScalar(mxGetField(prhs[idxB],0,"pSmin")); pImax = (int)mxGetScalar(mxGetField(prhs[idxB],0,"pImax")); deltaK = (int)mxGetScalar(mxGetField(prhs[idxB],0,"deltaK")); */ basisopts = mxGetPr(prhs[1]); Lemax = (int)basisopts[0]; Lomax = (int)basisopts[1]; Kmax = (int)basisopts[2]; Mmax = (int)basisopts[3]; jKmin = (int)basisopts[4]; pSmin = (int)basisopts[5]; deltaK = (int)basisopts[6]; MeirovitchSymm = (int)basisopts[7]; pImax = (int)basisopts[8]; /* mexPrintf("(%d %d %d %d) jKmin %d, pSmin %d, pImax %d, deltaK %d\n", Lemax,Lomax,Kmax,Mmax,jKmin,pSmin,pImax,deltaK); */ /*mexPrintf("Parsing diffusion structure...\n"); */ idxD = 2; Diff.Exchange = mxGetScalar(mxGetField(prhs[idxD],0,"Exchange")); Diff.xlk = mxGetPr(mxGetField(prhs[idxD],0,"xlk")); Diff.maxL = mxGetScalar(mxGetField(prhs[idxD],0,"maxL")); R = mxGetPr(mxGetField(prhs[idxD],0,"Diff")); Diff.Rxx = R[0]; Diff.Ryy = R[1]; Diff.Rzz = R[2]; allocationOptions = mxGetPr(prhs[3]); maxElements = (long)allocationOptions[0]; maxRows = (long)allocationOptions[1]; if (Display) mexPrintf(" max elements: %d, max rows: %d\n",maxElements,maxRows); N = BasisSize(); maxRows = N+1; if (Display) mexPrintf(" basis function count: %d\n",N); plhs[0] = mxCreateDoubleMatrix(maxElements,1,mxREAL); plhs[1] = mxCreateDoubleMatrix(maxElements,1,mxREAL); plhs[2] = mxCreateDoubleMatrix(maxElements,1,mxCOMPLEX); ridx = mxGetPr(plhs[0]); cidx = mxGetPr(plhs[1]); MatrixRe = mxGetPr(plhs[2]); MatrixIm = mxGetPi(plhs[2]); if (Display) mexPrintf(" starting matrix make...\n"); makematrix(); if (Display) mexPrintf(" finishing matrix make...\n"); plhs[3] = mxCreateDoubleScalar(nRows); plhs[4] = mxCreateDoubleScalar(nElements); return; }
void mexFunction ( int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin [ ] ) { double xmin, xmax ; Long *Ap, *Ai ; double *Ax, *Az ; Long nrow, ncol, nnz, mkind, skind, mkind_in ; char mtype [4] ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ if (nargin != 1 || nargout > 3) { mexErrMsgTxt ("Usage: [mtype mkind skind] = RBtype (A)") ; } /* ---------------------------------------------------------------------- */ /* get A */ /* ---------------------------------------------------------------------- */ if (!mxIsClass (pargin [0], "double") || !mxIsSparse (pargin [0])) { mexErrMsgTxt ("A must be sparse and double") ; } Ap = (Long *) mxGetJc (pargin [0]) ; Ai = (Long *) mxGetIr (pargin [0]) ; Ax = mxGetPr (pargin [0]) ; Az = mxGetPi (pargin [0]) ; nrow = mxGetM (pargin [0]) ; ncol = mxGetN (pargin [0]) ; /* ---------------------------------------------------------------------- */ /* determine the mtype of A */ /* ---------------------------------------------------------------------- */ mkind_in = mxIsComplex (pargin [0]) ? 2 : 0 ; RBkind (nrow, ncol, Ap, Ai, Ax, Az, mkind_in, &mkind, &skind, mtype, &xmin, &xmax, NULL) ; /* ---------------------------------------------------------------------- */ /* return the result */ /* ---------------------------------------------------------------------- */ pargout [0] = mxCreateString (mtype) ; if (nargout >= 2) { pargout [1] = mxCreateDoubleScalar ((double) mkind) ; } if (nargout >= 3) { pargout [2] = mxCreateDoubleScalar ((double) skind) ; } }
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { Engine *ep; mxArray *T = NULL, *a = NULL, *d = NULL; char buffer[BUFSIZE+1]; double *Dreal, *Dimag; double time[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; /* * Start the MATLAB engine */ if (!(ep = engOpen(NULL))) { MessageBox ((HWND)NULL, (LPSTR)"Can't start MATLAB engine", (LPSTR) "Engwindemo.c", MB_OK); exit(-1); } /* * PART I * * For the first half of this demonstration, we will send data * to MATLAB, analyze the data, and plot the result. */ /* * Create a variable from our data */ T = mxCreateDoubleMatrix(1, 10, mxREAL); memcpy((char *) mxGetPr(T), (char *) time, 10*sizeof(double)); /* * Place the variable T into the MATLAB workspace */ engPutVariable(ep, "T", T); /* * Evaluate a function of time, distance = (1/2)g.*t.^2 * (g is the acceleration due to gravity) */ engEvalString(ep, "D = .5.*(-9.8).*T.^2;"); /* * Plot the result */ engEvalString(ep, "plot(T,D);"); engEvalString(ep, "title('Position vs. Time for a falling object');"); engEvalString(ep, "xlabel('Time (seconds)');"); engEvalString(ep, "ylabel('Position (meters)');"); /* * PART II * * For the second half of this demonstration, we will create another mxArray * put it into MATLAB and calculate its eigen values * */ a = mxCreateDoubleMatrix(3, 2, mxREAL); memcpy((char *) mxGetPr(a), (char *) Areal, 6*sizeof(double)); engPutVariable(ep, "A", a); /* * Calculate the eigen value */ engEvalString(ep, "d = eig(A*A')"); /* * Use engOutputBuffer to capture MATLAB output. Ensure first that * the buffer is always NULL terminated. */ buffer[BUFSIZE] = '\0'; engOutputBuffer(ep, buffer, BUFSIZE); /* * the evaluate string returns the result into the * output buffer. */ engEvalString(ep, "whos"); MessageBox ((HWND)NULL, (LPSTR)buffer, (LPSTR) "MATLAB - whos", MB_OK); /* * Get the eigen value mxArray */ d = engGetVariable(ep, "d"); engClose(ep); if (d == NULL) { MessageBox ((HWND)NULL, (LPSTR)"Get Array Failed", (LPSTR)"Engwindemo.c", MB_OK); } else { Dreal = mxGetPr(d); Dimag = mxGetPi(d); if (Dimag) sprintf(buffer,"Eigenval 2: %g+%gi",Dreal[1],Dimag[1]); else sprintf(buffer,"Eigenval 2: %g",Dreal[1]); MessageBox ((HWND)NULL, (LPSTR)buffer, (LPSTR)"Engwindemo.c", MB_OK); mxDestroyArray(d); } /* * We're done! Free memory, close MATLAB engine and exit. */ mxDestroyArray(T); mxDestroyArray(a); return(0); }
mxArray *sfmult_AT_XN_YN // 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 (m != 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 (n, k, 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) ; } //-------------------------------------------------------------------------- // allocate workspace //-------------------------------------------------------------------------- sfmult_walloc ((k == 2) ? 2 : 4, m, &Wx, &Wz) ; //-------------------------------------------------------------------------- // Y = A'*X, in blocks of up to 4 columns of X using sfmult_atxtyn //-------------------------------------------------------------------------- k1 = k % 4 ; if (k1 == 1) { // Y (:,1) = A' * X(:,1) sfmult_AT_x_1 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Xx, Xz, ac, xc, yc) ; Yx += n ; Yz += n ; Xx += m ; Xz += m ; } else if (k1 == 2) { // W = X (:,1:2)' for (i = 0 ; i < m ; i++) { Wx [2*i ] = Xx [i ] ; Wx [2*i+1] = Xx [i+m] ; } // Y = A' * W' sfmult_AT_XT_YN_2 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Wx, Wz, ac, xc, yc) ; Yx += 2*n ; Yz += 2*n ; Xx += 2*m ; Xz += 2*m ; } else if (k1 == 3) { // W = X (:,1:3)' for (i = 0 ; i < m ; i++) { Wx [4*i ] = Xx [i ] ; Wx [4*i+1] = Xx [i+m ] ; Wx [4*i+2] = Xx [i+2*m] ; } // Y = A' * W' sfmult_AT_XT_YN_3 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Wx, Wz, ac, xc, yc) ; Yx += 3*n ; Yz += 3*n ; Xx += 3*m ; Xz += 3*m ; } for ( ; k1 < k ; k1 += 4) { // W = X (:,1:4)' for (i = 0 ; i < m ; i++) { Wx [4*i ] = Xx [i ] ; Wx [4*i+1] = Xx [i+m ] ; Wx [4*i+2] = Xx [i+2*m] ; Wx [4*i+3] = Xx [i+3*m] ; } // Y (:,k1+(1:4)) = A' * W' sfmult_AT_XT_YN_4 (Yx, Yz, Ap, Ai, Ax, Az, m, n, Wx, Wz, ac, xc, yc) ; Yx += 4*n ; Yz += 4*n ; Xx += 4*m ; Xz += 4*m ; } //-------------------------------------------------------------------------- // free workspace and return result //-------------------------------------------------------------------------- mxFree (Wx) ; return (Y) ; }
input_t get_input(int nlhs,int nrhs,const mxArray *prhs[]) { input_t input; int n,i; double *x,*ry_temp,*iy_temp,*third,fourth,fifth; COMPLEX_T *y; input.stop_params.threshold = DEFAULT_THRESHOLD; input.stop_params.tolerance = DEFAULT_TOLERANCE; input.allocated_x=0; #ifdef _ALT_MEXERRMSGTXT_ input.error_flag=0; #endif input.max_imfs=0; input.nbphases=DEFAULT_NBPHASES; /* argument checking*/ if (nrhs>5) mexErrMsgTxt("Too many arguments"); if (nrhs<2) mexErrMsgTxt("Not enough arguments"); if (nlhs>2) mexErrMsgTxt("Too many output arguments"); if (!mxIsEmpty(prhs[0])) if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0]) || (mxGetNumberOfDimensions(prhs[0]) > 2)) mexErrMsgTxt("X must be either empty or a double precision real vector."); if (!mxIsNumeric(prhs[1]) || !mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1]) ||/* length of vector x */ (mxGetNumberOfDimensions(prhs[1]) > 2)) mexErrMsgTxt("Y must be a double precision complex vector."); /* input reading: x and y */ n=GREATER(mxGetN(prhs[1]),mxGetM(prhs[1])); /* length of vector x */ if (mxIsEmpty(prhs[0])) { input.allocated_x = 1; x = (double *)malloc(n*sizeof(double)); for(i=0;i<n;i++) x[i] = i; } else x=mxGetPr(prhs[0]); ry_temp=mxGetPr(prhs[1]); iy_temp=mxGetPi(prhs[1]); /* third argument */ if (nrhs>=3) { if(!mxIsEmpty(prhs[2])) { if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2]) || !mxIsDouble(prhs[2]) || (mxGetN(prhs[2])!=1 && mxGetM(prhs[2])!=1)) mexPrintf("STOP must be a real vector of 1 or 2 elements"); i = GREATER(mxGetN(prhs[2]),mxGetM(prhs[2])); if (i>2) mexErrMsgTxt("STOP must be a vector of 1 or 2 elements"); third=mxGetPr(prhs[2]); switch (i) { case 1 : { input.stop_params.threshold=*third; break; } case 2 : { input.stop_params.threshold=third[0]; input.stop_params.tolerance=third[1]; } } /* input checking */ if (input.stop_params.threshold <= 0) mexErrMsgTxt("threshold must be a positive number"); if (input.stop_params.threshold >= 1) mexWarnMsgTxt("threshold should be lower than 1"); if (input.stop_params.tolerance < 0 || input.stop_params.tolerance >= 1) mexErrMsgTxt("tolerance must be a real number in [O,1]"); } } /* fourth argument */ if (nrhs>=4) { if (!mxIsEmpty(prhs[3])) { /* if empty -> do nothing */ if (!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) || mxIsSparse(prhs[3]) || !mxIsDouble(prhs[3]) || mxGetN(prhs[3])!=1 || mxGetM(prhs[3])!=1) mexErrMsgTxt("NB_IMFS must be a positive integer"); fourth=*mxGetPr(prhs[3]); if ((unsigned int)fourth != fourth) mexErrMsgTxt("NB_IMFS must be a positive integer"); input.max_imfs=(int)fourth; } } /* fifth argument */ if (nrhs==5) { if(!mxIsNumeric(prhs[4]) || mxIsComplex(prhs[4]) || mxIsSparse(prhs[4]) || mxGetN(prhs[4])!=1 || mxGetM(prhs[4])!=1) mexErrMsgTxt("NBPHASES must be a positive integer"); fifth=*mxGetPr(prhs[4]); if ((int)fifth != fifth) mexErrMsgTxt("NBPHASES must be a positive integer"); input.nbphases = (int)fifth; } /* more input checking */ if (!input.allocated_x && SMALLER(mxGetN(prhs[0]),mxGetM(prhs[0]))!=1 || SMALLER(mxGetN(prhs[1]),mxGetM(prhs[1]))!=1) mexErrMsgTxt("X and Y must be vectors"); if (GREATER(mxGetN(prhs[1]),mxGetM(prhs[1]))!=n) mexErrMsgTxt("X and Y must have the same length"); i=1; while (i<n && x[i]>x[i-1]) i++; if (i<n) mexErrMsgTxt("Values in X must be non decreasing"); /* copy vector y to avoid erasing input data */ y=(COMPLEX_T *)malloc(n*sizeof(COMPLEX_T)); #ifdef C99_OK for (i=0;i<n;i++) y[i]=ry_temp[i]+I*iy_temp[i]; #else for (i=0;i<n;i++) { y[i].r=ry_temp[i]; y[i].i=iy_temp[i]; } #endif input.n=n; input.x=x; input.y=y; return input; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // check inputs if (nrhs < 3 || nrhs > 6) mexErrMsgTxt("invalid number of inputs: [x,y,]z,xi,yi[,method]"); if (nlhs != 1) mexErrMsgTxt("invalid number of outputs: zi"); const char *_argin[] = { "x","y","z","xi","yi","method" }; const char **argin = (nrhs < 4)? &_argin[2] : _argin; char buf[1024]; // Check input data const mxArray *X = NULL, *Y = NULL, *Z, *XI, *YI; if (nrhs < 4) Z = prhs[0], XI = prhs[1], YI = prhs[2]; else X = prhs[0], Y = prhs[1], Z = prhs[2], XI = prhs[3], YI = prhs[4]; if (nrhs == 4 || nrhs == 6) nrhs--; // Ignore method for (int ri = 0; ri < nrhs; ri++) { if (!prhs[ri]) { sprintf(buf,"invalid mxArray(%s)", argin[ri]); mexErrMsgTxt(buf); } if (!mxIsDouble(prhs[ri])) { sprintf(buf,"data must be double (%s)", argin[ri]); mexErrMsgTxt(buf); } } if (mxGetNumberOfDimensions(Z) != 2) mexErrMsgTxt("invalid Z dimension: should be 2"); // Need to check whether dims of X,Y,Z matche if (mxGetNumberOfElements(XI) != mxGetNumberOfElements(YI)) mexErrMsgTxt("XI and YI does not match"); // Build output data const int *dimz = mxGetDimensions(Z), *dim = mxGetDimensions(XI); int ndim = mxGetNumberOfDimensions(XI); register double dx = -1, dy = -1, sx = 1, sy = 1; if (nrhs >= 4) { int nx = mxGetNumberOfElements(X), ny = mxGetNumberOfElements(Y); double *pX = mxGetPr(X), *pY = mxGetPr(Y); if (nx == dimz[1] && ny == dimz[0]) dx = -pX[0], sx = (dimz[1]-1)/(pX[nx-1]-pX[0]), dy = -pY[0], sy = (dimz[0]-1)/(pY[ny-1]-pY[0]); else if (nx == ny && ny == mxGetNumberOfElements(Z)) dx = -pX[0], sx = (dimz[1]-1)/(pX[(dimz[1]-1)*dimz[0]]-pX[0]), dy = -pY[0], sy = (dimz[0]-1)/(pY[dimz[0]-1]-pY[0]); else mexErrMsgTxt("X and Y do not match with Z"); } if (mxIsComplex(Z)) { mxArray *ZI = plhs[0] = mxCreateNumericArray(ndim, dim, mxDOUBLE_CLASS, mxCOMPLEX); // Load input data and fill output array double *pZr = mxGetPr(Z), *pZi = mxGetPi(Z), *pXI = mxGetPr(XI), *pYI = mxGetPr(YI); double *pZIr = mxGetPr(ZI), *pZIi = mxGetPi(ZI); // cvImage<double> imgr(pZr, dimz[0], dimz[1]), imgi(pZi, dimz[0], dimz[1]); int h = dimz[0], w = dimz[1]; for (int i = 0, n = mxGetNumberOfElements(XI); i < n; i++) { pZIr[i] = interp(pZr, w,h, sx*(pXI[i]+dx), sy*(pYI[i]+dy)); pZIi[i] = interp(pZi, w,h, sx*(pXI[i]+dx), sy*(pYI[i]+dy)); // cvtPoint<double> p(sy*(pYI[i]+dy),sx*(pXI[i]+dx)); // pZIr[i] = imgr.interp<double,double>(p); // pZIi[i] = imgi.interp<double,double>(p); } } else { mxArray *ZI = plhs[0] = mxCreateNumericArray(ndim, dim, mxDOUBLE_CLASS, mxREAL); // Load input data and fill output array double *pZ = mxGetPr(Z), *pXI = mxGetPr(XI), *pYI = mxGetPr(YI); double *pZI = mxGetPr(ZI); // cvImage<double> img(pZ, dimz[0], dimz[1]); int h = dimz[0], w = dimz[1]; for (int i = 0, n = mxGetNumberOfElements(XI); i < n; i++) { pZI[i] = interp(pZ, w,h, sx*(pXI[i]+dx), sy*(pYI[i]+dy)); // cvtPoint<double> p(sy*(pYI[i]+dy),sx*(pXI[i]+dx)); // pZI[i] = img.interp<double,double>(p); } } }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* Declare variable */ mwSize m,n; mwSize nzmax; mwIndex *irs,*jcs,j,k; int cmplx,isfull; double *pr,*pi,*si,*sr; double percent_sparse; /* Check for proper number of input and output arguments */ if (nrhs != 1) { mexErrMsgIdAndTxt( "MATLAB:fulltosparse:invalidNumInputs", "One input argument required."); } if(nlhs > 1){ mexErrMsgIdAndTxt( "MATLAB:fulltosparse:maxlhs", "Too many output arguments."); } /* Check data type of input argument */ if (!(mxIsDouble(prhs[0]))){ mexErrMsgIdAndTxt( "MATLAB:fulltosparse:inputNotDouble", "Input argument must be of type double."); } if (mxGetNumberOfDimensions(prhs[0]) != 2){ mexErrMsgIdAndTxt( "MATLAB:fulltosparse:inputNot2D", "Input argument must be two dimensional\n"); } /* Get the size and pointers to input data */ m = mxGetM(prhs[0]); n = mxGetN(prhs[0]); pr = mxGetPr(prhs[0]); pi = mxGetPi(prhs[0]); cmplx = (pi==NULL ? 0 : 1); /* Allocate space for sparse matrix * NOTE: Assume at most 20% of the data is sparse. Use ceil * to cause it to round up. */ percent_sparse = 0.2; nzmax=(mwSize)ceil((double)m*(double)n*percent_sparse); plhs[0] = mxCreateSparse(m,n,nzmax,cmplx); sr = mxGetPr(plhs[0]); si = mxGetPi(plhs[0]); irs = mxGetIr(plhs[0]); jcs = mxGetJc(plhs[0]); /* Copy nonzeros */ k = 0; isfull=0; for (j=0; (j<n); j++) { mwSize i; jcs[j] = k; for (i=0; (i<m ); i++) { if (IsNonZero(pr[i]) || (cmplx && IsNonZero(pi[i]))) { /* Check to see if non-zero element will fit in * allocated output array. If not, increase percent_sparse * by 10%, recalculate nzmax, and augment the sparse array */ if (k>=nzmax){ mwSize oldnzmax = nzmax; percent_sparse += 0.1; nzmax = (mwSize)ceil((double)m*(double)n*percent_sparse); /* make sure nzmax increases atleast by 1 */ if (oldnzmax == nzmax) nzmax++; mxSetNzmax(plhs[0], nzmax); mxSetPr(plhs[0], mxRealloc(sr, nzmax*sizeof(double))); if(si != NULL) mxSetPi(plhs[0], mxRealloc(si, nzmax*sizeof(double))); mxSetIr(plhs[0], mxRealloc(irs, nzmax*sizeof(mwIndex))); sr = mxGetPr(plhs[0]); si = mxGetPi(plhs[0]); irs = mxGetIr(plhs[0]); } sr[k] = pr[i]; if (cmplx){ si[k]=pi[i]; } irs[k] = i; k++; } } pr += m; pi += m; } jcs[n] = k; }
/* This function computes the generalised matrix products. Basicially it works by spliting the input X and Y matrices into 2 *virtual* sub-matrices, one for the "outer" product dimensions (x/y rest) (over which the cartesian product is computed) and one for the "inner" product matrices (over which the inner product - or multiply accumulate - is computed). Once these 2 matrices have been computed the result is simply an outer product in tprod and inner product in macc */ void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) { int i, maccnd=0, seqnd=0, BLKSZ=DEFAULTBLKSZ, err=OK; const int xargi=0, ydimspecarg=3; int xdimspecarg=0, yargi=0; /* possibly other way round? */ bool useMATLAB=true; int callType=0; MxInfo xinfo, yinfo, zinfo; MxInfo xmacc, ymacc, zrest, xrest, yrest; int znd, xnidx=0, ynidx=0; int *x2yIdx=0; if (nrhs < 4 || nrhs >6) { ERROR("tprod: Incorrect number of inputs."); err=OTHERERROR; } if (nlhs > 1) { ERROR("tprod: Too many output arguments."); err=OTHERERROR; } if ( mxGetNumberOfDimensions(prhs[ydimspecarg]) > 2 ){ ERROR("tprod: ydimspec must be a vector"); err=OTHERERROR; } /* parse the tprod options list */ if( nrhs >= 5 && mxIsChar(prhs[4]) ) { char *opnmStr=mxArrayToString(prhs[4]); for (i=0 ; opnmStr[i] != 0; i++ ) { switch ( opnmStr[i] ) { case 'm': case 'M': useMATLAB=false; break; case 'n': case 'N': callType=1; break; /* new call type */ case 'o': case 'O': callType=-1; break; /* old call type */ default: WARNING("tprod: Unrecognised tprod option"); } } mxFree(opnmStr); opnmStr=0; } if ( nrhs==6 && mxGetNumberOfElements(prhs[5])==1 ){ BLKSZ=(int)mxGetScalar(prhs[5]); } /* Get X */ xinfo = mkmxInfoMxArray(prhs[xargi],0); /* remove trailing singlenton dimensions from x and y */ for( i=xinfo.nd; i>1; i-- ) if ( xinfo.sz[i-1]!=1 ) break; xinfo.nd=i; /*----------------------------------------------------------------------*/ /* Identify the calling convention used */ if ( callType == 0 ) { /* Try and identify the calling convention used, i.e. X,Y,xdimspec,ydimspec, or X,xdimspec,Y,ydimspec (deprecated) */ if ( mxGetNumberOfDimensions(prhs[1])==2 && ( (mxGetN(prhs[1])==1 && mxGetM(prhs[1])>=xinfo.nd) /* Xdimspec OK */ || (mxGetN(prhs[1])>=xinfo.nd && mxGetM(prhs[1])==1) ) ) { int ynd = 0; const int *ysz = 0; yargi = 2; /* start by trying new call type */ ynd=mxGetNumberOfDimensions(prhs[yargi]); ysz = mxGetDimensions(prhs[yargi]); /* size of poss Y*/ for( i=ynd; i>1; i-- ) if ( ysz[i-1]!=1 ) break; ynd=i; if( mxGetNumberOfElements(prhs[ydimspecarg]) >= ynd ){/*Ydimspec OK*/ callType = 1 ; /* new call type */ } } if( mxGetNumberOfDimensions(prhs[2])==2 && ((mxGetN(prhs[2])==1 && mxGetM(prhs[2])>=xinfo.nd)/* xdimspec OK */ || (mxGetN(prhs[2])>=xinfo.nd && mxGetM(prhs[2])==1) ) ) { /* Consitent so far, check the ydimspec is OK */ int ynd = 0; const int *ysz = 0; yargi = 1; /* start by trying new call type */ ynd=mxGetNumberOfDimensions(prhs[yargi]); ysz = mxGetDimensions(prhs[yargi]); /* size of poss Y*/ for( i=ynd; i>1; i-- ) if ( ysz[i-1]!=1 ) break; ynd=i; if ( mxGetNumberOfElements(prhs[ydimspecarg]) >= ynd ) { if ( callType == 0 ) { /* argument 3 is CONSISTENT, and 2 *WASN'T* */ callType = -1; } else { /* argument 2 consistent ALSO */ /* of one of them matches exactly and the other doesn't */ int xnd = mxGetNumberOfDimensions(prhs[xargi]); /* num input X dims */ if ( xnd==2 && xinfo.nd == 1 ) xnd=1; /* col vec is special case*/ if ( xnd == mxGetNumberOfElements(prhs[1]) /* 1 matches *exactly* */ && xnd != mxGetNumberOfElements(prhs[2]) ) { /* 2 doesn't */ callType = 1; } else if( xnd == mxGetNumberOfElements(prhs[2])/* 2 *exact* match */ && xnd != mxGetNumberOfElements(prhs[1]) ){/* 1 doesn't */ callType = -1; } else { /* neither or both match exactly */ callType = 1; WARNING("tprod: Could not unambigiously determine calling convention, tprod(X,xdimspec,Y,ydimspec) assumed. Use 'n' or 'o' to force new/old convention."); } } } } } switch ( callType ) { case 1: xdimspecarg=1; yargi=2; break;/* new type: X,xdimspec,Y,xdimspec */ case -1: xdimspecarg=2; yargi=1; break;/* old type: X,Y,xdimspec,xdimspec */ default: ERROR("tprod: Couldnt identify calling convention."); err=OTHERERROR; } /* Now we know where the Y is we can get it too! */ yinfo = mkmxInfoMxArray(prhs[yargi],0); /* empty set as input for y means make it copy of x */ if ( yinfo.numel==0 && yinfo.nd==2 && yinfo.sz[0]==0 && yinfo.sz[1]==0 ) { yinfo=copymxInfo(xinfo); } /* remove trailing singlenton dimensions from x and y */ for( i=yinfo.nd; i>1; i-- ) if ( yinfo.sz[i-1]!=1 ) break; yinfo.nd=i; /* check the types are what we can use */ if ( !(xinfo.dtype == DOUBLE_DTYPE || xinfo.dtype == SINGLE_DTYPE ) ){ ERROR("tprod: X type unsuppored: only full double/single"); err=UNSUPPORTEDINPUTS; } if ( mxIsSparse(prhs[xargi]) ){ ERROR("tprod: X is sparse, only full double/single supported"); err=UNSUPPORTEDINPUTS; } if ( !(yinfo.dtype == DOUBLE_DTYPE || yinfo.dtype == SINGLE_DTYPE ) ){ ERROR("tprod: Y type unsuppored: only double, single"); err=UNSUPPORTEDINPUTS; } if ( mxIsSparse(prhs[yargi]) ){ ERROR("tprod: X is sparse, only full double/single supported"); err=UNSUPPORTEDINPUTS; } /* fill in the x2yIdx for the new type of indicies */ maccnd=0; xnidx=mxGetNumberOfElements(prhs[xdimspecarg]); ynidx=mxGetNumberOfElements(prhs[ydimspecarg]); err = compx2yIdx_dd(xinfo,xnidx,mxGetPr(prhs[xdimspecarg]), yinfo,ynidx,mxGetPr(prhs[ydimspecarg]), &x2yIdx,&znd,&maccnd,&seqnd); if ( err != 0 ) { /* FREE and return */ delmxInfo(&xinfo); delmxInfo(&yinfo); if ( x2yIdx != 0 ) FREE(x2yIdx); return ; } #ifdef LOGGING FILE *fd = fopen("/tmp/tprod.log","a"); if( fd==0 ){WARNING("Couldn't open log file /tmp/tprod.log\n"); fd=stderr;} fprintf(fd,"tprod( "); printMxInfoSummary(fd,xinfo);fprintf(fd," ,["); for(i=0; i<xnidx; i++) fprintf(fd,"%d ", (int)mxGetPr(prhs[xdimspecarg])[i]); fprintf(fd,"] , "); printMxInfoSummary(fd,yinfo);fprintf(fd," ,["); for(i=0; i<ynidx; i++) fprintf(fd,"%d ", (int)mxGetPr(prhs[ydimspecarg])[i]); fprintf(fd,"] )\n"); if ( fd!=stderr ) fclose(fd); #endif /* compute the mxInfo for the accumulated and rest sub-matrices */ xmacc = mkemptymxInfo(maccnd); ymacc = mkemptymxInfo(maccnd); /* N.B. xrest.sz holds the size of the combined x and y rest matrix */ xrest = mkemptymxInfo(znd); yrest = mkemptymxInfo(znd); err = initrestmaccmxInfo(znd, xinfo, yinfo, x2yIdx, xnidx, ynidx, &xrest, &yrest, &xmacc, &ymacc); if ( err != 0 ) { /* FREE and return */ delmxInfo(&xinfo); delmxInfo(&yinfo); delmxInfo(&xmacc); delmxInfo(&ymacc); delmxInfo(&xrest); delmxInfo(&yrest); FREE(x2yIdx); return; } /* compute the size of the output matrix */ zinfo=initzmxInfo(znd, xinfo, yinfo, x2yIdx, xnidx, ynidx); /* optimise/standardize the query so its the way tprod wants it */ zrest = copymxInfo(zinfo); err = optimisetprodQuery(&zrest, &xrest, &yrest, &xmacc, &ymacc); if ( err != OK ) { /* free everything and return */ delmxInfo(&xinfo); delmxInfo(&yinfo); delmxInfo(&zinfo); delmxInfo(&xmacc); delmxInfo(&ymacc); delmxInfo(&xrest); delmxInfo(&yrest); delmxInfo(&zrest); FREE(x2yIdx); return; } if ( xrest.rp != xinfo.rp ) { /* swap xinfo/yinfo if needed */ MxInfo tmp = xinfo; xinfo=yinfo; yinfo=tmp; } /* Now do the actuall work to compute the result */ if ( yinfo.numel==0 || xinfo.numel== 0 ) { /* deal with null inputs */ WARNING("tprod: Empty matrix input!"); /* return an empty matrix */ plhs[0]=mxCreateNumericArray(zinfo.nd,zinfo.sz,mxDOUBLE_CLASS, (xinfo.ip==0&&yinfo.ip==0)?mxREAL:mxCOMPLEX); } else if ( useMATLAB && /* allowed */ seqnd==0 && /* no sequential dims */ xmacc.nd <= 1 && /* at most 1 macc dim */ xrest.nd <= 2 && /* at most 2 output dims */ (xrest.nd<= 1 || /* 1 from X */ ((xrest.stride[0]==0) || (stride(xrest,1)==0))) && (yrest.nd<= 1 || /* 1 from Y */ ((yrest.stride[0]==0) || (stride(yrest,1)==0))) && (xmacc.numel*(2+(xinfo.ip==0)+(yinfo.ip==0)) < MATLABMACCTHRESHOLDSIZE ) /* not tooo big! */ ){ /* Phew! we can use matlab! */ if ( xrest.stride[0]>0 ) { /* x comes before y in output */ plhs[0]=MATLAB_mm(zinfo,xinfo,yinfo,xrest,yrest, xmacc,ymacc); } else { /* y comes before x in output, reverse order of inputs */ plhs[0]=MATLAB_mm(zinfo,yinfo,xinfo,yrest,xrest, ymacc,xmacc); } } else { /* otherwise do it ourselves */ /* create the data for the z matrix and set its pointer */ plhs[0]=mxCreateNumericArray(zinfo.nd,zinfo.sz,zinfo.dtype, (xinfo.ip==0&&yinfo.ip==0)?mxREAL:mxCOMPLEX); zinfo.rp = mxGetPr(plhs[0]); zrest.rp=zinfo.rp; zinfo.ip = mxGetPi(plhs[0]); zrest.ip=zinfo.ip; /* call tprod to do the real work */ /* do the (appropriately typed) operation */ if( xrest.dtype==DOUBLE_DTYPE && yrest.dtype==DOUBLE_DTYPE ) {/*dd*/ err= ddtprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ); } else if( xrest.dtype==DOUBLE_DTYPE && yrest.dtype==SINGLE_DTYPE ) {/*ds*/ err= dstprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ); } else if( xrest.dtype==SINGLE_DTYPE && yrest.dtype==DOUBLE_DTYPE ) {/*sd*/ err= sdtprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ); } else if( xrest.dtype==SINGLE_DTYPE && yrest.dtype==SINGLE_DTYPE ){/*ss*/ err= sstprod(zrest,xrest,yrest,xmacc,ymacc,BLKSZ); } else { err= UNSUPPORTEDINPUTS; } /* check for errors */ switch ( err ) { case ZTYPEMISMATCH : ERROR("tprod: Z is of unsupported type"); break; case XTYPEMISMATCH : ERROR("tprod: X is of unsupported type"); break; case YTYPEMISMATCH : ERROR("tprod: Y is of unsupported type"); break; case INTYPEMISMATCH : ERROR("tprod: input real/complex mix unsupported"); break; case OTHERERROR : ERROR("tprod: Something else went wrong, sorry!"); break; case UNSUPPORTEDINPUTS : ERROR("tprod: Inputs of unsupported type: only double/single"); break; default: ; } } /* ensure the output has the size we want */ if ( err==OK && plhs[0] ) mxSetDimensions(plhs[0],zinfo.sz,zinfo.nd); /* free up all the memory we've allocated */ /* N.B. not clear we need to do this from the matlab web-site should happen automatically */ delmxInfo(&xinfo);delmxInfo(&yinfo);delmxInfo(&zinfo); delmxInfo(&xmacc); delmxInfo(&ymacc); delmxInfo(&xrest); delmxInfo(&yrest); FREE(x2yIdx); }
void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] ) { #ifdef LTFAT_DOUBLE if(p_old==0) { mexAtExit(fftrealAtExit); } #endif int L, W, L2; LTFAT_REAL *f, *cout_r, *cout_i; LTFAT_FFTW(iodim) dims[1], howmanydims[1]; LTFAT_FFTW(plan) p; L = mxGetM(prhs[0]); W = mxGetN(prhs[0]); L2 = (L/2)+1; // Get pointer to input. f= (LTFAT_REAL*) mxGetPr(prhs[0]); plhs[0] = ltfatCreateMatrix(L2, W, LTFAT_MX_CLASSID, mxCOMPLEX); // Get pointer to output. cout_r = (LTFAT_REAL*) mxGetPr(plhs[0]); cout_i = (LTFAT_REAL*) mxGetPi(plhs[0]); // Create plan. Copy data from f to cout. dims[0].n = L; dims[0].is = 1; dims[0].os = 1; howmanydims[0].n = W; howmanydims[0].is = L; howmanydims[0].os = L2; // The calling prototype //fftw_plan fftw_plan_guru_split_dft_r2c( // int rank, const fftw_iodim *dims, // int howmany_rank, const fftw_iodim *howmany_dims, // double *in, double *ro, double *io, // unsigned flags); /* We are violating this here: You must create the plan before initializing the input, because FFTW_MEASURE overwrites the in/out arrays. (Technically, FFTW_ESTIMATE does not touch your arrays, but you should always create plans first just to be sure.) */ p = LTFAT_FFTW(plan_guru_split_dft_r2c)(1, dims, 1, howmanydims, f, cout_r, cout_i, FFTW_ESTIMATE); /* FFTW documentation qote http://www.fftw.org/fftw3_doc/New_002darray-Execute-Functions.html#New_002darray-Execute-Functions: ... creating a new plan is quick once one exists for a given size ... so why not to store the old plan.. */ if(p_old!=0) { fftw_destroy_plan(*p_old); free(p_old); } p_old = malloc(sizeof(p)); memcpy(p_old,&p,sizeof(p)); // Real FFT. LTFAT_FFTW(execute)(p); // LTFAT_FFTW(destroy_plan)(p); return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* [keyOut,valOut,k] = spot_mex_msspoly_make_canonical_combine_coeff(key,val) * * key -- m-by-n array, identical rows must be contiguous (e.g. key is sorted) * val -- m-by-1 array * * keyOut -- m-by-n array * valOut -- m-by-1 array * k -- 1-by-1 non-negative integer. * * k is the nubmer of unique rows in key. keyOut(1:k,:) contains the unique rows * valOut(j) = sum_{ i | key(i,:)=keyOut(j,:)} val(i). * */ mxArray *mx_key; mxArray *mx_val; int m,n; double *key; double *valR; double *valI; // Take in arguments. getArgSized(&mx_key,"double",0,nrhs,prhs,-1,-1); key = mxGetPr(mx_key); m = mxGetM(mx_key); n = mxGetN(mx_key); getArgSized(&mx_val,"double",1,nrhs,prhs,m,1); valR = mxGetPr(mx_val); valI = mxGetPi(mx_val); int i,j; mxArray *mx_keyOut; mxArray *mx_valOut; int k; double *keyOut; double *valOutR; double *valOutI; bool flag = mxIsComplex(mx_val); mx_keyOut = mxCreateDoubleMatrix(m,n,mxREAL); keyOut = mxGetPr(mx_keyOut); mx_valOut = mxCreateDoubleMatrix(m,1,flag ? mxCOMPLEX : mxREAL); valOutR = mxGetPr(mx_valOut); valOutI = mxGetPi(mx_valOut); k=-1; for(i = 0; i < m; i++){ if( i == 0 || !rowMatch(keyOut,k,key,i,m,n)){ k++; for(j = 0; j < n; j++){ keyOut[j*m+k] = key[j*m+i]; } valOutR[k] = valR[i]; if(flag == mxCOMPLEX) valOutI[k] = valI[i]; } else { valOutR[k] += valR[i]; if(flag == mxCOMPLEX) valOutI[k] += valI[i]; } } if(nlhs > 0) plhs[0] = mxCreateDoubleScalar(k+1); if(nlhs > 1) plhs[1] = mx_keyOut; if(nlhs > 2) plhs[2] = mx_valOut; }
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 */ ) { Zmat A; ZAMGlevelmat *PRE; ZILUPACKparam *param; integer n; const char **fnames; const mwSize *dims; mxClassID *classIDflags; mxArray *tmp, *fout, *A_input , *b_input, *x0_input, *options_input, *PRE_input, *options_output, *x_output; char *pdata, *input_buf, *output_buf; mwSize mrows, ncols, buflen, ndim,nnz; int ifield, status, nfields, ierr,i,j,k,l,m; size_t sizebuf; double dbuf, *A_valuesR, *A_valuesI, *convert, *sr, *pr, *pi; doublecomplex *sol, *rhs; mwIndex *irs, *jcs, *A_ja, /* row indices of input matrix A */ *A_ia; /* column pointers of input matrix A */ if (nrhs != 5) mexErrMsgTxt("five input arguments required."); else if (nlhs !=2) mexErrMsgTxt("Too many output arguments."); else if (!mxIsStruct(prhs[2])) mexErrMsgTxt("Third input must be a structure."); else if (!mxIsNumeric(prhs[0])) mexErrMsgTxt("First input must be a matrix."); /* The first input must be a square matrix.*/ A_input = (mxArray *) prhs [0] ; /* get size of input matrix A */ mrows = mxGetM (A_input) ; ncols = mxGetN (A_input) ; nnz = mxGetNzmax(A_input); if (mrows!=ncols) { mexErrMsgTxt("First input must be a square matrix."); } if (!mxIsSparse (A_input)) { mexErrMsgTxt ("ILUPACK: input matrix must be in sparse format.") ; } /* copy input matrix to sparse row format */ A.nc=A.nr=mrows; A.ia=(integer *) MAlloc((size_t)(A.nc+1)*sizeof(integer),"ZGNLSYMilupacksolver"); A.ja=(integer *) MAlloc((size_t)nnz *sizeof(integer),"ZGNLSYMilupacksolver"); A. a=(doublecomplex *) MAlloc((size_t)nnz *sizeof(doublecomplex), "ZGNLSYMilupacksolver"); A_ja = (mwIndex *) mxGetIr (A_input) ; A_ia = (mwIndex *) mxGetJc (A_input) ; A_valuesR = (double *) mxGetPr(A_input); if (mxIsComplex(A_input)) A_valuesI = (double *) mxGetPi(A_input); /* -------------------------------------------------------------------- */ /* .. Convert matrix from 0-based C-notation to Fortran 1-based */ /* notation. */ /* -------------------------------------------------------------------- */ /* for (i = 0 ; i < ncols ; i++) for (j = A_ia[i] ; j < A_ia[i+1] ; j++) printf("i=%d j=%d A.real=%e\n", i+1, A_ja[j]+1, A_valuesR[j]); */ for (i=0; i<=A.nr; i++) A.ia[i]=0; /* remember that MATLAB uses storage by columns and NOT by rows! */ for (i=0; i<A.nr; i++) { for (j=A_ia[i]; j<A_ia[i+1]; j++) { k=A_ja[j]; A.ia[k+1]++; } } /* now we know how many entries are located in every row */ /* switch to pointer structure */ for (i=0; i<A.nr; i++) A.ia[i+1]+=A.ia[i]; if (mxIsComplex(A_input)) { for (i=0; i<ncols; i++) { for (j=A_ia[i]; j<A_ia[i+1]; j++) { /* row index l in C-notation */ l=A_ja[j]; /* where does row l currently start */ k=A.ia[l]; /* column index will be i in FORTRAN notation */ A.ja[k]=i+1; A.a [k].r =A_valuesR[j]; A.a [k++].i=A_valuesI[j]; A.ia[l]=k; } } } else { for (i=0; i<ncols; i++) { for (j=A_ia[i]; j<A_ia[i+1]; j++) { /* row index l in C-notation */ l=A_ja[j]; /* where does row l currently start */ k=A.ia[l]; /* column index will be i in FORTRAN notation */ A.ja[k]=i+1; A.a [k].r =A_valuesR[j]; A.a [k++].i=0; A.ia[l]=k; } } } /* switch to FORTRAN style */ for (i=A.nr; i>0; i--) A.ia[i]=A.ia[i-1]+1; A.ia[0]=1; /* for (i = 0 ; i < A.nr ; i++) for (j = A.ia[i]-1 ; j < A.ia[i+1]-1 ; j++) printf("i=%d j=%d A.real=%e A.imag=%e\n", i+1, A.ja[j], A.a[j].r, A.a[j].i); */ /* import pointer to the preconditioner */ PRE_input = (mxArray*) prhs [1] ; /* get number of levels of input preconditioner structure `PREC' */ /* nlev=mxGetN(PRE_input); */ nfields = mxGetNumberOfFields(PRE_input); /* allocate memory for storing pointers */ fnames = mxCalloc((size_t)nfields, (size_t)sizeof(*fnames)); for (ifield = 0; ifield < nfields; ifield++) { fnames[ifield] = mxGetFieldNameByNumber(PRE_input,ifield); /* check whether `PREC.ptr' exists */ if (!strcmp("ptr",fnames[ifield])) { /* field `ptr' */ tmp = mxGetFieldByNumber(PRE_input,0,ifield); pdata = mxGetData(tmp); memcpy(&PRE, pdata, (size_t)sizeof(size_t)); } else if (!strcmp("param",fnames[ifield])) { /* field `param' */ tmp = mxGetFieldByNumber(PRE_input,0,ifield); pdata = mxGetData(tmp); memcpy(¶m, pdata, (size_t)sizeof(size_t)); } } mxFree(fnames); /* rescale input matrix */ /* obsolete for (i=0; i <A.nr; i++) { for (j=A.ia[i]-1; j<A.ia[i+1]-1; j++) { A.a[j].r*=PRE->rowscal[i].r*PRE->colscal[A.ja[j]-1].r; A.a[j].i*=PRE->rowscal[i].r*PRE->colscal[A.ja[j]-1].r; } } */ /* Get third input argument `options' */ options_input=(mxArray*)prhs[2]; nfields = mxGetNumberOfFields(options_input); /* Allocate memory for storing classIDflags */ classIDflags = (mxClassID *) mxCalloc((size_t)nfields+1, (size_t)sizeof(mxClassID)); /* allocate memory for storing pointers */ fnames = mxCalloc((size_t)nfields+1, (size_t)sizeof(*fnames)); /* Get field name pointers */ j=-1; for (ifield = 0; ifield < nfields; ifield++) { fnames[ifield] = mxGetFieldNameByNumber(options_input,ifield); /* check whether `options.niter' already exists */ if (!strcmp("niter",fnames[ifield])) j=ifield; } if (j==-1) fnames[nfields]="niter"; /* mexPrintf("search for niter completed\n"); fflush(stdout); */ /* import data */ for (ifield = 0; ifield < nfields; ifield++) { /* mexPrintf("%2d\n",ifield+1); fflush(stdout); */ tmp = mxGetFieldByNumber(options_input,0,ifield); classIDflags[ifield] = mxGetClassID(tmp); ndim = mxGetNumberOfDimensions(tmp); dims = mxGetDimensions(tmp); /* Create string/numeric array */ if (classIDflags[ifield] == mxCHAR_CLASS) { /* Get the length of the input string. */ buflen = (mxGetM(tmp) * mxGetN(tmp)) + 1; /* Allocate memory for input and output strings. */ input_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char)); /* Copy the string data from tmp into a C string input_buf. */ status = mxGetString(tmp, input_buf, buflen); if (!strcmp("amg",fnames[ifield])) { if (strcmp(param->amg,input_buf)) { param->amg=(char *)MAlloc((size_t)buflen*sizeof(char),"ilupacksolver"); strcpy(param->amg,input_buf); } } else if (!strcmp("presmoother",fnames[ifield])) { if (strcmp(param->presmoother,input_buf)) { param->presmoother=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->presmoother,input_buf); } } else if (!strcmp("postsmoother",fnames[ifield])) { if (strcmp(param->postsmoother,input_buf)) { param->postsmoother=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->postsmoother,input_buf); } } else if (!strcmp("typecoarse",fnames[ifield])) { if (strcmp(param->typecoarse,input_buf)) { param->typecoarse=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->typecoarse,input_buf); } } else if (!strcmp("typetv",fnames[ifield])) { if (strcmp(param->typetv,input_buf)) { param->typetv=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->typetv,input_buf); } } else if (!strcmp("FCpart",fnames[ifield])) { if (strcmp(param->FCpart,input_buf)) { param->FCpart=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->FCpart,input_buf); } } else if (!strcmp("solver",fnames[ifield])) { if (strcmp(param->solver,input_buf)) { param->solver=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->solver,input_buf); } } else if (!strcmp("ordering",fnames[ifield])) { if (strcmp(param->ordering,input_buf)) { param->ordering=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->ordering,input_buf); } } else { /* mexPrintf("%s ignored\n",fnames[ifield]);fflush(stdout); */ } } else { if (!strcmp("elbow",fnames[ifield])) { param->elbow=*mxGetPr(tmp); } else if (!strcmp("lfilS",fnames[ifield])) { param->lfilS=*mxGetPr(tmp); } else if (!strcmp("lfil",fnames[ifield])) { param->lfil=*mxGetPr(tmp); } else if (!strcmp("maxit",fnames[ifield])) { param->maxit=*mxGetPr(tmp); } else if (!strcmp("droptolS",fnames[ifield])) { param->droptolS=*mxGetPr(tmp); } else if (!strcmp("droptolc",fnames[ifield])) { param->droptolc=*mxGetPr(tmp); } else if (!strcmp("droptol",fnames[ifield])) { param->droptol=*mxGetPr(tmp); } else if (!strcmp("condest",fnames[ifield])) { param->condest=*mxGetPr(tmp); } else if (!strcmp("restol",fnames[ifield])) { param->restol=*mxGetPr(tmp); } else if (!strcmp("npresmoothing",fnames[ifield])) { param->npresmoothing=*mxGetPr(tmp); } else if (!strcmp("npostmoothing",fnames[ifield])) { param->npostsmoothing=*mxGetPr(tmp); } else if (!strcmp("ncoarse",fnames[ifield])) { param->ncoarse=*mxGetPr(tmp); } else if (!strcmp("matching",fnames[ifield])) { param->matching=*mxGetPr(tmp); } else if (!strcmp("nrestart",fnames[ifield])) { param->nrestart=*mxGetPr(tmp); } else if (!strcmp("damping",fnames[ifield])) { param->damping.r=*mxGetPr(tmp); if (mxIsComplex(tmp)) param->damping.i=*mxGetPi(tmp); else param->damping.i=0; } else if (!strcmp("mixedprecision",fnames[ifield])) { param->mixedprecision=*mxGetPr(tmp); } else { /* mexPrintf("%s ignored\n",fnames[ifield]);fflush(stdout); */ } } } /* copy right hand side `b' */ b_input = (mxArray *) prhs [3] ; /* get size of input matrix A */ rhs=(doublecomplex*) MAlloc((size_t)A.nr*sizeof(doublecomplex),"ZGNLSYMilupacksolver:rhs"); pr=mxGetPr(b_input); if (!mxIsComplex(b_input)) { for (i=0; i<A.nr; i++) { rhs[i].r=pr[i]; rhs[i].i=0; } } else { pi=mxGetPi(b_input); for (i=0; i<A.nr; i++) { rhs[i].r=pr[i]; rhs[i].i=pi[i]; } } /* copy initial solution `x0' */ x0_input = (mxArray *) prhs [4] ; /* numerical solution */ sol=(doublecomplex *)MAlloc((size_t)A.nr*sizeof(doublecomplex),"ZGNLSYMilupacksolver:sol"); pr=mxGetPr(x0_input); if (!mxIsComplex(x0_input)) { for (i=0; i<A.nr; i++) { sol[i].r=pr[i]; sol[i].i=0; } } else { pi=mxGetPi(x0_input); for (i=0; i<A.nr; i++) { sol[i].r=pr[i]; sol[i].i=pi[i]; } } ierr=ZGNLSYMAMGsolver(&A, PRE, param, rhs, sol); /* Create a struct matrices for output */ nlhs=2; if (j==-1) plhs[1] = mxCreateStructMatrix((mwSize)1, (mwSize)1, (mwSize)nfields+1, fnames); else plhs[1] = mxCreateStructMatrix((mwSize)1, (mwSize)1, (mwSize)nfields, fnames); if (plhs[1]==NULL) mexErrMsgTxt("Could not create structure mxArray\n"); options_output=plhs[1]; /* export data */ for (ifield = 0; ifield<nfields; ifield++) { tmp = mxGetFieldByNumber(options_input,0,ifield); classIDflags[ifield] = mxGetClassID(tmp); ndim = mxGetNumberOfDimensions(tmp); dims = mxGetDimensions(tmp); /* Create string/numeric array */ if (classIDflags[ifield] == mxCHAR_CLASS) { if (!strcmp("amg",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->amg)+1, (size_t)sizeof(char)); strcpy(output_buf,param->amg); fout = mxCreateString(output_buf); } else if (!strcmp("presmoother",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->presmoother)+1, (size_t)sizeof(char)); strcpy(output_buf,param->presmoother); fout = mxCreateString(output_buf); } else if (!strcmp("postsmoother",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->postsmoother)+1, (size_t)sizeof(char)); strcpy(output_buf,param->postsmoother); fout = mxCreateString(output_buf); } else if (!strcmp("typecoarse",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->typecoarse)+1, (size_t)sizeof(char)); strcpy(output_buf,param->typecoarse); fout = mxCreateString(output_buf); } else if (!strcmp("typetv",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->typetv)+1, (size_t)sizeof(char)); strcpy(output_buf,param->typetv); fout = mxCreateString(output_buf); } else if (!strcmp("FCpart",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->FCpart)+1, (size_t)sizeof(char)); strcpy(output_buf,param->FCpart); fout = mxCreateString(output_buf); } else if (!strcmp("solver",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->solver)+1, (size_t)sizeof(char)); strcpy(output_buf, param->solver); fout = mxCreateString(output_buf); } else if (!strcmp("ordering",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->ordering)+1, (size_t)sizeof(char)); strcpy(output_buf, param->ordering); fout = mxCreateString(output_buf); } else { /* Get the length of the input string. */ buflen = (mxGetM(tmp) * mxGetN(tmp)) + 1; /* Allocate memory for input and output strings. */ input_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char)); output_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char)); /* Copy the string data from tmp into a C string input_buf. */ status = mxGetString(tmp, input_buf, buflen); sizebuf = (size_t)buflen*sizeof(char); memcpy(output_buf, input_buf, sizebuf); fout = mxCreateString(output_buf); } } else { /* real case */ if (mxGetPi(tmp)==NULL && strcmp("damping",fnames[ifield])) fout = mxCreateNumericArray(ndim, dims, classIDflags[ifield], mxREAL); else { /* complex case */ fout = mxCreateNumericArray(ndim, dims, classIDflags[ifield], mxCOMPLEX); } pdata = mxGetData(fout); sizebuf = mxGetElementSize(tmp); if (!strcmp("elbow",fnames[ifield])) { dbuf=param->elbow; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("lfilS",fnames[ifield])) { dbuf=param->lfilS; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("lfil",fnames[ifield])) { dbuf=param->lfil; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("maxit",fnames[ifield])) { dbuf=param->maxit; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("droptolS",fnames[ifield])) { dbuf=param->droptolS; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("droptolc",fnames[ifield])) { dbuf=param->droptolc; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("droptol",fnames[ifield])) { dbuf=param->droptol; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("condest",fnames[ifield])) { dbuf=param->condest; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("restol",fnames[ifield])) { dbuf=param->restol; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("npresmoothing",fnames[ifield])) { dbuf=param->npresmoothing; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("npostmoothing",fnames[ifield])) { dbuf=param->npostsmoothing; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("ncoarse",fnames[ifield])) { dbuf=param->ncoarse; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("matching",fnames[ifield])) { dbuf=param->matching; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("nrestart",fnames[ifield])) { dbuf=param->nrestart; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("damping",fnames[ifield])) { pr=mxGetPr(fout); pi=mxGetPi(fout); *pr=param->damping.r; *pi=param->damping.i; } else if (!strcmp("mixedprecision",fnames[ifield])) { dbuf=param->mixedprecision; memcpy(pdata, &dbuf, sizebuf); } else { memcpy(pdata, mxGetData(tmp), sizebuf); } } /* Set each field in output structure */ mxSetFieldByNumber(options_output, (mwIndex)0, ifield, fout); } /* store number of iteration steps */ if (j==-1) ifield=nfields; else ifield=j; fout=mxCreateDoubleMatrix((mwSize)1,(mwSize)1, mxREAL); pr=mxGetPr(fout); *pr=param->ipar[26]; /* set each field in output structure */ mxSetFieldByNumber(options_output, (mwIndex)0, ifield, fout); mxFree(fnames); mxFree(classIDflags); /* mexPrintf("options exported\n"); fflush(stdout); */ /* export approximate solution */ plhs[0] = mxCreateDoubleMatrix((mwSize)A.nr, (mwSize)1, mxCOMPLEX); x_output=plhs[0]; pr=mxGetPr(x_output); pi=mxGetPi(x_output); for (i=0; i<A.nr; i++) { pr[i]=sol[i].r; pi[i]=sol[i].i; } /* release right hand side */ free(rhs); /* release solution */ free(sol); /* release input matrix */ free(A.ia); free(A.ja); free(A.a); switch (ierr) { case 0: /* perfect! */ break; case -1: /* too many iteration steps */ mexPrintf("!!! ILUPACK Warning !!!\n"); mexPrintf("number of iteration steps exceeded its limit.\nEither increase `options.maxit'\n or recompute ILUPACK preconditioner using a smaller `options.droptol'"); break; case -2: /* weird, should not occur */ mexErrMsgTxt("not enough workspace provided."); plhs[0]=NULL; break; case -3: /* breakdown */ mexErrMsgTxt("iterative solver breaks down.\nMost likely you need to recompute ILUPACK preconditioner using a smaller `options.droptol'"); plhs[0]=NULL; break; default: /* zero pivot encountered at step number ierr */ mexPrintf("iterative solver exited with error code %d",ierr); mexErrMsgTxt("."); plhs[0]=NULL; break; } /* end switch */ return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* deal with the underscores now so that they can be ignored after this point */ #ifdef WINDOWS double (*my_ddot)( int *, double *, int *, double *, int *) = ddot; complex16 (*my_zdot)( int *, complex16 *, int *, complex16 *, int *) = zdotu; void (*my_dgemm)(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *) = dgemm; void (*my_zgemm)(char *, char *, int *, int *, int *, complex16 *, complex16 *, int *, complex16 *, int *, complex16 *, complex16 *, int *) = zgemm; #else double (*my_ddot)( int *, double *, int *, double *, int *) = ddot_; complex16 (*my_zdot)( int *, complex16 *, int *, complex16 *, int *) = zdotu_; void (*my_dgemm)(char *, char *, int *, int *, int *, double *, double *, int *, double *, int *, double *, double *, int *) = dgemm_; void (*my_zgemm)(char *, char *, int *, int *, int *, complex16 *, complex16 *, int *, complex16 *, int *, complex16 *, complex16 *, int *) = zgemm_; #endif mwSize M, N, K, K2; mwSize nOmega1, nOmega2, nOmega; mwIndex i,j,k,m; double *U, *V, *output, *outputBLAS; double *U_imag, *V_imag, *output_imag; /* for complex data */ complex16 *U_cplx, *V_cplx, temp_cplx; /* for complex data */ double *omega, *omegaX, *omegaY; mwIndex *omegaI, *omegaJ; /* for sparse version */ int SPARSE = false; int COMPLEX = false; int USE_BLAS = false; int LARGE_BIT = false; int MODE_THREE = false; complex16 alpha_cplx, beta_cplx; complex16 *output_cplx; int one = 1; char transA = 'N', transB = 'T'; mwSize LDA, LDB; double alpha, beta; double BLAS_CUTOFF; /* Check for proper number of input and output arguments */ if ( (nrhs < 3) || (nrhs > 5) ) { printUsage(); mexErrMsgTxt("Three to five input argument required."); } if(nlhs > 1){ printUsage(); mexErrMsgTxt("Too many output arguments."); } /* Check data type of input argument */ if (!(mxIsDouble(prhs[0])) || !((mxIsDouble(prhs[1]))) ){ printUsage(); mexErrMsgTxt("Input arguments wrong data-type (must be doubles)."); } /* Get the size and pointers to input data */ /* TRANSPOSE VERSION: switch mxGetM and mxGetN */ M = mxGetN(prhs[0]); K = mxGetM(prhs[0]); N = mxGetN(prhs[1]); K2 = mxGetM(prhs[1]); if ( K != K2 ) { printUsage(); mexErrMsgTxt("Inner dimension of U and V' must agree."); } COMPLEX = (( (mxIsComplex(prhs[0])) ) || (mxIsComplex(prhs[1])) ); nOmega1 = mxGetM( prhs[2] ); nOmega2 = mxGetN( prhs[2] ); /* on 64-bit systems, these may be longs, but I really want * them to be ints so that they work with the BLAS calls */ mxAssert(M<INT_MAX,"Matrix is too large for 32-bit FORTRAN"); mxAssert(N<INT_MAX,"Matrix is too large for 32-bit FORTRAN"); mxAssert(K<INT_MAX,"Matrix is too large for 32-bit FORTRAN"); if ( (nOmega1 != 1) && (nOmega2 != 1) ) { /* mexErrMsgTxt("Omega must be a vector"); */ /* Update: * if this happens, we assume Omega is really a sparse matrix * and everything is OK */ if ( ( nOmega1 != M ) || ( nOmega2 != N ) || (!mxIsSparse( prhs[2] )) ){ printUsage(); mexErrMsgTxt("Omega must be a vector or a sparse matrix"); } nOmega = mxGetNzmax( prhs[2] ); SPARSE = true; } else { nOmega = nOmega1 < nOmega2 ? nOmega2 : nOmega1; if ( nOmega > N*M ) { printUsage(); mexErrMsgTxt("Omega must have M*N or fewer entries"); } } U = mxGetPr(prhs[0]); V = mxGetPr(prhs[1]); if (COMPLEX) { U_imag = mxGetPi(prhs[0]); V_imag = mxGetPi(prhs[1]); plhs[0] = mxCreateDoubleMatrix(nOmega, 1, mxCOMPLEX); output = mxGetPr(plhs[0]); output_imag = mxGetPi(plhs[0]); U_cplx = (complex16 *)mxMalloc( M*K*sizeof(complex16) ); V_cplx = (complex16 *)mxMalloc( N*K*sizeof(complex16) ); if ( (U_cplx == NULL) || ( V_cplx == NULL ) ) { /* this should be very rare */ mexErrMsgTxt("Unable to allocate memory. Matrix too large?"); } for ( i=0 ; i < M*K ; i++ ){ U_cplx[i].re = (double)U[i]; U_cplx[i].im = (double)U_imag[i]; } for ( i=0 ; i < N*K ; i++ ){ V_cplx[i].re = (double)V[i]; V_cplx[i].im = -(double)V_imag[i]; /* minus sign, since adjoint, not transpose */ } } else { plhs[0] = mxCreateDoubleMatrix(nOmega, 1, mxREAL); /* mxCreateDoubleMatrix automatically zeros out the entries */ output = mxGetPr(plhs[0]); } /* Check for the optional input argument that specifies the cutoff * for level-3 BLAS */ BLAS_CUTOFF = 0.4; MODE_THREE = false; if ( nrhs > 4 ) { BLAS_CUTOFF = (double)*mxGetPr( prhs[4] ); MODE_THREE = true; } else if (nrhs > 3 ) { /* decide if this third argument is BLAS_CUTOFF, * or omegaX */ nOmega1 = mxGetM( prhs[3] ); nOmega2 = mxGetN( prhs[3] ); if ( (nOmega1 == 1) && (nOmega2 == 1) ) { BLAS_CUTOFF = (double)*mxGetPr( prhs[3] ); MODE_THREE = false; } else { MODE_THREE = true; } } /* Decide if we'll make a level-3 BLAS call */ USE_BLAS = ( nOmega >= BLAS_CUTOFF * (M*N) ); /* * We have 3 "modes": * Mode 1 * if omega is a vector of linear indices * Mode 2 * if omega is given only by the nonzero elements of an input * sparse matrix Y * Mode 3 * if omega is given as a set of subscripts, i.e. omegaX, omegaY * then the "for" loop is slightly different * * October 29, 2009: changing this a bit. * For any of the modes, we first check if length(omega) > .8*M*N * If so, we make a level-3 BLAS call (dgemm), and then use this * matrix as needed. * */ /* determine if we're on a 64-bit processor */ LARGE_BIT = ( sizeof( size_t ) > 4 ); if ( USE_BLAS ) { /* we need to compute A itself, so use level-3 BLAS */ /* TRANSPOSE VERSION: switch N and T below, and change the step size and LDA */ /* transA = 'N'; transB = 'T'; LDA = M; LDB = N; */ transA = 'T'; transB = 'N'; LDA = K; LDB = K; if (COMPLEX) { alpha_cplx.re = 1.0; alpha_cplx.im = 0.0; beta_cplx.re = 0.0; beta_cplx.im = 0.0; /* need to make a new complex data structure */ output_cplx = (complex16 *) mxMalloc( M*N*sizeof(complex16) ); if ( output_cplx == NULL ) { /* we don't have enough RAM available */ USE_BLAS = false; } else { my_zgemm(&transA,&transB,(int*)&M,(int*)&N,(int*)&K, &alpha_cplx,U_cplx,(int*)&LDA,V_cplx,(int*)&LDB,&beta_cplx,output_cplx,(int *)&M ); } } else { outputBLAS = (double *)mxMalloc( M*N*sizeof(double) ); if ( outputBLAS == NULL ) { /* we don't have enough RAM available */ USE_BLAS = false; } else { alpha = 1.0; beta = 0.0; my_dgemm(&transA,&transB,(int*)&M,(int*)&N,(int*)&K, &alpha,U,(int*)&LDA,V,(int*)&LDB,&beta,outputBLAS,(int*)&M ); } } } /* --- MODE 1 ---*/ if ( (!MODE_THREE) && (!SPARSE) ) { /* by default, make output the same shape (i.e. row- or column- * vector) as the input "omega" */ mxSetM( plhs[0], mxGetM( prhs[2] ) ); mxSetN( plhs[0], mxGetN( prhs[2] ) ); omega = mxGetPr(prhs[2]); if ( !USE_BLAS ) { if ( (COMPLEX) && (LARGE_BIT) ) { /* TRANSPOSE VERSION: this needs to be tested!!! */ for ( k=0 ; k < nOmega ; k++ ){ i = (mwIndex) ( (mwIndex)(omega[k]-1) % M); j = (mwIndex) ( (mwIndex)(omega[k]-1)/ M); /* implement the BLAS call myself, since BLAS isn't working for me * ZDOTU(N,ZX,INCX,ZY,INCY) * */ temp_cplx.re = 0.0; temp_cplx.im = 0.0; for ( m=0 ; m < K ; m++ ){ /*temp_cplx.re += U_cplx[i+m*M].re * V_cplx[j+m*N].re - U_cplx[i+m*M].im * V_cplx[j+m*N].im; temp_cplx.im += U_cplx[i+m*M].im * V_cplx[j+m*N].re + U_cplx[i+m*M].re * V_cplx[j+m*N].im; */ temp_cplx.re += U_cplx[K*i+m].re * V_cplx[K*j+m].re - U_cplx[K*i+m].im * V_cplx[K*j+m].im; temp_cplx.im += U_cplx[K*i+m].im * V_cplx[K*j+m].re + U_cplx[K*i+m].re * V_cplx[K*j+m].im; } output[k] = temp_cplx.re; output_imag[k] = temp_cplx.im; } } else if (COMPLEX) { /* TRANSPOSE VERSION: UPDATED */ for ( k=0 ; k < nOmega ; k++ ){ i = (mwIndex) ( (mwIndex)(omega[k]-1) % M); j = (mwIndex) ( (mwIndex)(omega[k]-1)/ M); /*temp_cplx = my_zdot( (int*) &K, U_cplx+i, (int*)&M, V_cplx+j, (int*)&N ); */ temp_cplx = my_zdot( (int*) &K, U_cplx+i*K, (int*)&one, V_cplx+j*K, (int*)&one ); output[k] = temp_cplx.re; output_imag[k] = temp_cplx.im; } } else { /* TRANSPOSE VERSION: UPDATED */ for ( k=0 ; k < nOmega ; k++ ){ /* don't forget that Matlab is 1-indexed, C is 0-indexed */ i = (mwIndex) ( (mwIndex)(omega[k]-1) % M); j = (mwIndex) ( (mwIndex)(omega[k]-1)/ M); /*output[k] = my_ddot( (int*)&K, U+i, (int*)&M, V+j, (int*)&N );*/ output[k] = my_ddot( (int*)&K, U+i*K, (int*)&one, V+j*K, (int*)&one ); } } } else { /* (USE_BLAS) is true */ /* We already have the full matrix, so just find the entries */ if (COMPLEX) { for ( k=0 ; k < nOmega ; k++ ){ output[k] = output_cplx[ (mwIndex)omega[k] -1 ].re; output_imag[k] = output_cplx[ (mwIndex)omega[k] - 1 ].im; } mxFree( output_cplx ); } else { for ( k=0 ; k < nOmega ; k++ ){ /* i = (mwIndex) ( (mwIndex)(omega[k]-1) % M); j = (mwIndex) ( (mwIndex)(omega[k]-1)/ M); output[k] = outputBLAS( j*M + i ); */ /* This now simplifies a lot! */ output[k] = outputBLAS[ (mwIndex)omega[k] - 1 ]; } mxFree( outputBLAS ); } } } else { /* ----------- MODE 2 ------------------------------- */ if (SPARSE) { /* sparse array indices in Matlab are rather confusing; * see the mxSetJc help file to get started. The Ir index * is straightforward: it contains rows indices of nonzeros, * in column-major order. But the Jc index is tricky... * Basically, Jc (which has N+1 entries, not nnz entries like Ir) * tells you which Ir entries correspond to the jth row, thus fully * specifying the indices. Ir[ Jc[j]:Jc[J+1] ] are the rows * that correspond to column j. This works because Ir is * in column-major order. For this to work (and match A(omega)), * we need omega to be sorted! *Note: everything is already 0-based, not 1-based * */ omegaI = mxGetIr( prhs[2] ); omegaJ = mxGetJc( prhs[2] ); if ( USE_BLAS ) { /* We already have the full matrix, so just find the entries */ if (COMPLEX) { for ( j=0 ; j < N ; j++ ){ for ( k = omegaJ[j] ; k < omegaJ[j+1] ; k++ ) { i = omegaI[k]; output[k] = output_cplx[ j*M + i ].re; output_imag[k] = output_cplx[ j*M + i ].im; } } mxFree( output_cplx ); } else { for ( j=0 ; j < N ; j++ ){ for ( k = omegaJ[j] ; k < omegaJ[j+1] ; k++ ) { i = omegaI[k]; output[k] = outputBLAS[ j*M + i ]; } } mxFree( outputBLAS ); } } else if ((COMPLEX)&&(LARGE_BIT)) { /* TRANSPOSE VERSION: this needs to be tested!!! */ for ( j=0 ; j < N ; j++ ){ for ( k = omegaJ[j] ; k < omegaJ[j+1] ; k++ ) { i = omegaI[k]; temp_cplx.re = 0.0; temp_cplx.im = 0.0; for ( m=0 ; m < K ; m++ ){ /*temp_cplx.re += U_cplx[i+m*M].re * V_cplx[j+m*N].re - U_cplx[i+m*M].im * V_cplx[j+m*N].im; temp_cplx.im += U_cplx[i+m*M].im * V_cplx[j+m*N].re + U_cplx[i+m*M].re * V_cplx[j+m*N].im;*/ temp_cplx.re += U_cplx[K*i+m].re * V_cplx[K*j+m].re - U_cplx[K*i+m].im * V_cplx[K*j+m].im; temp_cplx.im += U_cplx[K*i+m].im * V_cplx[K*j+m].re + U_cplx[K*i+m].re * V_cplx[K*j+m].im; } output[k] = temp_cplx.re; output_imag[k] = temp_cplx.im; } } } else if (COMPLEX) { /* TRANSPOSE VERSION: UPDATED */ for ( j=0 ; j < N ; j++ ){ for ( k = omegaJ[j] ; k < omegaJ[j+1] ; k++ ) { i = omegaI[k]; /* temp_cplx = my_zdot((int*) &K, U_cplx+i, (int*)&M, V_cplx+j, (int*)&N ); */ temp_cplx = my_zdot((int*) &K, U_cplx+i*K, (int*)&one, V_cplx+j*K, (int*)&one ); output[k] = temp_cplx.re; output_imag[k] = temp_cplx.im; } } } else { /* simple case */ /* TRANSPOSE VERSION: UPDATED */ for ( j=0 ; j < N ; j++ ){ for ( k = omegaJ[j] ; k < omegaJ[j+1] ; k++ ) { i = omegaI[k]; /*output[k] = my_ddot( (int*)&K, U+i, (int*)&M, V+j, (int*)&N );*/ output[k] = my_ddot( (int*)&K, U+i*K, (int*)&one, V+j*K, (int*)&one ); } } } /* ----------- MODE 3 ------------------------------- */ } else { /* we have omegaX and omegaY, the row and column indices */ nOmega1 = mxGetM( prhs[3] ); nOmega2 = mxGetN( prhs[3] ); if ( (nOmega1 != 1) && (nOmega2 != 1) ) { printUsage(); mexErrMsgTxt("OmegaY must be a vector"); } nOmega1 = nOmega1 < nOmega2 ? nOmega2 : nOmega1; if ( nOmega1 != nOmega ) { printUsage(); mexErrMsgTxt("In subscript index format, subscript vectors must be same length."); } omegaX = mxGetPr(prhs[2]); omegaY = mxGetPr(prhs[3]); if ( USE_BLAS ) { /* We already have the full matrix, so just find the entries */ if (COMPLEX) { for ( k=0 ; k < nOmega ; k++ ){ i = omegaX[k] - 1; j = omegaY[k] - 1; output[k] = output_cplx[ j*M + i ].re; output_imag[k] = output_cplx[ j*M + i ].im; } mxFree( output_cplx ); } else { for ( k=0 ; k < nOmega ; k++ ){ i = omegaX[k] - 1; j = omegaY[k] - 1; output[k] = outputBLAS[ j*M + i ]; } mxFree( outputBLAS ); } } else if ((COMPLEX)&&(LARGE_BIT)) { /* TRANSPOSE VERSION: this needs to be tested!!! */ for ( k=0 ; k < nOmega ; k++ ){ i = omegaX[k] - 1; j = omegaY[k] - 1; temp_cplx.re = 0.0; temp_cplx.im = 0.0; for ( m=0 ; m < K ; m++ ){ /*temp_cplx.re += U_cplx[i+m*M].re * V_cplx[j+m*N].re - U_cplx[i+m*M].im * V_cplx[j+m*N].im; temp_cplx.im += U_cplx[i+m*M].im * V_cplx[j+m*N].re + U_cplx[i+m*M].re * V_cplx[j+m*N].im; */ temp_cplx.re += U_cplx[K*i+m].re * V_cplx[K*j+m].re - U_cplx[K*i+m].im * V_cplx[K*j+m].im; temp_cplx.im += U_cplx[K*i+m].im * V_cplx[K*j+m].re + U_cplx[K*i+m].re * V_cplx[K*j+m].im; } output[k] = temp_cplx.re; output_imag[k] = temp_cplx.im; } } else if (COMPLEX) { /* TRANSPOSE VERSION: UPDATED */ for ( k=0 ; k < nOmega ; k++ ){ i = omegaX[k] - 1; j = omegaY[k] - 1; /* temp_cplx = my_zdot( (int*)&K, U_cplx+i, (int*)&M, V_cplx+j, (int*)&N ); */ temp_cplx = my_zdot( (int*)&K, U_cplx+i*K, (int*)&one, V_cplx+j*K, (int*)&one ); output[k] = temp_cplx.re; output_imag[k] = temp_cplx.im; } } else { /* TRANSPOSE VERSION: UPDATED */ for ( k=0 ; k < nOmega ; k++ ){ i = omegaX[k] - 1; j = omegaY[k] - 1; /* output[k] = my_ddot( (int*)&K, U+i, (int*)&M, V+j, (int*)&N ); */ output[k] = my_ddot( (int*)&K, U+i*K, (int*)&one, V+j*K, (int*)&one ); } } } } }
cholmod_sparse *sputil_get_sparse ( const mxArray *Amatlab, /* MATLAB version of the matrix */ cholmod_sparse *A, /* CHOLMOD version of the matrix */ double *dummy, /* a pointer to a valid scalar double */ mwSize stype /* -1: lower, 0: unsymmetric, 1: upper */ ) { mwSize *Ap ; A->nrow = mxGetM (Amatlab) ; A->ncol = mxGetN (Amatlab) ; A->p = (mwSize *) mxGetJc (Amatlab) ; A->i = (mwSize *) mxGetIr (Amatlab) ; Ap = (mwSize*)A->p ; A->nzmax = Ap [A->ncol] ; A->packed = TRUE ; A->sorted = TRUE ; A->nz = NULL ; A->itype = CHOLMOD_LONG ; /* was CHOLMOD_INT in v1.6 and earlier */ A->dtype = CHOLMOD_DOUBLE ; A->stype = stype ; #ifndef MATLAB6p1_OR_EARLIER if (mxIsLogical (Amatlab)) { A->x = NULL ; A->z = NULL ; A->xtype = CHOLMOD_PATTERN ; } else if (mxIsEmpty (Amatlab)) { /* this is not dereferenced, but the existence (non-NULL) of these * pointers is checked in CHOLMOD */ A->x = dummy ; A->z = dummy ; A->xtype = mxIsComplex (Amatlab) ? CHOLMOD_ZOMPLEX : CHOLMOD_REAL ; } else if (mxIsDouble (Amatlab)) { A->x = mxGetPr (Amatlab) ; A->z = mxGetPi (Amatlab) ; A->xtype = mxIsComplex (Amatlab) ? CHOLMOD_ZOMPLEX : CHOLMOD_REAL ; } else { /* only logical and complex/real double matrices supported */ //sputil_error (ERROR_INVALID_TYPE, 0) ; // modified by AS, Oct 2009 } #else if (mxIsEmpty (Amatlab)) { /* this is not dereferenced, but the existence (non-NULL) of these * pointers is checked in CHOLMOD */ A->x = dummy ; A->z = dummy ; A->xtype = mxIsComplex (Amatlab) ? CHOLMOD_ZOMPLEX : CHOLMOD_REAL ; } else { /* in MATLAB 6.1, the matrix is sparse, so it must be double */ A->x = mxGetPr (Amatlab) ; A->z = mxGetPi (Amatlab) ; A->xtype = mxIsComplex (Amatlab) ? CHOLMOD_ZOMPLEX : CHOLMOD_REAL ; } #endif return (A) ; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* Declare variable */ mwSize M, N; mwIndex i, j, m, n; double *b, *S, *omega; int SORTED = true; int COMPLEX; /* Check for proper number of input and output arguments */ if ( (nrhs < 2) || (nrhs > 3) ) { printUsage(); mexErrMsgTxt("Needs 2 or 3 input arguments"); } if ( nrhs == 3 ) SORTED = false; if(nlhs > 0){ printUsage(); mexErrMsgTxt("No output arguments!"); } /* Check data type of input argument */ if (!(mxIsSparse(prhs[0])) || !((mxIsDouble(prhs[1]))) ){ printUsage(); mexErrMsgTxt("Input arguments wrong data-type (must be sparse, double)."); } /* check if "b" is complex */ if ( mxIsComplex(prhs[1]) ) { COMPLEX = 1; /* mexPrintf("Input is complex\n"); */ if (!mxIsComplex( prhs[0] )) { printUsage(); mexErrMsgTxt("if second input is complex, first input must be also"); } }else{ COMPLEX = 0; if (mxIsComplex( prhs[0] )) { printUsage(); mexErrMsgTxt("if first input is complex, second input must be also"); } } /* Get the size and pointers to input data */ /* Check second input */ N = mxGetN( prhs[1] ); M = mxGetM( prhs[1] ); if ( (M>1) && (N>1) ) { printUsage(); mexErrMsgTxt("Second argument must be a vector"); } N = (N>M) ? N : M; /* Check first input */ M = mxGetNzmax( prhs[0] ); if ( M != N ) { printUsage(); mexErrMsgTxt("Length of second argument must match nnz of first argument"); } /* Check that the sparse matrix contains doubles, not logicals * or something else */ if (!mxIsDouble( prhs[0] )) { printUsage(); mexErrMsgTxt("First input must contain numeric entries (double floats), not logicals"); } /* if 3rd argument provided, check that it agrees with 2nd argument */ if (!SORTED) { m = mxGetM( prhs[2] ); n = mxGetN( prhs[2] ); if ( (m>1) && (n>1) ) { printUsage(); mexErrMsgTxt("Third argument must be a vector"); } n = (n>m) ? n : m; if ( n != N ) { printUsage(); mexErrMsgTxt("Third argument must be same length as second argument"); } omega = mxGetPr( prhs[2] ); } b = mxGetPr( prhs[1] ); S = mxGetPr( prhs[0] ); if (SORTED) { /* And here's the really fancy part: */ for ( i=0 ; i < N ; i++ ) S[i] = b[i]; } else { for ( i=0 ; i < N ; i++ ) { /* this is a little slow, but I should really check * to make sure the index is not out-of-bounds, otherwise * Matlab could crash */ j = (int)omega[i]-1; /* the -1 because Matlab is 1-based */ if ((j >= N)||(j<0)){ printUsage(); mexErrMsgTxt("Third argument must have values < length of 2nd argument"); } /* S[ j ] = b[i]; */ /* this is incorrect */ S[ i ] = b[j]; /* this is the correct form */ } } if (COMPLEX){ b = mxGetPi( prhs[1] ); S = mxGetPi( prhs[0] ); if (SORTED) { for ( i=0 ; i < N ; i++ ) S[i] = b[i]; } else { for ( i=0 ; i < N ; i++ ) { j = (int)omega[i]-1; S[ i ] = b[j]; } } } }
mxArray *ssmult_dot /* returns C = A'*B */ ( const mxArray *A, const mxArray *B, int ac, /* if true: conj(A) if false: A. ignored if A real */ int bc, /* if true: conj(B) if false: B. ignored if B real */ int cc /* if true: conj(C) if false: C. ignored if C real */ ) { double cx, cz, ax, az, bx, bz ; mxArray *C ; double *Ax, *Az, *Bx, *Bz, *Cx, *Cz ; Int *Ap, *Ai, *Bp, *Bi, *Cp, *Ci ; Int m, n, k, cnzmax, i, j, p, paend, pbend, ai, bi, cnz, pa, pb, zallzero, A_is_complex, B_is_complex, C_is_complex ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ m = mxGetM (A) ; n = mxGetN (A) ; k = mxGetN (B) ; if (m != mxGetM (B)) ssmult_invalid (ERROR_DIMENSIONS) ; Ap = mxGetJc (A) ; Ai = mxGetIr (A) ; Ax = mxGetPr (A) ; Az = mxGetPi (A) ; A_is_complex = mxIsComplex (A) ; Bp = mxGetJc (B) ; Bi = mxGetIr (B) ; Bx = mxGetPr (B) ; Bz = mxGetPi (B) ; B_is_complex = mxIsComplex (B) ; /* ---------------------------------------------------------------------- */ /* allocate C as an n-by-k full matrix but do not initialize it */ /* ---------------------------------------------------------------------- */ /* NOTE: integer overflow cannot occur here, because this function is not called unless O(n*k) is less than O(m+nnz(A)). The test is done in the caller, not here. */ cnzmax = n*k ; cnzmax = MAX (cnzmax, 1) ; Cx = mxMalloc (cnzmax * sizeof (double)) ; C_is_complex = A_is_complex || B_is_complex ; Cz = C_is_complex ? mxMalloc (cnzmax * sizeof (double)) : NULL ; /* ---------------------------------------------------------------------- */ /* C = A'*B using sparse dot products */ /* ---------------------------------------------------------------------- */ /* NOTE: this method REQUIRES the columns of A and B to be sorted on input. That is, the row indices in each column must appear in ascending order. This is the standard in all versions of MATLAB to date, and likely will be for some time. However, if MATLAB were to use unsorted sparse matrices in the future (a lazy sort) then a test should be included in ssmult to not use ssmult_dot if A or B are unsorted, or they should be sorted on input. */ cnz = 0 ; for (j = 0 ; j < k ; j++) { for (i = 0 ; i < n ; i++) { /* compute C (i,j) = A (:,i)' * B (:,j) */ pa = Ap [i] ; paend = Ap [i+1] ; pb = Bp [j] ; pbend = Bp [j+1] ; if (pa == paend /* nnz (A (:,i)) == 0 */ || pb == pbend /* nnz (B (:,j)) == 0 */ || Ai [paend-1] < Bi [pb] /* max(find(A(:,i)))<min(find(B(:,j))) */ || Ai [pa] > Bi [pbend-1]) /* min(find(A(:,i)))>max(find(B(:,j))) */ { Cx [i+j*n] = 0 ; /* no work to do */ if (C_is_complex) { Cz [i+j*n] = 0 ; } continue ; } cx = 0 ; cz = 0 ; while (pa < paend && pb < pbend) { /* The dot product looks like the merge in mergesort, except */ /* no "clean-up" phase is need when one list is exhausted. */ ai = Ai [pa] ; bi = Bi [pb] ; if (ai == bi) { /* c += A (ai,i) * B (ai,j), and "consume" both entries */ if (!C_is_complex) { cx += Ax [pa] * Bx [pb] ; } else { /* complex case */ ax = Ax [pa] ; bx = Bx [pb] ; az = Az ? (ac ? (-Az [pa]) : Az [pa]) : 0.0 ; bz = Bz ? (bc ? (-Bz [pb]) : Bz [pb]) : 0.0 ; cx += ax * bx - az * bz ; cz += az * bx + ax * bz ; } pa++ ; pb++ ; } else if (ai < bi) { /* consume A(ai,i) and discard it, since B(ai,j) is zero */ pa++ ; } else { /* consume B(bi,j) and discard it, since A(ai,i) is zero */ pb++ ; } } Cx [i+j*n] = cx ; if (C_is_complex) { Cz [i+j*n] = cz ; } } /* count the number of nonzeros in C(:,j) */ for (i = 0 ; i < n ; i++) { /* This could be done above, except for the gcc compiler bug when cx is an 80-bit nonzero in register above, but becomes zero here when stored into memory. We need the latter, to correctly handle the case when cx underflows to zero in 64-bit floating-point. Do not attempt to "optimize" this code by doing this test above, unless the gcc compiler bug is fixed (as of gcc version 4.1.0). */ if (Cx [i+j*n] != 0 || (C_is_complex && Cz [i+j*n] != 0)) { cnz++ ; } } } /* ---------------------------------------------------------------------- */ /* convert C to real if the imaginary part is all zero */ /* ---------------------------------------------------------------------- */ if (C_is_complex) { zallzero = 1 ; for (p = 0 ; zallzero && p < cnzmax ; p++) { if (Cz [p] != 0) { zallzero = 0 ; } } if (zallzero) { /* the imaginary part of C is all zero */ C_is_complex = 0 ; mxFree (Cz) ; Cz = NULL ; } } /* ---------------------------------------------------------------------- */ /* allocate integer part of C but do not initialize it */ /* ---------------------------------------------------------------------- */ cnz = MAX (cnz, 1) ; C = mxCreateSparse (0, 0, 0, C_is_complex ? mxCOMPLEX : mxREAL) ; mxFree (mxGetJc (C)) ; mxFree (mxGetIr (C)) ; mxFree (mxGetPr (C)) ; mxFree (mxGetPi (C)) ; Cp = mxMalloc ((k + 1) * sizeof (Int)) ; Ci = mxMalloc (cnz * sizeof (Int)) ; mxSetJc (C, Cp) ; mxSetIr (C, Ci) ; mxSetM (C, n) ; mxSetN (C, k) ; /* ---------------------------------------------------------------------- */ /* C = sparse (C). Note that this is done in-place. */ /* ---------------------------------------------------------------------- */ p = 0 ; for (j = 0 ; j < k ; j++) { Cp [j] = p ; for (i = 0 ; i < n ; i++) { cx = Cx [i+j*n] ; cz = (C_is_complex ? Cz [i+j*n] : 0) ; if (cx != 0 || cz != 0) { Ci [p] = i ; Cx [p] = cx ; if (C_is_complex) Cz [p] = (cc ? (-cz) : cz) ; p++ ; } } } Cp [k] = p ; /* ---------------------------------------------------------------------- */ /* reduce the size of Cx and Cz and return result */ /* ---------------------------------------------------------------------- */ if (cnz < cnzmax) { Cx = mxRealloc (Cx, cnz * sizeof (double)) ; if (C_is_complex) { Cz = mxRealloc (Cz, cnz * sizeof (double)) ; } } mxSetNzmax (C, cnz) ; mxSetPr (C, Cx) ; if (C_is_complex) { mxSetPi (C, Cz) ; } return (C) ; }
/* * mexFunction * * This is like main for a matlab integration point. When matlab calls the * function which is setup to associate with this file, this will be the entry * point. * * int nlhs - number of LHS arguments (return arguments) * mxArray *plhs - an array to fill with these return arguments * int nrhs - number of RHS arguments (function arguments) * mxArray *prhs - an array containing these function arguments * * In our specific case, we are expecting the following input arguments: * * KTrans - array of floats [2D, real valued] * k_ep - array of floats [2D, real valued] * dt_i - float * Ti - int * dt_j - float * Tj - int * Cpi - vector of floats [2D, real valued] * samplingRate - float * gpuAccelerate - bool * * and the following output arguments: * * imgSeq - array of floats [3D, complex valued] */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Check for the correct number of input arguments */ if (nrhs != 9) { mexPrintf("Wrong number of arguments, expecting ...(kTrans, kEp, t0, samplingRate)\n"); return; } /* Check for the correct number of output arguments */ if (nlhs != 1) { mexPrintf("Wrong number of return values, expecting 1"); return; } /* Extract specific mxArray input structures */ const mxArray *mx_KTrans = prhs[0]; const mxArray *mx_k_ep = prhs[1]; const mxArray *mx_dt_i = prhs[2]; const mxArray *mx_Ti = prhs[3]; const mxArray *mx_dt_j = prhs[4]; const mxArray *mx_Tj = prhs[5]; const mxArray *mx_Cpi = prhs[6]; const mxArray *mx_samplingRate = prhs[7]; const mxArray *mx_gpuAccelerate = prhs[8]; /* Extract specific input data ptrs */ float *KTrans = (float *)mxGetPr(mx_KTrans); float *k_ep = (float *)mxGetPr(mx_k_ep); float dt_i = *(float *)mxGetPr(mx_dt_i); int Ti = *(int *)mxGetPr(mx_Ti); float dt_j = *(float *)mxGetPr(mx_dt_j); int Tj = *(int *)mxGetPr(mx_Tj); float *Cpi = (float *)mxGetPr(mx_Cpi); float samplingRate = *(float *)mxGetPr(mx_samplingRate); bool gpuAccelerate = *(bool *)mxGetPr(mx_gpuAccelerate); /* Extract other useful information from input */ const mwSize *kTransDims = mxGetDimensions(mx_KTrans); /* Setup output matrix */ mwSize ndim = 3; mwSize *dims = (mwSize *)mxMalloc(ndim * sizeof(mwSize)); dims[0] = kTransDims[0]; dims[1] = kTransDims[1]; dims[2] = Tj; mxArray *mxImgSeq = mxCreateNumericArray(ndim, dims, mxSINGLE_CLASS, mxCOMPLEX); /* Extract specific output data ptrs */ float *imgSeqR = (float *)mxGetPr(mxImgSeq); float *imgSeqI = (float *)mxGetPi(mxImgSeq); /* Call the appropriate kernel with the translated data */ int success; if (gpuAccelerate) { /* Call the CUDA kernel */ success = gpuSetupAndConvolve( KTrans, k_ep, dt_i, Ti, dt_j, Tj, Cpi, samplingRate, imgSeqR, imgSeqI, dims[0], dims[1]); } else { /* Call a sequential C version of the kernel */ success = cSetupAndConvolve( KTrans, k_ep, dt_i, Ti, dt_j, Tj, Cpi, samplingRate, imgSeqR, imgSeqI, dims[0], dims[1]); } /* Check that cuda code completed successfully */ if (success != 0) { mexPrintf("Cuda host encountered a memory error.\n"); } /* Free memory */ mxFree(dims); /* Set output to computed matrix */ plhs[0] = mxImgSeq; }
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) ; }
/* ************************************************************ PROCEDURE mexFunction - Entry for Matlab ************************************************************ */ void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) { mwIndex i,j,jnz,MAXN, m,dimflqr,lenfull,reallength, nf,nx,ns, iwsize; mwIndex *iwork, *sdpNL, *cpxf, *cpxx, *cpxs, *cpxsi; bool *cwork; const double *cpxfPr, *cpxxPr, *cpxsPr, *xpi; mxArray *MY_FIELD; coneK cK; jcir x,y; /* ------------------------------------------------------------ Check for proper number of arguments ------------------------------------------------------------ */ mxAssert(nrhs >= NPARIN, "makereal requires more input arguments"); mxAssert(nlhs <= NPAROUT, "makereal produces less output arguments"); /* ------------------------------------------------------------ Disassemble cone K structure ------------------------------------------------------------ */ conepars(K_IN, &cK); dimflqr = cK.frN + cK.lpN + cK.qDim; for(i = 0; i < cK.rconeN; i++) /* add dim of rotated cone */ dimflqr += cK.rconeNL[i]; lenfull = dimflqr + cK.rDim + cK.hDim; /* ------------------------------------------------------------ Disassemble cpx structure ------------------------------------------------------------ */ mxAssert(mxIsStruct(CPX_IN), "Parameter `cpx' should be a structure."); if( (MY_FIELD = mxGetField(CPX_IN,(mwIndex)0,"f")) == NULL) /* cpx.f */ nf = 0; else{ nf = mxGetM(MY_FIELD) * mxGetN(MY_FIELD); cpxfPr = mxGetPr(MY_FIELD); } if( (MY_FIELD = mxGetField(CPX_IN,(mwIndex)0,"s")) == NULL) /* cpx.s */ ns = 0; else{ ns = mxGetM(MY_FIELD) * mxGetN(MY_FIELD); cpxsPr = mxGetPr(MY_FIELD); } if( (MY_FIELD = mxGetField(CPX_IN,(mwIndex)0,"x")) == NULL) /* cpx.x */ nx = 0; else{ nx = mxGetM(MY_FIELD) * mxGetN(MY_FIELD); cpxxPr = mxGetPr(MY_FIELD); } /* ------------------------------------------------------------ Get input matrix x ------------------------------------------------------------ */ mxAssert(mxGetM(X_IN) == lenfull, "Size x mismatch."); m = mxGetN(X_IN); /* number of columns to handle */ mxAssert( mxIsSparse(X_IN), "X should be sparse."); x.pr = mxGetPr(X_IN); if(mxIsComplex(X_IN)) xpi = mxGetPi(X_IN); else xpi = (double *) NULL; x.jc = mxGetJc(X_IN); x.ir = mxGetIr(X_IN); /* ------------------------------------------------------------ Allocate iwork[iwsiz], cwork[MAXN], {K.s, cpx.{f[nf],x[nx],s[ns],si[2*ns]}} ------------------------------------------------------------ */ MAXN = MAX(MAX(nf,nx),2*ns); iwsize = floor(log(1.0 + MAXN) / log(2.0)); /* for binary tree search */ iwsize += 2 * ns + 2 + MAXN; iwork = (mwIndex *) mxCalloc(iwsize, sizeof(mwIndex)); cwork = (bool *) mxCalloc(MAX(1,MAXN), sizeof(bool)); sdpNL = (mwIndex *) mxCalloc(MAX(1, cK.sdpN + nf + nx + 3*ns), sizeof(mwIndex)); cpxf = sdpNL + cK.sdpN; cpxx = cpxf + nf; cpxs = cpxx + nx; cpxsi = cpxs + ns; /* length 2*ns */ /* ------------------------------------------------------------ Convert double to mwIndex ------------------------------------------------------------ */ for(i = 0; i < cK.sdpN; i++){ /* K.s */ j = cK.sdpNL[i]; sdpNL[i] = j; /* These are lengths, not subscripts!*/ } for(i = 0; i < nf; i++){ /* cpx.f */ j = cpxfPr[i]; cpxf[i] = --j; } for(i = 0; i < nx; i++){ /* cpx.x */ j = cpxxPr[i]; cpxx[i] = --j; } for(i = 0; i < ns; i++){ /* cpx.s */ j = cpxsPr[i]; cpxs[i] = --j; } /* ------------------------------------------------------------ Create cpxsi(1:2*ns). This lists the 1st subscript and the 1-beyond-last subscript of each Hermitian PSD matrix in x. ------------------------------------------------------------ */ jnz = dimflqr; j = 0; for(i = 0; i < ns; i++){ for(; j < cpxs[i]; j++) jnz += SQR(sdpNL[j]); cpxsi[2 * i] = jnz; /* start of Hermitian block */ jnz += SQR(sdpNL[j]); j++; cpxsi[2 * i + 1] = jnz; /* end of Hermitian block */ } /* ------------------------------------------------------------ Allocate output Y = sparse([],[],[],reallength(x),m,2 * nnz(x)) ------------------------------------------------------------ */ reallength = lenfull + nf + nx; for(i = 0; i < ns; i++){ reallength += cpxsi[2*i+1] - cpxsi[2*i]; } jnz = x.jc[m]; if(xpi != (double *) NULL) jnz *= 2; /* reserve room for imaginary parts */ Y_OUT = mxCreateSparse(reallength, m, jnz, mxREAL); y.pr = mxGetPr(Y_OUT); y.jc = mxGetJc(Y_OUT); y.ir = mxGetIr(Y_OUT); /* ------------------------------------------------------------ The real job, MAKEREAL: ------------------------------------------------------------ */ y.jc[0] = 0; jnz = 0; for(i = 0; i < m; i++){ y.jc[i] = jnz; j = x.jc[i+1] - x.jc[i]; jnz += makereal(y.ir+jnz, y.pr+jnz, x.ir+x.jc[i],x.pr+x.jc[i],xpi,j, cpxf,nf, cpxx,nx, cpxsi,ns, lenfull, dimflqr, cwork, iwork, iwsize); if(xpi != (double *) NULL) xpi += j; /* To next imaginary column */ } y.jc[i] = jnz; mxAssert(jnz <= mxGetNzmax(Y_OUT),""); /* ------------------------------------------------------------ REALLOC: Shrink Y to its current size ------------------------------------------------------------ */ jnz = MAX(jnz,1); if( (y.pr = (double *) mxRealloc(y.pr, jnz*sizeof(double))) == NULL) mexErrMsgTxt("Memory reallocation error"); mxSetPr(Y_OUT,y.pr); if( (y.ir = (mwIndex *) mxRealloc(y.ir, jnz*sizeof(mwIndex))) == NULL) mexErrMsgTxt("Memory reallocation error"); mxSetIr(Y_OUT,y.ir); mxSetNzmax(Y_OUT,jnz); /* ------------------------------------------------------------ Release working arrays ------------------------------------------------------------ */ mxFree(sdpNL); mxFree(cwork); mxFree(iwork); }