void mexFunction(int nOut, mxArray *pOut[], int nIn, const mxArray *pIn[]) { mxArray *dataA, *dataB; mxLogical value; if (mxIsClass(pIn[0], "pointer") && mxIsClass(pIn[1], "pointer")) { dataA = GetPointerData(pIn[0]); if (!GetPointerData(dataA)) dataA = NULL; dataB = GetPointerData(pIn[1]); if (!GetPointerData(dataB)) dataB = NULL; } else if (mxIsClass(pIn[0], "pointer") && mxIsDouble(pIn[1]) && mxGetM(pIn[1])*mxGetN(pIn[1]) == 1 && !mxGetScalar(pIn[1])) { dataA = GetPointerData(GetPointerData(pIn[0])); dataB = NULL; } else if (mxIsClass(pIn[1], "pointer") && mxIsDouble(pIn[0]) && mxGetM(pIn[0])*mxGetN(pIn[0]) == 1 && !mxGetScalar(pIn[0])) { dataA = NULL; dataB = GetPointerData(GetPointerData(pIn[1])); } else mexErrMsgTxt("Both inputs must be pointers or one of them is pointer and other is scalar 0 (= NULL)"); value = dataA == dataB; pOut[0] = mxCreateLogicalScalar(value); }
//encoding = ... // LLCEncodeHelper(dictWords,imWords,nearestNeighborResult,beta,outputFullMat) // * dictWords, imWords and nearestNeighborResult must be of type double // * encoding is returned as a sparse matrix // * hist is returned as a vector of type double void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // parameter validation if (!(mxIsClass(prhs[0], "double")) || !(mxIsClass(prhs[1], "double")) || !(mxIsClass(prhs[2], "double"))){ mexErrMsgTxt("dictWords, imWords and nearestNeighborResult " "should all be of type DOUBLE."); } // load in data double* dict_words = mxGetPr(prhs[0]); double* im_words = mxGetPr(prhs[1]); double* nn_ind = mxGetPr(prhs[2]); double beta = mxGetScalar(prhs[3]); bool output_full_mat = mxIsLogicalScalarTrue(prhs[4]); ptrdiff_t dim = mxGetM(prhs[0]); //size(dictWords,1) - dims of descs ptrdiff_t dict_size = mxGetN(prhs[0]); //size(dictWords,2) - # visual words ptrdiff_t im_size = mxGetN(prhs[1]); //size(imWords,2) - # descs in img ptrdiff_t nn_size = mxGetM(prhs[2]); //number of nearest neighbours // matlab index starts with 1 instead 0 for(mwIndex i=0;i<nn_size*im_size;i++) nn_ind[i]--; double* encoding_sr; mwIndex* encoding_ir; mwIndex* encoding_jc; double* hist; if (output_full_mat) { /* encoding matrix should be sparse */ plhs[0] = mxCreateSparse(dict_size,im_size,nn_size*im_size,mxREAL); /* encoding matrix indexed as (val,row,col) tuple */ encoding_sr = mxGetPr(plhs[0]); encoding_ir = mxGetIr(plhs[0]); encoding_jc = mxGetJc(plhs[0]); /* create empty vars for encoding hist */ hist = 0; } else { /* histogram should be double */ plhs[0] = mxCreateDoubleMatrix(dict_size,1,mxREAL); hist = mxGetPr(plhs[0]); /* create empty vars for encoding matrix */ encoding_sr = 0; encoding_ir = 0; encoding_jc = 0; } encode(dict_words, im_words, nn_ind, dim, dict_size, im_size, nn_size, beta, encoding_sr, encoding_ir, encoding_jc, hist, output_full_mat); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /***************************************************************************/ /** Check input ************************************************************/ /***************************************************************************/ if(debug) mexWarnMsgTxt("Pool_VisualMark operation!"); if (nrhs !=3) mexErrMsgTxt("Must have 3 input arguments"); if (nlhs !=1) mexErrMsgTxt("Must have 1 output arguments"); // if (mxIsComplex(prhs[0]) || !(mxIsClass(prhs[0],"single") || mxIsClass(prhs[0],"double"))) // mexErrMsgTxt("Input data must be real, single/double type"); if (mxIsComplex(prhs[1]) || !(mxIsClass(prhs[1],"single") || mxIsClass(prhs[1],"double"))) mexErrMsgTxt("dimensions (rows, cols) must be real, single/double type"); if (mxGetNumberOfDimensions(prhs[1]) < 2) mexErrMsgTxt("Input data must have at least 2-dimensions (rows, cols, nchannels, nsamples) " "\nThe last two dimensions will be considered to be 1."); // if (mxGetNumberOfDimensions(prhs[1]) != 2) // mexErrMsgTxt("Pooling data must have 2-dimensions (prows, pcols)"); mxClassID classID = mxGetClassID(prhs[1]); /** This is mainly to avoid two typenames. Should not be a big usability issue. */ // if (mxGetClassID(prhs[1]) != classID) // mexErrMsgTxt("Input data and pooling need to be of the same type"); /***************************************************************************/ /** Switch for the supported data types */ /***************************************************************************/ if (classID == mxSINGLE_CLASS) { if (debug) mexWarnMsgTxt("Executing the single version\n"); Pool_VisualMark<float>(nlhs, plhs, nrhs, prhs, classID); } else if (classID == mxDOUBLE_CLASS) { if (debug) mexWarnMsgTxt("Executing the double version\n"); Pool_VisualMark<double>(nlhs, plhs, nrhs, prhs, classID); } }
CGGrid *mxArray2CGGrid( const mxArray *array ) { CGGrid *cgg; mxArray *address; if( ! mxIsClass( array, "cggrid" ) ) { mexWarnMsgTxt( "Input must be a cggrid object" ); return 0; } address = mxGetField( array, 0, "address" ); if( address == (mxArray *) NULL ) { return (CGGrid *) NULL; } cgg = (CGGrid *) mxArrayToUlong( address ); if( ! ATM_cggrid_is_registered( cgg ) ) { mexWarnMsgTxt( "cggrid object no longer registered" ); return (CGGrid *) NULL; } if( cgg == (CGGrid *) NULL ) { return (CGGrid *) NULL; } else { return cgg; } }
void mexFunction(int nargout, mxArray *out[], int nargin, const mxArray *in[]) { mwSize width, height, nsegms; mwSize *sizes; unsigned long *image, *o1, *o2, num_elems; /* check argument */ if (nargin<1) { mexErrMsgTxt("One input argument required ( the image in row * column form with the class uint32)"); } if (nargout>2) { mexErrMsgTxt("Too many output arguments"); } sizes = (mwSize *)mxGetDimensions(in[0]); height = sizes[0]; width = sizes[1]; if (!mxIsClass(in[0],"uint32")) { mexErrMsgTxt("Usage: image must be a 2-dimensional uint32 matrix"); } image = (unsigned long *) mxGetData(in[0]); unsigned long n_elems = count_zeros(image, width, height); out[0] = mxCreateNumericMatrix(n_elems, 1 ,mxUINT32_CLASS, mxREAL); out[1] = mxCreateNumericMatrix(NHOOD_SIZE,n_elems,mxUINT32_CLASS, mxREAL); if (out[0]==NULL || out[1]==NULL) { mexErrMsgTxt("Not enough memory for the output matrix"); } o1 = (unsigned long *) mxGetPr(out[0]); o2 = (unsigned long *) mxGetPr(out[1]); find_unique_elems_in_neighborhood(image, width, height, o1, o2); }
void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] ) { // Check that the number of input and output parameters is valid if ( nrhs != 1 ) mexErrMsgTxt("One input parameter expected."); if ( nlhs > 1 ) mexErrMsgTxt("One output parameter expected."); // Make sure that the input is a float (single) scalar if ( !mxIsClass( prhs[ 0 ], "uint16" ) || mxGetN( prhs[ 0 ] ) * mxGetM( prhs[ 0 ] ) != 1 ) mexErrMsgTxt( "The input parameter must be a scalar of class uint16!" ); // Get a pointer to the input float (uint16) scalar unsigned short *fIn = ( unsigned short *) mxGetData( prhs[ 0 ] ); // Create an unsigned int numeric array to hold the 'converted' uint16 const mwSize dims[ ] = { 1, sizeof( unsigned short ) }; plhs[ 0 ] = mxCreateNumericArray( 2, dims, mxUINT8_CLASS, mxREAL); // Get a pointer to the output char array unsigned char * cOut = ( unsigned char * ) mxGetData( plhs[ 0 ] ); // Get the corresponding unsigned char array representation of // the input single (uint16) std::memcpy( cOut, fIn, sizeof( unsigned short ) ); }
void diagnosticDispatcher(VlSvmPegasos* svm) { if (svm->diagnosticCallerRef) { mxArray *lhs,*rhs[3]; DiagnosticsDispatcher* dispatcherObject = (DiagnosticsDispatcher*) svm->diagnosticCallerRef ; rhs[0] = dispatcherObject->diagnosticsHandle ; if (dispatcherObject->callerRef) { rhs[1] = dispatcherObject->callerRef ; } else { mwSize dims[2] ; dims[0] = 1 ; dims[1] = 1 ; rhs[1] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL) ; } rhs[2] = createInfoStruct(svm) ; if (mxIsClass( rhs[0] , "function_handle")) { mexCallMATLAB(0,&lhs,3,rhs,"feval") ; } mxDestroyArray(rhs[2]) ; if (dispatcherObject->verbose) { mexPrintf("vl_pegasos: Iteration = %d\n",svm->iterations) ; mexPrintf("vl_pegasos: elapsed time = %f\n",svm->elapsedTime) ; mexPrintf("vl_pegasos: energy = %f\n",svm->objective->energy) ; } } }
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) { /* Initialize int variables to store matrix dimensions */ int Mrows,Mcols; int Nrows,Ncols; /* Check that the number of input and output parameters is valid */ if (nrhs != 2) mexErrMsgTxt("Two input parameters required."); if (nlhs > 1) mexErrMsgTxt("One output parameter required."); /* Read input parameter dimensions */ Mrows = mxGetM(prhs[0]); Mcols = mxGetN(prhs[0]); Nrows = mxGetM(prhs[1]); Ncols = mxGetN(prhs[1]); /* Check input parameter dimension */ if ((Mcols>3) || (Ncols>3)) mexErrMsgTxt("Point coordinates in more than 3 dimensions are not supported."); if (Mcols!=Ncols) mexErrMsgTxt("The points in the coordinate matrices have different number of dimensions."); if (mxIsClass(prhs[0], "double")){ double *M, *N; double *D; /* Create matrix for the return argument D */ plhs[0] = mxCreateDoubleMatrix(Mrows,Nrows, mxREAL); /* Assign pointers to each input and output */ M = mxGetPr(prhs[0]); N = mxGetPr(prhs[1]); D = mxGetPr(plhs[0]); /* Call the correcponding C function */ if (Mcols==1) { calcDistMatrix1D(D,M,N,Mrows,Nrows); } if (Mcols==2) { calcDistMatrix2D(D,M,N,Mrows,Nrows); } if (Mcols==3) { calcDistMatrix3D(D,M,N,Mrows,Nrows); } } else{ float *M, *N; float *D; /* Create matrix for the return argument D */ plhs[0] = mxCreateNumericMatrix(Mrows,Nrows, mxSINGLE_CLASS, mxREAL); /* Assign pointers to each input and output */ M = mxGetData(prhs[0]); N = mxGetData(prhs[1]); D = mxGetData(plhs[0]); /* Call the correcponding C function */ if (Mcols==1) { calcDistMatrix1Df(D,M,N,Mrows,Nrows); } if (Mcols==2) { calcDistMatrix2Df(D,M,N,Mrows,Nrows); } if (Mcols==3) { calcDistMatrix3Df(D,M,N,Mrows,Nrows); } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { GPUmatResult_t status = GPUmatSuccess; // tmp mxArray *lhs[2]; if (nrhs != 1) mexErrMsgTxt("Wrong number of arguments"); // the passed element should be a GPUsingle if (!(mxIsClass(prhs[0], "GPUdouble"))) mexErrMsgTxt(ERROR_EXPECTED_GPUDOUBLE); if (init == 0) { // Initialize function mexLock(); // load GPUmanager mexCallMATLAB(2, &lhs[0], 0, NULL, "GPUmanager"); GPUman = (GPUmanager *) (UINTPTR mxGetScalar(lhs[0])); mxDestroyArray(lhs[0]); init = 1; } GPUtype *p = mxToGPUtype(prhs[0], GPUman); int numel = p->getNumel(); int ndims = p->getNdims(); int *size = p->getSize(); int mysize = p->getMySize(); gpuTYPE_t type = p->getType(); // create dest array // dims re set to [1 numel]. A reshape is required outside // this function mwSize dims[2]; // create destination if (type == gpuDOUBLE) { dims[0] = 1; dims[1] = numel; plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); } else if (type == gpuCDOUBLE) { dims[0] = 1; dims[1] = 2 * numel; plhs[0] = mxCreateNumericArray(2, dims, mxDOUBLE_CLASS, mxREAL); } try { status = GPUopCudaMemcpy(mxGetPr(plhs[0]), p->getGPUptr(), mysize * numel, cudaMemcpyDeviceToHost, p->getGPUmanager()); } catch (GPUexception ex) { mexErrMsgTxt(ex.getError()); } }
/* * sample file that shows how to transform an array of structs * containing (id, handle) pairs to a callback list and return the * pointer to the data. the callback list can thus be passed to the * second file in this example (exec_callbacks.cpp). * * The passed matlab functions must not have any argument as this example here * doesn't take care of those arguments. */ void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if (nrhs != 1) mexErrMsgTxt("Function requires exactly one argument.\n"); if (nlhs != 1) mexErrMsgTxt("Function returns exactly one value.\n"); if (!mxIsStruct(prhs[0])) mexErrMsgTxt("Function requires a structure array as argument\n"); int nfields = mxGetNumberOfFields(prhs[0]); mwSize nstructs = mxGetNumberOfElements(prhs[0]); std::vector<callback*> *cb_list = new std::vector<callback*>(); // parse each struct for (mwIndex i = 0; i < nstructs; i++) { bool id_found = false; bool fn_found = false; callback *cb = new callback(); for (int j = 0; j < nfields; j++) { mxArray *field = mxGetFieldByNumber(prhs[0], i, j); if (!field) { mexWarnMsgTxt("Invalid structure found\n"); continue; } const char *fname = mxGetFieldNameByNumber(prhs[0], j); if (!strncmp(fname, "id", sizeof("id"))) { if (!mxIsNumeric(field) || mxGetNumberOfElements(field) != 1) { mexWarnMsgTxt("Invalid id (must be numeric scalar).\n"); continue; } id_found = true; cb->id = (int)mxGetScalar(field); } else if (!strncmp(fname, "handle", sizeof("handle"))) { if (!mxIsClass(field, "function_handle")) { mexWarnMsgTxt("Invalid handle (must be function_handle).\n"); continue; } fn_found = true; cb->fn = field; } } if (!id_found || !fn_found) delete cb; else cb_list->push_back(cb); } // return the list plhs[0] = create_mex_obj(cb_list); }
/* solveTV2d_DR.cpp Solves the 2 dimensional TV proximity problem by applying a Douglas-Rachford splitting algorithm. Parameters: - 0: bidimensional reference signal y. - 1: lambda penalties over the columns - 2: lambda penalties over the rows - 3: norm to apply over the columns - 4: norm to apply over the rows - 5: (optional) number of cores to use (default: as defined by environment variable OMP_NUM_THREADS) - 6: (optional) maximum number of iterations to run (default: as defined in TVopt.h) Outputs: - 0: solution x. - 1: array with optimizer information: + [0]: number of iterations run. + [1]: stopping tolerance. */ void mexFunction(int nlhs, mxArray *plhs[ ],int nrhs, const mxArray *prhs[ ]) { const mwSize *sDims; double *x=NULL,*y,*info=NULL,*dims; double lambda1, lambda2, norm1, norm2; int *ns=NULL; int nds,N,M,ncores,maxIters,i; #define FREE \ if(!nlhs) free(x); \ if(ns) free(ns); #define CANCEL(txt) \ printf("Error in solveTV2D_DR: %s\n",txt); \ if(x) free(x); \ if(info) free(info); \ return; /* Check input correctness */ if(nrhs < 5){CANCEL("not enought inputs");} if(!mxIsClass(prhs[0],"double")) {CANCEL("input signal must be in double format")} /* Find number of dimensions of the input signal */ nds=mxGetNumberOfDimensions(prhs[0]); /* Must be 2 */ if ( nds != 2 ) {CANCEL("input signal must be 2-dimensional")} M = mxGetM(prhs[0]); N = mxGetN(prhs[0]); /* Get dimensions of input signal */ sDims = mxGetDimensions(prhs[0]); /* Convert dimensions to C array */ ns = (int*)malloc(sizeof(int)*nds); if(!ns) {CANCEL("out of memory")} for(i=0;i<nds;i++) ns[i] = (int)sDims[i]; /* Get input signal */ y = mxGetPr(prhs[0]); /* Get rest of inputs */ lambda1 = mxGetScalar(prhs[1]); lambda2 = mxGetScalar(prhs[2]); norm1 = mxGetScalar(prhs[3]); norm2 = mxGetScalar(prhs[4]); if(nrhs >= 6) ncores = (int)(mxGetPr(prhs[5]))[0]; else ncores = 1; if(nrhs >= 7) maxIters = (int)(mxGetPr(prhs[6]))[0]; else maxIters = 0; /* Create output arrays */ if(nlhs >= 1){ plhs[0]=mxCreateNumericArray(nds,sDims,mxDOUBLE_CLASS,mxREAL); if(!plhs[0]){CANCEL("out of memory")} x=mxGetPr(plhs[0]); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int rows,cols,common,m,n,p; double y1, y2; double *arr1, *arr2, *arr3; if (nrhs!=2 || nlhs>1) mexErrMsgTxt("max_mult requires two inputs and one output"); if (mxIsChar(prhs[0]) || mxIsClass(prhs[0], "sparse") || mxIsComplex(prhs[0]) || mxIsChar(prhs[1]) || mxIsClass(prhs[1], "sparse") || mxIsComplex(prhs[1])) mexErrMsgTxt("Inputs must be real, full, and nonstring"); if (mxGetN(prhs[0])!=mxGetM(prhs[1])) mexErrMsgTxt("The number of columns of A must be the same as the number of rows of x"); arr1=mxGetPr(prhs[0]); arr2=mxGetPr(prhs[1]); p=mxGetN(prhs[0]); m=mxGetM(prhs[0]); n=mxGetN(prhs[1]); plhs[0]=mxCreateDoubleMatrix(m, n, mxREAL); arr3=mxMalloc(m*n*sizeof(double)); for (rows=0; rows<m ; rows++) for (cols=0; cols<n ; cols++) { y1=arr1[rows]*arr2[cols*p]; for (common=1; common<p; common++) { y2=arr1[rows+common*m]*arr2[common+cols*p]; if (y2>y1) y1=y2; } arr3[rows+cols*m]=y1; } mxSetPr(plhs[0], arr3); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *use,*covF,*dfFtrs,*dfSc,*stdFtrs,stdScM,maxCo,val; int N,F,f1,f2,f; /* Error checking on arguments */ if( nrhs!=4) mexErrMsgTxt("Two input arguments required."); if( nlhs>1 ) mexErrMsgTxt("Too many output arguments."); if( !mxIsClass(prhs[0], "double") || !mxIsClass(prhs[1], "double") || !mxIsClass(prhs[2], "double")) mexErrMsgTxt("Input arrays are of incorrect type."); /* extract inputs */ dfFtrs = (double*) mxGetData(prhs[0]); /* N x F */ dfSc = (double*) mxGetData(prhs[1]); /* N x 1 */ stdFtrs = (double*) mxGetData(prhs[2]); /* F x F */ stdScM = (double) mxGetScalar(prhs[3]); /*Scalar */ N=mxGetM(prhs[0]); F=mxGetN(prhs[0]); covF = (double*) mxCalloc(F,sizeof(double)); for (f=0;f<F;f++){ covF[f] = computeCov(dfFtrs,dfSc,f,N); } plhs[0] = mxCreateNumericMatrix(2, 1, mxDOUBLE_CLASS, mxREAL); use = (double*) mxGetData(plhs[0]); maxCo = 0; for (f1=0;f1<F;f1++){ for (f2=f1+1;f2<F;f2++){ val=(covF[f1]-covF[f2])/(stdFtrs[f1+(f2*F)]*stdScM); if(val>maxCo){ maxCo=val;use[0]=f1+1;use[1]=f2+1; } } } mxFree(covF); }
static void checkInput(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* check proper input and output */ if (nrhs != 2 && nrhs != 3) { mexErrMsgTxt("Usage: prombs(g, f) OR prombs(g, f, m)."); } if (nlhs > 1) { mexErrMsgTxt("Too many output arguments."); } if (!mxIsClass(prhs[0], "double") || !mxIsClass(prhs[1], "double")) { mexErrMsgTxt("All vectors and matrices must be of type double."); } if (nrhs == 3 && ((mxGetM(prhs[2]) > 1) || (mxGetN(prhs[2]) > 1))) { mexErrMsgTxt("Third input argument is not a scalar."); } if (mxGetM(prhs[0]) > 1) { mexErrMsgTxt("First input is not a row vector."); } if (mxGetM(prhs[1]) != mxGetN(prhs[0]) || mxGetN(prhs[1]) != mxGetN(prhs[0])) { mexErrMsgTxt("Second input is not an LxL matrix."); } }
void mexFunction(int nOut, mxArray *pOut[], int nIn, const mxArray *pIn[]) { mxArray *address, *data; if (!mxIsClass(pIn[0], "pointer")) mexErrMsgTxt("Input must be pointer"); address = GetPointerData(pIn[0]); data = GetPointerData(address); mxDestroyArray(data); SetPointerData(address, NULL); }
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { //Validate input if (nrhs != 1) { mexErrMsgTxt("Wrong number of input arguments (expected 1)"); } if (nlhs != 1) { mexErrMsgTxt("Wrong number of output arguments (expected 1)"); } if (!mxIsClass(prhs[0], MEX_INPUT_CLASS_NAME)) { mexErrMsgTxt("Input array of wrong type, you may need to recompile with HIGH_PRECISION on/off"); } if (mxIsComplex(prhs[0])) { mexErrMsgTxt("Input array is complex."); } //Create a copy of indata since it is modified which is not normal matlab behaviour mxArray* inArray = mxDuplicateArray(prhs[0]); //Get number of dimensions. Note: matlab treats 1d arrays as 2d. mwSize ndim = mxGetNumberOfDimensions(inArray); const mwSize* dims = mxGetDimensions(inArray); if (ndim > 3) { mexErrMsgTxt("Input array size not supported."); } bool is1D = (ndim == 2 && (dims[0] == 1 || dims[1] == 1)); //Classify as 1D if either dimension is 1 //Validate data size mwSize numel = mxGetNumberOfElements(inArray); if (numel > INT_MAX) { mexErrMsgTxt("Number of elements is to large, has to fit in INT_MAX"); } //Allocate output data plhs[0] = mxCreateNumericArray(ndim, dims, MEX_INPUT_CLASS_TYPE, 0); //Get the data pointers FLOAT* out = mxGetPr(plhs[0]); FLOAT* in = mxGetPr(inArray); //Perform the wavelet transform if (is1D) { invwavelet_transform1D(in, (int)(dims[0] * dims[1]), out); } else if (ndim == 2) { invwavelet_transform2D(in, (int)(dims[0]), (int)(dims[1]), out); } else if (ndim == 3) { invwavelet_transform3D(in, (int)(dims[0]), (int)(dims[1]), (int)(dims[2]), out); } }
void is_type(char *type, const mxArray *prhs[], int i) { if (strcmp (type,"double")==0) { if (!mxIsDouble(prhs[i])) { char* numero[200]; sprintf(numero, "%d", i); char* errmsg[200]; strcpy (errmsg, "The type of the data number "); strcat (errmsg, numero); strcat (errmsg, " must be double."); mexErrMsgTxt(errmsg); } } else if (strcmp (type,"string")==0) { if (!mxIsClass(prhs[i],"mxCHAR_CLASS")) { char* numero[200]; sprintf(numero, "%d", i); char* errmsg[200]; strcpy (errmsg, "The type of the data number "); strcat (errmsg, numero); strcat (errmsg, " must be string."); mexErrMsgTxt(errmsg); } } else if(strcmp (type,"structure")==0) { if (!mxIsStruct(prhs[i])) { char* numero[200]; sprintf(numero, "%d", i); char* errmsg[200]; strcpy (errmsg, "The type of the data number "); strcat (errmsg, numero); strcat (errmsg, " must be a structure."); mexErrMsgTxt(errmsg); } } else { mexErrMsgTxt("Ask the programmer of this soft to clear up this issue"); } }
EXPORT int create_matlab(OBJECT **obj, OBJECT *parent) { try { *obj = gl_create_object(oclass,sizeof(mxArray*)); if (*obj!=NULL) { gl_set_parent(*obj,parent); char createcall[1024]; if (engPutVariable(engine,"object",defaults)) { gl_error("matlab::%s_create(...) unable to set defaults for object", oclass->name); throw "create failed"; } if (parent) { // @todo transfer parent data in matlab create call mxArray *pParent = mxCreateStructMatrix(0,0,0,NULL); engPutVariable(engine,"parent",pParent); sprintf(createcall,"create(object,parent)"); } else sprintf(createcall,"create(object,[])"); if (engEvalString(engine,createcall)!=0) { gl_error("matlab::%s_create(...) unable to evaluate '%s' in Matlab", oclass->name, createcall); throw "create failed"; } else gl_matlab_output(); mxArray *ans= engGetVariable(engine,"ans"); mxArray **my = OBJECTDATA(*obj,mxArray*); if (ans && mxIsClass(ans,oclass->name)) *my = engGetVariable(engine,"ans"); else { *my = NULL; gl_error("matlab::@%s/create(...) failed to return an object of class %s",oclass->name,oclass->name); throw "create failed"; } return 1; } else throw "create failed due to memory allocation failure"; }
/* solveTV2_morec.cpp Solves the TV-L2 proximity problem by applying a More-Sorensen + Projected Gradient algorithm. Parameters: - 0: reference signal y. - 1: lambda penalty. Outputs: - 0: primal solution x. - 1: array with optimizer information: + [0]: number of iterations run. + [1]: dual gap. */ void mexFunction(int nlhs, mxArray *plhs[ ],int nrhs, const mxArray *prhs[ ]) { double *x=NULL,*y,*info=NULL; double lambda; int M,N,nn,i; #define FREE \ if(!nlhs) free(x); #define CANCEL(txt) \ printf("Error in solveTV2_morec2: %s\n",txt); \ if(x) free(x); \ if(info) free(info); \ return; /* Check input correctness */ if(nrhs < 2){CANCEL("not enought inputs");} if(!mxIsClass(prhs[0],"double")) {CANCEL("input signal must be in double format")} /* Create output arrays */ M = mxGetM(prhs[0]); N = mxGetN(prhs[0]); nn = (M > N) ? M : N; if(nlhs >= 1){ plhs[0] = mxCreateDoubleMatrix(nn,1,mxREAL); x = mxGetPr(plhs[0]); } else x = (double*)malloc(sizeof(double)*nn); if(nlhs >= 2){ plhs[1] = mxCreateDoubleMatrix(N_INFO,1,mxREAL); info = mxGetPr(plhs[1]); } /* Retrieve input data */ y = mxGetPr(prhs[0]); lambda = mxGetScalar(prhs[1]); /* Run Projected Newton */ morePG_TV2(y,lambda,x,info,nn,NULL); /* Free resources */ FREE return; }
/* solveTV1_johnson.cpp Solves the TV-L1 proximity problem by applying Johnson's dynamic programming method. Parameters: - 0: reference signal y. - 1: lambda penalty. Outputs: - 0: primal solution x. */ void mexFunction(int nlhs, mxArray *plhs[ ],int nrhs, const mxArray *prhs[ ]) { double *x=NULL,*y; float lambda; int M,N,nn,i; #define FREE \ if(!nlhs) free(x); #define CANCEL(txt) \ printf("Error in solveTV1_condat: %s\n",txt); \ if(x) free(x); \ return; /* Check input correctness */ if(nrhs < 2){CANCEL("not enought inputs");} if(!mxIsClass(prhs[0],"double")) {CANCEL("input signal must be in double format")} /* Create output arrays */ M = mxGetM(prhs[0]); N = mxGetN(prhs[0]); nn = (M > N) ? M : N; if(nlhs >= 1){ plhs[0] = mxCreateDoubleMatrix(nn,1,mxREAL); x = mxGetPr(plhs[0]); } else x = (double*)malloc(sizeof(double)*nn); /* Retrieve input data */ y = mxGetPr(prhs[0]); lambda = mxGetScalar(prhs[1]); /* Run Johnson's method */ dp(nn, y, lambda, x); /* Free resources */ FREE return; #undef FREE #undef CANCEL }
mxArray *CGGrid2mxArray( CGGrid *cgg ) { mxArray *address; mxArray *input[2]; mxArray *array[1]; input[0] = mxCreateStructMatrix(cggrid_struct_nrows, cggrid_struct_ncols, cggrid_struct_nfields, cggrid_struct_fieldnames); input[1] = mxCreateString("cggrid"); address = UlongToMxArray( (unsigned long) cgg ); if( address == NULL ) { mxDestroyArray( input[0] ); mxDestroyArray( input[1] ); return (mxArray *) NULL; } else { mxSetField( input[0], 0, "address", address ); } mexCallMATLAB( 1, array, 2, input, "class" ); mxDestroyArray( input[0] ); mxDestroyArray( input[1] ); if( ! mxIsClass( array[0], "cggrid" ) ) { mxDestroyArray( array[0] ); return (mxArray *) NULL; } else { return array[0]; } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Variables */ int n1,n2,e,nNodes,nEdges,*edgeEnds; double *nodeEnergy,*edgeEnergy; /* Inputs */ nodeEnergy = mxGetPr(prhs[0]); edgeEnergy = mxGetPr(prhs[1]); edgeEnds = (int*)mxGetPr(prhs[2]); if (!mxIsClass(prhs[2],"int32")) mexErrMsgTxt("edgeEnds must be int32"); nNodes = mxGetDimensions(prhs[0])[0]; nEdges = mxGetDimensions(prhs[2])[0]; for(e=0;e<nEdges;e++) { n1 = edgeEnds[e]-1; n2 = edgeEnds[e+nEdges]-1; nodeEnergy[n1+nNodes] += edgeEnergy[1 + 2*(0 + 2*e)] - edgeEnergy[0 + 2*(0 + 2*e)]; nodeEnergy[n2+nNodes] += edgeEnergy[1 + 2*(1 + 2*e)] - edgeEnergy[1 + 2*(0 + 2*e)]; } }
void mexFunction(int nOut, mxArray *pOut[], int nIn, const mxArray *pIn[]) { mwSize width, height; float* borders; float* orientations; int* textons; unsigned int *in_image; mwSize dims[3]; mwSize orientation_dims[3]; if((nIn != 1) || (nOut != 3)) mexErrMsgTxt("Usage: border,textons,orientations = gpb(image)"); if (!mxIsClass(pIn[0],"uint8") || mxGetNumberOfDimensions(pIn[0]) != 3) { mexErrMsgTxt("Usage: th argument must be a unsigned int matrix"); } const mwSize *indims= mxGetDimensions(pIn[0]); if (indims[0]!=4) mexErrMsgTxt("Image needs to be of shape 4 x widht x height"); width = indims[2]; height = indims[1]; mexPrintf("width %d, height %d\n",width,height); mexPrintf("Element-size: %d, sizeof(int): %d, sizeof(char) %d\n",mxGetElementSize(pIn[0]),sizeof(int),sizeof(unsigned char)); dims[0]=width; dims[1]=height; //for rgb0 mexPrintf("width: %d height: %d\n",width, height); pOut[0]=mxCreateNumericMatrix(height,width,mxSINGLE_CLASS,mxREAL); pOut[1]=mxCreateNumericMatrix(height,width,mxINT32_CLASS,mxREAL); orientation_dims[0]=width; orientation_dims[1]=height; orientation_dims[2]=8; pOut[2]=mxCreateNumericArray(3,orientation_dims,mxSINGLE_CLASS,mxREAL); borders=(float*) mxGetPr(pOut[0]); textons=(int*) mxGetPr(pOut[1]); orientations=(float*) mxGetPr(pOut[2]); in_image = (unsigned int*) mxGetData(pIn[0]); gpb(in_image,height,width,borders,textons,orientations); }
void mexFunction ( int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin [ ] ) { int iscomplex ; mwSignedIndex nrow, ncol, i, j ; double *Ax, *Az ; char filename [MAXLINE], s [MAXLINE] ; FILE *f ; /* ---------------------------------------------------------------------- */ /* check inputs */ /* ---------------------------------------------------------------------- */ if (nargout > 0 || nargin != 2) { mexErrMsgTxt ("usage: UFfull (filename,A)") ; } if (mxIsSparse (pargin [1]) || !mxIsClass (pargin [1], "double")) { mexErrMsgTxt ("A must be full and double") ; } /* ---------------------------------------------------------------------- */ /* get filename and open the file */ /* ---------------------------------------------------------------------- */ if (!mxIsChar (pargin [0])) { mexErrMsgTxt ("first parameter must be a filename") ; } mxGetString (pargin [0], filename, MAXLINE) ; f = fopen (filename, "w") ; if (f == NULL) { mexErrMsgTxt ("error openning file") ; } /* ---------------------------------------------------------------------- */ /* get the matrix */ /* ---------------------------------------------------------------------- */ iscomplex = mxIsComplex (pargin [1]) ; nrow = mxGetM (pargin [1]) ; ncol = mxGetN (pargin [1]) ; Ax = mxGetPr (pargin [1]) ; Az = mxGetPi (pargin [1]) ; /* ---------------------------------------------------------------------- */ /* write the matrix */ /* ---------------------------------------------------------------------- */ if (iscomplex) { fprintf (f, "%%%%MatrixMarket matrix array complex general\n") ; } else { fprintf (f, "%%%%MatrixMarket matrix array real general\n") ; } fprintf (f, "%.0f %.0f\n", (double) nrow, (double) ncol) ; for (j = 0 ; j < ncol ; j++) { for (i = 0 ; i < nrow ; i++) { print_value (f, Ax [i + j*nrow], s) ; if (iscomplex) { fprintf (f, " ") ; print_value (f, Az [i + j*nrow], s) ; } fprintf (f, "\n") ; } } /* ---------------------------------------------------------------------- */ /* close the file */ /* ---------------------------------------------------------------------- */ fclose (f) ; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int k; long i,j,nVars,nSamples,one=1; double gi,Hi,alphaOld,c,d,UB,LB,scaling,scaling2; char trans='N'; mwIndex *jc, *ir; if (nrhs < 4) mexErrMsgTxt("At least 4 arguments are needed: {alpha,yXt,lambda,jVals[,w,yxxy]}"); double *alpha = mxGetPr(prhs[0]); double *yXt = mxGetPr(prhs[1]); double lambda = mxGetScalar(prhs[2]); int *iVals = (int*)mxGetPr(prhs[3]); /* Compute Sizes */ nSamples = mxGetN(prhs[1]); nVars = mxGetM(prhs[1]); int maxIter = mxGetM(prhs[3]); /* Basic input checking */ if (nSamples != mxGetM(prhs[0]) || 1 != mxGetN(prhs[0])) mexErrMsgTxt("alpha should be a column vector, with length equal to the number of columns of yXt"); if (!mxIsClass(prhs[3],"int32") || 1 != mxGetN(prhs[3])) mexErrMsgTxt("iVals must be an int32 column vector"); int sparse = 0; if (mxIsSparse(prhs[1])) { sparse = 1; jc = mxGetJc(prhs[1]); ir = mxGetIr(prhs[1]); } lambda = lambda*nSamples; /* Initialize w */ double *w; if (nrhs >= 5) { w = mxGetPr(prhs[4]); if (nVars != mxGetM(prhs[4]) || 1 != mxGetN(prhs[4])) mexErrMsgTxt("w should be a column vector, with the same number of rows as yXt"); } else { w = mxCalloc(nVars,sizeof(double)); if (sparse) { for(i = 0;i < nSamples;i++) { if (sparse) { for(j = jc[i];j < jc[i+1];j++) { w[ir[j]] -= yXt[j]*alpha[i]/lambda; } } } } else { scaling = -1/lambda; scaling2 = 0; dgemv(&trans,&nVars,&nSamples,&scaling,yXt,&nVars,alpha,&one,&scaling2,w,&one); } } /* Compute yxxy */ double *yxxy; if (nrhs >= 6) { yxxy = mxGetPr(prhs[5]); if (nSamples != mxGetM(prhs[5]) || 1 != mxGetN(prhs[5])) mexErrMsgTxt("yxxy should be a column vector, with length equal to the number of columns in yXt"); } else { yxxy = mxCalloc(nSamples,sizeof(double)); for(i = 0;i < nSamples;i++) { if (sparse) { for(j = jc[i];j < jc[i+1];j++) { yxxy[i] += yXt[j]*yXt[j]; } } else { yxxy[i] = ddot(&nVars,&yXt[nVars*i],&one,&yXt[nVars*i],&one); } } } for(k=0;k<maxIter;k++) { /* Select next sample to update */ i = iVals[k]-1; alphaOld = alpha[i]; if(alphaOld == 0 || alphaOld == 1) alpha[i] = 0.5; LB = 0.0; UB = 1.0; c = (alphaOld/lambda)*yxxy[i]; if (sparse) { for(j = jc[i];j < jc[i+1];j++) { c += w[ir[j]]*yXt[j]; } } else c += ddot(&nVars,w,&one,&yXt[nVars*i],&one); d = yxxy[i]/lambda; gi = log(alpha[i]) - log(1-alpha[i]) - c + alpha[i]*d; while (fabs(gi) > 1e-8 && UB-LB > 1e-15) { Hi = 1/alpha[i] + 1/(1-alpha[i]) + d; alpha[i] -= gi/Hi; if (alpha[i] <= LB || alpha[i] >= UB) alpha[i] = (LB+UB)/2; gi = log(alpha[i]) - log(1-alpha[i]) - c + alpha[i]*d; if (gi > 0) UB = alpha[i]; else LB = alpha[i]; } if (sparse) { for(j = jc[i];j < jc[i+1];j++) { w[ir[j]] += yXt[j]*(alphaOld - alpha[i])/lambda; } } else { scaling = (alphaOld - alpha[i])/lambda; daxpy(&nVars,&scaling,&yXt[i*nVars],&one,w,&one); } } if (nrhs < 5) mxFree(w); if (nrhs < 6) mxFree(yxxy); }
/*! * @copybrief max_pool.cpp * * @param IMAGES prhs[0] // The stack of images you want to pool: n x m x c x dmatrix * @param POOL_SIZE prhs[1] // The size of the subregions to pool over: 1x2 matrix indicating the p x q size of the regino. * @param INDICES prhs[2] // Previous indices from a pooling operation (optional). They must be the same size of the resulting output of pooling the IMAGES by this POOL_SIZE. Pass in [] to ignore this and set number of compute threads as 4th input. * @param INPUT_THREADS prhs[4] // User can optionally input the number of computation threads to parallelized over. * * @retval POOLED plhs[0] // Pooled stack of images. This will be roughly n/q x m/p x c x d * @retval POOLED_INDICES plhs[1] // The indices of where the max within each subregion was located. */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { int num_dims, number_threads; float *imagesp; unsigned short int *inputindsp; // Pointers to input. float *outputp; unsigned short int *indicesp; // Pointers to outputs. double *poolp; // For the pool_size array. bool INDICES_PROVIDED=false; int *number_threadsp; int blocksx, blocksy, remx, remy, bcoljump, plane3jump, plane4jump, top_left; int poolx, pooly, poolsizex, poolsizey; const mwSize *dims; const mwSize *inddims; int* outputdims = NULL; // Check for proper number of arguments if (nrhs < 2) { mexErrMsgTxt("Two input arguments required at minimum."); } else if (nlhs > 2) { mexErrMsgTxt("Too many output arguments."); } // If number of threads was not input, then use default set abvoe. if (nrhs < 5) number_threads = MAX_NUM_THREADS; else number_threads = (int)mxGetScalar(INPUT_THREADS); // Get dimensions of image and kernel num_dims = mxGetNumberOfDimensions(IMAGES); dims = (mwSize*) mxCalloc(num_dims, sizeof(mwSize)); dims = mxGetDimensions(IMAGES); // Make sure the indices are provided and the same number of dimensions as input. if (nrhs >=3 && mxIsEmpty(INDICES)==false){ inddims = (mwSize*) mxCalloc(num_dims, sizeof(mwSize)); inddims = mxGetDimensions(INDICES); INDICES_PROVIDED = true; if(mxIsClass(INDICES,"uint16") == 1){ inputindsp = (unsigned short int *) mxGetData(INDICES); }else{ mexErrMsgTxt("Input Indices must be a unsigned char (uint16)."); } } // // Passed in an non-empty array // if(inddims[0]>0){ // INDICES_PROVIDED=true; // mexPrintf("number_threads: %d and %d Indices dims: %d x %d\n", number_threads,mxIsSingle(IMAGES),inddims[0],inddims[1]); // mexPrintf("indices(2,2): %f\n",inputindsp[6]); // } // Get pointers to IMAGE and POOL_SIZE if (mxIsSingle(IMAGES) == 1){ imagesp = (float*) mxGetData(IMAGES); }else{ mexErrMsgTxt("Input Images must be a single precision (float)."); } poolp = mxGetPr(POOL_SIZE); // Get the pool region size poolx = (int) poolp[0]; pooly = (int) poolp[1]; if(poolx*pooly>65536){ mexErrMsgTxt("Cannot pool in 2D larger than 256x256 due to uint16 indices limitation."); } // Number of blocks in rows on each plane. blocksx = (int)dims[0]/poolx; // Remaining elements past blocksx remx = (int)(dims[0])%poolx; // Number of block in columns on each plane. blocksy = (int)dims[1]/pooly; // Remaining elements past blocksy remy = (int)(dims[1])%pooly; if(remx>0) blocksx = blocksx+1; if(remy>0) blocksy = blocksy+1; // mexPrintf("imagesp: %f %f %f poolp: %p: %d x %d\n", imagesp[0], imagesp[1], imagesp[2], poolp,poolx, pooly); // mexPrintf("blocksx: %d blocksy: %d, remx: %d, remy %d\n", blocksx, blocksy, remx, remy); outputdims = new int[4]; // Number of blocks is the output x and y dimensions. outputdims[0] = blocksx; outputdims[1] = blocksy; // Remaining dimensions are same as input. for(int k=2;k<(int)num_dims;k++){ outputdims[k] = dims[k]; } // Set dimensions like matlab. if(num_dims==2){ outputdims[2] = 1; outputdims[3] = 1; }else if(num_dims==3){ outputdims[3] = 1; } // Create the output arrays. POOLED = mxCreateNumericArray(num_dims, (mwSize*) outputdims, mxSINGLE_CLASS, mxREAL); // Get pointer to output matrix outputp = (float*) mxGetData(POOLED); // Create new indices array if none provided. POOLED_INDICES = mxCreateNumericArray(num_dims, (mwSize*) outputdims, mxUINT16_CLASS, mxREAL); indicesp = (unsigned short int*) mxGetData(POOLED_INDICES); // How much each bcol jumps in linear indices bcoljump = pooly*dims[0]; plane3jump = dims[0]*dims[1]; plane4jump = dims[0]*dims[1]*dims[2]; // mexPrintf("Number of input dimensions: %d %d %d %d, num_dims: %d", dims[0], dims[1], dims[2], dims[3], num_dims); // mexPrintf("Number of output dimensions: %d %d %d %d, bcoljump %d plane3jump %d",outputdims[0],outputdims[1],outputdims[2],outputdims[3],bcoljump,plane3jump); // mexErrMsgTxt("Kernel must be a single precision (float), not double."); if(INDICES_PROVIDED==false){ // Have to actually do the max pooling if(num_dims==2){ // Just pool the single image. // mexPrintf("dims: %d x %d \n", dims[0], dims[1]); float max, min = 0; int brow, bcol, i, j = 0; unsigned short int maxi, mini = 0; #pragma omp parallel for num_threads(number_threads) shared(imagesp, outputp, indicesp) private(brow, bcol, i, j, top_left, poolsizex, poolsizey, max, min, maxi, mini) for(bcol=0;bcol<blocksy;bcol++){ // Loop over blocks in columns for(brow=0;brow<blocksx;brow++){ // Loop of blocks in rows // Have to adjust poolsizes for non even block ratio if(remx>0 && brow==blocksx-1){poolsizex = remx;}else{poolsizex = poolx;} if(remy>0 && bcol==blocksy-1){poolsizey = remy;}else{poolsizey = pooly;} // Linear index into the top left element of the block (note this uses the original block sizes always). top_left = bcol*(bcoljump)+brow*poolx; // mexPrintf("poosizex: %d poolsizey: %d topleft: %d, brow %d, bcol %d\n",poolsizex,poolsizey,top_left,brow,bcol); max = 0; min = 0; maxi = 0; mini = 0; for(j=0;j<poolsizey;j++){ for(i=0;i<poolsizex;i++){ // Loop over rows of pool region int elem = top_left+j*dims[0]+i; if(imagesp[elem]>max){ max = imagesp[elem]; maxi = j*poolx+i; }else if(imagesp[elem]<min){ min = imagesp[elem]; mini = j*poolx+i; } // mexPrintf("%f (%d) i,j(%d,%d) (max,min)=(%f,%f) (maxi,mini)=(%d,%d)\n", imagesp[top_left+j*dims[0]+i],top_left+j*dims[0]+i,i,j,max,min,maxi,mini); } } // Take the max absolute value. if(max<fabs(min)){ max=min; maxi=mini; } // Adjust for 0,1 index start in C,Matlab maxi = maxi; // mexPrintf("Max: %f Index: %d\n\n",max,maxi); outputp[bcol*blocksx+brow] = max; indicesp[bcol*blocksx+brow] = maxi; } } }else if(num_dims==3){ // Pool each plane independently // mexPrintf("dims: %d x %d x %d \n", dims[0], dims[1], dims[2]); float max, min = 0; int brow, bcol, i, j,plane3 = 0; unsigned short int maxi, mini = 0; #pragma omp parallel for num_threads(number_threads) shared(imagesp, outputp, indicesp) private(plane3, brow, bcol, i, j, top_left, poolsizex, poolsizey, max, min, maxi, mini) for(plane3=0;plane3<outputdims[2];plane3++){ // Loop over the planes int he 3rd dimension for(bcol=0;bcol<blocksy;bcol++){ // Loop over blocks in columns for(brow=0;brow<blocksx;brow++){ // Loop of blocks in rows // Have to adjust poolsizes for non even block ratio if(remx>0 && brow==blocksx-1){ poolsizex = remx; }else{ poolsizex = poolx; } if(remy>0 && bcol==blocksy-1){ poolsizey = remy; }else{ poolsizey = pooly; } // Linear index into the top left element of the block (note this uses the original block sizes always). top_left = plane3*(plane3jump)+bcol*(bcoljump)+brow*poolx; // mexPrintf("poosizex: %d poolsizey: %d topleft: %d, brow %d, bcol %d\n",poolsizex,poolsizey,top_left,brow,bcol); max = 0; min = 0; maxi = 0; mini = 0; for(j=0;j<poolsizey;j++){ for(i=0;i<poolsizex;i++){ // Loop over rows of pool region int elem = top_left+j*dims[0]+i; if(imagesp[elem]>max){ max = imagesp[elem]; maxi = j*poolx+i; }else if(imagesp[elem]<min){ min = imagesp[elem]; mini = j*poolx+i; } // mexPrintf("%f (%d) i,j(%d,%d) (max,min)=(%f,%f) (maxi,mini)=(%d,%d)\n", imagesp[top_left+j*dims[0]+i],top_left+j*dims[0]+i,i,j,max,min,maxi,mini); } } // Take the max absolute value. if(max<fabs(min)){ max=min; maxi=mini; } // Adjust for 0,1 index start in C,Matlab maxi = maxi; // mexPrintf("Max: %f Index: %d\n\n",max,maxi); // mexPrintf("Index: %d\n",plane3*(blocksx*blocksy)+bcol*blocksx+brow); int outputelem = plane3*(blocksx*blocksy)+bcol*blocksx+brow; outputp[outputelem] = max; indicesp[outputelem] = maxi; } } } }else if(num_dims==4){ // Pool each plane independently // mexPrintf("dims: %d x %d x %d \n", dims[0], dims[1], dims[2]); float max, min = 0; int brow, bcol, i, j, plane3, plane4 = 0; unsigned short int maxi, mini = 0; #pragma omp parallel for num_threads(number_threads) shared(imagesp, outputp, indicesp) private(plane4, plane3, brow, bcol, i, j, top_left, poolsizex, poolsizey, max, min, maxi, mini) for(plane4=0;plane4<outputdims[3];plane4++){ for(plane3=0;plane3<outputdims[2];plane3++){ // Loop over the planes int he 3rd dimension for(bcol=0;bcol<blocksy;bcol++){ // Loop over blocks in columns for(brow=0;brow<blocksx;brow++){ // Loop of blocks in rows // Have to adjust poolsizes for non even block ratio if(remx>0 && brow==blocksx-1){ poolsizex = remx; }else{ poolsizex = poolx; } if(remy>0 && bcol==blocksy-1){ poolsizey = remy; }else{ poolsizey = pooly; } // Linear index into the top left element of the block (note this uses the original block sizes always). top_left = plane4*(plane4jump)+plane3*(plane3jump)+bcol*(bcoljump)+brow*poolx; // mexPrintf("poosizex: %d poolsizey: %d topleft: %d, brow %d, bcol %d\n",poolsizex,poolsizey,top_left,brow,bcol); max = 0; min = 0; maxi = 0; mini = 0; for(j=0;j<poolsizey;j++){ for(i=0;i<poolsizex;i++){ // Loop over rows of pool region int elem = top_left+j*dims[0]+i; if(imagesp[elem]>max){ max = imagesp[elem]; maxi = j*poolx+i; }else if(imagesp[elem]<min){ min = imagesp[elem]; mini = j*poolx+i; } // mexPrintf("%f (%d) i,j(%d,%d) (max,min)=(%f,%f) (maxi,mini)=(%d,%d)\n", imagesp[top_left+j*dims[0]+i],top_left+j*dims[0]+i,i,j,max,min,maxi,mini); } } // Take the max absolute value. if(max<fabs(min)){ max=min; maxi=mini; } // Adjust for 0,1 index start in C,Matlab maxi = maxi; // mexPrintf("Max: %f Index: %d\n\n",max,maxi); // mexPrintf("Index: %d\n",plane3*(blocksx*blocksy)+bcol*blocksx+brow); int outputelem = plane4*(blocksx*blocksy*outputdims[2])+plane3*(blocksx*blocksy)+bcol*blocksx+brow; outputp[outputelem] = max; indicesp[outputelem] = maxi; } } } } } }else{ // // // //Just select the max locations from IMAGES and return them in POOLED // // // // // if(num_dims==2){ // Just pool the single image. int brow, bcol, i, j,inputelem = 0; float max; unsigned short int maxi = 0; #pragma omp parallel for num_threads(number_threads) shared(imagesp, outputp, indicesp, inputindsp) private(brow, bcol, i, j, top_left, maxi, max, inputelem) for(bcol=0;bcol<blocksy;bcol++){ // Loop over blocks in columns for(brow=0;brow<blocksx;brow++){ // Loop of blocks in rows // Linear index into the top left element of the block (note this uses the original block sizes always). top_left = bcol*(blocksx)+brow; // Get the index at the pooled location from the input indices. maxi = inputindsp[top_left]; maxi = maxi; // convert from MATLAB indexing // Get the row and column offsets. i = maxi%poolx; j = (int)(maxi/poolx); // Have to skip (brow*poolx)+i elements down, bcol*poolx+j elements over. inputelem = brow*poolx+i+(bcol*pooly+j)*dims[0]; // mexPrintf("Input Index: %d, i: %d, j: %dm top_left: %d, inputelem: %d, dims[0]: %d\n",maxi+1,i,j,top_left,inputelem,dims[0]); max = imagesp[inputelem]; // Output at the pooled index is the selected element using the input indices. outputp[top_left] = max; indicesp[top_left] = inputindsp[top_left]; } } }else if(num_dims==3){ // Pool each plane independently int brow, bcol, i, j, inputelem, plane3 = 0; float max; unsigned short int maxi=0; #pragma omp parallel for num_threads(number_threads) shared(imagesp, outputp, indicesp, inputindsp) private(plane3, brow, bcol, i, j, top_left, maxi, max, inputelem) for(plane3=0;plane3<outputdims[2];plane3++){ // Loop over the planes int he 3rd dimension for(bcol=0;bcol<blocksy;bcol++){ // Loop over blocks in columns for(brow=0;brow<blocksx;brow++){ // Loop of blocks in rows // Linear index into the top left element of the block (note this uses the original block sizes always). top_left = plane3*(blocksx*blocksy)+bcol*(blocksx)+brow; // Get the index at the pooled location from the input indices. maxi = inputindsp[top_left]; maxi = maxi; // convert from MATLAB indexing // Get the row and column offsets. i = maxi%poolx; j = (int)(maxi/poolx); // Have to skip (brow*poolx)+i elements down, bcol*poolx+j elements over. inputelem = plane3*(dims[0]*dims[1])+brow*poolx+i+(bcol*pooly+j)*dims[0]; // mexPrintf("Input Index: %d, i: %d, j: %dm top_left: %d, inputelem: %d, dims[0]: %d\n",maxi+1,i,j,top_left,inputelem,dims[0]); max = imagesp[inputelem]; // Output at the pooled index is the selected element using the input indices. outputp[top_left] = max; indicesp[top_left] = inputindsp[top_left]; } } } }else if(num_dims==4){ // Pool each plane independently int brow, bcol, i, j, inputelem, plane3, plane4 = 0; float max; unsigned short int maxi=0; #pragma omp parallel for num_threads(number_threads) shared(imagesp, outputp, indicesp, inputindsp) private(plane4, plane3, brow, bcol, i, j, top_left, maxi, max, inputelem) for(plane4=0;plane4<outputdims[3];plane4++){ for(plane3=0;plane3<outputdims[2];plane3++){ // Loop over the planes int he 3rd dimension for(bcol=0;bcol<blocksy;bcol++){ // Loop over blocks in columns for(brow=0;brow<blocksx;brow++){ // Loop of blocks in rows // Linear index into the top left element of the block (note this uses the original block sizes always). top_left = plane4*(blocksx*blocksy*outputdims[2])+plane3*(blocksx*blocksy)+bcol*(blocksx)+brow; // Get the index at the pooled location from the input indices. maxi = inputindsp[top_left]; maxi = maxi; // convert from MATLAB indexing // Get the row and column offsets. i = maxi%poolx; j = (int)(maxi/poolx); // Have to skip (brow*poolx)+i elements down, bcol*poolx+j elements over. inputelem = plane4*(dims[0]*dims[1]*dims[2])+plane3*(dims[0]*dims[1])+brow*poolx+i+(bcol*pooly+j)*dims[0]; // mexPrintf("Input Index: %d, i: %d, j: %dm top_left: %d, inputelem: %d, dims[0]: %d\n",maxi+1,i,j,top_left,inputelem,dims[0]); max = imagesp[inputelem]; // Output at the pooled index is the selected element using the input indices. outputp[top_left] = max; indicesp[top_left] = inputindsp[top_left]; } } } } } } return; }
/** * MEX function entry point. */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { double *q, *qd, *qdd; double *tau; unsigned int m,n; int j, njoints, p, nq; double *fext = NULL; double *grav = NULL; Robot robot; mxArray *link0; mxArray *mx_robot; mxArray *mx_links; static int first_time = 0; /* fprintf(stderr, "Fast RNE: (c) Peter Corke 2002-2011\n"); */ if ( !mxIsClass(ROBOT_IN, "SerialLink") ) mexErrMsgTxt("frne: first argument is not a robot structure\n"); mx_robot = (mxArray *)ROBOT_IN; njoints = mstruct_getint(mx_robot, 0, "n"); /*********************************************************************** * Handle the different calling formats. * Setup pointers to q, qd and qdd inputs ***********************************************************************/ switch (nrhs) { case 2: /* * TAU = RNE(ROBOT, [Q QD QDD]) */ if (NUMCOLS(A1_IN) != 3 * njoints) mexErrMsgTxt("frne: too few cols in [Q QD QDD]"); q = POINTER(A1_IN); nq = NUMROWS(A1_IN); qd = &q[njoints*nq]; qdd = &q[2*njoints*nq]; break; case 3: /* * TAU = RNE(ROBOT, [Q QD QDD], GRAV) */ if (NUMCOLS(A1_IN) != (3 * njoints)) mexErrMsgTxt("frne: too few cols in [Q QD QDD]"); q = POINTER(A1_IN); nq = NUMROWS(A1_IN); qd = &q[njoints*nq]; qdd = &q[2*njoints*nq]; if (NUMELS(A2_IN) != 3) mexErrMsgTxt("frne: gravity vector expected"); grav = POINTER(A2_IN); break; case 4: /* * TAU = RNE(ROBOT, Q, QD, QDD) * TAU = RNE(ROBOT, [Q QD QDD], GRAV, FEXT) */ if (NUMCOLS(A1_IN) == (3 * njoints)) { q = POINTER(A1_IN); nq = NUMROWS(A1_IN); qd = &q[njoints*nq]; qdd = &q[2*njoints*nq]; if (NUMELS(A2_IN) != 3) mexErrMsgTxt("frne: gravity vector expected"); grav = POINTER(A2_IN); if (NUMELS(A3_IN) != 6) mexErrMsgTxt("frne: Fext vector expected"); fext = POINTER(A3_IN); } else { int nqd = NUMROWS(A2_IN), nqdd = NUMROWS(A3_IN); nq = NUMROWS(A1_IN); if ((nq != nqd) || (nqd != nqdd)) mexErrMsgTxt("frne: Q QD QDD must be same length"); if ( (NUMCOLS(A1_IN) != njoints) || (NUMCOLS(A2_IN) != njoints) || (NUMCOLS(A3_IN) != njoints) ) mexErrMsgTxt("frne: Q must have Naxis columns"); q = POINTER(A1_IN); qd = POINTER(A2_IN); qdd = POINTER(A3_IN); } break; case 5: { /* * TAU = RNE(ROBOT, Q, QD, QDD, GRAV) */ int nqd = NUMROWS(A2_IN), nqdd = NUMROWS(A3_IN); nq = NUMROWS(A1_IN); if ((nq != nqd) || (nqd != nqdd)) mexErrMsgTxt("frne: Q QD QDD must be same length"); if ( (NUMCOLS(A1_IN) != njoints) || (NUMCOLS(A2_IN) != njoints) || (NUMCOLS(A3_IN) != njoints) ) mexErrMsgTxt("frne: Q must have Naxis columns"); q = POINTER(A1_IN); qd = POINTER(A2_IN); qdd = POINTER(A3_IN); if (NUMELS(A4_IN) != 3) mexErrMsgTxt("frne: gravity vector expected"); grav = POINTER(A4_IN); break; } case 6: { /* * TAU = RNE(ROBOT, Q, QD, QDD, GRAV, FEXT) */ int nqd = NUMROWS(A2_IN), nqdd = NUMROWS(A3_IN); nq = NUMROWS(A1_IN); if ((nq != nqd) || (nqd != nqdd)) mexErrMsgTxt("frne: Q QD QDD must be same length"); if ( (NUMCOLS(A1_IN) != njoints) || (NUMCOLS(A2_IN) != njoints) || (NUMCOLS(A3_IN) != njoints) ) mexErrMsgTxt("frne: Q must have Naxis columns"); q = POINTER(A1_IN); qd = POINTER(A2_IN); qdd = POINTER(A3_IN); if (NUMELS(A4_IN) != 3) mexErrMsgTxt("frne: gravity vector expected"); grav = POINTER(A4_IN); if (NUMELS(A5_IN) != 6) mexErrMsgTxt("frne: Fext vector expected"); fext = POINTER(A5_IN); break; } default: mexErrMsgTxt("frne: wrong number of arguments."); } /* * fill out the robot structure */ robot.njoints = njoints; if (grav) robot.gravity = (Vect *)grav; else robot.gravity = (Vect *)mxGetPr( mxGetProperty(mx_robot, (mwIndex)0, "gravity") ); robot.dhtype = mstruct_getint(mx_robot, 0, "mdh"); /* build link structure */ robot.links = (Link *)mxCalloc((mwSize) njoints, (mwSize) sizeof(Link)); /*********************************************************************** * Now we have to get pointers to data spread all across a cell-array * of Matlab structures. * * Matlab structure elements can be found by name (slow) or by number (fast). * We assume that since the link structures are all created by the same * constructor, the index number for each element will be the same for all * links. However we make no assumption about the numbers themselves. ***********************************************************************/ /* get pointer to the first link structure */ link0 = mxGetProperty(mx_robot, (mwIndex) 0, "links"); if (link0 == NULL) mexErrMsgTxt("couldnt find element link in robot object"); /* * Elements of the link structure are: * * alpha: * A: * theta: * D: * offset: * sigma: * mdh: * m: * r: * I: * Jm: * G: * B: * Tc: */ if (first_time == 0) { mexPrintf("Fast RNE: (c) Peter Corke 2002-2012\n"); first_time = 1; } /* * copy data from the Link objects into the local links structure * to save function calls later */ for (j=0; j<njoints; j++) { Link *l = &robot.links[j]; mxArray *links = mxGetProperty(mx_robot, (mwIndex) 0, "links"); // links array l->alpha = mxGetScalar( mxGetProperty(links, (mwIndex) j, "alpha") ); l->A = mxGetScalar( mxGetProperty(links, (mwIndex) j, "a") ); l->theta = mxGetScalar( mxGetProperty(links, (mwIndex) j, "theta") ); l->D = mxGetScalar( mxGetProperty(links, (mwIndex) j, "d") ); l->sigma = mxGetScalar( mxGetProperty(links, (mwIndex) j, "sigma") ); l->offset = mxGetScalar( mxGetProperty(links, (mwIndex) j, "offset") ); l->m = mxGetScalar( mxGetProperty(links, (mwIndex) j, "m") ); l->rbar = (Vect *)mxGetPr( mxGetProperty(links, (mwIndex) j, "r") ); l->I = mxGetPr( mxGetProperty(links, (mwIndex) j, "I") ); l->Jm = mxGetScalar( mxGetProperty(links, (mwIndex) j, "Jm") ); l->G = mxGetScalar( mxGetProperty(links, (mwIndex) j, "G") ); l->B = mxGetScalar( mxGetProperty(links, (mwIndex) j, "B") ); l->Tc = mxGetPr( mxGetProperty(links, (mwIndex) j, "Tc") ); } /* Create a matrix for the return argument */ TAU_OUT = mxCreateDoubleMatrix((mwSize) nq, (mwSize) njoints, mxREAL); tau = mxGetPr(TAU_OUT); #define MEL(x,R,C) (x[(R)+(C)*nq]) /* for each point in the input trajectory */ for (p=0; p<nq; p++) { /* * update all position dependent variables */ for (j = 0; j < njoints; j++) { Link *l = &robot.links[j]; switch (l->sigma) { case REVOLUTE: rot_mat(l, MEL(q,p,j)+l->offset, l->D, robot.dhtype); break; case PRISMATIC: rot_mat(l, l->theta, MEL(q,p,j)+l->offset, robot.dhtype); break; } #ifdef DEBUG rot_print("R", &l->R); vect_print("p*", &l->r); #endif } newton_euler(&robot, &tau[p], &qd[p], &qdd[p], fext, nq); } mxFree(robot.links); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mxArray *MatlabFunctionHandle; direct_algorithm theAlgorithm=DIRECT_ORIGINAL; const direct_objective_func f=&MatlabCallback; size_t numDim; double *lowerBounds; double *upperBounds; int maxFEval=500; int maxIter=100; double epsilon=1e-4; double epsilonAbs=0; double volumeRelTol=1e-10; double sigmaRelTol=0; double fGlobal=DIRECT_UNKNOWN_FGLOBAL; double fGlobalRelTol=DIRECT_UNKNOWN_FGLOBAL; int maxDiv=5000; //To hold return values direct_return_code retVal; double *x; double fVal; if(nrhs<3||nrhs>4){ mexErrMsgTxt("Wrong number of inputs"); } if(nlhs>3) { mexErrMsgTxt("Wrong number of outputs."); } //Check that a function handle was passed. if(!mxIsClass(prhs[0],"function_handle")) { mexErrMsgTxt("The first input must be a function handle."); } MatlabFunctionHandle=prhs[0]; //Check the lower and upper bounds checkRealDoubleArray(prhs[1]); checkRealDoubleArray(prhs[2]); numDim=mxGetM(prhs[1]); if(numDim<1||mxGetN(prhs[1])!=1) { mexErrMsgTxt("The lower bounds have the wrong dimensionality."); } if(mxGetM(prhs[2])!=numDim||mxGetN(prhs[1])!=1) { mexErrMsgTxt("The upper bounds have the wrong dimensionality."); } //The function in the library only uses integers for dimensions. if(numDim>INT_MAX) { mexErrMsgTxt("The problem has too many dimensions to be solved using this function."); } lowerBounds=(double*)mxGetData(prhs[1]); upperBounds=(double*)mxGetData(prhs[2]); //If a structure of options was given if(nrhs>3&&!mxIsEmpty(prhs[3])) { //We have to check for every possible structure member. mxArray *theField; if(!mxIsStruct(prhs[3])) { mexErrMsgTxt("The options must be given in a structure."); } theField=mxGetField(prhs[3],0,"algorithm"); if(theField!=NULL) {//If the field is present. int algType=getIntFromMatlab(theField); //Algorithm type switch(algType) { case 0: theAlgorithm=DIRECT_ORIGINAL; break; case 1: theAlgorithm=DIRECT_GABLONSKY; break; default: mexErrMsgTxt("Invalid algorithm specified"); } } theField=mxGetField(prhs[3],0,"maxDiv"); if(theField!=NULL) {//If the field is present. maxDiv=getIntFromMatlab(theField); if(maxDiv<1) { mexErrMsgTxt("Invalid maxDiv specified"); } } theField=mxGetField(prhs[3],0,"maxIter"); if(theField!=NULL) {//If the field is present. maxIter=getIntFromMatlab(theField); if(maxIter<1) { mexErrMsgTxt("Invalid maxIter specified"); } } theField=mxGetField(prhs[3],0,"maxFEval"); if(theField!=NULL) {//If the field is present. maxFEval=getIntFromMatlab(theField); if(maxIter<1) { mexErrMsgTxt("Invalid maxFEval specified"); } } theField=mxGetField(prhs[3],0,"epsilon"); if(theField!=NULL) {//If the field is present. epsilon=getDoubleFromMatlab(theField); if(fabs(epsilon)>=1) { mexErrMsgTxt("Invalid epsilon specified"); } } theField=mxGetField(prhs[3],0,"epsilonAbs"); if(theField!=NULL) {//If the field is present. epsilonAbs=getDoubleFromMatlab(theField); if(epsilonAbs>=1||epsilonAbs<0) { mexErrMsgTxt("Invalid epsilonAbs specified"); } } theField=mxGetField(prhs[3],0,"volumeRelTol"); if(theField!=NULL) {//If the field is present. volumeRelTol=getDoubleFromMatlab(theField); if(volumeRelTol>=1||volumeRelTol<0) { mexErrMsgTxt("Invalid volumeRelTol specified"); } } theField=mxGetField(prhs[3],0,"sigmaRelTol"); if(theField!=NULL) {//If the field is present. sigmaRelTol=getDoubleFromMatlab(theField); if(sigmaRelTol>=1||sigmaRelTol<0) { mexErrMsgTxt("Invalid sigmaRelTol specified"); } } theField=mxGetField(prhs[3],0,"fGlobal"); if(theField!=NULL) {//If the field is present. fGlobal=getDoubleFromMatlab(theField); fGlobalRelTol=1e-12;//Default value if fGlobal is given. } theField=mxGetField(prhs[3],0,"fGlobalRelTol"); if(theField!=NULL) {//If the field is present. fGlobalRelTol=getDoubleFromMatlab(theField); if(fGlobalRelTol<0) { mexErrMsgTxt("Invalid fGlobalRelTol specified"); } } } //Allocate space for the return values x=mxCalloc(numDim, sizeof(double)); retVal=direct_optimize(f,//Objective function pointer (void*)MatlabFunctionHandle,//Data that passed to the objective function. Here, the function handle passed by the user. (int)numDim,//The dimensionality of the problem lowerBounds,//Array of the lower bound of each dimension. upperBounds,//Array of the upper bound of each dimension. x,//An array that will be set to the optimum value on return. &fVal,//On return, set to the minimum value. maxFEval,//Maximum number of function evaluations. maxIter,//Maximum number of iterations epsilon,//Jones' epsilon parameter (1e-4 is recommended) epsilonAbs,//An absolute version of magic_eps //Relative tolerance on the hypercube volume (use 0 if none). This is //a percentage (0-1) of the volume of the original hypercube volumeRelTol, //Relative tolerance on the hypercube measure (0 if none) sigmaRelTol, //A pointer to a variable that can terminate the optimization. This is //in the library's code so that an external thread can write to this //and force the optimization to stop. Here, we are not using it, so we //can pass NULL. NULL, fGlobal,//Function value of the global optimum, if known. Use DIRECT_UNKNOWN_FGLOBAL if unknown. fGlobalRelTol,//Relative tolerance for convergence if fglobal is known. If unknown, use DIRECT_UNKNOWN_FGLOBAL. NULL,//There is no output to a file. theAlgorithm,//The algorithm to use maxDiv);//The maximum number of hyperrectangle divisions //If an error occurred if(retVal<0) { mxFree(x); switch(retVal){ case DIRECT_INVALID_BOUNDS: mexErrMsgTxt("Upper bounds are <= lower bounds for one or more dimensions."); case DIRECT_MAXFEVAL_TOOBIG: mexErrMsgTxt("maxFEval is too large."); case DIRECT_INIT_FAILED: mexErrMsgTxt("An initialization step failed."); case DIRECT_SAMPLEPOINTS_FAILED: mexErrMsgTxt("An error occurred creating sampling points."); case DIRECT_SAMPLE_FAILED: mexErrMsgTxt("An error occurred while sampling the function."); case DIRECT_OUT_OF_MEMORY: mexErrMsgTxt("Out of memory"); case DIRECT_INVALID_ARGS: mexErrMsgTxt("Invalid arguments provided"); //These errors should not occur either because they should //never be called or because retVal>=0 so these are not //actually errors. case DIRECT_FORCED_STOP: case DIRECT_MAXFEVAL_EXCEEDED: case DIRECT_MAXITER_EXCEEDED: case DIRECT_GLOBAL_FOUND: case DIRECT_VOLTOL: case DIRECT_SIGMATOL: case DIRECT_MAXTIME_EXCEEDED: default: mexErrMsgTxt("An unknown error occurred."); } } //Set the return values plhs[0]=mxCreateNumericMatrix(0, 0, mxDOUBLE_CLASS, mxREAL); mxFree(mxGetPr(plhs[0])); mxSetPr(plhs[0], x); mxSetM(plhs[0], numDim); mxSetN(plhs[0], 1); if(nlhs>1) { plhs[1]=doubleMat2Matlab(&fVal,1,1); if(nlhs>2) { plhs[2]=intMat2MatlabDoubles(&retVal,1,1); } } }
void mexFunction( int nl, mxArray *pl[], int nr, const mxArray *pr[] ) { if( nr==0 ){ usage(MATLAB_OPTIONS); return; } if ( nl != 1){ usage(MATLAB_OPTIONS); mexErrMsgTxt("error: returns one output"); return; } if( nr < 2 || nr > 4){ usage(MATLAB_OPTIONS); mexErrMsgTxt("error: takes two to four inputs"); return; } // The code is originally written for C-order arrays. // We thus transpose all arrays in this mex-function which is not efficient... const int *pDims; if( mxGetNumberOfDimensions(pr[0]) != 3 ) mexErrMsgTxt("input images must have 3 dimensions"); if( !mxIsClass(pr[0], "single") ) mexErrMsgTxt("input images must be single"); pDims = mxGetDimensions(pr[0]); if( pDims[2]!=3 ) mexErrMsgTxt("input images must have 3 channels"); const int h = pDims[0], w = pDims[1]; color_image_t *im1 = input3darray_to_color_image( pr[0] ); if( mxGetNumberOfDimensions(pr[1]) != 3 ) mexErrMsgTxt("input images must have 3 dimensions"); if( !mxIsClass(pr[1], "single") ) mexErrMsgTxt("input images must be single"); pDims = mxGetDimensions(pr[1]); if( pDims[0]!=h || pDims[1]!=w || pDims[2]!=3) mexErrMsgTxt( "input images must have the same size" ); color_image_t *im2 = input3darray_to_color_image( pr[1] ); image_t *match_x = NULL, *match_y = NULL, *match_z = NULL; if( nr>2 && !mxIsEmpty(pr[2]) ){ if( mxGetNumberOfDimensions(pr[2]) != 2 ) mexErrMsgTxt("input matches must be a 2d-matrix"); if( !mxIsClass(pr[2], "single")) mexErrMsgTxt("input matches must be single"); pDims = mxGetDimensions(pr[1]); if( pDims[1]<4) mexErrMsgTxt( "input matches must have at least 4 columns: x1 y1 x2 y2" ); match_x = image_new(w, h); match_y = image_new(w, h); match_z = image_new(w, h); input2darray_to_matches( match_x, match_y, match_z, pr[2]); } // set params to default optical_flow_params_t* params = (optical_flow_params_t*) malloc(sizeof(optical_flow_params_t)); if(!params){ fprintf(stderr,"error deepflow2(): not enough memory\n"); exit(1); } optical_flow_params_default(params); // read options if( nr > 3 ){ char *options = mxArrayToString(pr[3]); if( !options ) mexErrMsgTxt("Fourth parameter must be a string"); int argc=0; char* argv[256]; argv[argc]=strtok(options," "); while(argv[argc]!=NULL) { argv[++argc]=strtok(NULL," "); } parse_options(params, argc, argv, MATLAB_OPTIONS, w, h); } image_t *wx = image_new(im1->width,im1->height), *wy = image_new(im1->width,im1->height); optical_flow(wx, wy, im1, im2, params, match_x, match_y, match_z); int dims[3] = {h,w,2}; pl[0] = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL); flow_to_output3darray(wx, wy, pl[0]); image_delete(wx); image_delete(wy); image_delete(match_x); image_delete(match_y); image_delete(match_z); color_image_delete(im1); color_image_delete(im2); free(params); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i, j; mxArray *xm, *cell, *xm_cell; double *src; double *dest; double *dest_cell; int valid_vars; int steps; int this_var_errors; int warned_diags; int prepare_for_c = 0; int extra_solves; const char *status_names[] = {"optval", "gap", "steps", "converged"}; mwSize dims1x1of1[1] = {1}; mwSize dims[1]; const char *var_names[] = {"phi", "rho", "vd"}; const int num_var_names = 3; /* Avoid compiler warnings of unused variables by using a dummy assignment. */ warned_diags = j = 0; extra_solves = 0; set_defaults(); /* Check we got the right number of arguments. */ if (nrhs == 0) mexErrMsgTxt("Not enough arguments: You need to specify at least the parameters.\n"); if (nrhs > 1) { /* Assume that the second argument is the settings. */ if (mxGetField(prhs[1], 0, "eps") != NULL) settings.eps = *mxGetPr(mxGetField(prhs[1], 0, "eps")); if (mxGetField(prhs[1], 0, "max_iters") != NULL) settings.max_iters = *mxGetPr(mxGetField(prhs[1], 0, "max_iters")); if (mxGetField(prhs[1], 0, "refine_steps") != NULL) settings.refine_steps = *mxGetPr(mxGetField(prhs[1], 0, "refine_steps")); if (mxGetField(prhs[1], 0, "verbose") != NULL) settings.verbose = *mxGetPr(mxGetField(prhs[1], 0, "verbose")); if (mxGetField(prhs[1], 0, "better_start") != NULL) settings.better_start = *mxGetPr(mxGetField(prhs[1], 0, "better_start")); if (mxGetField(prhs[1], 0, "verbose_refinement") != NULL) settings.verbose_refinement = *mxGetPr(mxGetField(prhs[1], 0, "verbose_refinement")); if (mxGetField(prhs[1], 0, "debug") != NULL) settings.debug = *mxGetPr(mxGetField(prhs[1], 0, "debug")); if (mxGetField(prhs[1], 0, "kkt_reg") != NULL) settings.kkt_reg = *mxGetPr(mxGetField(prhs[1], 0, "kkt_reg")); if (mxGetField(prhs[1], 0, "s_init") != NULL) settings.s_init = *mxGetPr(mxGetField(prhs[1], 0, "s_init")); if (mxGetField(prhs[1], 0, "z_init") != NULL) settings.z_init = *mxGetPr(mxGetField(prhs[1], 0, "z_init")); if (mxGetField(prhs[1], 0, "resid_tol") != NULL) settings.resid_tol = *mxGetPr(mxGetField(prhs[1], 0, "resid_tol")); if (mxGetField(prhs[1], 0, "extra_solves") != NULL) extra_solves = *mxGetPr(mxGetField(prhs[1], 0, "extra_solves")); else extra_solves = 0; if (mxGetField(prhs[1], 0, "prepare_for_c") != NULL) prepare_for_c = *mxGetPr(mxGetField(prhs[1], 0, "prepare_for_c")); } valid_vars = 0; this_var_errors = 0; xm = mxGetField(prhs[0], 0, "A"); if (xm == NULL) { printf("could not find params.A.\n"); } else { if (!((mxGetM(xm) == 6) && (mxGetN(xm) == 34))) { printf("A must be size (6,34), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter A must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter A must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter A must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.A; src = mxGetPr(xm); for (i = 0; i < 204; i++) *dest++ = *src++; valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "C"); if (xm == NULL) { printf("could not find params.C.\n"); } else { if (!((mxGetM(xm) == 6) && (mxGetN(xm) == 6))) { printf("C must be size (6,6), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter C must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter C must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter C must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.C; src = mxGetPr(xm); warned_diags = 0; for (i = 0; i < 6; i++) { for (j = 0; j < 6; j++) { if (i == j) { *dest++ = *src; } else if (!warned_diags && (*src != 0)) { printf("\n!!! Warning: ignoring off-diagonal elements in C !!!\n\n"); warned_diags = 1; } src++; } } valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "Js"); if (xm == NULL) { printf("could not find params.Js.\n"); } else { if (!((mxGetM(xm) == 34) && (mxGetN(xm) == 34))) { printf("Js must be size (34,34), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter Js must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter Js must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter Js must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.Js; src = mxGetPr(xm); for (i = 0; i < 1156; i++) *dest++ = *src++; valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "Lambda"); if (xm == NULL) { printf("could not find params.Lambda.\n"); } else { if (!((mxGetM(xm) == 34) && (mxGetN(xm) == 34))) { printf("Lambda must be size (34,34), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter Lambda must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter Lambda must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter Lambda must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.Lambda; src = mxGetPr(xm); warned_diags = 0; for (i = 0; i < 34; i++) { for (j = 0; j < 34; j++) { if (i == j) { *dest++ = *src; } else if (!warned_diags && (*src != 0)) { printf("\n!!! Warning: ignoring off-diagonal elements in Lambda !!!\n\n"); warned_diags = 1; } src++; } } valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "Qphi"); if (xm == NULL) { printf("could not find params.Qphi.\n"); } else { if (!((mxGetM(xm) == 6) && (mxGetN(xm) == 10))) { printf("Qphi must be size (6,10), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter Qphi must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter Qphi must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter Qphi must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.Qphi; src = mxGetPr(xm); for (i = 0; i < 60; i++) *dest++ = *src++; valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "Qrho"); if (xm == NULL) { printf("could not find params.Qrho.\n"); } else { if (!((mxGetM(xm) == 6) && (mxGetN(xm) == 64))) { printf("Qrho must be size (6,64), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter Qrho must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter Qrho must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter Qrho must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.Qrho; src = mxGetPr(xm); for (i = 0; i < 384; i++) *dest++ = *src++; valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "WPhi"); if (xm == NULL) { printf("could not find params.WPhi.\n"); } else { if (!((mxGetM(xm) == 10) && (mxGetN(xm) == 10))) { printf("WPhi must be size (10,10), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter WPhi must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter WPhi must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter WPhi must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.WPhi; src = mxGetPr(xm); warned_diags = 0; for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { if (i == j) { *dest++ = *src; } else if (!warned_diags && (*src != 0)) { printf("\n!!! Warning: ignoring off-diagonal elements in WPhi !!!\n\n"); warned_diags = 1; } src++; } } valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "WRho"); if (xm == NULL) { printf("could not find params.WRho.\n"); } else { if (!((mxGetM(xm) == 64) && (mxGetN(xm) == 64))) { printf("WRho must be size (64,64), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter WRho must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter WRho must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter WRho must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.WRho; src = mxGetPr(xm); warned_diags = 0; for (i = 0; i < 64; i++) { for (j = 0; j < 64; j++) { if (i == j) { *dest++ = *src; } else if (!warned_diags && (*src != 0)) { printf("\n!!! Warning: ignoring off-diagonal elements in WRho !!!\n\n"); warned_diags = 1; } src++; } } valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "WRhoSmoother"); if (xm == NULL) { printf("could not find params.WRhoSmoother.\n"); } else { if (!((mxGetM(xm) == 64) && (mxGetN(xm) == 64))) { printf("WRhoSmoother must be size (64,64), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter WRhoSmoother must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter WRhoSmoother must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter WRhoSmoother must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.WRhoSmoother; src = mxGetPr(xm); warned_diags = 0; for (i = 0; i < 64; i++) { for (j = 0; j < 64; j++) { if (i == j) { *dest++ = *src; } else if (!warned_diags && (*src != 0)) { printf("\n!!! Warning: ignoring off-diagonal elements in WRhoSmoother !!!\n\n"); warned_diags = 1; } src++; } } valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "Ws"); if (xm == NULL) { printf("could not find params.Ws.\n"); } else { if (!((mxGetM(xm) == 34) && (mxGetN(xm) == 34))) { printf("Ws must be size (34,34), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter Ws must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter Ws must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter Ws must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.Ws; src = mxGetPr(xm); warned_diags = 0; for (i = 0; i < 34; i++) { for (j = 0; j < 34; j++) { if (i == j) { *dest++ = *src; } else if (!warned_diags && (*src != 0)) { printf("\n!!! Warning: ignoring off-diagonal elements in Ws !!!\n\n"); warned_diags = 1; } src++; } } valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "b"); if (xm == NULL) { printf("could not find params.b.\n"); } else { if (!((mxGetM(xm) == 6) && (mxGetN(xm) == 1))) { printf("b must be size (6,1), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter b must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter b must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter b must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.b; src = mxGetPr(xm); for (i = 0; i < 6; i++) *dest++ = *src++; valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "c"); if (xm == NULL) { printf("could not find params.c.\n"); } else { if (!((mxGetM(xm) == 6) && (mxGetN(xm) == 1))) { printf("c must be size (6,1), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter c must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter c must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter c must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.c; src = mxGetPr(xm); for (i = 0; i < 6; i++) *dest++ = *src++; valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "phiMax"); if (xm == NULL) { printf("could not find params.phiMax.\n"); } else { if (!((mxGetM(xm) == 10) && (mxGetN(xm) == 1))) { printf("phiMax must be size (10,1), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter phiMax must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter phiMax must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter phiMax must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.phiMax; src = mxGetPr(xm); for (i = 0; i < 10; i++) *dest++ = *src++; valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "phiMin"); if (xm == NULL) { printf("could not find params.phiMin.\n"); } else { if (!((mxGetM(xm) == 10) && (mxGetN(xm) == 1))) { printf("phiMin must be size (10,1), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter phiMin must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter phiMin must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter phiMin must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.phiMin; src = mxGetPr(xm); for (i = 0; i < 10; i++) *dest++ = *src++; valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "ps"); if (xm == NULL) { printf("could not find params.ps.\n"); } else { if (!((mxGetM(xm) == 34) && (mxGetN(xm) == 1))) { printf("ps must be size (34,1), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter ps must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter ps must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter ps must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.ps; src = mxGetPr(xm); for (i = 0; i < 34; i++) *dest++ = *src++; valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "rhoMin"); if (xm == NULL) { printf("could not find params.rhoMin.\n"); } else { if (!((mxGetM(xm) == 64) && (mxGetN(xm) == 1))) { printf("rhoMin must be size (64,1), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter rhoMin must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter rhoMin must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter rhoMin must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.rhoMin; src = mxGetPr(xm); for (i = 0; i < 64; i++) *dest++ = *src++; valid_vars++; } } this_var_errors = 0; xm = mxGetField(prhs[0], 0, "rhoPrevious"); if (xm == NULL) { printf("could not find params.rhoPrevious.\n"); } else { if (!((mxGetM(xm) == 64) && (mxGetN(xm) == 1))) { printf("rhoPrevious must be size (64,1), not (%d,%d).\n", mxGetM(xm), mxGetN(xm)); this_var_errors++; } if (mxIsComplex(xm)) { printf("parameter rhoPrevious must be real.\n"); this_var_errors++; } if (!mxIsClass(xm, "double")) { printf("parameter rhoPrevious must be a full matrix of doubles.\n"); this_var_errors++; } if (mxIsSparse(xm)) { printf("parameter rhoPrevious must be a full matrix.\n"); this_var_errors++; } if (this_var_errors == 0) { dest = params.rhoPrevious; src = mxGetPr(xm); for (i = 0; i < 64; i++) *dest++ = *src++; valid_vars++; } } if (valid_vars != 17) { printf("Error: %d parameters are invalid.\n", 17 - valid_vars); mexErrMsgTxt("invalid parameters found."); } if (prepare_for_c) { printf("settings.prepare_for_c == 1. thus, outputting for C.\n"); for (i = 0; i < 204; i++) printf(" params.A[%d] = %.6g;\n", i, params.A[i]); for (i = 0; i < 6; i++) printf(" params.b[%d] = %.6g;\n", i, params.b[i]); for (i = 0; i < 6; i++) printf(" params.C[%d] = %.6g;\n", i, params.C[i]); for (i = 0; i < 1156; i++) printf(" params.Js[%d] = %.6g;\n", i, params.Js[i]); for (i = 0; i < 34; i++) printf(" params.ps[%d] = %.6g;\n", i, params.ps[i]); for (i = 0; i < 34; i++) printf(" params.Ws[%d] = %.6g;\n", i, params.Ws[i]); for (i = 0; i < 64; i++) printf(" params.WRho[%d] = %.6g;\n", i, params.WRho[i]); for (i = 0; i < 10; i++) printf(" params.WPhi[%d] = %.6g;\n", i, params.WPhi[i]); for (i = 0; i < 34; i++) printf(" params.Lambda[%d] = %.6g;\n", i, params.Lambda[i]); for (i = 0; i < 64; i++) printf(" params.rhoPrevious[%d] = %.6g;\n", i, params.rhoPrevious[i]); for (i = 0; i < 64; i++) printf(" params.WRhoSmoother[%d] = %.6g;\n", i, params.WRhoSmoother[i]); for (i = 0; i < 384; i++) printf(" params.Qrho[%d] = %.6g;\n", i, params.Qrho[i]); for (i = 0; i < 60; i++) printf(" params.Qphi[%d] = %.6g;\n", i, params.Qphi[i]); for (i = 0; i < 6; i++) printf(" params.c[%d] = %.6g;\n", i, params.c[i]); for (i = 0; i < 64; i++) printf(" params.rhoMin[%d] = %.6g;\n", i, params.rhoMin[i]); for (i = 0; i < 10; i++) printf(" params.phiMin[%d] = %.6g;\n", i, params.phiMin[i]); for (i = 0; i < 10; i++) printf(" params.phiMax[%d] = %.6g;\n", i, params.phiMax[i]); } /* Perform the actual solve in here. */ steps = solve(); /* For profiling purposes, allow extra silent solves if desired. */ settings.verbose = 0; for (i = 0; i < extra_solves; i++) solve(); /* Update the status variables. */ plhs[1] = mxCreateStructArray(1, dims1x1of1, 4, status_names); xm = mxCreateDoubleMatrix(1, 1, mxREAL); mxSetField(plhs[1], 0, "optval", xm); *mxGetPr(xm) = work.optval; xm = mxCreateDoubleMatrix(1, 1, mxREAL); mxSetField(plhs[1], 0, "gap", xm); *mxGetPr(xm) = work.gap; xm = mxCreateDoubleMatrix(1, 1, mxREAL); mxSetField(plhs[1], 0, "steps", xm); *mxGetPr(xm) = steps; xm = mxCreateDoubleMatrix(1, 1, mxREAL); mxSetField(plhs[1], 0, "converged", xm); *mxGetPr(xm) = work.converged; /* Extract variable values. */ plhs[0] = mxCreateStructArray(1, dims1x1of1, num_var_names, var_names); xm = mxCreateDoubleMatrix(10, 1, mxREAL); mxSetField(plhs[0], 0, "phi", xm); dest = mxGetPr(xm); src = vars.phi; for (i = 0; i < 10; i++) { *dest++ = *src++; } xm = mxCreateDoubleMatrix(64, 1, mxREAL); mxSetField(plhs[0], 0, "rho", xm); dest = mxGetPr(xm); src = vars.rho; for (i = 0; i < 64; i++) { *dest++ = *src++; } xm = mxCreateDoubleMatrix(34, 1, mxREAL); mxSetField(plhs[0], 0, "vd", xm); dest = mxGetPr(xm); src = vars.vd; for (i = 0; i < 34; i++) { *dest++ = *src++; } }