void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { size_t numRow, numCol,numPoints, foundIdx; double *arr; mxArray *retIdx; if(nrhs<1){ mexErrMsgTxt("Not enough inputs."); return; } if(nrhs>1) { mexErrMsgTxt("Too many inputs."); return; } if(nlhs>1) { mexErrMsgTxt("Too many outputs."); } /*Verify the validity of the vector to search.*/ checkRealDoubleArray(prhs[0]); numRow = mxGetM(prhs[0]); numCol = mxGetN(prhs[0]); if(numRow>1&&numCol>1){ mexErrMsgTxt("Too many dimensions in the array provided."); return; } else { if(numRow>numCol) { numPoints=numRow; } else { numPoints=numCol; } } arr = reinterpret_cast<double*>(mxGetData(prhs[0])); foundIdx= findFirstMaxCPP(arr,numPoints); //Set the return value retIdx=allocUnsignedSizeMatInMatlab(1,1); *reinterpret_cast<size_t *>(mxGetData(retIdx))=foundIdx+1; plhs[0]=retIdx; }
void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) { double u, scalFactor; ClusterSetCPP<double> HBar; ClusterSetCPP<double> dHBardu;//The first derivatives ClusterSetCPP<double> d2HBardu2;//The second derivatives size_t M, numH, i; mxArray *CSRetVal; mxArray *clusterElsMATLAB,*clusterSizesMATLAB, *offsetArrayMATLAB; if(nrhs!=3){ mexErrMsgTxt("Incorrect number of inputs."); return; } u=getDoubleFromMatlab(prhs[0]); M=getSizeTFromMatlab(prhs[1]); scalFactor=getDoubleFromMatlab(prhs[2]); if(M<3) { mexErrMsgTxt("The maximum order should be at least 3."); return; } numH=(M+1)*(M+2)/2; //Allocate space for the results. clusterElsMATLAB=mxCreateDoubleMatrix(numH,1,mxREAL); clusterSizesMATLAB=allocUnsignedSizeMatInMatlab(M+1,1); offsetArrayMATLAB=allocUnsignedSizeMatInMatlab(M+1,1); HBar.numClust=M+1; HBar.totalNumEl=numH; HBar.clusterEls=reinterpret_cast<double*>(mxGetData(clusterElsMATLAB)); HBar.offsetArray=reinterpret_cast<size_t*>(mxGetData(offsetArrayMATLAB)); HBar.clusterSizes=reinterpret_cast<size_t*>(mxGetData(clusterSizesMATLAB)); //Initialize the offset array and cluster sizes. HBar.offsetArray[0]=0; HBar.clusterSizes[0]=1; for(i=1;i<=M;i++){ HBar.clusterSizes[i]=i+1; HBar.offsetArray[i]=HBar.offsetArray[i-1]+HBar.clusterSizes[i-1]; } normHelmHoltzCPP(HBar,u,scalFactor); //Set the first return value mexCallMATLAB(1,&CSRetVal,0, 0, "ClusterSet"); mxSetProperty(CSRetVal,0,"clusterEls",clusterElsMATLAB); mxSetProperty(CSRetVal,0,"clusterSizes",clusterSizesMATLAB); mxSetProperty(CSRetVal,0,"offsetArray",offsetArrayMATLAB); plhs[0]=CSRetVal; if(nlhs>1) {//Compute the first derivatives, if they are desired. mxArray *clusterEls1stDerivMATLAB=mxCreateDoubleMatrix(numH,1,mxREAL); dHBardu.numClust=M+1; dHBardu.totalNumEl=numH; dHBardu.clusterEls=reinterpret_cast<double*>(mxGetData(clusterEls1stDerivMATLAB)); dHBardu.offsetArray=reinterpret_cast<size_t*>(mxGetData(offsetArrayMATLAB)); dHBardu.clusterSizes=reinterpret_cast<size_t*>(mxGetData(clusterSizesMATLAB)); normHelmHoltzDerivCPP(dHBardu,HBar); //Set the second return value mexCallMATLAB(1,&CSRetVal,0, 0, "ClusterSet"); mxSetProperty(CSRetVal,0,"clusterEls",clusterEls1stDerivMATLAB); mxSetProperty(CSRetVal,0,"clusterSizes",clusterSizesMATLAB); mxSetProperty(CSRetVal,0,"offsetArray",offsetArrayMATLAB); plhs[1]=CSRetVal; mxDestroyArray(clusterEls1stDerivMATLAB); } if(nlhs>2) {//Compute the second derivatives if they are desired. mxArray *clusterEls2ndDerivMATLAB=mxCreateDoubleMatrix(numH,1,mxREAL); d2HBardu2.numClust=M+1; d2HBardu2.totalNumEl=numH; d2HBardu2.clusterEls=reinterpret_cast<double*>(mxGetData(clusterEls2ndDerivMATLAB)); d2HBardu2.offsetArray=reinterpret_cast<size_t*>(mxGetData(offsetArrayMATLAB)); d2HBardu2.clusterSizes=reinterpret_cast<size_t*>(mxGetData(clusterSizesMATLAB)); normHelmHoltzDeriv2CPP(d2HBardu2,HBar); //Set the third return value mexCallMATLAB(1,&CSRetVal,0, 0, "ClusterSet"); mxSetProperty(CSRetVal,0,"clusterEls",clusterEls2ndDerivMATLAB); mxSetProperty(CSRetVal,0,"clusterSizes",clusterSizesMATLAB); mxSetProperty(CSRetVal,0,"offsetArray",offsetArrayMATLAB); plhs[2]=CSRetVal; mxDestroyArray(clusterEls2ndDerivMATLAB); } //Free the buffers. The mxSetProperty command copied the data. mxDestroyArray(clusterElsMATLAB); mxDestroyArray(clusterSizesMATLAB); mxDestroyArray(offsetArrayMATLAB); }
void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) { size_t n,j; size_t nCard; bool isLast, lastPassed; mxArray *codeArray; if(nrhs<1){ mexErrMsgTxt("Not enough inputs."); } if(nrhs>2){ mexErrMsgTxt("Too many inputs."); } if(nlhs>4) { mexErrMsgTxt("Too many outputs."); } //If an empty code matrix is passed, then the second argument is //required, and we will return the first gray code in the sequence. if(mxIsEmpty(prhs[0])) { mwSize dims[2]; if(nrhs<2) { mexErrMsgTxt("The second argument is required when an empty code matrix is passed."); } dims[0]=getSizeTFromMatlab(prhs[1]); dims[1]=1; //Allocate the array; this also initializes all of the elements to //0. codeArray=mxCreateLogicalArray(2, dims); //This is the code plhs[0]=codeArray; if(nlhs>1) { //This is nCard plhs[1]=mxCreateDoubleScalar(0.0); if(nlhs>2) { //This is isLast plhs[2]=mxCreateLogicalScalar(false); if(nlhs>3) { //This is j. plhs[3]=mxCreateDoubleMatrix(0, 0, mxREAL); } } } return; } //The code array cannot be complex. if(mxIsComplex(prhs[0])!=false) { mexErrMsgTxt("The code array cannot be complex."); } //Copy the code value so that the input matrix is not modified on //return. { size_t n1,n2; n1=mxGetM(prhs[0]); n2=mxGetN(prhs[0]); if((n1==1&&n2>=1)||(n2==1&&n1>=1)) { n=std::max(n1,n2); codeArray=mxDuplicateArray(prhs[0]); } else { mexErrMsgTxt("The code vector has the wrong dimensionality."); } } if(nrhs>1) { nCard=getSizeTFromMatlab(prhs[1]); } else { mxArray *lhs[1]; //Sum up the ones in codeArray to get nCard if it is not provided. mexCallMATLAB(1,lhs,1, &codeArray, "sum"); nCard=getSizeTFromMatlab(lhs[0]); mxDestroyArray(lhs[0]); } //The type of the data in the code array is whatever the user passed to //the function. The function has to be called with the correct template //value for the type of the code. lastPassed=false; switch(mxGetClassID(codeArray)){ case mxCHAR_CLASS: { mxChar *code=(mxChar*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxLOGICAL_CLASS: { mxLogical* code=(mxLogical*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxDOUBLE_CLASS: { double* code=(double*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxSINGLE_CLASS: { float* code=(float*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxINT8_CLASS: { int8_T* code=(int8_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxUINT8_CLASS: { uint8_T* code=(uint8_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxINT16_CLASS: { int16_T* code=(int16_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxUINT16_CLASS: { uint16_T* code=(uint16_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxINT32_CLASS: { int32_T* code=(int32_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxUINT32_CLASS: { uint32_T* code=(uint32_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxINT64_CLASS: { int64_T* code=(int64_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } case mxUINT64_CLASS: { uint64_T* code=(uint64_T*)mxGetData(codeArray); if(nCard==(size_t)code[n-1]&&nCard!=0) { lastPassed=true; } else{ isLast=getNextGrayCodeCPP(n, code, nCard, j); } break; } default: mexErrMsgTxt("The code vector is of an unknown data type."); } //If the final gray code was passed, then just return empty matrices //and put n in nCard. That way, if called again, the function will //start from the beginning. if(lastPassed==true) { mxDestroyArray(codeArray); plhs[0]=mxCreateDoubleMatrix(0, 0, mxREAL); if(nlhs>1) { mxArray *nCardMat=allocUnsignedSizeMatInMatlab(1, 1); *(size_t*)mxGetData(nCardMat)=n; plhs[1]=nCardMat; if(nlhs>2) { //This is isLast plhs[2]=mxCreateDoubleMatrix(0, 0, mxREAL);; if(nlhs>3) { //This is j plhs[3]=mxCreateDoubleMatrix(0, 0, mxREAL);; } } } return; } //Set the return values for the case when the last code was not passed. plhs[0]=codeArray; if(nlhs>1) { mxArray *nCardMat=allocUnsignedSizeMatInMatlab(1, 1); *(size_t*)mxGetData(nCardMat)=nCard; plhs[1]=nCardMat; if(nlhs>2) { //This is isLast plhs[2]=mxCreateLogicalScalar(isLast); if(nlhs>3) { mxArray *jMat=allocUnsignedSizeMatInMatlab(1, 1); //Increment j to be an index for Matlab. j++; *(size_t*)mxGetData(jMat)=j; plhs[3]=jMat; } } } }