void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const int I = mxGetM(prhs[0]); const int J = mxGetN(prhs[0]); const int N = mxGetNumberOfElements(prhs[1]); const int L = mxGetM(prhs[3]); const int ***G = mxMalloc(sizeof(int**)*N); int n, g, nG; if (mxIsDouble(prhs[0])){ const double **Rb = mxMalloc(sizeof(double*)*N); for (n=0; n<N; n++){ Rb[n] = (double*) mxGetData(mxGetCell(prhs[2], n)); nG = mxGetN(mxGetCell(prhs[2], n)); G[n] = mxMalloc(sizeof(int*)*(nG+1)); for (g=0; g<=nG; g++){ G[n][g] = (int*) mxGetData(mxGetCell(mxGetCell(prhs[1], n), g)); } } const double *La = (double*) mxGetData(prhs[3]); plhs[0] = mxCreateNumericMatrix(L, I, mxDOUBLE_CLASS, mxREAL); double* V = (double*) mxGetData(plhs[0]); if (mxIsComplex(prhs[0])){ const double *Xr = (double*) mxGetData(prhs[0]); const double *Xi = (double*) mxGetImagData(prhs[0]); var_prox_d12_cplx_double(Xr, Xi, G, Rb, La, V, I, J, N, L); }else{ const double *X = (double*) mxGetData(prhs[0]); var_prox_d12_real_double(X, G, Rb, La, V, I, J, N, L); } }else{ const float **Rb = mxMalloc(sizeof(float*)*N); for (n=0; n<N; n++){ Rb[n] = (float*) mxGetData(mxGetCell(prhs[2], n)); nG = mxGetN(mxGetCell(prhs[2], n)); G[n] = mxMalloc(sizeof(int*)*(nG+1)); for (g=0; g<=nG; g++){ G[n][g] = (int*) mxGetData(mxGetCell(mxGetCell(prhs[1], n), g)); } } const float *La = (float*) mxGetData(prhs[3]); plhs[0] = mxCreateNumericMatrix(L, I, mxSINGLE_CLASS, mxREAL); float* V = (float*) mxGetData(plhs[0]); if (mxIsComplex(prhs[0])){ const float *Xr = (float*) mxGetData(prhs[0]); const float *Xi = (float*) mxGetImagData(prhs[0]); var_prox_d12_cplx_single(Xr, Xi, G, Rb, La, V, I, J, N, L); }else{ const float *X = (float*) mxGetData(prhs[0]); var_prox_d12_real_single(X, G, Rb, La, V, I, J, N, L); } } }
/* Gateway of inplaceprod */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { size_t i, n; double *Ard, *Aid, *Brd, *Bid; float *Ars, *Ais, *Brs, *Bis; double Ardi; float Arsi; mxClassID ClassA, ClassB; /* Get the classes of A and B */ ClassA = mxGetClassID(A); ClassB = mxGetClassID(B); /* n = numel(A) */ n = mxGetNumberOfElements(A); if (ClassA == mxDOUBLE_CLASS) { Ard = (double*)mxGetData(A); Aid = (double*)mxGetImagData(A); } else { Ars = (float*)mxGetData(A); Ais = (float*)mxGetImagData(A); } if (ClassB == mxDOUBLE_CLASS) { Brd = (double*)mxGetData(B); Bid = (double*)mxGetImagData(B); } else { Brs = (float*)mxGetData(B); Bis = (float*)mxGetImagData(B); } /* Call the macros depending of the classes of A and B */ if ((ClassA == mxDOUBLE_CLASS) && (ClassB == mxDOUBLE_CLASS)) { ENGINE(Ard, Aid, Brd, Bid, Ardi, double, double); } else if (ClassA == mxDOUBLE_CLASS) { ENGINE(Ard, Aid, Brs, Bis, Ardi, double, float); } else if (ClassB == mxDOUBLE_CLASS) { ENGINE(Ars, Ais, Brd, Bid, Arsi, float, double); } else { ENGINE(Ars, Ais, Brs, Bis, Arsi, float, float); } return; } /* of inplaceprod */
void callFFTN(double *data, size_t K, const mwSize *N, double **sol_r, double **sol_i ) { mxArray *F,*f; mxArray *LHS[1]; int N1 = N[0]; int N2 = N[1]; f = mxCreateNumericArray(K,N,mxDOUBLE_CLASS,mxCOMPLEX); memcpy(mxGetPr(f),data,sizeof(double)*N1*N2); mexCallMATLABWithTrap(1,LHS,1,&f,"fftn"); F = LHS[0]; *sol_r = (double *)mxGetData(F); *sol_i = (double *)mxGetImagData(F); DisplayMatrix("F",mxGetPr(F),mxGetPi(F),N1,N2); mxDestroyArray(f); // mxDestroyArray(F); }
/* Calling convention: * cout=comp_col2diag(cin); */ void LTFAT_NAME(ltfatMexFnc)(int UNUSED(nlhs), mxArray *plhs[], int UNUSED(nrhs), const mxArray *prhs[] ) { mwSize L = mxGetM(prhs[0]); plhs[0] = ltfatCreateMatrix(L, L, LTFAT_MX_CLASSID, LTFAT_MX_COMPLEXITY); #if defined(NOCOMPLEXFMTCHANGE) && !(MX_HAS_INTERLEAVED_COMPLEX) LTFAT_REAL* cout_r = mxGetData(plhs[0]); LTFAT_REAL* cin_r = mxGetData(prhs[0]); LTFAT_NAME(fwd_col2diag)(cin_r,L,cout_r); #ifdef LTFAT_COMPLEXTYPE // Treat the imaginary part LTFAT_REAL* cin_i= mxGetImagData(prhs[0]); LTFAT_REAL* cout_i= mxGetImagData(plhs[0]); LTFAT_NAME(fwd_col2diag)(cin_i, L,cout_i); #endif /* LTFAT_COMPLEXTYPE */ #else /* not NOCOMPLEXFMTCHANGE */ LTFAT_TYPE* cin_r= mxGetData(prhs[0]); LTFAT_TYPE* cout_r= mxGetData(plhs[0]); LTFAT_NAME(col2diag)(cin_r, L,cout_r); #endif /* NOCOMPLEXFMTCHANGE */ }
static void analyze_single(const mxArray *array_ptr) { float *pr, *pi; int total_num_of_elements, index; pr = (float *)mxGetData(array_ptr); pi = (float *)mxGetImagData(array_ptr); total_num_of_elements = mxGetNumberOfElements(array_ptr); for (index=0; index<total_num_of_elements; index++) { mexPrintf("\t"); display_subscript(array_ptr, index); if (mxIsComplex(array_ptr)) mexPrintf(" = %g + %gi\n", *pr++, *pi++); else mexPrintf(" = %g\n", *pr++); } }
void analyze_int16(const mxArray *array_ptr) { short int *pr, *pi; mwSize total_num_of_elements, index; pr = (short int *)mxGetData(array_ptr); pi = (short int *)mxGetImagData(array_ptr); total_num_of_elements = mxGetNumberOfElements(array_ptr); for (index=0; index<total_num_of_elements; index++) { mexPrintf("\t"); display_subscript(array_ptr, index); if (mxIsComplex(array_ptr)) { mexPrintf(" = %d + %di\n", *pr++, *pi++); } else { mexPrintf(" = %d\n", *pr++); } } }
static void analyze_int8(const mxArray *array_ptr) { signed char *pr, *pi; char total_num_of_elements, index; pr = (signed char *)mxGetData(array_ptr); pi = (signed char *)mxGetImagData(array_ptr); total_num_of_elements = mxGetNumberOfElements(array_ptr); for (index=0; index<total_num_of_elements; index++) { mexPrintf("\t"); display_subscript(array_ptr, index); if (mxIsComplex(array_ptr)) mexPrintf(" = %d + %di\n", *pr++, *pi++); else mexPrintf(" = %d\n", *pr++); } }
static void analyze_uint16(const mxArray *array_ptr) { unsigned short int *pr, *pi; int total_num_of_elements, index; pr = (unsigned short int *)mxGetData(array_ptr); pi = (unsigned short int *)mxGetImagData(array_ptr); total_num_of_elements = mxGetNumberOfElements(array_ptr); for (index=0; index<total_num_of_elements; index++) { mexPrintf("\t"); display_subscript(array_ptr, index); if (mxIsComplex(array_ptr)) mexPrintf(" = %u + %ui\n", *pr++, *pi++); else mexPrintf(" = %u\n", *pr++); } }
void analyze_uint64(const mxArray *array_ptr) { uint64_T *pr, *pi; mwSize total_num_of_elements, index; pr = (uint64_T *)mxGetData(array_ptr); pi = (uint64_T *)mxGetImagData(array_ptr); total_num_of_elements = mxGetNumberOfElements(array_ptr); for (index=0; index<total_num_of_elements; index++) { mexPrintf("\t"); display_subscript(array_ptr, index); if (mxIsComplex(array_ptr)) { mexPrintf(" = %" FMT64 "u + %" FMT64 "ui\n", *pr++, *pi++); } else { mexPrintf(" = %" FMT64 "u\n", *pr++); } } }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int n, nw, t; int16_T *yr, *yi, *xr, *xi, *wr, *wi; int Wfraclen; int16_T lowerbnd, upperbnd; double* nshifts; int isWComplex = mxIsComplex(W_IN); if (nrhs != N_INPUTS) mexErrMsgTxt("Wrong number of input arguments." USAGE); if (nlhs > N_OUTPUTS) mexErrMsgTxt("Too many output arguments." USAGE); if (!mxIsInt16(X_IN)) mexErrMsgTxt("X must be int16."); if (!mxIsInt16(W_IN)) mexErrMsgTxt("W must be int16."); n = mxGetNumberOfElements(X_IN); t = log2(n); /* n = 2^t */ nw = mxGetNumberOfElements(W_IN); Y_OUT = mxDuplicateArray(X_IN); NSHIFTS_OUT = mxCreateScalarDouble(0.0); if (n<=1) return; nshifts = mxGetPr(NSHIFTS_OUT); if (!isPowerOfTwo(n)) { mexErrMsgTxt("The length of X must be a power of two."); } if (nw != (n-1)) { mexErrMsgTxt("The length of the twiddle factor vector " "must be one less than the length of the input data."); } if (!mxIsComplex(X_IN)) { /* Grow imaginary part. */ int16_T* yi = mxCalloc(n,sizeof(int16_T)); mxSetImagData(Y_OUT, yi); } /* Overwrite a copy of the input data for the output */ xr = (int16_T*)mxGetData ( Y_OUT ); xi = (int16_T*)mxGetImagData( Y_OUT ); wr = (int16_T*)mxGetData ( W_IN ); if (isWComplex==1) { wi = (int16_T*)mxGetImagData( W_IN ); } else { wi = mxCalloc(n,sizeof(int16_T)); } Wfraclen = (int)mxGetScalar( WFRACTIONLENGTH_IN ); lowerbnd = (int16_T)mxGetScalar( XLOWERBOUND_IN ); upperbnd = (int16_T)mxGetScalar( XUPPERBOUND_IN ); fi_c_radix2fft_blockfloatingpoint(xr, xi, wr, wi, n, nw, t, Wfraclen, lowerbnd, upperbnd, nshifts); if (isWComplex==0) { mxFree(wi); } }
// Calling convention: // comp_filterbank(f,g,a); void mexFunction( int UNUSED(nlhs), mxArray *plhs[], int UNUSED(nrhs), const mxArray *prhs[] ) { static int atExitRegistered = 0; if(!atExitRegistered) { atExitRegistered = 1; mexAtExit(filterbankAtExit); } const mxArray* mxf = prhs[0]; const mxArray* mxg = prhs[1]; const mxArray* mxa = prhs[2]; // input data length const mwSize L = mxGetM(mxf); const mwSize W = mxGetN(mxf); // filter number const mwSize M = mxGetNumberOfElements(mxg); // a col count mwSize acols = mxGetN(mxa); // pointer to a double *a = (double*) mxGetData(mxa); if (acols > 1) { int isOnes = 1; for (mwIndex m = 0; m < M; m++) { isOnes = isOnes && a[M + m] == 1; } if (isOnes) { acols = 1; } } // Cell output plhs[0] = mxCreateCellMatrix(M, 1); // Stuff for sorting the filters mwSize tdCount = 0; mwSize fftCount = 0; mwSize fftblCount = 0; mwIndex tdArgsIdx[M]; mwIndex fftArgsIdx[M]; mwIndex fftblArgsIdx[M]; // WALK the filters to determine what has to be done for (mwIndex m = 0; m < M; m++) { mxArray * gEl = mxGetCell(mxg, m); if (mxGetField(gEl, 0, "h") != NULL) { tdArgsIdx[tdCount++] = m; continue; } if (mxGetField(gEl, 0, "H") != NULL) { if (acols == 1 && L == mxGetNumberOfElements(mxGetField(gEl, 0, "H"))) { fftArgsIdx[fftCount++] = m; continue; } else { fftblArgsIdx[fftblCount++] = m; continue; } } } if (tdCount > 0) { /* Here, we have to reformat the inputs and pick up results to comply with: c=comp_filterbank_td(f,g,a,offset,ext); BEWARE OF THE AUTOMATIC DEALLOCATION!! by the Matlab engine. Arrays can be very easily freed twice causing segfaults. This happends particulary when using mxCreateCell* which stores pointers to other mxArray structs. Setting all such pointers to NULL after they are used seems to solve it. */ mxArray* plhs_td[1]; mxArray* prhs_td[5]; prhs_td[0] = (mxArray*) mxf; prhs_td[1] = mxCreateCellMatrix(tdCount, 1); prhs_td[2] = mxCreateDoubleMatrix(tdCount, 1, mxREAL); double* aPtr = mxGetData(prhs_td[2]); prhs_td[3] = mxCreateDoubleMatrix(tdCount, 1, mxREAL); double* offsetPtr = mxGetData(prhs_td[3]); prhs_td[4] = mxCreateString("per"); for (mwIndex m = 0; m < tdCount; m++) { mxArray * gEl = mxGetCell(mxg, tdArgsIdx[m]); mxSetCell(prhs_td[1], m, mxGetField(gEl, 0, "h")); // This has overhead //mxSetCell((mxArray*)prhs_td[1],m,mxDuplicateArray(mxGetField(gEl,0,"h"))); aPtr[m] = a[tdArgsIdx[m]]; offsetPtr[m] = mxGetScalar(mxGetField(gEl, 0, "offset")); } // Finally call it! // comp_filterbank_td(1,plhs_td,5, prhs_td); // This has overhead: mexCallMATLAB(1, plhs_td, 5, prhs_td, "comp_filterbank_td"); // Copy pointers to a proper index in the output + unset all duplicate cell elements for (mwIndex m = 0; m < tdCount; m++) { mxSetCell(plhs[0], tdArgsIdx[m], mxGetCell(plhs_td[0], m)); mxSetCell(plhs_td[0], m, NULL); mxSetCell(prhs_td[1], m, NULL); } mxDestroyArray(plhs_td[0]); mxDestroyArray(prhs_td[1]); mxDestroyArray(prhs_td[2]); mxDestroyArray(prhs_td[3]); mxDestroyArray(prhs_td[4]); } if (fftCount > 0 || fftblCount > 0) { // Need to do FFT of mxf mwIndex ndim = 2; const mwSize dims[] = {L, W}; if (mxF == NULL || mxGetM(mxF) != L || mxGetN(mxF) != W || mxGetClassID(mxF) != mxGetClassID(mxf)) { if (mxF != NULL) { mxDestroyArray(mxF); mxF = NULL; // printf("Should be called just once\n"); } if (mxIsDouble(mxf)) { mxF = mxCreateNumericArray(ndim, dims, mxDOUBLE_CLASS, mxCOMPLEX); fftw_iodim fftw_dims[1]; fftw_iodim howmanydims[1]; fftw_dims[0].n = L; fftw_dims[0].is = 1; fftw_dims[0].os = 1; howmanydims[0].n = W; howmanydims[0].is = L; howmanydims[0].os = L; if (p_double == NULL) p_double = (fftw_plan*) malloc(sizeof(fftw_plan)); else fftw_destroy_plan(*p_double); // FFTW_MEASURE sometimes hangs here *p_double = fftw_plan_guru_split_dft( 1, fftw_dims, 1, howmanydims, mxGetData(mxF), mxGetImagData(mxF), mxGetData(mxF), mxGetImagData(mxF), FFTW_ESTIMATE); } else if (mxIsSingle(mxf)) { mxF = mxCreateNumericArray(ndim, dims, mxSINGLE_CLASS, mxCOMPLEX); // mexPrintf("M= %i, N= %i\n",mxGetM(mxF),mxGetN(mxF)); fftwf_iodim fftw_dims[1]; fftwf_iodim howmanydims[1]; fftw_dims[0].n = L; fftw_dims[0].is = 1; fftw_dims[0].os = 1; howmanydims[0].n = W; howmanydims[0].is = L; howmanydims[0].os = L; if (p_float == NULL) p_float = (fftwf_plan*) malloc(sizeof(fftwf_plan)); else fftwf_destroy_plan(*p_float); *p_float = fftwf_plan_guru_split_dft( 1, fftw_dims, 1, howmanydims, mxGetData(mxF), mxGetImagData(mxF), mxGetData(mxF), mxGetImagData(mxF), FFTW_ESTIMATE); } } if (mxIsDouble(mxf)) { memcpy(mxGetPr(mxF), mxGetPr(mxf), L * W * sizeof(double)); memset(mxGetPi(mxF), 0, L * W * sizeof(double)); if (mxIsComplex(mxf)) memcpy(mxGetPi(mxF), mxGetPi(mxf), L * W * sizeof(double)); fftw_execute(*p_double); } else if (mxIsSingle(mxf)) { memcpy(mxGetPr(mxF), mxGetPr(mxf), L * W * sizeof(float)); memset(mxGetPi(mxF), 0, L * W * sizeof(float)); if (mxIsComplex(mxf)) memcpy(mxGetPi(mxF), mxGetPi(mxf), L * W * sizeof(float)); fftwf_execute(*p_float); } } if (fftCount > 0) { mxArray* plhs_fft[1]; mxArray* prhs_fft[3]; prhs_fft[0] = mxF; prhs_fft[1] = mxCreateCellMatrix(fftCount, 1); prhs_fft[2] = mxCreateDoubleMatrix(fftCount, 1, mxREAL); double* aPtr = mxGetData(prhs_fft[2]); for (mwIndex m = 0; m < fftCount; m++) { mxArray * gEl = mxGetCell(mxg, fftArgsIdx[m]); mxSetCell(prhs_fft[1], m, mxGetField(gEl, 0, "H")); // This has overhead //mxSetCell((mxArray*)prhs_td[1],m,mxDuplicateArray(mxGetField(gEl,0,"h"))); aPtr[m] = a[fftArgsIdx[m]]; } //comp_filterbank_fft(1,plhs_fft,3, prhs_fft); mexCallMATLAB(1, plhs_fft, 3, prhs_fft, "comp_filterbank_fft"); for (mwIndex m = 0; m < fftCount; m++) { mxSetCell(plhs[0], fftArgsIdx[m], mxGetCell(plhs_fft[0], m)); mxSetCell(plhs_fft[0], m, NULL); mxSetCell(prhs_fft[1], m, NULL); } mxDestroyArray(plhs_fft[0]); mxDestroyArray(prhs_fft[1]); mxDestroyArray(prhs_fft[2]); } if (fftblCount > 0) { mxArray* plhs_fftbl[1]; mxArray* prhs_fftbl[5]; prhs_fftbl[0] = mxF; prhs_fftbl[1] = mxCreateCellMatrix(fftblCount, 1); prhs_fftbl[2] = mxCreateDoubleMatrix(fftblCount, 1, mxREAL); prhs_fftbl[3] = mxCreateDoubleMatrix(fftblCount, 2, mxREAL); prhs_fftbl[4] = mxCreateDoubleMatrix(fftblCount, 1, mxREAL); double* foffPtr = mxGetData(prhs_fftbl[2]); double* aPtr = mxGetData(prhs_fftbl[3]); double* realonlyPtr = mxGetData(prhs_fftbl[4]); // Set all realonly flags to zero memset(realonlyPtr, 0, fftblCount * sizeof * realonlyPtr); for (mwIndex m = 0; m < fftblCount; m++) { mxArray * gEl = mxGetCell(mxg, fftblArgsIdx[m]); mxSetCell(prhs_fftbl[1], m, mxGetField(gEl, 0, "H")); foffPtr[m] = mxGetScalar(mxGetField(gEl, 0, "foff")); aPtr[m] = a[fftblArgsIdx[m]]; if (acols > 1) aPtr[m + fftblCount] = a[fftblArgsIdx[m] + M]; else aPtr[m + fftblCount] = 1; // Only if realonly is specified mxArray* mxrealonly; if ((mxrealonly = mxGetField(gEl, 0, "realonly"))) realonlyPtr[m] = mxGetScalar(mxrealonly); } // comp_filterbank_fftbl(1,plhs_fftbl,5, prhs_fftbl); mexCallMATLAB(1, plhs_fftbl, 5, prhs_fftbl, "comp_filterbank_fftbl"); for (mwIndex m = 0; m < fftblCount; m++) { mxSetCell(plhs[0], fftblArgsIdx[m], mxGetCell(plhs_fftbl[0], m)); mxSetCell(plhs_fftbl[0], m, NULL); mxSetCell(prhs_fftbl[1], m, NULL); } mxDestroyArray(plhs_fftbl[0]); mxDestroyArray(prhs_fftbl[1]); mxDestroyArray(prhs_fftbl[2]); mxDestroyArray(prhs_fftbl[3]); mxDestroyArray(prhs_fftbl[4]); } if (mxF != NULL) mexMakeArrayPersistent(mxF); if (L * W > MAXARRAYLEN && mxF != NULL) { //printf("Damn. Should not get here\n"); mxDestroyArray(mxF); mxF = NULL; } }
/** Convert a numeric Python array to Matlab array of the same data type * :param obj: Object to convert [Borrow reference] */ mxArray *mx_from_py_arrayobject(PyObject* obj_) { PyArrayObject *obj = (PyArrayObject*)obj_; mxArray *r; mxClassID class; mxComplexity complexity; int stride; char *p; char *ip, *rp; int k, dim; int dummy_dim[2]; switch (obj->descr->type_num) { case PyArray_CHAR: case PyArray_UBYTE: class=mxUINT8_CLASS; complexity=mxREAL; break; #ifdef NUMPY case NPY_BYTE: #else case PyArray_SBYTE: #endif class=mxINT8_CLASS; complexity=mxREAL; break; case PyArray_SHORT: class=mxINT16_CLASS; complexity=mxREAL; break; case PyArray_USHORT: class=mxUINT16_CLASS; complexity=mxREAL; break; #if LP64 case PyArray_LONG: class=mxINT64_CLASS; complexity=mxREAL; break; #else case PyArray_LONG: #endif case PyArray_INT: class=mxINT32_CLASS; complexity=mxREAL; break; case PyArray_UINT: class=mxUINT32_CLASS; complexity=mxREAL; break; case PyArray_FLOAT: class=mxSINGLE_CLASS; complexity=mxREAL; break; case PyArray_DOUBLE: class=mxDOUBLE_CLASS; complexity=mxREAL; break; case PyArray_CFLOAT: class=mxSINGLE_CLASS; complexity=mxCOMPLEX; break; case PyArray_CDOUBLE: class=mxDOUBLE_CLASS; complexity=mxCOMPLEX; break; case PyArray_OBJECT: return mx_from_py_arrayobject_object(obj); #ifdef NUMPY case PyArray_STRING: /* 0d-string arrays */ if (obj->nd == 0) { mxChar *cp; int len; char buf[1024]; dummy_dim[0] = 1; dummy_dim[1] = obj->descr->elsize; r = mxCreateCharArray(2, dummy_dim); cp = mxGetData(r); p = obj->data; for (len = dummy_dim[1]; len > 0; --len) { *cp = *p; ++cp; ++p; } return r; } else { return mx_from_py_unknown(obj_); } break; #endif default: return mx_from_py_unknown(obj_); } if (obj->nd == 0) { /* array scalar */ dummy_dim[0] = 1; r = mxCreateNumericArray(1, dummy_dim, class, complexity); if (complexity == mxCOMPLEX) { memcpy(mxGetData(r), obj->data, obj->descr->elsize/2); memcpy(mxGetImagData(r), obj->data+obj->descr->elsize/2, obj->descr->elsize/2); } else { memcpy(mxGetData(r), obj->data, obj->descr->elsize); } return r; } else {
/* Function: WriteMatlabStructureToRTWFile ===================================== * Abstract: * This routine writes out a matlab structure to the the rtw file. Nested * structures inside structures are also supported, i.e., any field(s) of * the mxArray passed in can be structures. However, the basic atomic * units have to be either row strings or non-sparse, numeric vectors or * matrices. For example, fields cannot be things like a matrix of strings * or nd arrays. * * In order to avoid name clashes with records (espeically ones that might * be added in future) written out by Simulink, your structure name should * start with the string "SFcn". For example, instead of naming your * structure "ParseTree" you should name it "SFcnParseTree". * * Returns: * 1 -on success * 0 -on failure */ bool WriteMatlabStructureToRTWFile(SimStruct *S, const mxArray *mlStruct, const char *structName, char *strBuffer, const int strBufferLen) { int numStructs; int numFields; int i; if (mlStruct == NULL) { return(1); } numStructs = mxGetNumberOfElements(mlStruct); numFields = mxGetNumberOfFields(mlStruct); /* make sure strBuffer is long enough for sprintf, be conservative */ if ( strlen(structName)+5 >= ((size_t) strBufferLen) ) { return(0); } for (i=0; i<numStructs; i++) { int j; (void) sprintf(strBuffer, "%s {",structName); if ( !ssWriteRTWStr(S, strBuffer) ) { return(0); } for (j=0; j<numFields; j++) { const char *fieldName = mxGetFieldNameByNumber(mlStruct, j); const mxArray *field = mxGetFieldByNumber(mlStruct, i, j); int nRows; int nCols; int nElements; int nDims; if (field == NULL) { continue; } nRows = mxGetM(field); nCols = mxGetN(field); nElements = mxGetNumberOfElements(field); nDims = mxGetNumberOfDimensions(field); if ( mxIsStruct(field) ) { /* struct param */ if ( !WriteMatlabStructureToRTWFile(S, field, fieldName, strBuffer, strBufferLen) ) { return(0); } } else if ( mxIsChar(field) ) { /* string param */ /* can handle only "row" strings */ if ( nDims > 2 || nRows > 1 ) { return(0); } if ( mxGetString(field,strBuffer,strBufferLen) ) { return(0); } if ( !ssWriteRTWStrParam(S,fieldName,strBuffer) ) { return(0); } } else if ( mxIsNumeric(field) ) { /* numeric param */ const void *rval = mxGetData(field); int isCmplx = mxIsComplex(field); DTypeId dTypeId = ssGetDTypeIdFromMxArray(field); int dtInfo = DTINFO(dTypeId, isCmplx); const void *ival = (isCmplx) ? mxGetImagData(field) : NULL; /* can handle only non-sparse, numeric vectors or matrices */ if (nDims > 2 || nRows*nCols != nElements || mxIsSparse(field)){ return(0); } if (nRows == 1 || nCols == 1) { /* vector param */ if ( !ssWriteRTWMxVectParam(S, fieldName, rval, ival, dtInfo, nElements) ) { return(0); } } else { /* matrix param */ if ( !ssWriteRTWMx2dMatParam(S, fieldName, rval, ival, dtInfo, nRows, nCols) ) { return(0); } } } else { return(0); } } if ( !ssWriteRTWStr(S, "}") ) { return(0); } } return(1); } /* end WriteMatlabStructureToRTWFile */
void mexFunction(int nlhs_m, mxArray *plhs_m[], int nrhs_m, const mxArray *prhs_m[]) { int i; int * m; int * n; int * nrhs; float * a; int * lda; float * b; int * ldb; int * jpvt; float * rcond; int * rank; float * work; int * lwork; float * rwork; int * info; plhs_m[0]=mxDuplicateArray(prhs_m[0]); m=(int *)mxGetPr(plhs_m[0]); plhs_m[1]=mxDuplicateArray(prhs_m[1]); n=(int *)mxGetPr(plhs_m[1]); plhs_m[2]=mxDuplicateArray(prhs_m[2]); nrhs=(int *)mxGetPr(plhs_m[2]); plhs_m[4]=mxDuplicateArray(prhs_m[4]); lda=(int *)mxGetPr(plhs_m[4]); plhs_m[6]=mxDuplicateArray(prhs_m[6]); ldb=(int *)mxGetPr(plhs_m[6]); plhs_m[9]=mxDuplicateArray(prhs_m[9]); rank=(int *)mxGetPr(plhs_m[9]); plhs_m[11]=mxDuplicateArray(prhs_m[11]); lwork=(int *)mxGetPr(plhs_m[11]); plhs_m[13]=mxDuplicateArray(prhs_m[13]); info=(int *)mxGetPr(plhs_m[13]); a=malloc((*lda)*(*n)*2*sizeof(float)); for (i=0; i<(*lda)*(*n); i++) { a[i*2]=((float*)mxGetData(prhs_m[3]))[i]; if (mxIsComplex(prhs_m[3])) a[i*2+1]=((float*)mxGetImagData(prhs_m[3]))[i]; else a[i*2+1]=0; } b=malloc((*ldb)*(*nrhs)*2*sizeof(float)); for (i=0; i<(*ldb)*(*nrhs); i++) { b[i*2]=((float*)mxGetData(prhs_m[5]))[i]; if (mxIsComplex(prhs_m[5])) b[i*2+1]=((float*)mxGetImagData(prhs_m[5]))[i]; else b[i*2+1]=0; } plhs_m[7]=mxDuplicateArray(prhs_m[7]); jpvt = (int *) mxGetPr(plhs_m[7]); plhs_m[8]=mxDuplicateArray(prhs_m[8]); rcond = (float*) mxGetPr(plhs_m[8]); work=malloc((max(1,*lwork))*(1)*2*sizeof(float)); for (i=0; i<(max(1,*lwork))*(1); i++) { work[i*2]=((float*)mxGetData(prhs_m[10]))[i]; if (mxIsComplex(prhs_m[10])) work[i*2+1]=((float*)mxGetImagData(prhs_m[10]))[i]; else work[i*2+1]=0; } plhs_m[12]=mxDuplicateArray(prhs_m[12]); rwork = (float*) mxGetPr(plhs_m[12]); #ifdef F77_INT F77_INT* F77_m = m , F77_n = n , F77_nrhs = nrhs , F77_lda = lda , F77_ldb = ldb , F77_jpvt = jpvt , F77_rank = rank , F77_lwork = lwork , F77_info = info ; #else #define F77_m m #define F77_n n #define F77_nrhs nrhs #define F77_lda lda #define F77_ldb ldb #define F77_jpvt jpvt #define F77_rank rank #define F77_lwork lwork #define F77_info info #endif f77_cgelsy(F77_m, F77_n, F77_nrhs, a, F77_lda, b, F77_ldb, F77_jpvt, rcond, F77_rank, work, F77_lwork, rwork, F77_info); plhs_m[3] = mxCreateNumericMatrix((*lda),(*n),mxSINGLE_CLASS,mxCOMPLEX); for (i=0; i<(*lda)*(*n); i++) { ((float*)mxGetData(plhs_m[3]))[i]=a[2*i]; if (mxIsComplex(plhs_m[3])) ((float*)mxGetImagData(plhs_m[3]))[i]=a[2*i+1]; } plhs_m[5] = mxCreateNumericMatrix((*ldb),(*nrhs),mxSINGLE_CLASS,mxCOMPLEX); for (i=0; i<(*ldb)*(*nrhs); i++) { ((float*)mxGetData(plhs_m[5]))[i]=b[2*i]; if (mxIsComplex(plhs_m[5])) ((float*)mxGetImagData(plhs_m[5]))[i]=b[2*i+1]; } plhs_m[10] = mxCreateNumericMatrix((max(1,*lwork)),(1),mxSINGLE_CLASS,mxCOMPLEX); for (i=0; i<(max(1,*lwork))*(1); i++) { ((float*)mxGetData(plhs_m[10]))[i]=work[2*i]; if (mxIsComplex(plhs_m[10])) ((float*)mxGetImagData(plhs_m[10]))[i]=work[2*i+1]; } return; }
void mexFunction( int nargout, mxArray *varargout[], int nargin, const mxArray *varargin[]) { bool xIsDouble; if(nargin!=1) mexErrMsgIdAndTxt("Horizon:FastVar:input","1 input required."); if(nargout!=1) mexErrMsgIdAndTxt("Horizon:FastVar:output","One output required."); xIsDouble = mxIsDouble(varargin[0]); if (!xIsDouble && !mxIsSingle(varargin[0])) mexErrMsgIdAndTxt("Horizon:FastVar:input","Input x must be a single or double array."); if (xIsDouble) { if(mxIsComplex(varargin[0])) { mwSize numElements = mxGetNumberOfElements(varargin[0]); double meanR = 0; double meanI = 0; double var = 0; double *xInR = mxGetPr(varargin[0]); double *xInI = mxGetPi(varargin[0]); double *xr = xInR; double *xi = xInI; double n = numElements; while (n-- > 0) { meanR += *xr++; meanI += *xi++; } meanR = meanR / (double) numElements; meanI = meanI / (double) numElements; xr = xInR; xi = xInI; n = numElements; while (n-- > 0) { double r = fabs(*xr++ - meanR); double i = fabs(*xi++ - meanI); var += r*r + i*i; } if (numElements > 1) var = var / (double) (numElements-1); else var = var / (double) numElements; varargout[0] = mxCreateDoubleMatrix(1, 1, mxREAL); *mxGetPr(varargout[0]) = var; } else { mwSize numElements = mxGetNumberOfElements(varargin[0]); double mean = 0; double var = 0; double *xIn = mxGetPr(varargin[0]); double *x = xIn; double n = numElements; while (n-- > 0) mean += *x++; mean = mean / (double) numElements; x = xIn; n = numElements; while (n-- > 0) { double tempX = fabs(*x++ - mean); var += tempX*tempX; } if (numElements > 1) var = var / (double) (numElements-1); else var = var / (double) numElements; varargout[0] = mxCreateDoubleMatrix(1, 1, mxREAL); *mxGetPr(varargout[0]) = var; } } else { if(mxIsComplex(varargin[0])) { mwSize numElements = mxGetNumberOfElements(varargin[0]); float meanR = 0; float meanI = 0; float var = 0; float *xInR = (float*) mxGetData(varargin[0]); float *xInI = (float*) mxGetImagData(varargin[0]); float *xr = xInR; float *xi = xInI; float n = numElements; while (n-- > 0) { meanR += *xr++; meanI += *xi++; } meanR = meanR / (float) numElements; meanI = meanI / (float) numElements; xr = xInR; xi = xInI; n = numElements; while (n-- > 0) { float r = fabs(*xr++ - meanR); float i = fabs(*xi++ - meanI); var += r*r + i*i; } if (numElements > 1) var = var / (float) (numElements-1); else var = var / (float) numElements; varargout[0] = mxCreateDoubleMatrix(1, 1, mxREAL); *(float*) mxGetData(varargout[0]) = var; } else { mwSize numElements = mxGetNumberOfElements(varargin[0]); float mean = 0; float var = 0; float *xIn = (float*) mxGetData(varargin[0]); float *x = xIn; float n = numElements; while (n-- > 0) mean += *x++; mean = mean / (float) numElements; x = xIn; n = numElements; while (n-- > 0) { float tempX = fabs(*x++ - mean); var += tempX*tempX; } if (numElements > 1) var = var / (float) (numElements-1); else var = var / (float) numElements; varargout[0] = mxCreateNumericMatrix(1, 1, mxSINGLE_CLASS, mxREAL); *(float*) mxGetData(varargout[0]) = var; } } }
/***********************************************************************//** * \brief mexFunction to append a stack to an existing em-file. **************************************************************************/ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]) { size_t filename_length = 0; #define __MAX_FILENAME_LENGTH__ ((int)2048) char filename[__MAX_FILENAME_LENGTH__+1]; #define __MAX_S__LENGTH__ (4096) char s[__MAX_S__LENGTH__+1]; #define __BUFFERLENGTH_SYNOPSIS__ 1024 char synopsis[__BUFFERLENGTH_SYNOPSIS__]; size_t i, j, k; const void *w_data; int w_iotype; size_t dims[3]; uint32_t *subregion = NULL; uint32_t subregion_field[6]; tom_io_em_header header; float *complexCopy = 0; char autoval_magic = 1; size_t stridey=0, stridez=0; memset(&header, 0, sizeof(header)); snprintf(synopsis, __BUFFERLENGTH_SYNOPSIS__, "%s(filename, data, [subregion_in, magic, comment, emdata, userdata])", mexFunctionName()); if (nrhs==0 && nlhs==0) { /* Print help */ mexPrintf("SYNOPSIS: %s\n", synopsis); mexPrintf("mex-file compiled from file \"" __FILE__ "\" at " __DATE__ ", " __TIME__ ".\n"); return; } if (nlhs>0 || nrhs<2 || nrhs>7) { snprintf(s, __MAX_S__LENGTH__, "%s: Wrong number of in/output arguments: %s.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } { #define __MAX_UINT32_T__ 0xFFFFFFFF const mxArray *arg; mxArray *tmpArray = NULL; const mwSize *size; double *pdouble; int8_t *pint8; int32_t *pint32; mxClassID type; /* filename */ arg = prhs[0]; if (!mxIsChar(arg) || mxGetNumberOfDimensions(arg)!=2 || mxGetM(arg)!=1 || (filename_length=mxGetN(arg))<1 || filename_length>=__MAX_FILENAME_LENGTH__) { snprintf(s, __MAX_S__LENGTH__, "%s: needs file name as first parameter: %s.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } mxGetString(arg, filename, __MAX_FILENAME_LENGTH__); /* subregion */ if (nrhs >= 3) { arg = prhs[2]; i = mxGetM(arg); j = mxGetN(arg); if (!mxIsNumeric(arg) || mxIsComplex(arg) || mxGetNumberOfDimensions(arg)!=2 || !((i==0&&j==0) || (i==1&&j==6) || (i==6&&j==1))) { snprintf(s, __MAX_S__LENGTH__, "%s: The subregion must be either [] or a 1x6 vector: %s", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (i!=0) { if (!(tmpArray=getDoubleArray(arg))) { snprintf(s, __MAX_S__LENGTH__, "%s: Error creating a copy of the subregion. Maybe out of memory.", mexFunctionName()); mexErrMsgTxt(s); } pdouble = mxGetPr(tmpArray); for (k=0; k<6; k++) { if (pdouble[k] != floor(pdouble[k]) || pdouble[k]<0 || (k>=3&&pdouble[k]<=0) || pdouble[k]>__MAX_UINT32_T__) { snprintf(s, __MAX_S__LENGTH__, "%s: The subregion must contain positive integer values: %s", mexFunctionName(), synopsis); mexErrMsgTxt(s); } subregion_field[k] = (uint32_t)pdouble[k]; } subregion = subregion_field; mxDestroyArray(tmpArray); } } /* magic */ if (nrhs >= 4) { arg = prhs[3]; if (!mxIsNumeric(arg) || mxIsComplex(arg) || mxGetNumberOfDimensions(arg)!=2) { snprintf(s, __MAX_S__LENGTH__, "%s: magic must be a 4-vector of int8 or [].", mexFunctionName()); mexErrMsgTxt(s); } if (mxGetNumberOfElements(arg) > 0) { if (mxGetClassID(arg)!=mxINT8_CLASS || mxGetNumberOfElements(arg)!=4 || (mxGetN(arg)!=1&&mxGetM(arg)!=1)) { snprintf(s, __MAX_S__LENGTH__, "%s: magic must be a 4-vector of int8 or [].", mexFunctionName()); mexErrMsgTxt(s); } pint8 = (int8_t *)mxGetData(arg); header.machine = pint8[0]; header.byte2 = pint8[1]; header.byte3 = pint8[2]; header.type = pint8[3]; autoval_magic = 0; } } /* comment */ if (nrhs >= 5) { arg = prhs[4]; if (!mxIsNumeric(arg) || mxIsComplex(arg) || mxGetNumberOfDimensions(arg)!=2) { snprintf(s, __MAX_S__LENGTH__, "%s: comment must be a 80-vector of int8 or [].", mexFunctionName()); mexErrMsgTxt(s); } if (mxGetNumberOfElements(arg) > 0) { if (mxGetClassID(arg)!=mxINT8_CLASS || mxGetNumberOfElements(arg)!=80 || (mxGetN(arg)!=1&&mxGetM(arg)!=1)) { snprintf(s, __MAX_S__LENGTH__, "%s: comment must be a 80-vector of int8 or [].", mexFunctionName()); mexErrMsgTxt(s); } pint8 = (int8_t *)mxGetData(arg); for (i=0; i<80; i++) { header.comment[i] = pint8[i]; } } } /* emdata */ if (nrhs >= 6) { arg = prhs[5]; if (!mxIsNumeric(arg) || mxIsComplex(arg) || mxGetNumberOfDimensions(arg)!=2) { snprintf(s, __MAX_S__LENGTH__, "%s: emdata must be a 40-vector of int32 or [].", mexFunctionName()); mexErrMsgTxt(s); } if (mxGetNumberOfElements(arg) > 0) { if (mxGetClassID(arg)!=mxINT32_CLASS || mxGetNumberOfElements(arg)!=40 || (mxGetN(arg)!=1&&mxGetM(arg)!=1)) { snprintf(s, __MAX_S__LENGTH__, "%s: comment must be a 40-vector of int32 or [].", mexFunctionName()); mexErrMsgTxt(s); } pint32 = (int32_t *)mxGetData(arg); for (i=0; i<40; i++) { header.emdata[i] = pint32[i]; } } } /* userdata */ if (nrhs >= 7) { arg = prhs[6]; if (!mxIsNumeric(arg) || mxIsComplex(arg) || mxGetNumberOfDimensions(arg)!=2) { snprintf(s, __MAX_S__LENGTH__, "%s: userdata must be a 256-vector of int8 or [].", mexFunctionName()); mexErrMsgTxt(s); } if (mxGetNumberOfElements(arg) > 0) { if (mxGetClassID(arg)!=mxINT8_CLASS || mxGetNumberOfElements(arg)!=256 || (mxGetN(arg)!=1&&mxGetM(arg)!=1)) { snprintf(s, __MAX_S__LENGTH__, "%s: userdata must be a 256-vector of int8 or [].", mexFunctionName()); mexErrMsgTxt(s); } pint8 = (int8_t *)mxGetData(arg); for (i=0; i<256; i++) { header.userdata[i] = pint8[i]; } } } arg = prhs[1]; if (!mxIsNumeric(arg) || mxGetNumberOfDimensions(arg)>3 || mxGetNumberOfElements(arg)<1) { snprintf(s, __MAX_S__LENGTH__, "%s: The volume must be a non-empty numeric array.", mexFunctionName()); mexErrMsgTxt(s); } size = mxGetDimensions(arg); dims[0] = size[0]; dims[1] = size[1]; dims[2] = mxGetNumberOfDimensions(arg)==3 ? size[2] : 1; type = mxGetClassID(arg); if (mxIsComplex(arg)) { const size_t numel = dims[0]*dims[1]*dims[2]; float *pdst; if (!autoval_magic && tom_io_em_get_iotype(&header)!=TOM_IO_TYPE_COMPLEX4) { snprintf(s, __MAX_S__LENGTH__, "%s: Saving complex data is only possible as complex (single) floating point.", mexFunctionName()); mexErrMsgTxt(s); } if (!(complexCopy = malloc(numel*2*sizeof(float)))) { snprintf(s, __MAX_S__LENGTH__, "%s: Error allocating memory for temporary copy of complex data.", mexFunctionName()); mexErrMsgTxt(s); } pdst = complexCopy; if (type == mxSINGLE_CLASS) { const float *psrc_re, *psrc_im; psrc_re = (float *)mxGetData(arg); psrc_im = (float *)mxGetImagData(arg); for (i=0; i<numel; i++) { *pdst++ = psrc_re[i]; *pdst++ = psrc_im[i]; } } else if (type == mxDOUBLE_CLASS) { const double *psrc_re, *psrc_im; psrc_re = mxGetPr(arg); psrc_im = mxGetPr(arg); for (i=0; i<numel; i++) { *pdst++ = psrc_re[i]; *pdst++ = psrc_im[i]; } } else { free(complexCopy); snprintf(s, __MAX_S__LENGTH__, "%s: EM supports only floating point complex data (single).", mexFunctionName(), type); mexErrMsgTxt(s); } w_iotype = TOM_IO_TYPE_COMPLEX4; w_data = complexCopy; } else { switch (type) { case mxINT8_CLASS: w_iotype = TOM_IO_TYPE_INT8; break; case mxINT16_CLASS: w_iotype = TOM_IO_TYPE_INT16; break; case mxINT32_CLASS: w_iotype = TOM_IO_TYPE_INT32; break; case mxSINGLE_CLASS: w_iotype = TOM_IO_TYPE_FLOAT; break; case mxDOUBLE_CLASS: w_iotype = TOM_IO_TYPE_DOUBLE; break; default: snprintf(s, __MAX_S__LENGTH__, "%s: The volume has type %s: This can not be saved to EM without conversion.", mexFunctionName(), type); mexErrMsgTxt(s); } w_data = mxGetData(arg); } if (subregion) { if (subregion[0]+subregion[3]>dims[0] || subregion[1]+subregion[4]>dims[1] || subregion[2]+subregion[5]>dims[2]) { snprintf(s, __MAX_S__LENGTH__, "%s: The subregion is out of the volume.", mexFunctionName()); mexErrMsgTxt(s); } header.dims[0] = subregion[3]; header.dims[1] = subregion[4]; header.dims[2] = subregion[5]; w_data = (const char *)w_data + ((((subregion[2]*dims[1] + subregion[1]))*dims[0] + subregion[0])*tom_io_iotype_datasize(w_iotype)); stridey = dims[0] * tom_io_iotype_datasize(w_iotype); stridez = dims[1] * stridey; } else { if (dims[0]>=__MAX_UINT32_T__ || dims[1]>=__MAX_UINT32_T__ || dims[2]>=__MAX_UINT32_T__) { snprintf(s, __MAX_S__LENGTH__, "%s: The volume is too large to save it to EM.", mexFunctionName()); mexErrMsgTxt(s); } header.dims[0] = dims[0]; header.dims[1] = dims[1]; header.dims[2] = dims[2]; } if (autoval_magic) { header.machine = 6; tom_io_em_set_iotype(&header, w_iotype); } if (!tom_io_em_is_valid_header(&header, sizeof(header))) { if (complexCopy) { free(complexCopy); } snprintf(s, __MAX_S__LENGTH__, "%s: The given EM-Header is not valid. Check the content of magic.", mexFunctionName()); mexErrMsgTxt(s); } #undef __MAX_UINT32_T__ } { /*printf("WRITE: swapped: %d, %d->%d %20.15f\n", tom_io_em_is_swaped(&header), w_iotype, tom_io_em_get_iotype(&header), *((double *)w_data));*/ int i; if ((i=tom_io_em_write(filename, &header, w_data, w_iotype, 0, stridey, stridez)) != TOM_ERR_OK) { if (complexCopy) { free(complexCopy); } if (i == TOM_ERR_WRONG_IOTYPE_CONVERSION) { snprintf(s, __MAX_S__LENGTH__, "%s: The type conversion from %d to %d is not implemented/supported.", mexFunctionName(), w_iotype, tom_io_em_get_iotype(&header)); } else { snprintf(s, __MAX_S__LENGTH__, "%s: Error saving the file (%d).", mexFunctionName(), i); } mexErrMsgTxt(s); } } if (complexCopy) { free(complexCopy); } }
// Takes a MATLAB variable and writes in in Mathematica form to link void toMma(const mxArray *var, MLINK link) { // the following may occur when retrieving empty struct fields // it showsup as [] in MATLAB so we return {} // note that non-existent variables are caught and handled in eng_get() if (var == NULL) { MLPutFunction(link, "List", 0); return; } // get size information mwSize depth = mxGetNumberOfDimensions(var); const mwSize *mbDims = mxGetDimensions(var); // handle zero-size arrays if (mxIsEmpty(var)) { if (mxIsChar(var)) MLPutString(link, ""); else MLPutFunction(link, "List", 0); return; } // translate dimension information to Mathematica order std::vector<int> mmDimsVec(depth); std::reverse_copy(mbDims, mbDims + depth, mmDimsVec.begin()); int *mmDims = &mmDimsVec[0]; int len = mxGetNumberOfElements(var); // numerical (sparse or dense) if (mxIsNumeric(var)) { mxClassID classid = mxGetClassID(var); // verify that var is of a supported class switch (classid) { case mxDOUBLE_CLASS: case mxSINGLE_CLASS: case mxINT32_CLASS: case mxINT16_CLASS: case mxUINT16_CLASS: case mxINT8_CLASS: case mxUINT8_CLASS: break; default: putUnknown(var, link); return; } if (mxIsSparse(var)) { // Note: I realised that sparse arrays can only hold double precision numerical types // in MATLAB R2013a. I will leave the below implementation for single precision & integer // types in case future versions of MATLAB will add support for them. int ncols = mxGetN(var); // number of columns mwIndex *jc = mxGetJc(var); mwIndex *ir = mxGetIr(var); int nnz = jc[ncols]; // number of nonzeros MLPutFunction(link, CONTEXT "matSparseArray", 4); mlpPutIntegerList(link, jc, ncols + 1); mlpPutIntegerList(link, ir, nnz); // if complex, put as im*I + re if (mxIsComplex(var)) { MLPutFunction(link, "Plus", 2); MLPutFunction(link, "Times", 2); MLPutSymbol(link, "I"); switch (classid) { case mxDOUBLE_CLASS: MLPutReal64List(link, mxGetPi(var), nnz); break; case mxSINGLE_CLASS: MLPutReal32List(link, (float *) mxGetImagData(var), nnz); break; case mxINT16_CLASS: MLPutInteger16List(link, (short *) mxGetImagData(var), nnz); break; case mxINT32_CLASS: MLPutInteger32List(link, (int *) mxGetImagData(var), nnz); break; default: assert(false); // should never reach here } } switch (classid) { case mxDOUBLE_CLASS: MLPutReal64List(link, mxGetPr(var), nnz); break; case mxSINGLE_CLASS: MLPutReal32List(link, (float *) mxGetData(var), nnz); break; case mxINT16_CLASS: MLPutInteger16List(link, (short *) mxGetData(var), nnz); break; case mxINT32_CLASS: MLPutInteger32List(link, (int *) mxGetData(var), nnz); break; default: assert(false); // should never reach here } MLPutInteger32List(link, mmDims, depth); } else // not sparse { MLPutFunction(link, CONTEXT "matArray", 2); // if complex, put as im*I + re if (mxIsComplex(var)) { MLPutFunction(link, "Plus", 2); MLPutFunction(link, "Times", 2); MLPutSymbol(link, "I"); switch (classid) { case mxDOUBLE_CLASS: MLPutReal64Array(link, mxGetPi(var), mmDims, NULL, depth); break; case mxSINGLE_CLASS: MLPutReal32Array(link, (float *) mxGetImagData(var), mmDims, NULL, depth); break; case mxINT32_CLASS: MLPutInteger32Array(link, (int *) mxGetImagData(var), mmDims, NULL, depth); break; case mxINT16_CLASS: MLPutInteger16Array(link, (short *) mxGetImagData(var), mmDims, NULL, depth); break; case mxUINT16_CLASS: { int *arr = new int[len]; unsigned short *mbData = (unsigned short *) mxGetImagData(var); std::copy(mbData, mbData + len, arr); MLPutInteger32Array(link, arr, mmDims, NULL, depth); delete [] arr; break; } case mxINT8_CLASS: { short *arr = new short[len]; char *mbData = (char *) mxGetImagData(var); std::copy(mbData, mbData + len, arr); MLPutInteger16Array(link, arr, mmDims, NULL, depth); delete [] arr; break; } case mxUINT8_CLASS: { short *arr = new short[len]; unsigned char *mbData = (unsigned char *) mxGetImagData(var); std::copy(mbData, mbData + len, arr); MLPutInteger16Array(link, arr, mmDims, NULL, depth); delete [] arr; break; } default: assert(false); // should never reach here } } switch (classid) { case mxDOUBLE_CLASS: MLPutReal64Array(link, mxGetPr(var), mmDims, NULL, depth); break; case mxSINGLE_CLASS: MLPutReal32Array(link, (float *) mxGetData(var), mmDims, NULL, depth); break; case mxINT32_CLASS: MLPutInteger32Array(link, (int *) mxGetData(var), mmDims, NULL, depth); break; case mxINT16_CLASS: MLPutInteger16Array(link, (short *) mxGetData(var), mmDims, NULL, depth); break; case mxUINT16_CLASS: { int *arr = new int[len]; unsigned short *mbData = (unsigned short *) mxGetData(var); std::copy(mbData, mbData + len, arr); MLPutInteger32Array(link, arr, mmDims, NULL, depth); delete [] arr; break; } case mxINT8_CLASS: { short *arr = new short[len]; char *mbData = (char *) mxGetData(var); std::copy(mbData, mbData + len, arr); MLPutInteger16Array(link, arr, mmDims, NULL, depth); delete [] arr; break; } case mxUINT8_CLASS: { short *arr = new short[len]; unsigned char *mbData = (unsigned char *) mxGetData(var); std::copy(mbData, mbData + len, arr); MLPutInteger16Array(link, arr, mmDims, NULL, depth); delete [] arr; break; } default: assert(false); // should never reach here } MLPutInteger32List(link, mmDims, depth); } } // logical (sparse or dense) else if (mxIsLogical(var)) if (mxIsSparse(var)) { int ncols = mxGetN(var); // number of columns mwIndex *jc = mxGetJc(var); mwIndex *ir = mxGetIr(var); mxLogical *logicals = mxGetLogicals(var); int nnz = jc[ncols]; // number of nonzeros MLPutFunction(link, CONTEXT "matSparseLogical", 4); mlpPutIntegerList(link, jc, ncols + 1); mlpPutIntegerList(link, ir, nnz); short *integers = new short[nnz]; std::copy(logicals, logicals+nnz, integers); MLPutInteger16List(link, integers, nnz); MLPutInteger32List(link, mmDims, depth); delete [] integers; } else // not sparse { mxLogical *logicals = mxGetLogicals(var); short *integers = new short[len]; std::copy(logicals, logicals+len, integers); MLPutFunction(link, CONTEXT "matLogical", 2); MLPutInteger16Array(link, integers, mmDims, NULL, depth); MLPutInteger32List(link, mmDims, depth); delete [] integers; } // char array else if (mxIsChar(var)) { assert(sizeof(mxChar) == sizeof(unsigned short)); // 1 by N char arrays (row vectors) are sent as a string if (depth == 2 && mbDims[0] == 1) { const mxChar *str = mxGetChars(var); MLPutFunction(link, CONTEXT "matString", 1); MLPutUTF16String(link, reinterpret_cast<const unsigned short *>(str), len); // cast may be required on other platforms: (mxChar *) str } // general char arrays are sent as an array of characters else { MLPutFunction(link, CONTEXT "matCharArray", 2); const mxChar *str = mxGetChars(var); MLPutFunction(link, "List", len); for (int i=0; i < len; ++i) MLPutUTF16String(link, reinterpret_cast<const unsigned short *>(str + i), 1); MLPutInteger32List(link, mmDims, depth); } } // struct else if (mxIsStruct(var)) { int nfields = mxGetNumberOfFields(var); MLPutFunction(link, CONTEXT "matStruct", 2); MLPutFunction(link, "List", len); for (int j=0; j < len; ++j) { MLPutFunction(link, "List", nfields); for (int i=0; i < nfields; ++i) { const char *fieldname; fieldname = mxGetFieldNameByNumber(var, i); MLPutFunction(link, "Rule", 2); MLPutString(link, fieldname); toMma(mxGetFieldByNumber(var, j, i), link); } } MLPutInteger32List(link, mmDims, depth); } // cell else if (mxIsCell(var)) { MLPutFunction(link, CONTEXT "matCell", 2); MLPutFunction(link, "List", len); for (int i=0; i < len; ++i) toMma(mxGetCell(var, i), link); MLPutInteger32List(link, mmDims, depth); } // unknown or failure; TODO distinguish between unknown and failure else { putUnknown(var, link); } }
static PyObject* mat2py(const mxArray *a) { size_t ndims = mxGetNumberOfDimensions(a); const mwSize *dims = mxGetDimensions(a); mxClassID cls = mxGetClassID(a); size_t nelem = mxGetNumberOfElements(a); char *data = (char*) mxGetData(a); char *imagData = (char*) mxGetImagData(a); if (debug) mexPrintf("cls = %d, nelem = %d, ndims = %d, dims[0] = %d, dims[1] = %d\n", cls, nelem, ndims, dims[0], dims[1]); if (cls == mxCHAR_CLASS) { char *str = mxArrayToString(a); PyObject *o = PyString_FromString(str); mxFree(str); return o; } else if (mxIsStruct(a)) { PyObject *o = PyDict_New(); PyObject *list; PyObject *pyItem; mxArray *item; int i, j; const char *fieldName; int nfields = mxGetNumberOfFields(a); if (debug) mexPrintf("nfields = %d, nelem = %d\n", nfields, nelem); for(i = 0; i < nfields; i++) { fieldName = mxGetFieldNameByNumber(a, i); list = PyList_New(nelem); for(j = 0; j < nelem; j++) { item = mxGetFieldByNumber(a, j, i); if(item == NULL) { Py_DECREF(list); Py_DECREF(o); mexErrMsgIdAndTxt("matpy:NullFieldValue", "Null field in struct"); } pyItem = mat2py(item); if(pyItem == NULL) { Py_DECREF(list); Py_DECREF(o); mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type in struct"); } PyList_SetItem(list, j, pyItem); } PyDict_SetItemString(o, fieldName, list); } Py_DECREF(list); return o; } PyObject *list = PyList_New(nelem); const char *dtype = NULL; if (mxIsCell(a)) { dtype = "object"; for (int i = 0; i < nelem; i++) { PyObject *item = mat2py(mxGetCell(a, i)); if(NULL != item) { PyList_SetItem(list, i, item); } else // Failure { Py_DECREF(list); mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type in a cell"); } } return list; } else { if (imagData == NULL) { #define CASE(cls,c_type,d_type,py_ctor) case cls: for (int i = 0; i < nelem; i++) { \ dtype=d_type; \ PyObject *item = py_ctor(*((c_type*) data)); \ if (debug) mexPrintf("Setting %d to %f (item = 0x%08X)\n", i, (double) *((c_type*) data), item); \ data += sizeof(c_type); \ if (PyList_SetItem(list, i, item) == -1) PyErr_Print(); } \ break switch(cls) { CASE(mxLOGICAL_CLASS, bool, "bool", PyBool_FromLong); CASE(mxDOUBLE_CLASS, double, "float64", PyFloat_FromDouble); CASE(mxSINGLE_CLASS, float, "float32", PyFloat_FromDouble); CASE(mxINT8_CLASS, char, "int8", PyInt_FromLong); CASE(mxUINT8_CLASS, unsigned char, "uint8", PyInt_FromLong); CASE(mxINT16_CLASS, short, "int16", PyInt_FromLong); CASE(mxUINT16_CLASS, unsigned short, "uint16", PyInt_FromLong); CASE(mxINT32_CLASS, int, "int32", PyInt_FromLong); CASE(mxUINT32_CLASS, unsigned int, "uint32", PyLong_FromLongLong); CASE(mxINT64_CLASS, long long, "int64", PyLong_FromLongLong); CASE(mxUINT64_CLASS, unsigned long long, "uint64", PyLong_FromUnsignedLongLong); default: mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type"); } } else { #undef CASE #define CASE(cls,c_type,d_type) case cls: for (int i = 0; i < nelem; i++) { \ dtype = d_type; \ PyObject *item = PyComplex_FromDoubles(*((c_type*) data), *((c_type*) imagData)); \ data += sizeof(c_type); \ imagData += sizeof(c_type); \ PyList_SetItem(list, i, item); } \ break switch(cls) { CASE(mxDOUBLE_CLASS, double, "complex128"); CASE(mxSINGLE_CLASS, float, "complex64"); CASE(mxINT8_CLASS, char, "complex64"); CASE(mxUINT8_CLASS, unsigned char, "complex64"); CASE(mxINT16_CLASS, short, "complex64"); CASE(mxUINT16_CLASS, unsigned short, "complex64"); CASE(mxINT32_CLASS, int, "complex128"); CASE(mxUINT32_CLASS, unsigned int, "complex128"); CASE(mxINT64_CLASS, long long, "complex128"); CASE(mxUINT64_CLASS, unsigned long long, "complex128"); default: mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type"); } } }
void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { // Register exit function only once static int atExitFncRegistered = 0; if(!atExitFncRegistered) { LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(dctMexAtExitFnc)); atExitFncRegistered = 1; } LTFAT_REAL *c_r, *c_i; const LTFAT_REAL *f_r, *f_i; dct_kind kind; mwIndex L = mxGetM(prhs[0]); mwIndex W = mxGetN(prhs[0]); mwIndex type = (mwIndex) mxGetScalar(prhs[1]); // Copy inputs and get pointers if( mxIsComplex(prhs[0])) { f_i = mxGetImagData(prhs[0]); plhs[0] = ltfatCreateMatrix(L, W, LTFAT_MX_CLASSID, mxCOMPLEX); c_i = mxGetImagData(plhs[0]); } else { plhs[0] = ltfatCreateMatrix(L, W, LTFAT_MX_CLASSID, mxREAL); } f_r = mxGetData(prhs[0]); c_r = mxGetData(plhs[0]); switch(type) { case 1: kind = DSTI; break; case 2: kind = DSTII; break; case 3: kind = DSTIII; break; case 4: kind = DSTIV; break; default: mexErrMsgTxt("Unknown type."); } LTFAT_FFTW(plan) p = LTFAT_NAME(dst_init)( L, W, c_r, kind); LTFAT_NAME(dctMexAtExitFnc)(); LTFAT_NAME(p_old) = p; LTFAT_NAME(dst_execute)(p,f_r,L,W,c_r,kind); if( mxIsComplex(prhs[0])) { LTFAT_NAME(dst_execute)(p,f_i,L,W,c_i,kind); } return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /*declare variables*/ const mwSize *dims; mwIndex indx; int i, numdims; int numelin; mxClassID classid; double *input1r, *input1i, *input2r, *input2i, *output1r, *output1i; double a, b, c, d, e, f, g, h, absa, absb, absc, absd, offr, offi; double ai, bi, ci, di, ei, fi, gi, hi; /*figure out the classid*/ classid = mxGetClassID(prhs[0]); /*check inputs*/ if (nrhs!=2) mexErrMsgTxt("Wrong number of input arguments"); /*associate inputs*/ input1r = mxGetData(prhs[0]); input1i = mxGetImagData(prhs[0]); input2r = mxGetData(prhs[1]); input2i = mxGetImagData(prhs[1]); /*figure out dimension info and number of elements*/ dims = mxGetDimensions(prhs[0]); numdims = mxGetNumberOfDimensions(prhs[0]); numelin = mxGetNumberOfElements(prhs[0]); /*associate output*/ if (input1i == NULL && input2i == NULL) { plhs[0] = mxCreateNumericArray(numdims, dims, classid, mxREAL); output1r = mxGetData(plhs[0]); } else { plhs[0] = mxCreateNumericArray(numdims, dims, classid, mxCOMPLEX); output1r = mxGetData(plhs[0]); output1i = mxGetImagData(plhs[0]); } /* do the computation*/ if (input1i == NULL && input2i == NULL) { for (i=0; i<numelin/4; i++) { a = input1r[i*4 ]; b = input1r[i*4+1]; c = input1r[i*4+2]; d = input1r[i*4+3]; e = input2r[i*4 ]; f = input2r[i*4+1]; g = input2r[i*4+2]; h = input2r[i*4+3]; output1r[i*4 ] = e*a*a + 2*f*a*c + h*c*c; output1r[i*4+1] = e*a*b + f*a*d + f*b*c + h*c*d; output1r[i*4+2] = e*a*b + f*b*c + f*a*d + h*c*d; output1r[i*4+3] = e*b*b + 2*f*b*d + h*d*d; } return; } else if (input1i == NULL) { for (i=0; i<numelin/4; i++) { /*matrix 1*/ a = input1r[i*4 ]; b = input1r[i*4+1]; c = input1r[i*4+2]; d = input1r[i*4+3]; /*matrix 2*/ e = input2r[i*4 ]; f = input2r[i*4+1]; g = input2r[i*4+2]; h = input2r[i*4+3]; ei = input2i[i*4 ]; fi = input2i[i*4+1]; gi = input2i[i*4+2]; hi = input2i[i*4+3]; /*compute some quantities only once*/ absa = a*a; absb = b*b; absc = c*c; absd = (d*d+di*di); offr = e*a*b + f*a*d + f*b*c + h*c*d; offi = -ei*a*b - fi*a*d + fi*b*c - hi*c*d; /*fill in the real part of the output matrix*/ output1r[i*4 ] = e*absa + 2*f*a*c + h*absc; output1r[i*4+1] = offr; output1r[i*4+2] = offr; output1r[i*4+3] = e*absb + 2*f*b*d + h*absd; /*fill in the imaginary part of the output matrix*/ output1i[i*4 ] = ei*absa + hi*absc; output1i[i*4+1] = -offi; output1i[i*4+2] = offi; output1i[i*4+3] = ei*absb + hi*absd; } } /*else if (input2i == NULL)*/ else { for (i=0; i<numelin/4; i++) { /*matrix 1*/ a = input1r[i*4 ]; b = input1r[i*4+1]; c = input1r[i*4+2]; d = input1r[i*4+3]; ai = input1i[i*4 ]; bi = input1i[i*4+1]; ci = input1i[i*4+2]; di = input1i[i*4+3]; /*matrix 2*/ e = input2r[i*4 ]; f = input2r[i*4+1]; g = input2r[i*4+2]; h = input2r[i*4+3]; ei = input2i[i*4 ]; fi = input2i[i*4+1]; gi = input2i[i*4+2]; hi = input2i[i*4+3]; /*compute some quantities only once*/ absa = (a*a+ai*ai); absb = (b*b+bi*bi); absc = (c*c+ci*ci); absd = (d*d+di*di); offr = (e*a*b+e*ai*bi-ei*a*bi+ei*ai*b) + (f*a*d+f*ai*di-fi*a*di+fi*ai*d) + (f*b*c+f*bi*ci-fi*b*ci+fi*bi*c) + (h*c*d+h*ci*di-hi*c*di+hi*ci*d); offi = (-ei*ai*bi-e*a*bi+e*ai*b-ei*a*b) + (-fi*ai*di-f*a*di+f*ai*d-fi*a*d) + (fi*bi*ci+f*b*ci-f*bi*c+fi*b*c) + (-hi*ci*di-h*c*di+h*ci*d-hi*c*d); /*fill in the real part of the output matrix*/ output1r[i*4 ] = e*absa + 2*(f*a*c+f*ai*ci-fi*a*ci+fi*ai*c) + h*absc; output1r[i*4+1] = offr; output1r[i*4+2] = offr; output1r[i*4+3] = e*absb + 2*(f*b*d+f*bi*di-fi*b*di+fi*bi*d) + h*absd; /*fill in the imaginary part of the output matrix*/ output1i[i*4 ] = ei*absa + hi*absc; output1i[i*4+1] = -offi; output1i[i*4+2] = offi; output1i[i*4+3] = ei*absb + hi*absd; } return; } }
/***********************************************************************//** * \brief mexFunction to append a stack to an existing em-file. **************************************************************************/ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[]) { size_t filename_length = 0; #define __MAX_FILENAME_LENGTH__ ((int)2048) char filename[__MAX_FILENAME_LENGTH__+1]; #define __MAX_S__LENGTH__ (__MAX_FILENAME_LENGTH__+1024) char s[__MAX_S__LENGTH__+1]; tom_io_em_header header; #define __BUFFERLENGTH_SYNOPSIS__ 1024 char synopsis[__BUFFERLENGTH_SYNOPSIS__]; void *data; mxArray *mxData; size_t sizex, sizey, sizez; mxClassID mxType; mxComplexity mxIsComplexVolume; size_t i; int res; int header_read; int allow_conversion = 1; mxArray *plhs_tmp[5] = { NULL, NULL, NULL, NULL, NULL }; snprintf(synopsis, __BUFFERLENGTH_SYNOPSIS__, "[size, magic, comment, emdata, userdata] = %s(filename, volume, [allow_conversion])", mexFunctionName()); if (nrhs==0 && nlhs==0) { /* Print help */ mexPrintf("SYNOPSIS: %s\n", synopsis); mexPrintf("mex-file compiled from file \"" __FILE__ "\" at " __DATE__ ", " __TIME__ ".\n"); return; } if (nrhs < 2 || nrhs > 3) { snprintf(s, __MAX_S__LENGTH__, "%s: call function with up to 3 parameters: %s.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (nlhs>5) { snprintf(s, __MAX_S__LENGTH__, "%s: Too many output parameters: %s.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } { const mxArray *PRHS_FILENAME = prhs[0]; const mxArray *PRHS_VOLUME = prhs[1]; const mwSize *size; /* Check input parameters! */ if (!mxIsChar(PRHS_FILENAME) || mxGetNumberOfDimensions(PRHS_FILENAME)!=2 || mxGetM(PRHS_FILENAME)!=1 || (filename_length=mxGetN(PRHS_FILENAME))<1) { snprintf(s, __MAX_S__LENGTH__, "%s: needs the file name as first parameter: %s.", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (filename_length >= __MAX_FILENAME_LENGTH__) { snprintf(s, __MAX_S__LENGTH__, "%s: Maximal length of file name exceeded. (Recompile with larger buffer :)", mexFunctionName()); mexErrMsgTxt(s); } mxGetString(PRHS_FILENAME, filename, __MAX_FILENAME_LENGTH__); if (!mxIsNumeric(PRHS_VOLUME) || mxGetNumberOfDimensions(PRHS_VOLUME)>3) { snprintf(s, __MAX_S__LENGTH__, "%s: needs a numerical volume as second parameter: %s", mexFunctionName(), synopsis); mexErrMsgTxt(s); } data = mxGetData(PRHS_VOLUME); size = mxGetDimensions(PRHS_VOLUME); mxType = mxGetClassID(PRHS_VOLUME); mxIsComplexVolume = mxIsComplex(PRHS_VOLUME); sizex = size[0]; sizey = size[1]; sizez = mxGetNumberOfDimensions(PRHS_VOLUME)==3 ? size[2] : 1; if (mxIsComplexVolume) { if (mxType==mxSINGLE_CLASS || mxType==mxDOUBLE_CLASS) { mwSize size[3]; size_t x, y, z; size[0] = sizex*2; size[1] = sizey; size[2] = sizez; if (!(mxData = mxCreateNumericArray(sizez==1 ? 2 : 3, size, mxType, mxREAL))) { mexErrMsgTxt("%s: Error allocating temporary buffer for complex data."); } data = mxGetData(mxData); if (mxType == mxSINGLE_CLASS) { float *data_as_real = (float *)data; const float *data_real = (const float *)mxGetData(PRHS_VOLUME); const float *data_complex = (const float *)mxGetImagData(PRHS_VOLUME); for (z=0; z<sizez; z++) { for (y=0; y<sizey; y++) { for (x=0; x<sizex; x++) { *data_as_real++ = *data_real++; *data_as_real++ = *data_complex++; } } } } else { double *data_as_real = (double *)data; const double *data_real = (const double *)mxGetData(PRHS_VOLUME); const double *data_complex = (const double *)mxGetImagData(PRHS_VOLUME); for (z=0; z<sizez; z++) { for (y=0; y<sizey; y++) { for (x=0; x<sizex; x++) { *data_as_real++ = *data_real++; *data_as_real++ = *data_complex++; } } } } } else { snprintf(s, __MAX_S__LENGTH__, "%s: Complex data for this type not supported (currently only for single and double).", mexFunctionName()); mexErrMsgTxt(s); } } if (nrhs >= 3) { mwSize numel; numel = mxGetM(prhs[2]) * mxGetN(prhs[2]); if (!(mxIsNumeric(prhs[2]) || mxIsLogical(prhs[2])) || numel>1) { snprintf(s, __MAX_S__LENGTH__, "%s: allow_conversion must be one of true, false or [].", mexFunctionName(), synopsis); mexErrMsgTxt(s); } if (numel == 1) { allow_conversion = mxGetScalar(prhs[2]) != 0.; } } } { /* Allocate the memory for the ouput, so that in case of successfully writing, no error can happen afterwards in the mexfunction. */ switch (nlhs) { case 5: if (!(plhs_tmp[4] = mxCreateNumericMatrix(1, 256, mxINT8_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 4: if (!(plhs_tmp[3] = mxCreateNumericMatrix(1, 40, mxINT32_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 3: if (!(plhs_tmp[2] = mxCreateNumericMatrix(1, 80, mxINT8_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 2: if (!(plhs_tmp[1] = mxCreateNumericMatrix(1, 4, mxINT8_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } case 1: if (!(plhs_tmp[0] = mxCreateNumericMatrix(3, 1, mxUINT32_CLASS, mxREAL))) { mexErrMsgTxt("Error allocating memory"); } } } res = tom_io_em_write_append_stack(filename, data, getIOTypeFromMxClassID(mxType, mxIsComplexVolume), sizex, sizey, sizez, 0, 0, 0, &header, &header_read, allow_conversion); if (res != TOM_ERR_OK) { if (res ==TOM_ERR_WRITE_FILE) { snprintf(s, __MAX_S__LENGTH__, "%s: IO-error occured. The em-file may now be damaged :(", mexFunctionName()); mexErrMsgTxt(s); } else if (res==TOM_ERR_OPEN_FILE) { snprintf(s, __MAX_S__LENGTH__, "%s: Error opening the file \"%s\" for writing.", mexFunctionName(), filename); mexErrMsgTxt(s); } else if (header_read && res==TOM_ERR_WRONG_IOTYPE_CONVERSION) { snprintf(s, __MAX_S__LENGTH__, "%s: Wrong typeconversion: can not convert volume of type %d to type %d as in the em-file.", mexFunctionName(), getIOTypeFromMxClassID(mxType, mxIsComplexVolume), tom_io_em_get_iotype_header(&header)); mexErrMsgTxt(s); } else if (res == TOM_ERR_IOTYPE_NOT_SUPPORTED) { snprintf(s, __MAX_S__LENGTH__, "%s: Saving data of type %d to em-file is (currently) not supported.", mexFunctionName(), getIOTypeFromMxClassID(mxType, mxIsComplexVolume)); mexErrMsgTxt(s); } else if (header_read && TOM_ERR_WRONG_DATA_SIZE && (sizex!=header.dims[0] || sizey!=header.dims[1])) { snprintf(s, __MAX_S__LENGTH__, "%s: Size mismatch: The volume has dimension %dx%dx%d, but the em-file has size %dx%dx%d.", mexFunctionName(), sizex, sizey, sizez, header.dims[0], header.dims[1], header.dims[2]); mexErrMsgTxt(s); } else { snprintf(s, __MAX_S__LENGTH__, "%s: Unexpected error. Is the \"%s\" a valid em-file? (%d)", mexFunctionName(), filename, res); mexErrMsgTxt(s); } } { /* Construct the output. */ void *pdata; switch (nlhs) { case 5: pdata = mxGetData(plhs[4] = plhs_tmp[4]); for (i=0; i<256; i++) { ((int8_t *)pdata)[i] = header.userdata[i]; } case 4: pdata = mxGetData(plhs[3] = plhs_tmp[3]); for (i=0; i<40; i++) { ((int32_t *)pdata)[i] = header.emdata[i]; } case 3: pdata = mxGetData(plhs[2] = plhs_tmp[2]); for (i=0; i<80; i++) { ((int8_t *)pdata)[i] = header.comment[i]; } case 2: pdata = mxGetData(plhs[1] = plhs_tmp[1]); ((int8_t *)pdata)[0] = header.machine; ((int8_t *)pdata)[1] = header.byte2; ((int8_t *)pdata)[2] = header.byte3; ((int8_t *)pdata)[3] = header.type; case 1: pdata = mxGetData(plhs[0] = plhs_tmp[0]); ((uint32_t *)pdata)[0] = header.dims[0]; ((uint32_t *)pdata)[1] = header.dims[1]; ((uint32_t *)pdata)[2] = header.dims[2]; break; case 0: default: break; } } }
void LTFAT_NAME(ltfatMexFnc)( int UNUSED(nlhs), mxArray *plhs[], int UNUSED(nrhs), const mxArray *prhs[] ) { // Register exit function only once static int atExitFncRegistered = 0; if (!atExitFncRegistered) { LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(dctMexAtExitFnc)); atExitFncRegistered = 1; } LTFAT_REAL *c_r, *c_i=NULL; const LTFAT_REAL *f_r, *f_i=NULL; dct_kind kind = DCTI; // This is overwritten mwIndex L = mxGetM(prhs[0]); mwIndex W = mxGetN(prhs[0]); mwIndex type = (mwIndex) mxGetScalar(prhs[1]); // Copy inputs and get pointers if ( mxIsComplex(prhs[0])) { f_i = mxGetImagData(prhs[0]); plhs[0] = ltfatCreateMatrix(L, W, LTFAT_MX_CLASSID, mxCOMPLEX); c_i = mxGetImagData(plhs[0]); } else { plhs[0] = ltfatCreateMatrix(L, W, LTFAT_MX_CLASSID, mxREAL); } f_r = mxGetData(prhs[0]); c_r = mxGetData(plhs[0]); switch (type) { case 1: kind = DCTI; break; case 2: kind = DCTII; break; case 3: kind = DCTIII; break; case 4: kind = DCTIV; break; default: mexErrMsgTxt("Unknown type."); } LTFAT_FFTW(plan) p = LTFAT_NAME(dct_init)( L, W, c_r, kind); /* The old plan is freed after the new one is cretaed. According to the FFTW doc. creating new plan is quick as long as there already exists a plan for the same length. */ LTFAT_NAME(dctMexAtExitFnc)(); LTFAT_NAME(p_old) = p; LTFAT_NAME(dct_execute)(p, f_r, L, W, c_r, kind); if ( mxIsComplex(prhs[0])) { LTFAT_NAME(dct_execute)(p, f_i, L, W, c_i, kind); } return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /*declare variables*/ const mwSize *dims; mwIndex indx; int i, numdims, indx1, indx2, indx3; int numelin; mxClassID classid; double *input1r, *input1i, *input2r, *input2i, *output1r, *output1i; double a[3][3], b[3][3], c[3][3]; double ai[3][3], bi[3][3], ci[3][3]; /*figure out the classid*/ classid = mxGetClassID(prhs[0]); /*check inputs*/ if (nrhs!=2) mexErrMsgTxt("Wrong number of input arguments"); /*associate inputs*/ input1r = mxGetData(prhs[0]); input1i = mxGetImagData(prhs[0]); input2r = mxGetData(prhs[1]); input2i = mxGetImagData(prhs[1]); /*figure out dimension info and number of elements*/ dims = mxGetDimensions(prhs[0]); numdims = mxGetNumberOfDimensions(prhs[0]); numelin = mxGetNumberOfElements(prhs[0]); /*associate output*/ if (input1i == NULL && input2i == NULL) { plhs[0] = mxCreateNumericArray(numdims, dims, classid, mxREAL); output1r = mxGetData(plhs[0]); } else { plhs[0] = mxCreateNumericArray(numdims, dims, classid, mxCOMPLEX); output1r = mxGetData(plhs[0]); output1i = mxGetImagData(plhs[0]); } /* do the computation*/ if (input1i == NULL && input2i == NULL) { for (i=0; i<numelin/9; i++) { /* real-valued case*/ for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { a[indx1][indx2] = input1r[i*9+indx1+indx2*3]; b[indx1][indx2] = input2r[i*9+indx1+indx2*3]; c[indx1][indx2] = 0; output1r[i*9+indx1+indx2*3] = 0; } for (indx3=0; indx3<3; ++indx3) for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { c[indx2][indx3] += a[indx2][indx1] * b[indx1][indx3]; } for (indx3=0; indx3<3; ++indx3) for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { output1r[i*9+indx2+indx3*3] += c[indx2][indx1] * a[indx3][indx1]; } } return; } else if (input1i == NULL && input2i != NULL) { for (i=0; i<numelin/9; i++) { /* first input real-valued case, second input complex*/ for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { a[indx1][indx2] = input1r[i*9+indx1+indx2*3]; b[indx1][indx2] = input2r[i*9+indx1+indx2*3]; bi[indx1][indx2] = input2i[i*9+indx1+indx2*3]; c[indx1][indx2] = 0; ci[indx1][indx2] = 0; output1r[i*9+indx1+indx2*3] = 0; output1i[i*9+indx1+indx2*3] = 0; } for (indx3=0; indx3<3; ++indx3) for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { c[indx2][indx3] += a[indx2][indx1] * b[indx1][indx3]; ci[indx2][indx3] += a[indx2][indx1] * bi[indx1][indx3]; } for (indx3=0; indx3<3; ++indx3) for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { output1r[i*9+indx2+indx3*3] += c[indx2][indx1] * a[indx3][indx1]; output1i[i*9+indx2+indx3*3] += ci[indx2][indx1] * a[indx3][indx1]; } } return; } else if (input1i != NULL && input2i == NULL) { for (i=0; i<numelin/9; i++) { /* first input complex-valued, second input real-valued*/ for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { a[indx1][indx2] = input1r[i*9+indx1+indx2*3]; b[indx1][indx2] = input2r[i*9+indx1+indx2*3]; ai[indx1][indx2] = input1i[i*9+indx1+indx2*3]; c[indx1][indx2] = 0; ci[indx1][indx2] = 0; output1r[i*9+indx1+indx2*3] = 0; output1i[i*9+indx1+indx2*3] = 0; } for (indx3=0; indx3<3; ++indx3) for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { c[indx2][indx3] += a[indx2][indx1] * b[indx1][indx3]; ci[indx2][indx3] += ai[indx2][indx1] * b[indx1][indx3]; } for (indx3=0; indx3<3; ++indx3) for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { output1r[i*9+indx2+indx3*3] += c[indx2][indx1] * a[indx3][indx1] + ci[indx2][indx1] * ai[indx3][indx1]; output1i[i*9+indx2+indx3*3] += ci[indx2][indx1] * a[indx3][indx1] - c[indx2][indx1] * ai[indx3][indx1]; } } return; } else { for (i=0; i<numelin/9; i++) { /* both inputs complex-valued*/ for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { a[indx1][indx2] = input1r[i*9+indx1+indx2*3]; b[indx1][indx2] = input2r[i*9+indx1+indx2*3]; ai[indx1][indx2] = input1i[i*9+indx1+indx2*3]; bi[indx1][indx2] = input2i[i*9+indx1+indx2*3]; c[indx1][indx2] = 0; ci[indx1][indx2] = 0; output1r[i*9+indx1+indx2*3] = 0; output1i[i*9+indx1+indx2*3] = 0; } for (indx3=0; indx3<3; ++indx3) for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { c[indx2][indx3] += a[indx2][indx1] * b[indx1][indx3] - ai[indx2][indx1] * bi[indx1][indx3]; ci[indx2][indx3] += ai[indx2][indx1] * b[indx1][indx3] + a[indx2][indx1] * bi[indx1][indx3]; } for (indx3=0; indx3<3; ++indx3) for (indx2=0; indx2<3; ++indx2) for (indx1=0; indx1<3; ++indx1) { output1r[i*9+indx2+indx3*3] += c[indx2][indx1] * a[indx3][indx1] + ci[indx2][indx1] * ai[indx3][indx1]; output1i[i*9+indx2+indx3*3] += ci[indx2][indx1] * a[indx3][indx1] - c[indx2][indx1] * ai[indx3][indx1]; } } return; } }
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) { mxClassID classid; mxArray *Amx, *Bmx; mwSize Adims[12] = {1,1,1,1,1,1,1,1,1,1,1,1}; mwSize Bdims[12] = {1,1,1,1,1,1,1,1,1,1,1,1}; mwSize Cdims[12]; int Andim, Bndim, Cndim; mxComplexity complexity; void *Apr, *Api, *Cpr, *Cpi; int i; // Check for bit length definitions if( sizeof(bit16) != 2 ) mexErrMsgTxt("Error using bsxarg: bit16 length is not 16-bits."); if( sizeof(bit32) != 4 ) mexErrMsgTxt("Error using bsxarg: bit32 length is not 32-bits."); if( sizeof(bit64) != 8 ) mexErrMsgTxt("Error using bsxarg: bit64 length is not 64-bits."); // Check for proper inputs if( nrhs != 2 ) mexErrMsgTxt("Error using bsxarg: Invalid number of inputs. Need two."); if( nlhs > 2 ) mexErrMsgTxt("Error using bsxarg: Invalid number of outputs. Not more than two."); // Set temporary operand pointers to the inputs. Amx = const_cast<mxArray*>(prhs[0]); Bmx = const_cast<mxArray*>(prhs[1]); // Check for supported operand classes switch( mxGetClassID(Amx) ) { case mxDOUBLE_CLASS: case mxINT64_CLASS: case mxUINT64_CLASS: case mxSINGLE_CLASS: case mxINT32_CLASS: case mxUINT32_CLASS: case mxCHAR_CLASS: case mxINT16_CLASS: case mxUINT16_CLASS: case mxLOGICAL_CLASS: case mxINT8_CLASS: case mxUINT8_CLASS: break; default: mexErrMsgTxt("Error using bsxarg: 1st argument class not supported"); } switch( mxGetClassID(Bmx) ) { case mxDOUBLE_CLASS: case mxINT64_CLASS: case mxUINT64_CLASS: case mxSINGLE_CLASS: case mxINT32_CLASS: case mxUINT32_CLASS: case mxCHAR_CLASS: case mxINT16_CLASS: case mxUINT16_CLASS: case mxLOGICAL_CLASS: case mxINT8_CLASS: case mxUINT8_CLASS: break; default: mexErrMsgTxt("Error using bsxarg: 2nd argument class not supported"); } // Generate the indexing multipliers Andim = mxGetNumberOfDimensions(Amx); if( Andim > 12 ) mexErrMsgTxt("Error using bsxarg: 1st array argument has too many dimensions."); memcpy(Adims, mxGetDimensions(Amx), Andim*sizeof(mwSize)); A1 = 1; A2 = Adims[0]; A3 = Adims[1]*A2; A4 = Adims[2]*A3; A5 = Adims[3]*A4; A6 = Adims[4]*A5; A7 = Adims[5]*A6; A8 = Adims[6]*A7; A9 = Adims[7]*A8; A10 = Adims[8]*A9; A11 = Adims[9]*A10; A12 = Adims[10]*A11; if( Adims[0] < 2 ) A1 = 0; if( Adims[1] < 2 ) A2 = 0; if( Adims[2] < 2 ) A3 = 0; if( Adims[3] < 2 ) A4 = 0; if( Adims[4] < 2 ) A5 = 0; if( Adims[5] < 2 ) A6 = 0; if( Adims[6] < 2 ) A7 = 0; if( Adims[7] < 2 ) A8 = 0; if( Adims[8] < 2 ) A9 = 0; if( Adims[9] < 2 ) A10 = 0; if( Adims[10] < 2 ) A11 = 0; if( Adims[11] < 2 ) A12 = 0; Bndim = mxGetNumberOfDimensions(Bmx); if( Bndim > 12 ) mexErrMsgTxt("Error using bsxarg: 2nd array argument has too many dimensions."); memcpy(Bdims, mxGetDimensions(Bmx), Bndim*sizeof(mwSize)); B1 = 1; B2 = Bdims[0]; B3 = Bdims[1]*B2; B4 = Bdims[2]*B3; B5 = Bdims[3]*B4; B6 = Bdims[4]*B5; B7 = Bdims[5]*B6; B8 = Bdims[6]*B7; B9 = Bdims[7]*B8; B10 = Bdims[8]*B9; B11 = Bdims[9]*B10; B12 = Bdims[10]*B11; if( Bdims[0] < 2 ) B1 = 0; if( Bdims[1] < 2 ) B2 = 0; if( Bdims[2] < 2 ) B3 = 0; if( Bdims[3] < 2 ) B4 = 0; if( Bdims[4] < 2 ) B5 = 0; if( Bdims[5] < 2 ) B6 = 0; if( Bdims[6] < 2 ) B7 = 0; if( Bdims[7] < 2 ) B8 = 0; if( Bdims[8] < 2 ) B9 = 0; if( Bdims[9] < 2 ) B10 = 0; if( Bdims[10] < 2 ) B11 = 0; if( Bdims[11] < 2 ) B12 = 0; k1 = MAX( Adims[0], Bdims[0] ); k2 = MAX( Adims[1], Bdims[1] ); k3 = MAX( Adims[2], Bdims[2] ); k4 = MAX( Adims[3], Bdims[3] ); k5 = MAX( Adims[4], Bdims[4] ); k6 = MAX( Adims[5], Bdims[5] ); k7 = MAX( Adims[6], Bdims[6] ); k8 = MAX( Adims[7], Bdims[7] ); k9 = MAX( Adims[8], Bdims[8] ); k10 = MAX( Adims[9], Bdims[9] ); k11 = MAX( Adims[10], Bdims[10] ); k12 = MAX( Adims[11], Bdims[11] ); for( i=0; i<12; i++ ) { if( Adims[i] != Bdims[i] && Adims[i] != 1 && Bdims[i] != 1 ) mexErrMsgTxt("Error using bsxarg: All non-singleton dimensions must match."); Cdims[i] = (Adims[i] && Bdims[i]) ? MAX( Adims[i], Bdims[i] ) : 0; } Cndim = MAX( Andim, Bndim ); // Fill in the values --------------------------------------------------------- classid = mxGetClassID(prhs[0]); complexity = mxIsComplex(prhs[0]) ? mxCOMPLEX : mxREAL; plhs[0] = mxCreateNumericArray(Cndim, Cdims, classid, complexity); if( mxGetNumberOfElements(plhs[0]) ) { Cpr = mxGetData(plhs[0]); Cpi = mxGetImagData(plhs[0]); Apr = mxGetData(prhs[0]); Api = mxGetImagData(prhs[0]); switch( classid ) { case mxDOUBLE_CLASS: case mxINT64_CLASS: case mxUINT64_CLASS: expand_64bits(Cpr, Cpi, Apr, Api, complexity); break; case mxSINGLE_CLASS: case mxINT32_CLASS: case mxUINT32_CLASS: expand_32bits(Cpr, Cpi, Apr, Api, complexity); break; case mxCHAR_CLASS: case mxINT16_CLASS: case mxUINT16_CLASS: expand_16bits(Cpr, Cpi, Apr, Api, complexity); break; case mxLOGICAL_CLASS: case mxINT8_CLASS: case mxUINT8_CLASS: expand_8bits(Cpr, Cpi, Apr, Api, complexity); break; } } if( nlhs < 2 ) return; classid = mxGetClassID(prhs[1]); complexity = mxIsComplex(prhs[1]) ? mxCOMPLEX : mxREAL; plhs[1] = mxCreateNumericArray(Cndim, Cdims, classid, complexity); if( mxGetNumberOfElements(plhs[1]) ) { Cpr = mxGetData(plhs[1]); Cpi = mxGetImagData(plhs[1]); Apr = mxGetData(prhs[1]); Api = mxGetImagData(prhs[1]); A1 = B1; A2 = B2; A3 = B3; A4 = B4; A5 = B5; A6 = B6; A7 = B7; A8 = B8; A9 = B9; A10 = B10; A11 = B11; A12 = B12; switch( classid ) { case mxDOUBLE_CLASS: case mxINT64_CLASS: case mxUINT64_CLASS: expand_64bits(Cpr, Cpi, Apr, Api, complexity); break; case mxSINGLE_CLASS: case mxINT32_CLASS: case mxUINT32_CLASS: expand_32bits(Cpr, Cpi, Apr, Api, complexity); break; case mxCHAR_CLASS: case mxINT16_CLASS: case mxUINT16_CLASS: expand_16bits(Cpr, Cpi, Apr, Api, complexity); break; case mxLOGICAL_CLASS: case mxINT8_CLASS: case mxUINT8_CLASS: expand_8bits(Cpr, Cpi, Apr, Api, complexity); break; } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /*declare variables*/ const mwSize *dims; mwIndex indx; int i, numdims; int numelin; mxClassID classid; double *input1r, *input1i, *output1r, *output1i; double a, b, c, d, denom; double ai, bi, ci, di, denomi, denomabs; /*figure out the classid*/ classid = mxGetClassID(prhs[0]); /*check inputs*/ if (nrhs>1) mexErrMsgTxt("Too many input arguments"); /*associate inputs*/ input1r = mxGetData(prhs[0]); input1i = mxGetImagData(prhs[0]); /*figure out dimension info and number of elements*/ dims = mxGetDimensions(prhs[0]); numdims = mxGetNumberOfDimensions(prhs[0]); numelin = mxGetNumberOfElements(prhs[0]); /*associate output*/ if (input1i == NULL) { plhs[0] = mxCreateNumericArray(numdims, dims, classid, mxREAL); output1r = mxGetData(plhs[0]); } else { plhs[0] = mxCreateNumericArray(numdims, dims, classid, mxCOMPLEX); output1r = mxGetData(plhs[0]); output1i = mxGetImagData(plhs[0]); } /* do the computation*/ if (input1i == NULL) { for (i=0; i<numelin/4; i++) { a = input1r[i*4 ]; b = input1r[i*4+1]; c = input1r[i*4+2]; d = input1r[i*4+3]; denom = a*d - b*c; output1r[i*4 ] = d/denom; output1r[i*4+1] = -b/denom; output1r[i*4+2] = -c/denom; output1r[i*4+3] = a/denom; } return; } else { for (i=0; i<numelin/4; i++) { /*matrix 1*/ a = input1r[i*4 ]; b = input1r[i*4+1]; c = input1r[i*4+2]; d = input1r[i*4+3]; ai = input1i[i*4 ]; bi = input1i[i*4+1]; ci = input1i[i*4+2]; di = input1i[i*4+3]; /*get the determinant*/ denom = (a*d-ai*di) - (b*c-bi*ci); denomi = (ai*d+a*di) - (bi*c+b*ci); denomabs = denom*denom + denomi*denomi; /*fill in the real part of the output matrix*/ output1r[i*4 ] = (d*denom+di*denomi)/denomabs; output1r[i*4+1] = -(b*denom+bi*denomi)/denomabs; output1r[i*4+2] = -(c*denom+ci*denomi)/denomabs; output1r[i*4+3] = (a*denom+ai*denomi)/denomabs; /*fill in the imaginary part of the output matrix*/ output1i[i*4 ] = -(d*denomi-di*denom)/denomabs; output1i[i*4+1] = (b*denomi-bi*denom)/denomabs; output1i[i*4+2] = (c*denomi-ci*denom)/denomabs; output1i[i*4+3] = -(a*denomi-ai*denom)/denomabs; } return; } /* do the computation*/ for (i=0; i<numelin/4; i++) { } return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /*declare variables*/ const mwSize *dims; mwSize *dimsout; mwIndex indx; int i, numdims; int numelin; mxClassID classid; double *input1r, *input1i, *output1r, *output1i; double a, b, c, d, e, f, g, h, j; double ai, bi, ci, di, ei, fi, gi, hi ,ji; /*figure out the classid*/ classid = mxGetClassID(prhs[0]); /*check inputs*/ if (nrhs>1) mexErrMsgTxt("Too many input arguments"); /*associate inputs*/ input1r = mxGetData(prhs[0]); input1i = mxGetImagData(prhs[0]); /*figure out dimension info and number of elements*/ dims = mxGetDimensions(prhs[0]); numdims = mxGetNumberOfDimensions(prhs[0]); numelin = mxGetNumberOfElements(prhs[0]); dimsout = mxMalloc(numdims * sizeof(mwSize)); for (i=0; i<numdims; i++) { dimsout[i] = dims[i]; } dimsout[0] = 1; dimsout[1] = 1; /*associate output*/ if (input1i == NULL) { plhs[0] = mxCreateNumericArray(numdims, dimsout, classid, mxREAL); output1r = mxGetData(plhs[0]); } else { plhs[0] = mxCreateNumericArray(numdims, dimsout, classid, mxCOMPLEX); output1r = mxGetData(plhs[0]); output1i = mxGetImagData(plhs[0]); } /* do the computation*/ if (input1i == NULL) { for (i=0; i<numelin/9; i++) { a = input1r[i*9 ]; b = input1r[i*9+1]; c = input1r[i*9+2]; d = input1r[i*9+3]; e = input1r[i*9+4]; f = input1r[i*9+5]; g = input1r[i*9+6]; h = input1r[i*9+7]; j = input1r[i*9+8]; output1r[i] = a*e*j - a*h*f - d*b*j + d*h*c +g*b*f - g*e*c; } return; } else { for (i=0; i<numelin/9; i++) { /*matrix 1*/ a = input1r[i*9 ]; b = input1r[i*9+1]; c = input1r[i*9+2]; d = input1r[i*9+3]; e = input1r[i*9+4]; f = input1r[i*9+5]; g = input1r[i*9+6]; h = input1r[i*9+7]; j = input1r[i*9+8]; ai = input1i[i*9 ]; bi = input1i[i*9+1]; ci = input1i[i*9+2]; di = input1i[i*9+3]; ei = input1i[i*9+4]; fi = input1i[i*9+5]; gi = input1i[i*9+6]; hi = input1i[i*9+7]; ji = input1i[i*9+8]; /*fill in the real part of the output matrix*/ output1r[i] = (a*e*j-ai*ei*j-a*ei*ji-ai*e*ji) - (a*h*f-ai*hi*f-a*hi*fi-ai*h*fi) - (d*b*j-di*bi*j-d*bi*ji-di*b*ji) + (d*h*c-di*hi*c-d*hi*ci-di*h*ci) + (g*b*f-gi*bi*f-g*bi*fi-gi*b*fi) - (g*e*c-gi*ei*c-g*ei*ci-gi*e*ci); /*fill in the imaginary part of the output matrix*/ output1i[i] = (a*ei*j+ai*e*j+a*e*ji-ai*ei*ji) - (a*hi*f+ai*h*f+a*h*fi-ai*hi*fi) - (d*bi*j+di*b*j+d*b*ji-di*bi*ji) + (d*hi*c+di*h*c+d*h*ci-di*hi*ci) + (g*bi*f+gi*b*f+g*b*fi-gi*bi*fi) - (g*ei*c+gi*e*c+g*e*ci-gi*ei*ci); } return; } }
//put a complex array void engputc(const char* VarName, const int* Dim, int Depth, const double* Re, int ReLen, const double* Im, int ImLen) { mwSize newDim[Depth]; int i; for(i = 0; i < Depth; ++i) { newDim[i] = (mwSize)Dim[i]; } mxArray* MxVar = NULL; //the variable to be put bool SUCCESS = true; //success flag if (NULL == Eng) //if not opened yet, open it { msg("eng::noMLB"); //message SUCCESS = false; goto epilog; } //create mxArray MxVar = mxCreateNumericArray(Depth, newDim, mxDOUBLE_CLASS, mxCOMPLEX); if (NULL == MxVar) { msg("engPut::ercrt"); SUCCESS = false; goto epilog; } unsigned char *start_of_pr; size_t bytes_to_copy; start_of_pr = (unsigned char *)mxGetData(MxVar); bytes_to_copy = ReLen * mxGetElementSize(MxVar); memcpy(start_of_pr,Re,bytes_to_copy); start_of_pr = (unsigned char *)mxGetImagData(MxVar); bytes_to_copy = ImLen * mxGetElementSize(MxVar); memcpy(start_of_pr,Im,bytes_to_copy); //and populate // memcpy((void *)(mxGetPr(MxVar)), (void *)Re, ReLen * sizeof(double)); // memcpy((void *)(mxGetPi(MxVar)), (void *)Im, ImLen * sizeof(double)); //put if(engPutVariable(Eng, VarName, MxVar)) //not successful { msg("engPut::erput"); SUCCESS = false; goto epilog; } epilog: if (MxVar != NULL) mxDestroyArray(MxVar); if(SUCCESS) MLPutString(stdlink, VarName); else MLPutSymbol(stdlink, "$Failed"); }
void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { static int atExitRegistered = 0; if(!atExitRegistered) { LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(fftrealAtExit)); atExitRegistered = 1; } mwSignedIndex 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= mxGetData(prhs[0]); plhs[0] = ltfatCreateMatrix(L2, W, LTFAT_MX_CLASSID, mxCOMPLEX); // Get pointer to output. cout_r = mxGetData(plhs[0]); cout_i = mxGetImagData(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); /* ... creating a new plan is quick once one exists for a given size ... so why not to store the old plan.. */ LTFAT_NAME(fftrealAtExit)(); LTFAT_NAME(p_old) = p; // Real FFT. LTFAT_FFTW(execute)(p); // LTFAT_FFTW(destroy_plan)(p); return; }