void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mxArray **analyticFnParam; mxArray *aRandVec, *aRandVecN; mxArray *aRandParam; double *pRandParam, *randU, *randN; mxArray *pointsM, *weightsM, *indicesM; double *points, *weights; BallTree::index* indices; unsigned int i; unsigned int Niter,Ndens,Ndim,Np; /********************************************************************* ** Verify arguments and initialize variables *********************************************************************/ if (nrhs < 3) mexErrMsgTxt("Takes 3-5 input arguments"); if (nlhs != 2) mexErrMsgTxt("Outputs 2 results"); Ndens = mxGetN(prhs[0]); // get # of densities /********************************************************************* ** Transform Matlab cell arrays into struct NPD representation *********************************************************************/ BallTreeDensity *trees = new BallTreeDensity[Ndens]; bool allGaussians = true; for (i=0; i < Ndens; i++) { trees[i] = BallTreeDensity( mxGetCell(prhs[0],i) ); if (trees[i].getType() != BallTreeDensity::Gaussian) allGaussians = false; } if (!allGaussians) mexErrMsgTxt("Sorry -- only Gaussian kernels supported"); Ndim = trees[0].Ndim(); // # of dimensions Np = (unsigned long) mxGetScalar(prhs[1]); // # of points to sample Niter = (unsigned int) mxGetScalar(prhs[2]); // # of gibbs iterations if ((nrhs < 5) || (mxGetN(prhs[3]) == 0)) { // load analytic function analyticFnParam = NULL; // params if required } else { analyticFnParam = (mxArray**) mxMalloc(3*sizeof(mxArray*)); analyticFnParam[0] = (mxArray*) prhs[3]; analyticFnParam[1] = (mxArray*) prhs[4]; } pointsM = plhs[0] = mxCreateDoubleMatrix(Ndim, Np, mxREAL); // set up matlab output points = (double*) mxGetData(plhs[0]); // plhs[1] = mxCreateDoubleMatrix(1, Np, mxREAL); // weights = (double*) mxGetData(plhs[1]); plhs[1] = mxCreateNumericMatrix(Ndens, Np, mxUINT32_CLASS, mxREAL); indices = (BallTree::index*) mxGetData(plhs[1]); unsigned long maxNp = Np; // largest # of particles we deal with for (unsigned int j=0; j<Ndens; j++) // compute Max Np over all densities if (maxNp < trees[j].Npts()) maxNp = trees[j].Npts(); unsigned int Nlevels = (unsigned int) (log((double)maxNp)/log((double)2))+1; // how many levels to a balanced binary tree? // Generate enough random numbers to get us through the rest of this aRandParam = mxCreateDoubleMatrix(1, 2, mxREAL); pRandParam = mxGetPr(aRandParam); pRandParam[0] = 1; pRandParam[1] = Np*Ndens*(Niter+1)*Nlevels; mexCallMATLAB(1, &aRandVec, 1, &aRandParam, "rand"); randU = mxGetPr(aRandVec); pRandParam[0] = 1; pRandParam[1] = Ndim*Np*(Niter+1)*Nlevels; mexCallMATLAB(1, &aRandVecN, 1, &aRandParam, "randn"); randN = mxGetPr(aRandVecN); mxDestroyArray(aRandParam); // Params: Ndens, trees, points, weights, indices, randomU, randomN gibbs2(Ndens,trees,Np,Niter,points,indices, randU,randN); delete[] trees; if (analyticFnParam != NULL) mxFree(analyticFnParam); mxDestroyArray(aRandVec); mxDestroyArray(aRandVecN); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i,j, k, status,buflen,Cnt, Hndl, L,M,N, NumHandles, commandswitch; int *HndlArray; mxArray *mymxArray; double *myDblPr; chtype RequestType; char PVName[PV_NAME_LENGTH_MAX+1]; // char MCAMessageString[MCA_MESSAGE_STRING_LENGTH_MAX+1]; dbr_string_t StrBuffer; const char *MCAInfoFields[]={"PVName","ElementCount","NativeType","State","MCAMessage","Host"}; char *NativeTypeStrings[] = {"STRING","INT","FLOAT","ENUM","CHAR","LONG","DOUBLE"}; if(!CA_INITIALIZED) // Initialize CA if not initialized (first call) { mexPrintf("Initializing MATLAB Channel Access ... \n"); status = ca_task_initialize(); if(status!=ECA_NORMAL) mexErrMsgTxt("Unable to initialise Challel Access\n"); CA_INITIALIZED = true; // Register a function to be called when a this mex-file is cleared from memory // with 'clear' or when exitting MATLAB mexAtExit(mca_cleanup); // Lock the mex-file so that it can not be cleared without explicitly // mexUnclock mexLock(); //start periodic polling: /* PollTimerHandle = SetTimer(NULL,NULL,MCA_POLL_PERIOD,background_poll); if(PollTimerHandle) mexPrintf("Periodic CA polling started! System Timer ID: %u\n",PollTimerHandle); else mexWarnMsgTxt("Failed to start periodic CA polling\n"); */ } commandswitch = (int)mxGetScalar(prhs[0]); switch(commandswitch) { case 0: mexUnlock(); break; case 1: // MCAOPEN - add channel(s) by PV names, all arguments following prhs[0] // must be strings - names of PV's for(i=1;i<nrhs;i++) { mxGetString(prhs[i],PVName,PV_NAME_LENGTH_MAX+1); status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID)); if(status == ECA_NORMAL) // if not - go on to the next PV name { status = ca_pend_io(MCA_SEARCH_TIMEOUT); if (status == ECA_NORMAL) { // Allocate persistent memory for the DataBuffer on this channel // to hold all elements of the DBR_XXX type // nearest to the native type // RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); // Cnt=ca_element_count(CHNLS[HandlesUsed].CHID); CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID); CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); CHNLS[HandlesUsed].MonitorEventCount = 0; switch(CHNLS[HandlesUsed].NativeType2DBR) { case DBR_STRING: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t)); break; case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_FLOAT: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); break; case DBR_ENUM: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); break; case DBR_CHAR: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); break; case DBR_LONG: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_DOUBLE: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); break; } mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer); if(CHNLS[HandlesUsed].NativeType2DBR==DBR_STRING) // CACHE { if(CHNLS[HandlesUsed].NumElements==1) // Create MATLAB string - originally empty CHNLS[HandlesUsed].CACHE = mxCreateString(""); else // Create MATLAB cell array of strings { CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements); for(k=0;k<CHNLS[HandlesUsed].NumElements;k++) { mymxArray = mxCreateString(""); mexMakeArrayPersistent(mymxArray); mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray); } } } else // Make CACHE a numeric mxArray { CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL); } mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE); plhs[i-1]=mxCreateScalarDouble(++HandlesUsed); } else plhs[i-1]=mxCreateScalarDouble(0); } else plhs[i-1]=mxCreateScalarDouble(0); } break; case 2:// MCAOPEN - add channel(s) by PV names. The arguments following prhs[0] // argument must be a cell array of strings - PV names L = mxGetM(prhs[1])*mxGetN(prhs[1]); plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<L;i++) { mymxArray = mxGetCell(prhs[1],i); mxGetString(mymxArray,PVName,PV_NAME_LENGTH_MAX+1); status = ca_search(PVName,&(CHNLS[HandlesUsed].CHID)); if(status == ECA_NORMAL) // if not - go on to the next PV name { status = ca_pend_io(MCA_IO_TIMEOUT); if (status == ECA_NORMAL) { // Allcate persistent memory for the DataBuffer on this channel //RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); CHNLS[HandlesUsed].NativeType2DBR = dbf_type_to_DBR(ca_field_type(CHNLS[HandlesUsed].CHID)); CHNLS[HandlesUsed].NumElements = ca_element_count(CHNLS[HandlesUsed].CHID); CHNLS[HandlesUsed].MonitorEventCount = 0; //Cnt=ca_element_count(CHNLS[HandlesUsed].CHID); switch(CHNLS[HandlesUsed].NativeType2DBR) { case DBR_STRING: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_string_t)); break; case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_FLOAT: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_float_t)); break; case DBR_ENUM: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_enum_t)); break; case DBR_CHAR: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_char_t)); break; case DBR_LONG: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_short_t)); break; case DBR_DOUBLE: CHNLS[HandlesUsed].DataBuffer = mxCalloc(CHNLS[HandlesUsed].NumElements,sizeof(dbr_double_t)); break; } mexMakeMemoryPersistent(CHNLS[HandlesUsed].DataBuffer); if(CHNLS[HandlesUsed].NativeType2DBR == DBR_STRING) // CACHE { CHNLS[HandlesUsed].CACHE = mxCreateCellMatrix(1,CHNLS[HandlesUsed].NumElements); for(k=0;k<CHNLS[HandlesUsed].NumElements;k++) { mymxArray = mxCreateString(StrBuffer); mexMakeArrayPersistent(mymxArray); mxSetCell(CHNLS[HandlesUsed].CACHE, k, mymxArray); } } else { CHNLS[HandlesUsed].CACHE = mxCreateDoubleMatrix(1,CHNLS[HandlesUsed].NumElements,mxREAL); } mexMakeArrayPersistent(CHNLS[HandlesUsed].CACHE); myDblPr[i] = ++HandlesUsed; } else myDblPr[i] = 0; } else myDblPr[i] = 0; } break; case 3: // MCAOPEN Return names of connected channels as cell array of strings plhs[0] = mxCreateCellArray(1, &HandlesUsed); for(i=0;i<HandlesUsed;i++) { if(CHNLS[i].CHID!=NULL) { mymxArray = mxCreateString(ca_name(CHNLS[i].CHID)); mxSetCell(plhs[0], i, mymxArray); } else { mymxArray = mxCreateString(""); //mexPrintf("Handle: %d PV: %s\n",i+1, "Cleared Channel"); mxSetCell(plhs[0], i, mymxArray); } } break; case 5: // MCACLOSE permanently clear channel Hndl = (int)mxGetScalar(prhs[1]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range"); // If a monitor is installed, set the EVID pointer to NULL // ca_clear_event dos not do it by itself if(CHNLS[Hndl-1].EVID) CHNLS[Hndl-1].EVID = NULL; // If there is Callback String - destroy it if(CHNLS[Hndl-1].MonitorCBString) { mxFree(CHNLS[Hndl-1].MonitorCBString); CHNLS[Hndl-1].MonitorCBString =NULL; } if(ca_state(CHNLS[Hndl-1].CHID)==3) mexWarnMsgTxt("Channel previously cleared"); else if(ca_clear_channel(CHNLS[Hndl-1].CHID)!=ECA_NORMAL) mexErrMsgTxt("ca_clear_channel failed"); break; case 10: // MCAINFO return channels info as MATLAB structure array if(HandlesUsed>0) { plhs[0] = mxCreateStructMatrix(1,HandlesUsed,6,MCAInfoFields); for(i=0;i<HandlesUsed;i++) { mxSetFieldByNumber(plhs[0],i,0,mxCreateString(ca_name(CHNLS[i].CHID))); mxSetFieldByNumber(plhs[0],i,1,mxCreateScalarDouble(ca_element_count(CHNLS[i].CHID))); mxSetFieldByNumber(plhs[0],i,5,mxCreateString(ca_host_name(CHNLS[i].CHID))); switch(ca_state(CHNLS[i].CHID)) { case 1: // Disconnected due to Server or Network - may reconnect mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Disconnected due to server or network problem")); break; case 2: // Normal connection mxSetFieldByNumber(plhs[0],i,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[i].CHID)])); mxSetFieldByNumber(plhs[0],i,3,mxCreateString("connected")); mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Normal connection")); break; case 3: // Disconnected by user mxSetFieldByNumber(plhs[0],i,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],i,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],i,4,mxCreateString("Permanently disconnected (cleared) by the user")); break; } } } else { mexWarnMsgTxt("No connected PV's found"); plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); } break; case 11: // MCAINFO return info for 1 channel by handle number Hndl = (int)mxGetScalar(prhs[1]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range"); plhs[0] = mxCreateStructMatrix(1,1,6,MCAInfoFields); mxSetFieldByNumber(plhs[0],0,0,mxCreateString(ca_name(CHNLS[Hndl-1].CHID))); mxSetFieldByNumber(plhs[0],0,1,mxCreateScalarDouble(ca_element_count(CHNLS[Hndl-1].CHID))); mxSetFieldByNumber(plhs[0],0,5,mxCreateString(ca_host_name(CHNLS[Hndl-1].CHID))); switch(ca_state(CHNLS[Hndl-1].CHID)) { case 1: // Disconnected due to Server or Network - may reconnect mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Disconnected due to server or network problem")); break; case 2: // Normal connection mxSetFieldByNumber(plhs[0],0,2,mxCreateString(NativeTypeStrings[ca_field_type(CHNLS[Hndl-1].CHID)])); mxSetFieldByNumber(plhs[0],0,3,mxCreateString("connected")); mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Normal connection")); break; case 3: // Disconnected by user mxSetFieldByNumber(plhs[0],0,2,mxCreateString("unknown")); mxSetFieldByNumber(plhs[0],0,3,mxCreateString("disconnected")); mxSetFieldByNumber(plhs[0],0,4,mxCreateString("Permanently disconnected (cleared) by the user")); break; }; break; case 12: // MCASTATE return an array of status (1 - OK, 0 - disconnected or cleared) if(HandlesUsed>0) { plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<HandlesUsed;i++) myDblPr[i] = (double)(ca_state(CHNLS[i].CHID)==2); } else { mexWarnMsgTxt("No connected PV's found"); plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); } break; case 30: // poll ca_poll(); break; case 50: // MCAGET Get PV values by their MCA handles for(i=0;i<nrhs-1;i++) // First loop: place all ca_get requests in the buffer { Hndl = (int)mxGetScalar(prhs[1+i]); //start from[1]: [0] argument is the commnads switch if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Invalid Handle"); RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); Cnt = ca_element_count(CHNLS[Hndl-1].CHID); status = ca_array_get(RequestType,Cnt,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer); if(status!=ECA_NORMAL) mexPrintf("Error in call to ca_array_get\n"); } status = ca_pend_io(MCA_GET_TIMEOUT); if(status!=ECA_NORMAL) mexErrMsgTxt("... ca_pend_io call timed out \n"); for(i=0;i<nrhs-1;i++) // Another loop to copy data from temp structures to MATLAB { Hndl = (int)mxGetScalar(prhs[1+i]); RequestType = RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); Cnt = ca_element_count(CHNLS[Hndl-1].CHID); if(RequestType==DBR_STRING) { if(Cnt==1) plhs[i] = mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)))); else { plhs[i] = mxCreateCellMatrix(1,Cnt); for(j=0;j<Cnt;j++) mxSetCell(plhs[i], j, mxCreateString((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+j)))); } } else { plhs[i] = mxCreateDoubleMatrix(1,Cnt,mxREAL); myDblPr = mxGetPr(plhs[i]); switch(dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID))) { case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_FLOAT: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_ENUM: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_CHAR: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_LONG: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; case DBR_DOUBLE: for(j=0;j<Cnt;j++) myDblPr[j]= (double)(*((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+j)); break; } } } break; case 51: // MCAGET Get scalar PV of the same type // second argument is an array of handles // returns an array of values myDblPr = mxGetPr(prhs[1]); M = mxGetM(prhs[1]); N = mxGetN(prhs[1]); NumHandles = M*N; plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL); for(i=0;i<NumHandles;i++) // First loop: place all ca_get requests in the buffer { Hndl = (int)myDblPr[i]; if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Invalid Handle"); RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); status = ca_array_get(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(plhs[0])+i); if(status!=ECA_NORMAL) mexPrintf("Error in call to ca_array_get\n"); } status = ca_pend_io(MCA_GET_TIMEOUT); if(status!=ECA_NORMAL) mexErrMsgTxt("... ca_pend_io call timed out \n"); break; case 70: // MCAPUT NumHandles = (nrhs-1)/2; for(i=0;i<NumHandles;i++) { j = 2+i*2; Hndl = (int)mxGetScalar(prhs[1+i*2]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range - no values written"); // Set the status to 0 - mcaput_callback will write 1, if successful CHNLS[Hndl-1].LastPutStatus = 0; RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); Cnt = ca_element_count(CHNLS[Hndl-1].CHID); // If a value to write is passed as a string - the number of elements to write // is 1 , NOT the length of the string returned by mxGetNumberOfElements if(mxIsChar(prhs[j])) L=1; else L = min(mxGetNumberOfElements(prhs[j]),Cnt); // Copy double or string data from MATLAB prhs[] to DataBuffer // on each channel if(RequestType==DBR_STRING) { // STRING type is is passed as a cell array of strings // A a 1-row MATLAB character array (1 string) may also be passed as a value if(mxIsChar(prhs[j])) { mxGetString(prhs[j], StrBuffer, sizeof(dbr_string_t)); strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer))),StrBuffer); } else if(mxIsCell(prhs[j])) { for(k=0;k<L;k++) { mxGetString(mxGetCell(prhs[j],k), StrBuffer, sizeof(dbr_string_t)); strcpy((char*)(*((dbr_string_t*)(CHNLS[Hndl-1].DataBuffer)+k)),StrBuffer); } } } else { myDblPr = mxGetPr(prhs[j]); switch(RequestType) { case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 for(k=0;k<L;k++) *((dbr_short_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_short_t)(myDblPr[k]); break; case DBR_FLOAT: for(k=0;k<L;k++) *((dbr_float_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_float_t)(myDblPr[k]); break; case DBR_ENUM: for(k=0;k<L;k++) *((dbr_enum_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_enum_t)(myDblPr[k]); break; case DBR_CHAR: for(k=0;k<L;k++) *((dbr_char_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_char_t)(myDblPr[k]); break; case DBR_LONG: for(k=0;k<L;k++) *((dbr_long_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_long_t)(myDblPr[k]); break; case DBR_DOUBLE: for(k=0;k<L;k++) *((dbr_double_t*)(CHNLS[Hndl-1].DataBuffer)+k) = (dbr_double_t)(myDblPr[k]); break; } } // place request in the que status = ca_array_put_callback(RequestType,L,CHNLS[Hndl-1].CHID,CHNLS[Hndl-1].DataBuffer, mcaput_callback,&(CHNLS[Hndl-1].LastPutStatus)); if(status!=ECA_NORMAL) mexPrintf("ca_array_put_callback failed\n"); } status = ca_pend_event(MCA_PUT_TIMEOUT); plhs[0]=mxCreateDoubleMatrix(1,NumHandles,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<NumHandles;i++) { Hndl = (int)mxGetScalar(prhs[1+i*2]); myDblPr[i] = (double)CHNLS[Hndl-1].LastPutStatus; } break; case 80: // MCAPUT - fast unconfirmed put for scalar numeric PV's myDblPr = mxGetPr(prhs[1]); M = mxGetM(prhs[1]); N = mxGetN(prhs[1]); NumHandles = M*N; plhs[0] = mxCreateDoubleMatrix(M,N,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<NumHandles;i++) { myDblPr = mxGetPr(plhs[0]); Hndl = (int)(*(mxGetPr(prhs[1])+i)); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Handle out of range - no values written"); status = ca_array_put(DBR_DOUBLE,1,CHNLS[Hndl-1].CHID,mxGetPr(prhs[2])+i); if(status!=ECA_NORMAL) { myDblPr[i] = 0; //mexPrintf("ca_array_put_callback failed\n"); } else { myDblPr[i] = 1; } } status = ca_pend_io(MCA_PUT_TIMEOUT); break; case 100: // MCAMON install Monitor or replace MonitorCBString Hndl = (int)mxGetScalar(prhs[1]); // Check if the handle is within range if(Hndl<1 || Hndl>HandlesUsed) { plhs[0]=mxCreateScalarDouble(0); mexErrMsgTxt("Invalid Handle"); } if(CHNLS[Hndl-1].EVID) // if VID is not NULL - another monitor is already installed - replace MonitorCBString { if(CHNLS[Hndl-1].MonitorCBString) // Free memory for occupied by the old MonitorCBString { mxFree(CHNLS[Hndl-1].MonitorCBString); CHNLS[Hndl-1].MonitorCBString = NULL; } if(nrhs>2) // Check if the new string is specified { if(mxIsChar(prhs[2])) { buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1; CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen); mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString); mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); } else mexErrMsgTxt("Third argument must be a string\n"); } plhs[0]=mxCreateScalarDouble(1); } else // No monitor is presently installed; { RequestType = dbf_type_to_DBR(ca_field_type(CHNLS[Hndl-1].CHID)); // Closest to the native if(nrhs>2) { if(mxIsChar(prhs[2])) { buflen = mxGetM(prhs[2])*mxGetN(prhs[2])+1; CHNLS[Hndl-1].MonitorCBString = (char *)mxMalloc(buflen); mexMakeMemoryPersistent(CHNLS[Hndl-1].MonitorCBString); mxGetString(prhs[2],CHNLS[Hndl-1].MonitorCBString,buflen); } else mexErrMsgTxt("Third argument must be a string\n"); } else CHNLS[Hndl-1].MonitorCBString = NULL; // Set MonitorCBString to NULL so that mcaMonitorEventHandler only copies data to CACHE // Count argument set to 0 - native count status = ca_add_array_event(RequestType,0,CHNLS[Hndl-1].CHID, mcaMonitorEventHandler, &CHNLS[Hndl-1], 0.0, 0.0, 0.0, &(CHNLS[Hndl-1].EVID)); if(status!=ECA_NORMAL) { mexPrintf("ca_add_array_event failed\n"); plhs[0]=mxCreateScalarDouble(0); } else { ca_poll(); plhs[0]=mxCreateScalarDouble(1); } } break; case 200: // Clear Monitor MCACLEARMON Hndl = (int)mxGetScalar(prhs[1]); if(Hndl<1 || Hndl>HandlesUsed) mexErrMsgTxt("Invalid Handle"); if(!CHNLS[Hndl-1].EVID) mexErrMsgTxt("No monitor installed - can not clear"); status = ca_clear_event(CHNLS[Hndl-1].EVID); if(status!=ECA_NORMAL) mexPrintf("ca_clear_event failed\n"); // Set the EVID pointer to NULL (ca_clear_event dos not do it by itself) // to use as a FLAG that no monitors are installed CHNLS[Hndl-1].EVID = NULL; // Reset CHNLS[Hndl-1].MonitorEventCount = 0; // If there is Callback String - destroy it if(CHNLS[Hndl-1].MonitorCBString) { mxFree(CHNLS[Hndl-1].MonitorCBString); CHNLS[Hndl-1].MonitorCBString =NULL; } break; case 300: // MCACACHE Get Cached values of a monitored PV for(i=0;i<nrhs-1;i++) { Hndl = (int)mxGetScalar(prhs[1+i]); // if(Hndl<1 || Hndl>HandlesUsed || !CHNLS[Hndl-1].CACHE) if(Hndl<1 || Hndl>HandlesUsed) plhs[i] = mxCreateDoubleMatrix(0,0,mxREAL); else { plhs[i] = mxDuplicateArray(CHNLS[Hndl-1].CACHE); CHNLS[Hndl-1].MonitorEventCount = 0; } } break; case 500: // MCAMON Info on installed monitors L = 0; HndlArray = (int*)mxCalloc(HandlesUsed,sizeof(int)); for(i=0;i<HandlesUsed;i++) // Count installed monitors { if(CHNLS[i].EVID) HndlArray[L++]=i+1; } if(L>0) { plhs[0] = mxCreateDoubleMatrix(1,L,mxREAL); myDblPr = mxGetPr(plhs[0]); plhs[1] = mxCreateCellMatrix(1,L); for(i=0;i<L;i++) { myDblPr[i] = (double)HndlArray[i]; mxSetCell(plhs[1],i,mxCreateString(CHNLS[HndlArray[i]-1].MonitorCBString)); } } else { plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); plhs[1] = mxCreateCellMatrix(0,0); } break; case 510: // MCAMONEVENTS Event count fot monitors plhs[0] = mxCreateDoubleMatrix(1,HandlesUsed,mxREAL); myDblPr = mxGetPr(plhs[0]); for(i=0;i<HandlesUsed;i++) myDblPr[i]=(double)(CHNLS[i].MonitorEventCount); break; case 1000: // print timeout settings plhs[0] = mxCreateDoubleMatrix(3,1,mxREAL); mexPrintf("MCA timeout settings\n:"); mexPrintf("mcaopen\t%f [s]\n", MCA_SEARCH_TIMEOUT ); mexPrintf("mcaget\t%f [s]\n", MCA_GET_TIMEOUT ); mexPrintf("mcaput\t%f [s]\n", MCA_PUT_TIMEOUT ); myDblPr = mxGetPr(plhs[0]); myDblPr[0] = MCA_SEARCH_TIMEOUT; myDblPr[1] = MCA_GET_TIMEOUT; myDblPr[2] = MCA_PUT_TIMEOUT; break; case 1001: // set MCA_SEARCH_TIMEOUT // return delay value MCA_SEARCH_TIMEOUT = mxGetScalar(prhs[1]); plhs[0] = mxCreateScalarDouble(MCA_SEARCH_TIMEOUT); break; case 1002: // set MCA_GET_TIMEOUT // return delay value MCA_GET_TIMEOUT = mxGetScalar(prhs[1]); plhs[0] = mxCreateScalarDouble(MCA_GET_TIMEOUT); break; case 1003: // set MCA_PUT_TIMEOUT // return delay value MCA_PUT_TIMEOUT = mxGetScalar(prhs[1]); plhs[0] = mxCreateScalarDouble(MCA_PUT_TIMEOUT); break; } }
bool mat_load_multi_array_vec2(MATFile *f, QString qsVarName, std::vector<std::vector<Array> > &vvA) { const char *name = 0; bool bRes = false; vvA.clear(); if (f != 0) { mxArray *matlab_mat = matGetNextVariable(f, &name); std::cout << name << std::endl; bool bLoaded = false; while (matlab_mat != 0 && !bLoaded) { if (qsVarName == name) { if (mxIsCell(matlab_mat)) { mwSize cell_ndim = mxGetNumberOfDimensions(matlab_mat); const mwSize *cell_dims = mxGetDimensions(matlab_mat); //std::cout << "number of cell dimensions: " << cell_ndim << endl; assert(cell_ndim == 2); for (int dim_idx = 0; dim_idx < 2; ++dim_idx) { std::cout << "extent of cell dim " << dim_idx << ": " << cell_dims[dim_idx] << std::endl; } uint N1 = cell_dims[0]; uint N2 = cell_dims[1]; //vvA.resize(N1, std::vector<Array>(N2, Array())); for (uint i1 = 0; i1 < N1; ++i1) { vvA.push_back(std::vector<Array>()); for (uint i2 = 0; i2 < N2; ++i2) { /* get dimensions of the current cell */ mwIndex subs[2]; subs[0] = i1; subs[1] = i2; mwIndex cell_idx = mxCalcSingleSubscript(matlab_mat, cell_ndim, subs); mxArray *E = mxGetCell(matlab_mat, cell_idx); mwSize mat_ndim = mxGetNumberOfDimensions(E); const mwSize *mat_dims = mxGetDimensions(E); //std::cout << "number of cell element dimensions: " << mat_ndim << endl; assert(mat_ndim == Array::dimensionality); /* copy from matlab matrix to Array */ boost::array<typename Array::size_type, Array::dimensionality> array_shape; for (uint i = 0; i < Array::dimensionality; ++i) array_shape[i] = mat_dims[i]; Array B(array_shape, boost::fortran_storage_order()); uint nElements = B.num_elements(); if (nElements > 0) { typename Array::element *data2 = B.data(); if (mxIsSingle(E)) { float *pE = (float *)mxGetPr(E); assert(pE != 0); for (uint i = 0; i < nElements; ++i) { *(data2 + i) = *pE; ++pE; } } else { double *pE = mxGetPr(E); assert(pE != 0); for (uint i = 0; i < nElements; ++i) { *(data2 + i) = *pE; ++pE; } } //vvA[i1][i2] = B; /* copy to array with normal storage order */ // Array A = B; // this does not work!!! (storage order is of course copied at construction :) Array A(array_shape); A = B; vvA.back().push_back(A); } } }// cell elements bRes = true; }// is cell else { std::cout << "variable is not a cell array" << std::endl; } bLoaded = true; } mxDestroyArray(matlab_mat); matlab_mat = 0; if (!bLoaded) matlab_mat = matGetNextVariable(f, &name); }// variables } assert(bRes && "variable not found or could not open file"); return bRes; }
// 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); } }
/* The matlab mex function */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* Vertex list input */ double *V; /* Neighbour list input */ const mxArray *Ne; mxArray *PneigMatlab; mwSize *PneigDims; int PneigLenght=0; /* Outputs */ double *ET_table; /* Edge tangents table */ double *EV_table; /* Edge velocity */ double *ETV_index; /* Edge tangents/velocity index for tables */ double Ea, Eb, Ec, s, h, x, Tb3D_length, Vv; double Np[3], Ns[3], Tb[3], Pm[3], X3[3], Y3[3], Tb3D[3]; double *Pn, *Pnop, *Pneig; /* Current vertex */ double P[3]={0,0,0}; /* Table Size */ mwSize table_Dims[2]={1,3}; /* Number of vertices */ const mwSize *VertexDims; int VertexN=0; /* Number of indices */ int ETV_num=0; /* Neighbour indices */ double neg; int neg1, neg2; /* Loop variables */ int i, j, k; /* Check for proper number of arguments. */ if(nrhs!=2) { mexErrMsgTxt("2 inputs are required."); } else if(nlhs!=3) { mexErrMsgTxt("3 output is required"); } /* Connect Inputs */ V=(double *)mxGetPr(prhs[0]); Ne=prhs[1]; /* Get number of VertexN */ VertexDims = mxGetDimensions(prhs[0]); VertexN=VertexDims[0]; /* Reserve memory */ table_Dims[0]=VertexN*6; table_Dims[1]=3; plhs[0]= mxCreateNumericArray(2, table_Dims, mxDOUBLE_CLASS, mxREAL); table_Dims[0]=VertexN*6; table_Dims[1]=1; plhs[1]= mxCreateNumericArray(2, table_Dims, mxDOUBLE_CLASS, mxREAL); table_Dims[0]=VertexN*6; table_Dims[1]=2; plhs[2] = mxCreateNumericArray(2, table_Dims, mxDOUBLE_CLASS, mxREAL); /* Connect Outputs */ ET_table=(double *)mxGetPr(plhs[0]); EV_table=(double *)mxGetPr(plhs[1]); ETV_index=(double *)mxGetPr(plhs[2]); Pn= (double *)malloc(VertexN*3*sizeof(double)); Pnop=(double *) malloc(VertexN*3*sizeof(double)); for (i=0; i<VertexN; i++) { P[0]=V[i]; P[1]=V[i+VertexN]; P[2]=V[i+VertexN*2]; PneigMatlab=mxGetCell(Ne, i); if( PneigMatlab == NULL) { PneigLenght=-1; } else { PneigDims=(mwSize *)mxGetDimensions(PneigMatlab); PneigLenght=(PneigDims[0]*PneigDims[1]); Pneig=(double *)mxGetPr(PneigMatlab); } /* Find the opposite vertex of each neigbourh vertex. */ /* incase of odd number of neigbourhs interpolate the opposite neigbourh */ if((PneigLenght%2)==0) { for (k=0; k<PneigLenght; k++) { neg =k+((double)PneigLenght)/2; neg1=(int)floor(neg); if(neg1>(PneigLenght-1)) { neg1=neg1-PneigLenght; } Pn[k] =V[(int)Pneig[k]-1]; Pn[k+VertexN] =V[(int)Pneig[k]-1+VertexN]; Pn[k+VertexN*2]=V[(int)Pneig[k]-1+VertexN*2]; Pnop[k] =V[(int)Pneig[neg1]-1]; Pnop[k+VertexN] =V[(int)Pneig[neg1]-1+VertexN]; Pnop[k+VertexN*2]=V[(int)Pneig[neg1]-1+VertexN*2]; } } else { for (k=0; k<PneigLenght; k++) { neg=(double)k+((double)PneigLenght)*0.5; neg1=(int)floor(neg); neg2=(int)ceil(neg); if(neg1>(PneigLenght-1)) { neg1=neg1-PneigLenght; } if(neg2>(PneigLenght-1)) { neg2=neg2-PneigLenght; } Pn[k] =V[(int)Pneig[k]-1]; Pn[k+VertexN] =V[(int)Pneig[k]-1+VertexN]; Pn[k+VertexN*2]=V[(int)Pneig[k]-1+VertexN*2]; Pnop[k] =(V[(int)Pneig[neg1]-1] + V[(int)Pneig[neg2]-1])/2; Pnop[k+VertexN] =(V[(int)Pneig[neg1]-1+VertexN] + V[(int)Pneig[neg2]-1+VertexN])/2; Pnop[k+VertexN*2]=(V[(int)Pneig[neg1]-1+VertexN*2] + V[(int)Pneig[neg2]-1+VertexN*2])/2; } } for(j=0;j<PneigLenght; j++) { /* Calculate length edges of face */ Ec= sqrt(pow2(Pn[j]-P[0]) +pow2(Pn[j+VertexN]-P[1]) +pow2(Pn[j+VertexN*2]-P[2]))+1e-14; Eb= sqrt(pow2(Pnop[j]-P[0]) +pow2(Pnop[j+VertexN]-P[1]) +pow2(Pnop[j+VertexN*2]-P[2]))+1e-14; Ea= sqrt(pow2(Pn[j]-Pnop[j])+pow2(Pn[j+VertexN]-Pnop[j+VertexN]) +pow2(Pn[j+VertexN*2]-Pnop[j+VertexN*2]))+1e-14; /* Calculate face surface area */ s = ((Ea+Eb+Ec)/2); h = (2/Ea)*sqrt(s*(s-Ea)*(s-Eb)*(s-Ec))+1e-14; x = (pow2(Ea)-pow2(Eb)+pow2(Ec))/(2*Ea); /* Calculate tangent of 2D triangle */ Np[0]=-h / sqrt(pow2(-h)+pow2(x)); Np[1]= x / sqrt(pow2(-h)+pow2(x)); Ns[0]=h / sqrt(pow2(h)+pow2(Ea-x)); Ns[1]=(Ea-x) / sqrt(pow2(h)+pow2(Ea-x)); Tb[0]= Np[1]+Ns[1] ; Tb[1]=-(Np[0]+Ns[0]); /* Back to 3D coordinates */ Pm[0]=(Pn[j]*x+Pnop[j]*(Ea-x))/Ea; Pm[1]=(Pn[j+VertexN]*x+Pnop[j+VertexN]*(Ea-x))/Ea; Pm[2]=(Pn[j+VertexN*2]*x+Pnop[j+VertexN*2]*(Ea-x))/Ea; X3[0]=(Pn[j]-Pnop[j])/Ea; X3[1]=(Pn[j+VertexN]-Pnop[j+VertexN])/Ea; X3[2]=(Pn[j+VertexN*2]-Pnop[j+VertexN*2])/Ea; Y3[0]=(P[0]-Pm[0])/h; Y3[1]=(P[1]-Pm[1])/h; Y3[2]=(P[2]-Pm[2])/h; /* 2D tangent to 3D tangent */ Tb3D[0]=(X3[0]*Tb[0]+Y3[0]*Tb[1]); Tb3D[1]=(X3[1]*Tb[0]+Y3[1]*Tb[1]); Tb3D[2]=(X3[2]*Tb[0]+Y3[2]*Tb[1]); Tb3D_length=sqrt(pow2(Tb3D[0])+pow2(Tb3D[1])+pow2(Tb3D[2]))+1e-14; Tb3D[0]=Tb3D[0]/Tb3D_length; Tb3D[1]=Tb3D[1]/Tb3D_length; Tb3D[2]=Tb3D[2]/Tb3D_length; /* Edge Velocity */ Vv=0.5*(Ec+0.5*Ea); /* Store the data */ ETV_index[ETV_num]=i+1; ETV_index[ETV_num+table_Dims[0]]=Pneig[j]; ET_table[ETV_num]=Tb3D[0]; ET_table[ETV_num+table_Dims[0]]=Tb3D[1]; ET_table[ETV_num+2*table_Dims[0]]=Tb3D[2]; EV_table[ETV_num]=Vv; ETV_num++; } } /* Remove temporary memory */ free(Pn); free(Pnop); }
void LTFAT_NAME(ltfatMexFnc)( int UNUSED(nlhs), mxArray *plhs[], int UNUSED(nrhs), const mxArray *prhs[] ) { static int atExitFncRegistered = 0; if(!atExitFncRegistered) { LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(fftblMexAtExitFnc)); atExitFncRegistered = 1; } const mxArray* mxF = prhs[0]; const mxArray* mxG = prhs[1]; double* foffDouble = (double*) mxGetData(prhs[2]); double* a = (double*) mxGetData(prhs[3]); double* realonlyDouble = (double*) mxGetData(prhs[4]); // input data length mwSize L = mxGetM(mxF); // number of channels mwSize W = mxGetN(mxF); // filter number mwSize M = mxGetNumberOfElements(mxG); // mwSize acols = mxGetN(prhs[3]); double afrac[M]; memcpy(afrac,a,M*sizeof*a); if(acols>1) { for(mwIndex m=0; m<M; m++) { afrac[m] = afrac[m]/a[M+m]; } } // output lengths mwSize outLen[M]; // Frequency offsets mwSignedIndex foff[M]; // realonly int realonly[M]; // POINTER TO THE INPUT LTFAT_COMPLEX* FPtr = mxGetData(prhs[0]); // POINTER TO THE FILTERS const LTFAT_COMPLEX* GPtrs[M]; // filter lengths mwSize Gl[M]; // POINTER TO OUTPUTS LTFAT_COMPLEX* cPtrs[M]; // C99 feature plhs[0] = mxCreateCellMatrix(M, 1); if(M!=LTFAT_NAME(oldM) || W != LTFAT_NAME(oldW)) { LTFAT_NAME(fftblMexAtExitFnc)(); LTFAT_NAME(oldM) = M; LTFAT_NAME(oldW) = W; LTFAT_NAME(oldLc) = ltfat_calloc(M,sizeof(mwSize)); LTFAT_NAME(oldPlans) = ltfat_calloc(M,sizeof*LTFAT_NAME(oldPlans)); } for(mwIndex m=0; m<M; ++m) { foff[m] = (mwSignedIndex) foffDouble[m]; realonly[m] = (realonlyDouble[m]>1e-3); outLen[m] = (mwSize) floor( L/afrac[m] +0.5); GPtrs[m] = mxGetData(mxGetCell(mxG, m)); Gl[m] = mxGetNumberOfElements(mxGetCell(mxG, m)); mxSetCell(plhs[0], m, ltfatCreateMatrix(outLen[m], W, LTFAT_MX_CLASSID,mxCOMPLEX)); cPtrs[m] = mxGetData(mxGetCell(plhs[0],m)); if(LTFAT_NAME(oldLc)[m]!=outLen[m]) { LTFAT_NAME(oldLc)[m] = outLen[m]; LTFAT_NAME(convsub_fftbl_plan) ptmp = LTFAT_NAME(convsub_fftbl_init)( L, Gl[m], W, afrac[m], cPtrs[m]); if(LTFAT_NAME(oldPlans)[m]!=0) { LTFAT_NAME(convsub_fftbl_done)(LTFAT_NAME(oldPlans)[m]); } LTFAT_NAME(oldPlans)[m]=ptmp; } } LTFAT_NAME(filterbank_fftbl_execute)( LTFAT_NAME(oldPlans),FPtr, GPtrs, M, foff, realonly, cPtrs); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { mxArray *rhs[2]; mxArray *blk_cell_pr, *A_cell_pr; double *A, *B, *blksize; mwIndex *irA, *jcA, *irB, *jcB; mwIndex *cumblksize, *blknnz; mwSize iscellA, mblk, mA, nA, m1, n1, rowidx, colidx, isspA, isspB; mwIndex subs[2]; mwSize nsubs=2; mwSize n, n2, k, nsub, index, numblk, NZmax; double ir2=1/sqrt(2); /* CHECK FOR PROPER NUMBER OF ARGUMENTS */ if (nrhs < 2){ mexErrMsgTxt("mexsmat: requires at least 2 input arguments."); } else if (nlhs>1){ mexErrMsgTxt("mexsmat: requires 1 output argument."); } /* CHECK THE DIMENSIONS */ iscellA = mxIsCell(prhs[1]); if (iscellA) { mA = mxGetM(prhs[1]); nA = mxGetN(prhs[1]); } else { mA = 1; nA = 1; } if (mxGetM(prhs[0]) != mA) { mexErrMsgTxt("mexsmat: blk and Avec not compatible"); } /***** main body *****/ if (nrhs > 3) {rowidx = (mwSize)*mxGetPr(prhs[3]); } else {rowidx = 1;} if (rowidx > mA) { mexErrMsgTxt("mexsmat: rowidx exceeds size(Avec,1)."); } subs[0] = rowidx-1; /* subtract 1 to adjust for Matlab index */ subs[1] = 1; index = mxCalcSingleSubscript(prhs[0],nsubs,subs); blk_cell_pr = mxGetCell(prhs[0],index); if (blk_cell_pr == NULL) { mexErrMsgTxt("mexsmat: blk not properly specified"); } numblk = mxGetN(blk_cell_pr); blksize = mxGetPr(blk_cell_pr); cumblksize = mxCalloc(numblk+1,sizeof(mwSize)); blknnz = mxCalloc(numblk+1,sizeof(mwSize)); cumblksize[0] = 0; blknnz[0] = 0; n = 0; n2 = 0; for (k=0; k<numblk; ++k) { nsub = (mwSize) blksize[k]; n += nsub; n2 += nsub*(nsub+1)/2; cumblksize[k+1] = n; blknnz[k+1] = n2; } /***** assign pomwSizeers *****/ if (iscellA) { subs[0] = rowidx-1; subs[1] = 0; index = mxCalcSingleSubscript(prhs[1],nsubs,subs); A_cell_pr = mxGetCell(prhs[1],index); A = mxGetPr(A_cell_pr); m1 = mxGetM(A_cell_pr); n1 = mxGetN(A_cell_pr); isspA = mxIsSparse(A_cell_pr); if (isspA) { irA = mxGetIr(A_cell_pr); jcA = mxGetJc(A_cell_pr); } } else { A = mxGetPr(prhs[1]); m1 = mxGetM(prhs[1]); n1 = mxGetN(prhs[1]); isspA = mxIsSparse(prhs[1]); if (isspA) { irA = mxGetIr(prhs[1]); jcA = mxGetJc(prhs[1]); } } if (numblk > 1) { isspB = 1; } else { if (nrhs > 2) {isspB = (mwSize)*mxGetPr(prhs[2]);} else {isspB = isspA;} } if (nrhs > 4) {colidx = (mwSize)*mxGetPr(prhs[4]) -1;} else {colidx = 0;} if (colidx > n1) { mexErrMsgTxt("mexsmat: colidx exceeds size(Avec,2)."); } /***** create return argument *****/ if (isspB) { if (isspA) { NZmax = jcA[colidx+1]-jcA[colidx]; } else { NZmax = blknnz[numblk]; } rhs[0] = mxCreateSparse(n,n,2*NZmax,mxREAL); B = mxGetPr(rhs[0]); irB = mxGetIr(rhs[0]); jcB = mxGetJc(rhs[0]); } else { plhs[0] = mxCreateDoubleMatrix(n,n,mxREAL); B = mxGetPr(plhs[0]); } /***** Do the computations in a subroutine *****/ if (numblk == 1) { smat1(n,ir2,A,irA,jcA,isspA,m1,colidx,B,irB,jcB,isspB); } else { smat2(n,numblk,cumblksize,blknnz,ir2,A,irA,jcA,isspA,m1,colidx,B,irB,jcB,isspB); } if (isspB) { /*** if isspB, (actual B) = B+B' ****/ mexCallMATLAB(1, &rhs[1], 1, &rhs[0], "transpose"); mexCallMATLAB(1, &plhs[0],2, rhs, "+"); mxDestroyArray(*rhs); } mxFree(blknnz); mxFree(cumblksize); return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* description: * given a set of reference stimuli and responses (forming a joint distribution), * this function will compute the log kernel density estimate over a grid of stimuli * for a set of test responses. Within kernel types a radial-symmetric kernel is used. Different kernels are combined multiplicatively. * * syntax: * out = kde_decode_general( stimulus, stimulus_grid, stimulus_kernel, stimulus_bandwidth, response, response_kernel, response_bandwidth, test_response[, offset[, distance[, timestamp, bins]]] ); * * arguments: * stimulus = number of spikes x number of stimulus dimensions * stimulus_grid = number of grid elements x number of stimulus dimensions * stimulus_kernel = 1 x number of stimulus dimensions * stimulus_bandwidth = 1 x number of stimulus dimensions * response = number of spikes x number of response dimensions * response_kernel = 1 x number of response_dimensions * response_bandwidth = 1 x number of response dimensions * test_response = number of test spikes x number of response dimensions * offset = number of grid elements * distance = optional matrix of distances. If this argument is present (and not empty), the stimulus and stimulus_grid arguments should be given as a zero-based index into the distance matrix. * timestamp = number of test spikes x 1 * bins = number of bins x 2 * * out = number of test spikes x number of stimulus grid elements (if no timestamps and bins arguments are provided) * out = number of bins x number of stimulus grid elements (if timestamps and bins arguments are provided) * * kernels: * 0 = gaussian * 1 = epanechnikov * 2 = von mises * 3 = kronecker * */ double cutoff = 2; /* cut-off (in standard deviations) for gaussian kernel */ double vm_cutoff = 0.1; /* cut-off (probability) for von mises kernel */ static const double pi = 3.141592653589793238462643383279502884197; /* INPUTS */ double *stimulus; /* NxQ */ double *stimulus_grid; /* GxQ */ double *stimulus_kernel; /* 1xQ */ double *stimulus_bandwidth; /* 1xQ */ double *response; /* NxD or Nx0 or empty*/ double *response_kernel; /* 1xD */ double *response_bandwidth; /* 1xD */ double *test_response; /* MxD or Mx0 or empty*/ double *timestamp; double *bins; double *stimulus_vonmises; double *response_vonmises; double *offset; /* VARIABLES */ int N, D, M, Q, G, B; int n, d, m, q, g, b; int sizeM, loopM; int next_idx, idx; double *skip_g, *z; double acc_a_gauss, acc_a_epa, acc_a_delta, acc_a_vm; double *acc_g_gauss, *acc_g_epa, *acc_g_delta, *acc_g_vm; double tmp; double *pout, *pout2; mxArray *out, *out2; int idx1, idx2; mxArray *tmpmat; int *use_distance_lookup; int *NI; double **distance; int ngauss = 0; int nepa = 0; int nmises = 0; int nkron = 0; double scaling_factor = 1; double v; double c1, c2; mxArray *argout=NULL, *argin[2]; double *pargin1; double *pargin2; /* CHECK NUMBER OF INPUTS */ if (nrhs<4) mexErrMsgTxt("This function requires at least four input arguments"); /* CHECK DIMENSIONS OF FIRST TWO ARGUMENTS */ if ( mxGetNumberOfDimensions(prhs[0])!=2 || mxGetNumberOfDimensions(prhs[1])!=2) mexErrMsgTxt("stimulus and stimulus_grid input arguments need to be matrices"); /* GET POINTERS TO FIRST FOUR ARGUMENTS */ stimulus = mxGetPr( prhs[0] ); stimulus_grid = mxGetPr( prhs[1] ); stimulus_kernel = mxGetPr( prhs[2] ); stimulus_bandwidth = mxGetPr( prhs[3] ); /* GET ARRAY SIZES */ N = mxGetM( prhs[0] ); /* number of source (encoding) spikes */ Q = mxGetN( prhs[0] ); /* number of stimulus dimensions */ G = mxGetM( prhs[1] ); /* number of points in stimulus grid */ /* CHECK NUMBER OF DIMENSIONS IN STIMULUS GRID */ if (mxGetN(prhs[1])!=Q) mexErrMsgTxt("Incompatible size of stimulus_grid input arguments"); /* CHECK NUMBER OF STIMULUS KERNELS AND BANDWIDTHS */ if (mxGetNumberOfElements(prhs[2])!=Q || mxGetNumberOfElements(prhs[3])!=Q) mexErrMsgTxt("Incompatible size of stimulus kernel and/or bandwidth arguments"); /* CHECK OPTIONAL INPUTS */ /* CHECK IF EITHER NO RESPONSE, OR RESPONSE + KERNEL + BANDWIDTH IS SPECIFIED */ if (nrhs>5 && nrhs<7) mexErrMsgTxt("Specify response, response kernel and bandwidth arguments"); if (nrhs>6) { /* CHECK DIMENSIONALITY OF SPIKE RESPONSE (ENCODING)*/ if ( mxGetNumberOfDimensions(prhs[4])!=2 ) mexErrMsgTxt("Response input argument needs to be a matrix"); response = mxGetPr( prhs[4] ); D = mxGetN( prhs[4] ); /* number of response dimensions */ /* CHECK NUMBER OF SPIKES IN RESPONSE */ if ( (D>0 && mxGetM(prhs[4])!=N ) ) mexErrMsgTxt("Incompatible size of response input argument"); response_kernel = mxGetPr( prhs[5] ); response_bandwidth = mxGetPr( prhs[6] ); /* CHECK NUMBER OF RESPONSE KERNELS AND BANDWIDTHS */ if (mxGetNumberOfElements(prhs[5])!=D || mxGetNumberOfElements(prhs[6])!=D) mexErrMsgTxt("Incompatible size of response kernel and/or bandwidth arguments"); } else { D = 0; /* no response specified */ } if (nrhs>7) { /* CHECK DIMENSIONALITY OF TEST RESPONSE (DECODING)*/ if ( mxGetNumberOfDimensions(prhs[7])!=2 ) mexErrMsgTxt("Test_response input argument needs to be a matrix"); test_response = mxGetPr( prhs[7] ); M = mxGetM( prhs[7] ); /* number of test (decoding) spikes */ /* CHECK NUMBER OF DIMENSIONS IN TEST RESPONSE */ if ( mxGetN(prhs[7])!=D ) mexErrMsgTxt("Incompatible size of test_response input argument"); } else { M = 0; /* no test spikes specified */ } if ( D==0 && M==0 ) M = 1; if (nrhs>8) { /* CHECK SIZE OF OFFSET VECTOR */ if ( !mxIsDouble( prhs[8] ) || mxGetNumberOfElements( prhs[8] )!=G ) mexErrMsgTxt("Incompatible size of offset vector"); offset = mxGetPr( prhs[8] ); } else { mexErrMsgTxt("Please provide offset vector"); } /* ALLOCATE ARRAYS FOR DISTANCE LOOK-UP TABLES */ use_distance_lookup = (int*) mxCalloc( Q, sizeof(int) ); distance = (double**) mxCalloc( Q, sizeof(double*) ); NI = (int*) mxCalloc( Q, sizeof(int) ); /* size of distance LUTs */ /* INITIALIZE ARRAY */ for (q=0;q<Q;q++) use_distance_lookup[q] = 0; if (nrhs>9) { /* CHECK CLASS AND SIZE OF DISTANCE LUTs */ if ( !mxIsCell( prhs[9] ) || mxGetNumberOfElements( prhs[9] )!=Q ) mexErrMsgTxt("Distance input argument needs to be a cell array with as many cells as stimulus dimensions"); for ( q=0 ; q<Q ; q++ ) { tmpmat = mxGetCell( prhs[9], q ); if (tmpmat==NULL || mxIsEmpty(tmpmat)) { use_distance_lookup[q] = 0; } else { /* CHECK SIZE OF DISTANCE LUT */ if ( mxGetNumberOfDimensions(tmpmat)!=2 || mxGetM( tmpmat )!=mxGetN( tmpmat ) ) mexErrMsgTxt("Distance arrays need to be square matrices"); distance[q] = (double*) mxGetPr( tmpmat ); NI[q] = mxGetM( tmpmat ); use_distance_lookup[q] = true; /* when using distance LUT, the corresponding stimulus and stimulus grid should be indices into the LUT */ /* CHECK IF STIMULUS AND STIMULUS_GRID >=0 && <NI[q] */ for ( n=0; n<N; n++ ) { if ( stimulus[n+q*N]<0 || stimulus[n+q*N]>=NI[q] ) mexErrMsgTxt("Invalid index"); } for ( g=0; g<G; g++ ) { if ( stimulus_grid[g+q*G]<0 || stimulus_grid[g+q*G]>=NI[q] ) mexErrMsgTxt("Invalid index"); } } } } B = 0; /* number of time bins */ if (nrhs>10) { /* CHECK DIMENSIONALITY OF TEST (DECODING) SPIKE TIMESTAMPS */ if ( mxGetNumberOfDimensions(prhs[10])!=2 ) mexErrMsgTxt("Timestamp input argument needs to be a matrix"); timestamp = mxGetPr( prhs[10] ); /* CHECK SIZE OF TEST (DECODING) SPIKE TIMESTAMPS */ if ( mxGetM( prhs[10] )!=M || mxGetN( prhs[10] )!=1 ) mexErrMsgTxt("Incompatible size of timestamp input argument"); } if (nrhs>11) { /* CHECK DIMENSIONALITY AND SIZE OF TIME BINS ARGUMENT */ if ( mxGetNumberOfDimensions(prhs[11])!=2 || mxGetN(prhs[11])!=2) mexErrMsgTxt("Bins input argument needs to be a Bx2 matrix"); B = mxGetM( prhs[11] ); /* number of time bins */ bins = mxGetPr( prhs[11] ); } cutoff *= cutoff; /* transform gaussian kernel cut-off to variance*/ /* COMPUTE CUT-OFFS FOR VON MISES KERNELS */ /* AND COUNT NUMBER OF DIMENSIONS WITH GAUSSIAN/EPANECHNIKOV/KRONECKER/VONMISES KERNELS */ stimulus_vonmises = (double*) mxCalloc( Q, sizeof(double) ); response_vonmises = (double*) mxCalloc( D, sizeof(double) ); argin[0] = mxCreateDoubleScalar(0); argin[1] = mxCreateDoubleScalar(0); pargin1 = mxGetPr(argin[0]); pargin2 = mxGetPr(argin[1]); for (q=0; q<Q; q++) { if (stimulus_kernel[q]==0) { ngauss++; } else if (stimulus_kernel[q]==1) { nepa++; } else if (stimulus_kernel[q]==2) { nmises++; pargin2[0] = stimulus_bandwidth[q]; mexCallMATLAB(1, &argout, 2, argin, "besseli"); stimulus_vonmises[q] = acos( log( vm_cutoff * 2*pi * mxGetScalar(argout) ) / stimulus_bandwidth[q] ); scaling_factor /= mxGetScalar(argout); } else { nkron++; } } for (d=0; d<D; d++) { if (response_kernel[d]==0) { ngauss++; } else if (response_kernel[d]==1) { nepa++; } else if (response_kernel[d]==2) { nmises++; pargin2[0] = response_bandwidth[d]; mexCallMATLAB(1, &argout, 2, argin, "besseli"); response_vonmises[d] = acos( log( vm_cutoff * 2*pi * mxGetScalar(argout) ) / response_bandwidth[d] ); scaling_factor /= mxGetScalar(argout); } else { nkron++; } } /* COMPUTE SCALING FACTOR */ if (ngauss>0) scaling_factor *= pow(2*pi,-((double)ngauss)/2); if (nepa>0) { /* compute volume of hypersphere */ pargin1[0] = ((double)nepa)/2 + 1; mexCallMATLAB(1, &argout, 1, argin, "gamma" ); v = pow(pi,0.5*(double)(nepa))/mxGetScalar(argout); scaling_factor *= 0.5*(double)(nepa+2)/v; } if (nmises>0) { scaling_factor /= pow(2*pi,(double)nmises); } if (nkron>0) { /* compute volume of hypersphere */ pargin1[0] = ((double)nkron)/2 + 1; mexCallMATLAB(1, &argout, 1, argin, "gamma" ); v = pow(pi,((double)nkron)/2)/mxGetScalar(argout); scaling_factor /= v; } /* ALLOCATE TEMPORARY ARRAYS AND OUTPUT ARRAYS */ acc_g_gauss = (double*) mxCalloc( G, sizeof(double) ); acc_g_epa = (double*) mxCalloc( G, sizeof(double) ); acc_g_delta = (double*) mxCalloc( G, sizeof(double) ); acc_g_vm = (double*) mxCalloc( G, sizeof(double) ); skip_g = (double*) mxCalloc( G, sizeof(double) ); if (B==0) { out = mxCreateDoubleMatrix( M, G, mxREAL ); z = mxGetPr( out ); } else { if (D==0) { z = (double*) mxCalloc( G, sizeof(double) ); } else { z = (double*) mxCalloc( M*G, sizeof(double) ); } out = mxCreateDoubleMatrix( B, G, mxREAL ); pout = mxGetPr( out ); out2 = mxCreateDoubleMatrix( B, 1, mxREAL ); pout2 = mxGetPr( out2 ); } loopM = sizeM = M; if (D==0) { loopM = 1; if (B>0) sizeM = 1; } /* COMPUTE KDE */ /* LOOP THROUGH SOURCE (ENCODING) SPIKES */ for ( n=0; n<N; n++ ) { /* LOOP THROUGH STIMULUS GRID */ for ( g=0; g<G; g++ ) { /* INITIALIZE ACCUMULATORS */ acc_g_gauss[g] = 0; acc_g_epa[g] = 0; acc_g_delta[g] = 0; acc_g_vm[g] = 0; skip_g[g] = 0; /* INITIALIZE INDICES */ idx1 = g; idx2 = n; /* LOOP THROUGH STIMULUS DIMENSIONS */ for ( q=0; q<Q; q++ ) { /* GAUSSIAN KERNEL */ if (stimulus_kernel[q]==0) { if (use_distance_lookup[q]) { tmp = distance[q][ ((int) stimulus_grid[idx1])*NI[q] + (int)stimulus[idx2] ]; } else { tmp = (stimulus_grid[idx1]-stimulus[idx2]); } acc_g_gauss[g] += tmp*tmp; if (acc_g_gauss[g]>cutoff) { skip_g[g] = 1; break; } /* EPANECHNIKOV KERNEL */ } else if (stimulus_kernel[q]==1) { if (use_distance_lookup[q]) { tmp = distance[q][ ((int) stimulus_grid[idx1])*NI[q] + (int)stimulus[idx2] ]; } else { tmp = (stimulus_grid[idx1]-stimulus[idx2]); } acc_g_epa[g]+=tmp*tmp; if (acc_g_epa[g]>1) { skip_g[g] = 1; break; } /* VON MISES KERNEL */ } else if (stimulus_kernel[q]==2) { if (use_distance_lookup[q]) { tmp = distance[q][ ((int) stimulus_grid[idx1])*NI[q] + (int)stimulus[idx2] ]; } else { tmp = fabs(stimulus_grid[idx1]-stimulus[idx2]); } if ( tmp<stimulus_vonmises[q] || tmp>(2*pi-stimulus_vonmises[q]) ) { acc_g_vm[g] += stimulus_bandwidth[q] * cos(tmp); } else { skip_g[g] = 1; break; } /* KRONECKER KERNEL */ } else { if (use_distance_lookup[q]) { tmp = distance[q][ ((int) stimulus_grid[idx1])*NI[q] + (int)stimulus[idx2] ]; } else { tmp = (stimulus_grid[idx1]-stimulus[idx2]); } acc_g_delta[g] += tmp*tmp; if (acc_g_delta[g]>1) { skip_g[g] = 1; break; } } /* UPDATE INDICES */ idx1 += G; idx2 += N; } } /* LOOP THROUGH TEST (DECODING) SPIKES */ for ( m=0; m<loopM; m++ ) { /* INITIALIZE ACCUMULATORS */ acc_a_gauss = 0; acc_a_epa = 0; acc_a_delta = 0; acc_a_vm = 0; /* INTIALIZE INDICES */ idx1 = m; idx2 = n; /* LOOP THROUGH RESPONSE DIMENSIONS */ for ( d=0; d<D; d++ ) { /* GAUSSIAN KERNEL */ if (response_kernel[d]==0) { tmp = (test_response[idx1]-response[idx2]); acc_a_gauss += tmp*tmp; if (acc_a_gauss>cutoff) { goto nextm; } /* EPANECHNIKOV KERNEL */ } else if (response_kernel[d]==1) { tmp = (test_response[idx1]-response[idx2]); acc_a_epa += tmp*tmp; if (acc_a_epa>1) { goto nextm; } /* VON MISES KERNEL */ } else if (response_kernel[d]==2) { tmp = fabs(test_response[idx1]-response[idx2]); if ( tmp<response_vonmises[d] || tmp>(2*pi-response_vonmises[d]) ) { acc_a_vm += response_bandwidth[d] * cos(tmp); } else { goto nextm; } /* KRONECKER KERNEL */ } else { tmp = (test_response[idx1]-response[idx2]); acc_a_delta += tmp*tmp; if (acc_a_delta>1) { goto nextm; } } /* UPDATE INDICES */ idx1 += sizeM; idx2 += N; } /* LOOP THROUGH STIMULUS GRID */ for ( g=0; g<G; g++ ) { if (skip_g[g] || acc_g_gauss[g]+acc_a_gauss>cutoff || acc_g_epa[g]+acc_a_epa>1 || acc_g_delta[g]+acc_a_delta>1) continue; z[m+g*sizeM] += exp( -0.5*(acc_g_gauss[g]+acc_a_gauss) + acc_g_vm[g] + acc_a_vm ) * (1-acc_g_epa[g]-acc_a_epa); } nextm: ; } } mxFree(acc_g_gauss); mxFree(acc_g_epa); mxFree(acc_g_delta); mxFree(acc_g_vm); mxFree(skip_g); mxFree(stimulus_vonmises); mxFree(response_vonmises); if (argout!=NULL) mxDestroyArray(argout); mxDestroyArray(argin[0]); mxDestroyArray(argin[1]); /* compute log */ c1 = log(scaling_factor) - log((double)N); if (B==0 && D==0) { for (g=0;g<G;g++) z[g*sizeM]=log( z[g*sizeM] + offset[g]*(double)N/scaling_factor ) + c1; } else { for (g=0; g<G; g++) { idx = g*loopM; c2 = offset[g]*(double)N/scaling_factor; for (m=0; m<loopM ; m++ ) z[m+idx] = log( z[m+idx] + c2) + c1; } } if (D==0 && B==0) { /* copy */ for (g=0; g<G; g++) { idx = g*sizeM; for (m=1; m<sizeM ; m++ ) z[m+idx] = z[idx]; } } if (B>0) { next_idx = 0; for (b=0; b<B; b++) { while (next_idx<M && (timestamp[next_idx]<bins[b])) next_idx++; idx = next_idx; while (idx<M && (timestamp[idx]<bins[b+B])) { if (D>0) { for (g=0; g<G; g++) pout[b+g*B] += z[idx+g*M]; } pout2[b]++; idx++; } if (D==0) { for (g=0; g<G; g++) { pout[b+g*B] = pout2[b] * z[g*sizeM]; } } } mxFree(z); } plhs[0] = out; plhs[1] = out2; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ int i, j, NS, NZB, count, bdim, match, domain, bindex, sindex, nzCounts=0; int *observed, *bsubv, *ssubv, *bir, *sir, *bjc, *sjc, *mask, *ssize, *bcumprod, *scumprod; double *pDomain, *pSize, *bpr, *spr; mxArray *pTemp; pTemp = mxGetField(prhs[0], 0, "CPT"); bpr = mxGetPr(pTemp); bir = mxGetIr(pTemp); bjc = mxGetJc(pTemp); NZB = bjc[1]; pTemp = mxGetField(prhs[0], 0, "sizes"); pSize = mxGetPr(pTemp); pDomain = mxGetPr(prhs[1]); bdim = mxGetNumberOfElements(prhs[1]); mask = malloc(bdim * sizeof(int)); ssize = malloc(bdim * sizeof(int)); observed = malloc(bdim * sizeof(int)); for(i=0; i<bdim; i++){ ssize[i] = (int)pSize[i]; } count = 0; for(i=0; i<bdim; i++){ domain = (int)pDomain[i] - 1; pTemp = mxGetCell(prhs[2], domain); if(pTemp){ mask[count] = i; ssize[i] = 1; observed[count] = (int)mxGetScalar(pTemp) - 1; count++; } } if(count == 0){ pTemp = mxGetField(prhs[0], 0, "CPT"); plhs[0] = mxDuplicateArray(pTemp); free(mask); free(ssize); free(observed); return; } bsubv = malloc(bdim * sizeof(int)); ssubv = malloc(count * sizeof(int)); bcumprod = malloc(bdim * sizeof(int)); scumprod = malloc(bdim * sizeof(int)); NS = 1; for(i=0; i<bdim; i++){ NS *= ssize[i]; } plhs[0] = mxCreateSparse(NS, 1, NS, mxREAL); spr = mxGetPr(plhs[0]); sir = mxGetIr(plhs[0]); sjc = mxGetJc(plhs[0]); sjc[0] = 0; sjc[1] = NS; bcumprod[0] = 1; scumprod[0] = 1; for(i=0; i<bdim-1; i++){ bcumprod[i+1] = bcumprod[i] * (int)pSize[i]; scumprod[i+1] = scumprod[i] * ssize[i]; } nzCounts = 0; for(i=0; i<NZB; i++){ bindex = bir[i]; ind_subv(bindex, bcumprod, bdim, bsubv); for(j=0; j<count; j++){ ssubv[j] = bsubv[mask[j]]; } match = 1; for(j=0; j<count; j++){ if((ssubv[j]) != observed[j]){ match = 0; break; } } if(match){ spr[nzCounts] = bpr[i]; sindex = subv_ind(bdim, scumprod, bsubv); sir[nzCounts] = sindex; nzCounts++; } } reset_nzmax(plhs[0], NS, nzCounts); free(mask); free(ssize); free(observed); free(bsubv); free(ssubv); free(bcumprod); free(scumprod); }
// Main function =============================================================== void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mxArray *A, *AC, *B, *BC; int nA, nB, iA, iB, ASlen, *BSlenp, *BSlen, Rlen, CaseSensitive = 1; double *RA, *RAp, *RB, *RBp; unsigned char **BS, **BSp, **BSEnd, *AS, *CaseArg; // Check for proper number of arguments: if (nrhs < 2 || nrhs > 3) { mexErrMsgTxt("*** CStrAinBP[mex]: 2 or 3 inputs required."); } if (nlhs > 2) { mexErrMsgTxt("*** CStrAinBP[mex]: 1 or 2 outputs allowed."); } // Set flag according to optional 3rd input: if (nrhs == 3) { // Compare first character of 3rd argument: if (mxGetNumberOfElements(prhs[2]) > 0) { CaseArg = (unsigned char *)mxGetData(prhs[2]); if (*CaseArg == 'i' || *CaseArg == 'I') { CaseSensitive = 0; } } } // Create a pointer to the input arrays: A = prhs[0]; B = prhs[1]; // Check that inputs are cells: if (!mxIsCell(A) || !mxIsCell(B)) { mexErrMsgTxt("*** CStrAinBP[mex]: Inputs must be cells."); } // Get number of dimensions of the input string and cell: nA = mxGetNumberOfElements(A); nB = mxGetNumberOfElements(B); // Create container for output arguments: RA = (double *)mxMalloc(nA * sizeof(double)); RB = (double *)mxMalloc(nA * sizeof(double)); // Make list of pointers to elements of B and their length: BSlen = (int *) mxMalloc(nB * sizeof(int)); BS = (unsigned char **)mxMalloc(nB * sizeof(unsigned char *)); BSEnd = BS + nB; for (iB = 0, BSp = BS, BSlenp = BSlen; iB < nB; iB++) { if ((BC = mxGetCell(B, iB)) == NULL) { // Uninitialized cell element: mexErrMsgTxt("*** CStrAinBP[mex]: Element of B is NULL."); } if (!mxIsChar(BC)) { mexErrMsgTxt("*** CStrAinBP[mex]: Element of B is no string."); } *BSlenp++ = mxGetNumberOfElements(BC); *BSp++ = (unsigned char *)mxGetData(BC); } // end for iB // Pointers to list of strings: RAp = RA; RBp = RB; if (CaseSensitive) { // ----------------------------------------------------- for (iA = 0; iA < nA; iA++) { // Loop over all strings of A: if ((AC = mxGetCell(A, iA)) == NULL) { // Uninitialized cell element: mexErrMsgTxt("*** CStrAinBP[mex]: Element of A is NULL."); } if (!mxIsChar(AC)) { // Check if cell element is a string: mexErrMsgTxt("*** CStrAinBP[mex]: Element of A is no string."); } AS = (unsigned char *)mxGetData(AC); ASlen = mxGetNumberOfElements(AC); BSlenp = BSlen; // Pointer to list of lengths of B's strings // Loop over pointers to strings of B: for (BSp = BS; BSp < BSEnd; BSp++) { if (ASlen == *BSlenp++) { // Cheap comparison of length if (memcmp(AS, *BSp, ASlen * sizeof(mxChar)) == 0) { *RAp++ = (double) (iA + 1); *RBp++ = (double) (BSp - BS + 1); break; // Just take first occurrence in B } } } // end for BSp } // end for iA } else { // Not case-sensitive: --------------------------------------------- // Same method except for memcmp -> my_memicmpW: for (iA = 0; iA < nA; iA++) { // Loop over all strings of A: if ((AC = mxGetCell(A, iA)) == NULL) { // Uninitialized cell element: mexErrMsgTxt("*** CStrAinBP[mex]: Element of A is NULL."); } if (!mxIsChar(AC)) { // Check if cell element is a string: mexErrMsgTxt("*** CStrAinBP[mex]: Element of A is no string."); } AS = (unsigned char *)mxGetData(AC); ASlen = mxGetNumberOfElements(AC); BSlenp = BSlen; // Pointer to list of lengths of B's strings // Loop over pointers to strings of B: for (BSp = BS; BSp < BSEnd; BSp++) { if (ASlen == *BSlenp++) { // Cheap comparison of length if (my_memicmpW(AS, *BSp, ASlen) == 0) { *RAp++ = (double) (iA + 1); *RBp++ = (double) (BSp - BS + 1); break; // Just take first occurrence in B } } } // end for BSp } // end for iA } // Create output arguments, [0 x 0] for empty arrays: Rlen = (int) (RAp - RA); // Number of found occurrences plhs[0] = mxCreateDoubleMatrix(Rlen ? 1 : 0, Rlen, mxREAL); memcpy(mxGetPr(plhs[0]), RA, Rlen * sizeof(double)); if (nlhs == 2) { plhs[1] = mxCreateDoubleMatrix(Rlen ? 1 : 0, Rlen, mxREAL); memcpy(mxGetPr(plhs[1]), RB, Rlen * sizeof(double)); } // Free memory for indices, strings and strings lengths: mxFree(RA); mxFree(RB); mxFree(BS); mxFree(BSlen); return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // input arguments GLuint programID = 0; size_t nBuffers = 0; size_t nNames = 0; size_t nOffsets = 0; size_t nIsNormalized = 0; // input data int i = 0; GLuint attribIndex = 1; mxArray* mxAttribName = NULL; char* attribName = NULL; double* mxOffsetData = NULL; double* mxIsNormalizedData = NULL; // VBO data GLuint bufferID = 0; size_t bytesPerElement = 0; size_t byteOffset = 0; GLint elementsPerVertex = 0; GLsizei elementStride = 0; GLsizei byteStride = 0; mxArray* mxData = NULL; GLenum glType = GL_FLOAT; GLboolean isNormalized = GL_FALSE; // status GLint maxAttributes = -1; size_t nSelected = 0; int status = 0; GLenum error = GL_NO_ERROR; dotsMglClearGLErrors(); // empty input means disable all generic vertex attributes, exept 0 if (nrhs < 1 || mxIsEmpty(prhs[0])) { glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttributes); if (maxAttributes > 0) { for (i=1; i<maxAttributes; i++) glDisableVertexAttribArray(i); } plhs[0] = mxCreateDoubleScalar(0); return; } // check input arguments if (nrhs < 2 || nrhs > 5 || !mxIsStruct(prhs[0]) || mxIsEmpty(prhs[0]) || !mxIsStruct(prhs[1]) || mxIsEmpty(prhs[1])) { plhs[0] = mxCreateDoubleScalar(-1); usageError("dotsMglSelectVertexAttributes"); return; } // is this a shader program info struct? programID = (GLuint)dotsMglGetInfoScalar(prhs[0], 0, "programID", &status); if (status < 0) { plhs[0] = mxCreateDoubleScalar(-2); return; } // how many attribute buffers? nBuffers = mxGetNumberOfElements(prhs[1]); // how many attribute names? if (nrhs >= 3 && mxIsCell(prhs[2]) && !mxIsEmpty(prhs[2])) { nNames = mxGetNumberOfElements(prhs[2]); if (nBuffers != nNames) { mexPrintf("(dotsMglSelectVertexAttributes) Number of buffer names %d must match number of buffers %d.\n", nNames, nBuffers); plhs[0] = mxCreateDoubleScalar(-3); return; } } // how many buffer offsets? if (nrhs >= 4 && mxIsDouble(prhs[3]) && !mxIsEmpty(prhs[3])) { nOffsets = mxGetNumberOfElements(prhs[3]); if (nBuffers != nOffsets) { mexPrintf("(dotsMglSelectVertexAttributes) Number of buffer offsets %d must match number of buffers %d.\n", nOffsets, nBuffers); plhs[0] = mxCreateDoubleScalar(-4); return; } mxOffsetData = mxGetPr(prhs[3]); } // how many buffer normalize flags? if (nrhs >= 5 && mxIsDouble(prhs[4]) && !mxIsEmpty(prhs[4])) { nIsNormalized = mxGetNumberOfElements(prhs[4]); if (nBuffers != nIsNormalized) { mexPrintf("(dotsMglSelectVertexAttributes) Number of buffer normalize flags %d must match number of buffers %d.\n", nIsNormalized, nBuffers); plhs[0] = mxCreateDoubleScalar(-5); return; } mxIsNormalizedData = mxGetPr(prhs[4]); } // iterate buffers to enable attributes for (i=0; i<nBuffers; i++) { // enable the next numbered attribute // ignoring attribute 0 attribIndex = i+1; glEnableVertexAttribArray(attribIndex); // assign a name to the numbered attribute? if (nNames > 0){ mxAttribName = mxGetCell(prhs[2], i); attribName = mxArrayToString(mxAttribName); glBindAttribLocation(programID, attribIndex, (const GLchar*)attribName); if (attribName != NULL){ mxFree(attribName); attribName = NULL; } error = glGetError(); if(error != GL_NO_ERROR) { mexPrintf("(dotsMglSelectVertexAttributes) Error assigning name %s to vertex attribute %d. glGetError()=%d\n", attribName, attribIndex, error); continue; } } // VBO accounting bufferID = (GLuint)dotsMglGetInfoScalar(prhs[1], i, "bufferID", &status); if (status < 0) { mexPrintf("(dotsMglSelectVertexAttributes) %dth buffer info struct is invalid.\n", i); continue; } // how are the VBO elements formatted? elementsPerVertex = (GLint)dotsMglGetInfoScalar(prhs[1], i, "elementsPerVertex", &status); elementStride = (GLsizei)dotsMglGetInfoScalar(prhs[1], i, "elementStride", &status); bytesPerElement = (size_t)dotsMglGetInfoScalar(prhs[1], i, "bytesPerElement", &status); byteStride = elementStride * bytesPerElement; mxData = mxGetField(prhs[1], i, "mxData"); glType = dotsMglGetGLNumericType(mxData); // use an offset into the VBO? if (nOffsets > 0 && mxOffsetData != NULL) byteOffset = (size_t)mxOffsetData[i] * bytesPerElement; else byteOffset = 0; // normalize data in the VBO? if (nIsNormalized > 0 && mxIsNormalizedData != NULL) isNormalized = mxIsNormalizedData[i] ? GL_TRUE : GL_FALSE; else isNormalized = 0; // assign the VBO to this numbered attribute glBindBuffer(GL_ARRAY_BUFFER, bufferID); glVertexAttribPointer(attribIndex, elementsPerVertex, glType, isNormalized, byteStride, BUFFER_OFFSET(byteOffset)); glBindBuffer(GL_ARRAY_BUFFER, 0); error = glGetError(); if(error != GL_NO_ERROR) { mexPrintf("(dotsMglSelectVertexAttributes) Error selecting vertex %s data. glGetError()=%d\n", attribName, error); continue; } // success for this attribute nSelected++; } // need to re-link the program when binding attribute names if (nNames > 0){ glLinkProgram(programID); error = glGetError(); if (error != GL_NO_ERROR) { mexPrintf("(dotsMglSelectVertexAttributes) Could not link program. glGetError()=%d\n", error); plhs[0] = mxCreateDoubleScalar(-10); return; } } // success? plhs[0] = mxCreateDoubleScalar(nSelected); }
void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] ) { #ifdef _DEBUG static int atExitFncRegistered = 0; if(!atExitFncRegistered) { LTFAT_NAME(ltfatMexAtExit)(LTFAT_NAME(tdMexAtExitFnc)); atExitFncRegistered = 1; } #endif const mxArray* mxf = prhs[0]; const mxArray* mxg = prhs[1]; double* a = (double*) mxGetData(prhs[2]); double* offset = (double*) mxGetData(prhs[3]); char* ext = mxArrayToString(prhs[4]); // input data length mwSize L = mxGetM(mxf); // number of channels mwSize W = mxGetN(mxf); // filter number mwSize M = mxGetNumberOfElements(mxg); // filter lengths mwSize filtLen[M]; //mwSize* filtLen = mxMalloc(M*sizeof(mwSize)); for(unsigned int m=0;m<M;m++) { filtLen[m] = (mwSize) mxGetNumberOfElements(mxGetCell(mxg,m)); } // output lengths mwSize outLen[M]; //mwSize* outLen = mxMalloc(M*sizeof(mwSize)); if(!strcmp(ext,"per")) { for(unsigned int m = 0; m < M; m++) { outLen[m] = (mwSize) ceil( L/a[m] ); } } else if(!strcmp(ext,"valid")) { for(unsigned int m = 0; m < M; m++) { outLen[m] = (mwSize) ceil( (L-(filtLen[m]-1))/a[m] ); } } else { for(unsigned int m = 0; m < M; m++) { outLen[m] = (mwSize) ceil( (L + filtLen[m] - 1 + offset[m] )/a[m] ); } } // POINTER TO THE INPUT LTFAT_TYPE* fPtr = (LTFAT_TYPE*) mxGetData(prhs[0]); // POINTER TO THE FILTERS LTFAT_TYPE* gPtrs[M]; // LTFAT_TYPE** gPtrs = (LTFAT_TYPE**) mxMalloc(M*sizeof(LTFAT_TYPE*)); for(mwIndex m=0;m<M;m++) { gPtrs[m] = (LTFAT_TYPE*) mxGetPr(mxGetCell(mxg, m)); } // POINTER TO OUTPUTS LTFAT_TYPE* cPtrs[M]; // C99 feature //LTFAT_TYPE** cPtrs = (LTFAT_TYPE**) mxMalloc(M*sizeof(LTFAT_TYPE*)); plhs[0] = mxCreateCellMatrix(M, 1); for(mwIndex m=0;m<M;++m) { mxSetCell(plhs[0], m, ltfatCreateMatrix(outLen[m], W,LTFAT_MX_CLASSID,LTFAT_MX_COMPLEXITY)); cPtrs[m] = (LTFAT_TYPE*) mxGetData(mxGetCell(plhs[0],m)); memset(cPtrs[m],0,outLen[m]*W*sizeof(LTFAT_TYPE)); } // over all channels // #pragma omp parallel for private(m) for(mwIndex m =0; m<M; m++) { for(mwIndex w =0; w<W; w++) { // Obtain pointer to w-th column in input LTFAT_TYPE *fPtrCol = fPtr + w*L; // Obtaing pointer to w-th column in m-th element of output cell-array LTFAT_TYPE *cPtrCol = cPtrs[m] + w*outLen[m]; //conv_td_sub(fPtrCol,L,&cPtrCol,outLen[m],(const double**)&gPtrs[m],filtLen[m],1,a[m],skip[m],ltfatExtStringToEnum(ext),0); LTFAT_NAME(convsub_td)(fPtrCol,L,cPtrCol,outLen[m],gPtrs[m],filtLen[m],a[m],-offset[m],ltfatExtStringToEnum(ext)); } } }
void recurse_object(const mxArray* in, json& obj) { // Go over all types if (mxIsCell(in)) { int N = mxGetNumberOfElements(in); for (int a = 0; a < N; ++a) { obj.emplace_back(); recurse_object(mxGetCell(in, a), obj.back()); } } else if (mxIsStruct(in)) { int M = mxGetNumberOfFields(in); std::vector<const char*> fnames(M); for (int b = 0; b < M; ++b) fnames[b] = mxGetFieldNameByNumber(in, b); int N = mxGetNumberOfElements(in); for (int a = 0; a < N; ++a) { json obj_; for (int b = 0; b < M; ++b) recurse_object(mxGetFieldByNumber(in, a, b), obj_[fnames[b]]); if (N == 1) obj = std::move(obj_); else obj.push_back(std::move(obj_)); } } else if (mxIsChar(in)) { obj = json::parse(mxArrayToString(in)); } else if (mxIsLogical(in)) { int N = mxGetNumberOfElements(in); const mxLogical* data = (const mxLogical*)mxGetData(in); if (N == 1) { obj = data[0] != 0; } else { for (int a = 0; a < N; ++a) obj.push_back(data[a] != 0); } } else if (mxIsNumeric(in)) { int N = mxGetNumberOfElements(in); const void* data = (const void*)mxGetData(in); switch (mxGetClassID(in)) { case mxDOUBLE_CLASS: if (N == 1) { obj = ((const double*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const double*)data)[a]); } break; case mxSINGLE_CLASS: if (N == 1) { obj = ((const float*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const float*)data)[a]); } break; case mxUINT8_CLASS: if (N == 1) { obj = ((const uint8_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const uint8_t*)data)[a]); } break; case mxINT8_CLASS: if (N == 1) { obj = ((const int8_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const int8_t*)data)[a]); } break; case mxUINT16_CLASS: if (N == 1) { obj = ((const uint16_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const uint16_t*)data)[a]); } break; case mxINT16_CLASS: if (N == 1) { obj = ((const int16_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const int16_t*)data)[a]); } break; case mxUINT32_CLASS: if (N == 1) { obj = ((const uint32_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const uint32_t*)data)[a]); } break; case mxINT32_CLASS: if (N == 1) { obj = ((const int32_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const int32_t*)data)[a]); } break; case mxUINT64_CLASS: if (N == 1) { obj = ((const uint64_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const uint64_t*)data)[a]); } break; case mxINT64_CLASS: if (N == 1) { obj = ((const int64_t*)data)[0]; } else { for (int a = 0; a < N; ++a) obj.push_back(((const int64_t*)data)[a]); } break; default: mexErrMsgTxt("Unsupported type."); break; } } else { mexErrMsgTxt("Unrecognized type."); } }
/* %COMP_IFILTERBANK_TD Synthesis filterbank % Usage: f=comp_ifilterbank_fft(c,g,a,Ls,offset,ext); % % Input parameters: % c : Cell array of length M, each element is N(m)*W matrix. % g : Filterbank filters - length M cell-array, each element is vector of length filtLen(m) % a : Upsampling factors - array of length M. % offset : Delay of the filters - scalar or array of length M. % Ls : Output length. % ext : Border exension technique. % % Output parameters: % f : Output Ls*W array. % */ void LTFAT_NAME(ltfatMexFnc)( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] ) { // printf("Filename: %s, Function name %s, %d \n.",__FILE__,__func__,mxIsDouble(prhs[0])); const mxArray* mxc = prhs[0]; const mxArray* mxg = prhs[1]; double* a = mxGetPr(prhs[2]); double* Lsdouble = mxGetPr(prhs[3]); unsigned int Ls = (unsigned int) *Lsdouble; double* offset = mxGetPr(prhs[4]); char* ext = mxArrayToString(prhs[5]); // number of channels unsigned int W = mxGetN(mxGetCell(mxc,0)); // filter number unsigned int M = mxGetNumberOfElements(mxg); // input data length unsigned int* Lc = mxMalloc(M*sizeof(unsigned int)); for(unsigned int m=0;m<M;m++) { Lc[m] = (unsigned int) mxGetM(mxGetCell(mxc,m)); } // filter lengths unsigned int* filtLen = mxMalloc(M*sizeof(unsigned int)); for(unsigned int m=0;m<M;m++) { filtLen[m] = (unsigned int) mxGetNumberOfElements(mxGetCell(mxg,m)); } // POINTER TO THE INPUT LTFAT_TYPE** cPtrs = (LTFAT_TYPE**) mxMalloc(M*sizeof(LTFAT_TYPE*)); for(unsigned int m=0;m<M;++m) { cPtrs[m] = (LTFAT_TYPE*) mxGetData(mxGetCell(mxc,m)); } // allocate output plhs[0] = ltfatCreateMatrix(Ls, W,LTFAT_MX_CLASSID,LTFAT_MX_COMPLEXITY); // POINTER TO OUTPUT LTFAT_TYPE* fPtr = (LTFAT_TYPE*) mxGetData(plhs[0]); // Set to zeros memset(fPtr,0,Ls*W*sizeof(LTFAT_TYPE)); // POINTER TO THE FILTERS LTFAT_TYPE** gPtrs = (LTFAT_TYPE**) mxMalloc(M*sizeof(LTFAT_TYPE*)); for(unsigned int m=0;m<M;m++) { gPtrs[m] = (LTFAT_TYPE*) mxGetData(mxGetCell(mxg, m)); } // over all channels // #pragma omp parallel for private(m) for(unsigned int m =0; m<M; m++) { for(unsigned int w =0; w<W; w++) { // Obtain pointer to w-th column in input LTFAT_TYPE *fPtrCol = fPtr + w*Ls; // Obtaing pointer to w-th column in m-th element of output cell-array LTFAT_TYPE *cPtrCol = cPtrs[m] + w*Lc[m]; //(upconv_td)(const LTFAT_TYPE *in, int inLen, LTFAT_TYPE *out, const int outLen, const LTFAT_TYPE *filts, int fLen, int up, int skip, enum ltfatWavExtType ext) LTFAT_NAME(upconv_td)(cPtrCol,Lc[m],fPtrCol,Ls,gPtrs[m],filtLen[m],a[m],-offset[m],ltfatExtStringToEnum(ext)); } } }
MVT_3D_Object::MVT_3D_Object(ENUM_OBJECT_CATEGORY object_category, const char* filepath_3dobject_model) { m_object_category = object_category; MATFile* mat = matOpen(filepath_3dobject_model,"r"); if( mat != NULL ) { mxArray* pmxCad = matGetVariable(mat, "cad"); pmxCad = mxGetCell(pmxCad,0); /* * Names of parts */ mxArray* pmxNames = mxGetField(pmxCad, 0, "pnames"); m_num_of_partsNroots = mxGetNumberOfElements(pmxNames); for( unsigned int i=0; i<m_num_of_partsNroots; i++) { mxArray* pmxName = mxGetCell(pmxNames, i); m_names_partsNroots.push_back(MxArray(pmxName).toString()); } /* * Parts2d_Front */ mxArray* pmxPars2d_front = mxGetField(pmxCad, 0, "parts2d_front"); for( unsigned int i=0; i<m_num_of_partsNroots; i++) { MVT_2D_Part_Front front; front.width = MxArray(mxGetField(pmxPars2d_front, i, "width" )).toDouble(); front.height = MxArray(mxGetField(pmxPars2d_front, i, "height" )).toDouble(); front.distance = MxArray(mxGetField(pmxPars2d_front, i, "distance")).toDouble(); cv::Mat mat_tmp = MxArray(mxGetField(pmxPars2d_front, i, "vertices")).toMat(); unsigned int n_row = mat_tmp.rows; for( unsigned int r=0; r<n_row ; r++) { front.vertices.push_back(cv::Point2d(mat_tmp.at<double>(r,0), mat_tmp.at<double>(r,1))); } front.center = MxArray(mxGetField(pmxPars2d_front, i, "center")).toPoint_<double>(); front.viewport = MxArray(mxGetField(pmxPars2d_front, i, "viewport")).toDouble(); front.name = MxArray(mxGetField(pmxPars2d_front, i, "pname")).toString(); m_2dparts_front.push_back(front); } /* * Part */ mxArray* pmxParts = mxGetField(pmxCad, 0, "parts"); m_num_of_parts = mxGetNumberOfElements(pmxParts); for( unsigned int i=0 ; i<m_num_of_parts; i++ ) { MVT_3D_Part part; /* Vertices */ mxArray* mxVertices = mxGetField(pmxParts, i, "vertices"); cv::Mat matVertices = MxArray(mxVertices).toMat(); unsigned int n_rows = matVertices.rows; for( unsigned int r=0; r<n_rows; r++) { cv::Mat matTmp = matVertices.row(r); part.vertices.push_back ( cv::Point3d( matTmp.at<double>(0), matTmp.at<double>(1), matTmp.at<double>(2) ) ); } /* plane */ MxArray MxPlane(mxGetField(pmxParts, i, "plane")); for( int j=0 ; j<4; j++ ) { part.plane[j] = MxPlane.at<double>(j); } /* center */ MxArray MxCenter(mxGetField(pmxParts, i, "center")); part.center.x = MxCenter.at<double>(0); part.center.y = MxCenter.at<double>(1); part.center.z = MxCenter.at<double>(2); /* xaxis */ MxArray MxXAxis(mxGetField(pmxParts, i, "xaxis")); part.xaxis.x = MxXAxis.at<double>(0); part.xaxis.y = MxXAxis.at<double>(1); part.xaxis.z = MxXAxis.at<double>(2); /* yaxis */ MxArray MxYAxis(mxGetField(pmxParts, i, "yaxis")); part.yaxis.x = MxYAxis.at<double>(0); part.yaxis.y = MxYAxis.at<double>(1); part.yaxis.z = MxYAxis.at<double>(2); m_3dparts.push_back(part); /* * Occlusion Information */ mxArray* pmxAzimuth = mxGetField(pmxCad, 0, "azimuth" ); m_disc_azimuth = MxArray(pmxAzimuth).toVector<MVT_AZIMUTH>(); mxArray* pmxElevation = mxGetField(pmxCad, 0, "elevation" ); m_disc_elevation = MxArray(pmxElevation).toVector<MVT_ELEVATION>(); mxArray* pmxDistance = mxGetField(pmxCad, 0, "distance" ); m_disc_distance = MxArray(pmxDistance).toVector<MVT_DISTANCE>(); mxArray* pmxParts2d = mxGetField(pmxCad, 0, "parts2d"); m_num_of_disc_azimuth = m_disc_azimuth.size(); m_num_of_disc_elevation = m_disc_elevation.size(); m_num_of_disc_distance = m_disc_distance.size(); m_is_occluded = new bool***[m_num_of_disc_azimuth]; for( unsigned int a=0; a<m_num_of_disc_azimuth; a++ ) { m_is_occluded[a] = new bool**[m_num_of_disc_elevation]; for( unsigned int e=0; e<m_num_of_disc_elevation; e++ ) { m_is_occluded[a][e] = new bool*[m_num_of_disc_distance]; for( unsigned int d=0; d<m_num_of_disc_distance; d++ ) { m_is_occluded[a][e][d] = new bool[m_num_of_partsNroots]; unsigned int idx = m_num_of_disc_distance*m_num_of_disc_elevation*a + m_num_of_disc_distance*e + d; for( unsigned int p=0; p<m_num_of_partsNroots; p++) { mxArray* pmxPart = mxGetField(pmxParts2d, idx, m_names_partsNroots[p].c_str()); m_is_occluded[a][e][d][p] = mxIsEmpty(pmxPart); } } } } } mxDestroyArray(pmxCad); matClose(mat); } }
void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] ) { if(nrhs < 4 || nrhs > 5) mexErrMsgTxt("Improper number of input arguments.\n\n" "ARGMAX_MEX estimates the position of landmarks.\n\n" "Synopsis: \n" " [ \\hat{s} ]= argmax_mex(options, W, mapTable, lbp [, L]) \n" "\n" " Input: \n" " options [1 x 1 structure] detector options\n" " W [n x 1 (double)] joint parameter vector\n" " mapTable [M x 4 (double)] mapping table for joint parameter vector W\n" " lbp [1 x M (cell)] LBP sparse features\n" " L [M x 1 (cell)] precomputed losses, optional parameter (for learning stage)\n" " Output: \n" " \\hat{s} [M x 2 (double)] estimated landmark positions\n"); //-------------------------------------------------------------------------- // Load input double * W; uint32_t W_ROWS, W_COLS; FLANDMARK_Options options; uint8_t M; const mwSize *dims; double * tmp_ptr; mxArray *tmp_field_ptr, *cell_ptr; mxArray * psigs0 = mxGetField(prhs[0], 0, "PsiGS0"); dims = mxGetDimensions(psigs0); options.PSIG_ROWS[0] = dims[0]; options.PSIG_COLS[0] = dims[1]; mxArray * psigs1 = mxGetField(prhs[0], 0, "PsiGS1"); dims = mxGetDimensions(psigs1); options.PSIG_ROWS[1] = dims[0]; options.PSIG_COLS[1] = dims[1]; mxArray * psigs2 = mxGetField(prhs[0], 0, "PsiGS2"); dims = mxGetDimensions(psigs2); options.PSIG_ROWS[2] = dims[0]; options.PSIG_COLS[2] = dims[1]; int tsize = -1, rows = -1, cols = -1; double * result; bool lossy = (nrhs > 4) ? true : false; // options ---------------------------------------------------------------- //options.M = 7; tmp_field_ptr = mxGetField(prhs[0], 0, "M"); tmp_ptr = (double*)mxGetPr(tmp_field_ptr); options.M = (int)tmp_ptr[0]; M = options.M; //int mapTable[7*4]; int * mapTable = (int*)calloc(M*4, sizeof(int)); options.S = (int*)calloc(4*M, sizeof(int)); // options.S --------------------------------------------------- tmp_field_ptr = mxGetField(prhs[0], 0, "S"); dims = mxGetDimensions(tmp_field_ptr); tmp_ptr = (double*)mxGetPr(tmp_field_ptr); for (int i = 0; i < 4*options.M; ++i) { options.S[i] = (int)tmp_ptr[i]; } // W ---------------------------------------------------------------------- dims = mxGetDimensions(prhs[1]); W_ROWS = dims[0]; W_COLS = dims[1]; bool WisSparse = mxIsSparse(prhs[1]); if (WisSparse) { W = (double*)calloc(W_ROWS*W_COLS, sizeof(double)); double * pr = (double*)mxGetPr(prhs[1]); mwIndex * ir = mxGetIr(prhs[1]); mwSize nzmax = mxGetNzmax(prhs[1]); for (int ii = 0; ii < nzmax; ++ii) { W[ir[ii]] = pr[ii]; } } else { W = (double*)mxGetPr(prhs[1]); } // ------------------------------------------------------------------------ // mapTable tmp_ptr = (double*)mxGetPr(prhs[2]); dims = mxGetDimensions(prhs[2]); if (dims[0]*dims[1] != M*4) { mexErrMsgTxt("mapTable must be a matrix [M x 4 (double)]"); } for (int i = 0; i < M*4; ++i) { mapTable[i] = (int)tmp_ptr[i]; } // prepare output matrix plhs[0] = mxCreateNumericMatrix(2, M, mxDOUBLE_CLASS, mxREAL); result = (double*)mxGetPr(plhs[0]); //-------------------------------------------------------------------------- // get Q, G double ** q = (double**)calloc(M, sizeof(double*)); double ** g = (double**)calloc((M-1), sizeof(double*)); int idx_qtemp = 0; double * L; for (int idx = 0; idx < M; ++idx) { // Q tsize = mapTable[INDEX(idx, 1, M)] - mapTable[INDEX(idx, 0, M)] + 1; double * q_temp = (double*)calloc(tsize, sizeof(double)); memcpy(q_temp, W+mapTable[INDEX(idx, 0, M)]-1, tsize*sizeof(double)); // sparse dot product <W_q, PSI_q> cell_ptr = mxGetCell(prhs[3], idx); dims = mxGetDimensions(cell_ptr); cols = dims[1]; rows = dims[0]; uint32_t *psi_temp = (uint32_t*)mxGetPr(cell_ptr); if (lossy) { L = (double*)mxGetPr(mxGetCell(prhs[4], idx)); } q[idx] = (double*)malloc(cols*sizeof(double)); for (int i = 0; i < cols; ++i) { double dotprod = 0.0f; for (int j = 0; j < rows; ++j) { idx_qtemp = psi_temp[(rows*i) + j]; dotprod += q_temp[ idx_qtemp ]; } q[idx][i] = dotprod; if (lossy) { q[idx][i] += L[i]; } } free(q_temp); // G if (idx > 0) { tsize = mapTable[INDEX(idx, 3, M)] - mapTable[INDEX(idx, 2, M)] + 1; g[idx - 1] = (double*)malloc(tsize*sizeof(double)); memcpy(g[idx - 1], W+mapTable[INDEX(idx, 2, M)]-1, tsize*sizeof(double)); } } // compute argmax int * indices = (int*)malloc(M*sizeof(int)); tsize = mapTable[INDEX(1, 3, M)] - mapTable[INDEX(1, 2, M)] + 1; // left branch - store maximum and index of s5 for all positions of s1 dims = mxGetDimensions(mxGetCell(prhs[3], 1)); int q1_length = dims[1]; double * s1 = (double *)calloc(2*q1_length, sizeof(double)); double * s1_maxs = (double *)calloc(q1_length, sizeof(double)); for (int i = 0; i < q1_length; ++i) { // dot product <g_5, PsiGS1> dims = mxGetDimensions(mxGetCell(psigs1, INDEX(i, 0, options.PSIG_ROWS[1]))); maximize_gdotprod( &s1[INDEX(0, i, 2)], &s1[INDEX(1, i, 2)], q[5], g[4], (double*)mxGetPr(mxGetCell(psigs1, INDEX(i, 0, options.PSIG_ROWS[1]))), dims[1], tsize); s1[INDEX(0, i, 2)] += q[1][i]; } for (int i = 0; i < q1_length; ++i) { s1_maxs[i] = s1[INDEX(0, i, 2)]; } // right branch (s2->s6) - store maximum and index of s6 for all positions of s2 dims = mxGetDimensions(mxGetCell(prhs[3], 2)); int q2_length = dims[1]; double * s2 = (double *)calloc(2*q2_length, sizeof(double)); double * s2_maxs = (double *)calloc(q2_length, sizeof(double)); for (int i = 0; i < q2_length; ++i) { // dot product <g_6, PsiGS2> dims = mxGetDimensions(mxGetCell(psigs2, INDEX(i, 0, options.PSIG_ROWS[2]))); maximize_gdotprod( &s2[INDEX(0, i, 2)], (double*)&s2[INDEX(1, i, 2)], q[6], g[5], (double*)mxGetPr(mxGetCell(psigs2, INDEX(i, 0, options.PSIG_ROWS[2]))), dims[1], tsize); s2[INDEX(0, i, 2)] += q[2][i]; } for (int i = 0; i < q2_length; ++i) { s2_maxs[i] = s2[INDEX(0, i, 2)]; } // the root s0 and its connections dims = mxGetDimensions(mxGetCell(prhs[3], 0)); int q0_length = dims[1]; double maxs0 = -FLT_MAX; int maxs0_idx = -1; double maxq10 = -FLT_MAX, maxq20 = -FLT_MAX, maxq30 = -FLT_MAX, maxq40 = -FLT_MAX, maxq70 = -FLT_MAX; double * s0 = (double *)calloc(M*q0_length, sizeof(double)); for (int i = 0; i < q0_length; ++i) { // q10 maxq10 = -FLT_MAX; dims = mxGetDimensions(mxGetCell(psigs0, INDEX(i, 0, options.PSIG_ROWS[0]))); maximize_gdotprod( &maxq10, &s0[INDEX(1, i, M)], s1_maxs, g[0], (double*)mxGetPr(mxGetCell(psigs0, INDEX(i, 0, options.PSIG_ROWS[0]))), dims[1], tsize); s0[INDEX(5, i, M)] = s1[INDEX(1, (int)s0[INDEX(1, i, M)], 2)]; // q20 maxq20 = -FLT_MAX; dims = mxGetDimensions(mxGetCell(psigs0, INDEX(i, 1, options.PSIG_ROWS[0]))); maximize_gdotprod( &maxq20, &s0[INDEX(2, i, M)], s2_maxs, g[1], (double*)mxGetPr(mxGetCell(psigs0, INDEX(i, 1, options.PSIG_ROWS[0]))), dims[1], tsize); s0[INDEX(6, i, M)] = s2[INDEX(1, (int)s0[INDEX(2, i, M)], 2)]; // q30 maxq30 = -FLT_MAX; dims = mxGetDimensions(mxGetCell(psigs0, INDEX(i, 2, options.PSIG_ROWS[0]))); maximize_gdotprod( &maxq30, &s0[INDEX(3, i, M)], q[3], g[2], (double*)mxGetPr(mxGetCell(psigs0, INDEX(i, 2, options.PSIG_ROWS[0]))), dims[1], tsize); // q40 maxq40 = -FLT_MAX; dims = mxGetDimensions(mxGetCell(psigs0, INDEX(i, 3, options.PSIG_ROWS[0]))); maximize_gdotprod( &maxq40, &s0[INDEX(4, i, M)], q[4], g[3], (double*)mxGetPr(mxGetCell(psigs0, INDEX(i, 3, options.PSIG_ROWS[0]))), dims[1], tsize); // q70 maxq70 = -FLT_MAX; dims = mxGetDimensions(mxGetCell(psigs0, INDEX(i, 4, options.PSIG_ROWS[0]))); maximize_gdotprod( &maxq70, &s0[INDEX(7, i, M)], q[7], g[6], (double*)mxGetPr(mxGetCell(psigs0, INDEX(i, 4, options.PSIG_ROWS[0]))), dims[1], tsize); // sum q10+q20+q30+q40+q70 if (maxs0 < maxq10+maxq20+maxq30+maxq40+maxq70+q[0][i]) { maxs0_idx = i; s0[INDEX(0, i, M)] = i; maxs0 = maxq10+maxq20+maxq30+maxq40+maxq70+q[0][i]; } } // get indices for (int i = 0; i < M; ++i) { indices[i] = (int)s0[INDEX(0, maxs0_idx, M)+i]+1; } // cleanup temp variables free(s0); free(s1); free(s1_maxs); free(s2); free(s2_maxs); // cleanup W if it was created if (WisSparse) { free(W); } // cleanup q for (int i = 0; i < M; ++i) { free(q[i]); } free(q); // cleanup g for (int i = 0; i < M - 1; ++i) { free(g[i]); } free(g); // convert 1D indices to 2D coordinates of estimated positions int * optionsS = &options.S[0]; for (int i = 0; i < M; ++i) { int rows = optionsS[INDEX(3, i, 4)] - optionsS[INDEX(1, i, 4)] + 1; result[INDEX(0, i, 2)] = COL(indices[i], rows) + optionsS[INDEX(0, i, 4)]; result[INDEX(1, i, 2)] = ROW(indices[i], rows) + optionsS[INDEX(1, i, 4)]; } free(indices); free(options.S); free(mapTable); return; }
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"); } } }
//usage:feature = feaGen( training,depth,ndim); //state:finishing //version:v1 //notation: maximum size of buffer is 1024 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray * prhs[]) { // check the input parameter if (nlhs != 1) mexErrMsgTxt(" error in using feaGen, one output is needed"); if (nrhs != 3) mexErrMsgTxt(" error in using feaGen, three input are needed"); if (!mxIsCell(prhs[0])) { mexErrMsgTxt(" input type error"); } mxArray * pp, *ptemp; mwSize M; mwSize depth, ndim; int i, j, k, m, n, intTemp; double *pointer; //get parameter depth = mxGetScalar(prhs[1]); ndim = mxGetScalar(prhs[2]); M = mxGetM(prhs[0]); //alloc the space char *buf = (char*) mxMalloc((unsigned int) (MAXSIZE) * sizeof(char)); char ** fea; fea = (char**) mxMalloc((unsigned int) ndim * sizeof(char*)); for (i = 0; i < ndim; i++) { fea[i] = (char*) mxMalloc((unsigned int) (MAXSIZE) * sizeof(char)); } feature fv(ndim, depth, M); for (i = 0; i < M; i++) { fv.addLine(); ptemp = mxGetCell(prhs[0], i); if (mxGetString(ptemp, buf, (unsigned int) MAXSIZE)) mexErrMsgTxt("error in the buffer of this function:line53"); #ifdef debug mexPrintf("%s",buf); #endif for (j = 0; buf[j] != '\0'; j++) { intTemp = char2num(buf[j]); for (int l = 0; l < ndim; l++) { fea[l][j] = (int)(intTemp & 0x1) + '0'; intTemp >>= 1; } } int len = j; #ifdef debug mexPrintf("%s",len); #endif char *temp; temp = (char*) mxMalloc((ndim * depth + 1) * sizeof(char)); for (j = 0; j <= len - depth; j++) { intTemp = 0; int mm, nn; for (nn = 0; nn < ndim; nn++) { for (mm = 0; mm < depth; mm++) { temp[intTemp++] = fea[nn][mm + j]; } } *(temp + ndim * depth) = '\0'; intTemp = ndim * depth; int index = to2num(temp, intTemp); if( index < 0 || index > power2(ndim,depth)) { mexErrMsgTxt("error in input format line:90"); } fv.store(index); } mxFree(temp); } mxFree(buf); for (i = 0; i < ndim; i++) { mxFree(fea[i]); } mxFree(fea); int lineSize = fv.getLineSize(); plhs[0] = mxCreateDoubleMatrix(fv.getLen(), lineSize, mxREAL); pointer = mxGetPr(plhs[0]); fv.transaction(pointer); }
void mexFunction(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) { char *filename; FILE *dta_file; int ret = 0; filename = (char *)malloc(1 + mxGetN(prhs[0])); mxGetString(prhs[0], filename, 1 + mxGetN(prhs[0])); char *ws = (char *)malloc(1 + mxGetN(prhs[3])); mxGetString(prhs[3], ws, 1 + mxGetN(prhs[3])); unsigned short total_names_length = 0; for(unsigned short i = 0; i < 3; i++) total_names_length += mxGetN(mxGetCell(prhs[1], i)); char *var_names_storage = (char *)malloc(3 + total_names_length); char *var_names[3]; var_names[0] = var_names_storage; var_names[1] = var_names[0] + 1 + mxGetN(mxGetCell(prhs[1], 0)); var_names[2] = var_names[1] + 1 + mxGetN(mxGetCell(prhs[1], 1)); for(unsigned short i = 0; i < 3; i++) { mxArray *the_var_name = mxGetCell(prhs[1], i); mxGetString(the_var_name, var_names[i], 1 + mxGetN(the_var_name)); } mxLogical *options = mxGetLogicals(prhs[2]); debug_msg(2, "opening: %s\n", filename); dta_file = fopen(filename, "rb"); if(!dta_file) mexErrMsgTxt("Error opening file."); // allocate on the heap so that memory debugging libraries that don't perform bounds checking // for stack based allocations will work. setup_control *setup_c = (setup_control *)malloc(sizeof(setup_control)); mx_m1_control *m1_c = (mx_m1_control *)malloc(sizeof(mx_m1_control)); mx_m2_control *m2_c = (mx_m2_control *)malloc(sizeof(mx_m2_control)); mx_m173_control *m173_c = (mx_m173_control *)malloc(sizeof(mx_m173_control)); mx_m211_control *m211_c = (mx_m211_control *)malloc(sizeof(mx_m211_control)); m110_data *p_info = (m110_data *)malloc(sizeof(m110_data)); memset(setup_c, 0, sizeof(setup_control)); memset(m1_c, 0, sizeof(mx_m1_control)); memset(m2_c, 0, sizeof(mx_m2_control)); memset(m173_c, 0, sizeof(mx_m173_control)); memset(m211_c, 0, sizeof(mx_m211_control)); memset(p_info, 0, sizeof(m110_data)); int n_pp_segs = 0; setup_c->m1_c = m1_c; setup_c->m2_c = m2_c; setup_c->m173_c = m173_c; setup_c->m211_c = m211_c; setup_c->input_file_handle = dta_file; setup_c->options = options; m1_c->partial_power_segs_p = m2_c->partial_power_segs_p = &n_pp_segs; m173_c->n_hitbased = m1_c->n_hitbased; m1_c->has_waveforms = &m173_c->has_waveforms; m1_c->process_waveforms = (bool)options[2]; m1_c->last_waveform_tot = m173_c->last_tot; m173_c->last_hit_tot = m1_c->last_tot; for(int i=0; i < (__AE_NUM_CHANNELS + 1); i++) { m173_c->last_tot[i] = -1.0; m1_c->last_tot[i] = -1.0; } m1_c->parametric_info = p_info; memset(mx_ctx, NULL, sizeof(mx_ctx)); mx_ctx[1] = m1_c; mx_ctx[2] = m2_c; mx_ctx[5] = m1_c; mx_ctx[6] = m2_c; mx_ctx[8] = dta_file; mx_ctx[23] = m173_c; mx_ctx[24] = m173_c; mx_ctx[26] = m173_c; mx_ctx[42] = dta_file; mx_ctx[109] = &n_pp_segs; mx_ctx[106] = setup_c; mx_ctx[110] = m1_c; mx_ctx[128] = setup_c; mx_ctx[173] = m173_c; mx_ctx[211] = m211_c; mx_setup_handlers_init(options[0], options[1], options[2], options[3]); parse_dta_file(mx_handlers, mx_ctx, dta_file); ret = setup(setup_c); if(ret != 0) { debug_msg(CRITICAL_MSG, "Setup was not successful\n"); goto done; } rewind(dta_file); debug_msg(2, "setup complete...\n"); mx_handlers_init(options[0], options[1], options[2], options[3]); parse_dta_file(mx_handlers, mx_ctx, dta_file); debug_msg(2, "parsing complete...\n"); if(options[0]) mexPutVariable(ws, var_names[0], m1_c->matlab_array_handle); if(options[1]) mexPutVariable(ws, var_names[1], m2_c->matlab_array_handle); if(options[3]) mexPutVariable(ws, var_names[2], m211_c->matlab_array_handle); debug_msg(2, "done...\n"); done: if(m1_c->characteristics) free(m1_c->characteristics); if(m2_c->characteristics) free(m2_c->characteristics); if(m2_c->parametrics) free(m2_c->parametrics); if(p_info->pids) free(p_info->pids); free(setup_c); free(m1_c); free(m2_c); free(m173_c); free(m211_c); free(p_info); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { PVs pvs = { {0} }; int i,j,ij,n; LcaError theErr; MultiArgRec args[1]; enum_states *strbuf MAY_ALIAS = 0; mxArray *tmp; lcaErrorInit(&theErr); LHSCHECK(nlhs, plhs); if ( nlhs > 1 ) { lcaSetError(&theErr, EZCA_INVALIDARG, "Too many output args"); goto cleanup; } if ( nrhs < 1 || nrhs > 1 ) { lcaSetError(&theErr, EZCA_INVALIDARG, "Expected 1 rhs argument"); goto cleanup; } if ( buildPVs(prhs[0], &pvs, &theErr) ) goto cleanup; MSetArg(args[0], sizeof(*strbuf), 0, &strbuf); if ( !multi_ezca_get_misc(pvs.names, pvs.m, (MultiEzcaFunc)ezcaGetEnumStrings, NumberOf(args), args, &theErr) ) goto cleanup; n = EZCA_ENUM_STATES; /* convert string array to a matlab cell array of matlab strings */ if ( !(plhs[0] = mxCreateCellMatrix(pvs.m, n)) ) { lcaSetError(&theErr, EZCA_FAILEDMALLOC, "Not enough memory"); goto cleanup; } ij = 0; for ( j = 0; j < n; j++ ) { for ( i = 0; i < pvs.m; i++ ) { if ( !(tmp = mxCreateString(strbuf[i][j])) ) { for ( j=0; j<ij; j++ ) { mxDestroyArray(mxGetCell(plhs[0],ij)); } mxDestroyArray(plhs[0]); plhs[0] = 0; lcaSetError(&theErr, EZCA_FAILEDMALLOC, "Not enough memory"); goto cleanup; } mxSetCell(plhs[0], ij, (mxArray*)tmp); ij++; } } nlhs = 0; cleanup: if ( strbuf ) lcaFree( strbuf ); releasePVs(&pvs); /* do this LAST (in case mexErrMsgTxt is called) */ ERR_CHECK(nlhs, plhs, &theErr); }
void mexFunction (int nout, mxArray ** out, int nin, mxArray const ** in) { SAMPLE sample; /* training sample */ LEARN_PARM learn_parm; KERNEL_PARM kernel_parm; STRUCT_LEARN_PARM struct_parm; STRUCTMODEL structmodel; int alg_type; enum {IN_ARGS=0, IN_SPARM} ; enum {OUT_W=0} ; /* SVM-light is not fully reentrant, so we need to run this patch first */ init_qp_solver() ; verbosity = 0 ; kernel_cache_statistic = 0 ; if (nin != 2) { mexErrMsgTxt("Two arguments required") ; } /* Parse ARGS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ char arg [1024 + 1] ; int argc ; char ** argv ; if (! uIsString(in[IN_ARGS], -1)) { mexErrMsgTxt("ARGS must be a string") ; } mxGetString(in[IN_ARGS], arg, sizeof(arg) / sizeof(char)) ; arg_split (arg, &argc, &argv) ; svm_struct_learn_api_init(argc+1, argv-1) ; read_input_parameters (argc+1,argv-1, &verbosity, &struct_verbosity, &struct_parm, &learn_parm, &kernel_parm, &alg_type ) ; if (kernel_parm.kernel_type != LINEAR && kernel_parm.kernel_type != CUSTOM) { mexErrMsgTxt ("Only LINEAR or CUSTOM kerneles are supported") ; } /* Parse SPARM ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ mxArray const * sparm_array = in [IN_SPARM] ; mxArray const * patterns_array ; mxArray const * labels_array ; mxArray const * kernelFn_array ; int numExamples, ei ; if (! sparm_array) { mexErrMsgTxt("SPARM must be a structure") ; } struct_parm.mex = sparm_array ; patterns_array = mxGetField(sparm_array, 0, "patterns") ; if (! patterns_array || ! mxIsCell(patterns_array)) { mexErrMsgTxt("SPARM.PATTERNS must be a cell array") ; } numExamples = mxGetNumberOfElements(patterns_array) ; labels_array = mxGetField(sparm_array, 0, "labels") ; if (! labels_array || ! mxIsCell(labels_array) || ! mxGetNumberOfElements(labels_array) == numExamples) { mexErrMsgTxt("SPARM.LABELS must be a cell array " "with the same number of elements of " "SPARM.PATTERNS") ; } sample.n = numExamples ; sample.examples = (EXAMPLE *) my_malloc (sizeof(EXAMPLE) * numExamples) ; for (ei = 0 ; ei < numExamples ; ++ ei) { sample.examples[ei].x.mex = mxGetCell(patterns_array, ei) ; sample.examples[ei].y.mex = mxGetCell(labels_array, ei) ; sample.examples[ei].y.isOwner = 0 ; } if (struct_verbosity >= 1) { mexPrintf("There are %d training examples\n", numExamples) ; } kernelFn_array = mxGetField(sparm_array, 0, "kernelFn") ; if (! kernelFn_array && kernel_parm.kernel_type == CUSTOM) { mexErrMsgTxt("SPARM.KERNELFN must be define for CUSTOM kernels") ; } if (kernelFn_array) { MexKernelInfo * info ; if (mxGetClassID(kernelFn_array) != mxFUNCTION_CLASS) { mexErrMsgTxt("SPARM.KERNELFN must be a valid function handle") ; } info = (MexKernelInfo*) kernel_parm.custom ; info -> structParm = sparm_array ; info -> kernelFn = kernelFn_array ; } /* Learning ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ switch (alg_type) { case 0: svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,NSLACK_ALG) ; break ; case 1: svm_learn_struct(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,NSLACK_SHRINK_ALG); break ; case 2: svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_PRIMAL_ALG); break ; case 3: svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_DUAL_ALG); break ; case 4: svm_learn_struct_joint(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel,ONESLACK_DUAL_CACHE_ALG); break ; case 9: svm_learn_struct_joint_custom(sample,&struct_parm,&learn_parm,&kernel_parm,&structmodel); break ; default: mexErrMsgTxt("Unknown algorithm type") ; } /* Write output ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Warning: The model contains references to the original data 'docs'. If you want to free the original data, and only keep the model, you have to make a deep copy of 'model'. */ mxArray * model_array = newMxArrayEncapsulatingSmodel (&structmodel) ; out[OUT_W] = mxDuplicateArray (model_array) ; destroyMxArrayEncapsulatingSmodel (model_array) ; free_struct_sample (sample) ; free_struct_model (structmodel) ; svm_struct_learn_api_exit () ; free_qp_solver () ; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { ALLOCATES(); real *X, XX[NN], Xk[NN], XXr[NN], D[N], DS[N], fD[N], V[NN], VS[NN], *O, Ok[NN]; long k1, K1, k2, K2, k3, K3, ii, jj; int ORDER[N]; char STR[100]; enum symmetrize_ { NONE , X_Xt , Xt_X , PLUS }; enum symmetrize_ symmetrize; enum outs_types { ID , INVERSE , EIGVALS , EIGVECS , EIGVALSDIAG , MAXDIFF , SQRT , LOG , EXP , evalFUN , DET , TRACE }; enum outs_types outs[50]; int ndims, Odims[50]; real det; int oid; int D_computed, V_computed, D_sorted, V_sorted, ORDER_computed; int dim1 , dim2; mxArray *mxX; if( nlhs == 0 ){ nlhs = 1; } if( nlhs > nrhs-2 ){ myErrMsgTxt("There are no enough inputs.\n"); } if( mxIsCell( prhs[0] ) ){ mxX = mxGetCell( prhs[0] , 0 ); dim1 = myGetValue( mxGetCell( prhs[0] , 1 ) ); dim2 = myGetValue( mxGetCell( prhs[0] , 2 ) ); } else { mxX = prhs[0]; dim1 = 1; dim2 = 2; } if( ( mySize( mxX , dim1-1 ) != N ) || ( mySize( mxX , dim1-1 ) != N ) ){ myErrMsgTxt("size( X , %d ) and size( X , %d ) have to be equal to three.\n",dim1,dim2); } if( myIsEmpty( prhs[1] ) ){ symmetrize = NONE; } else if( mxIsChar(prhs[1]) ){ mxGetString( prhs[1], STR, 100 ); if( !myStrcmpi(STR,"+") ) { symmetrize = PLUS; } else if( !myStrcmpi(STR,"xt*x") || !myStrcmpi(STR,"xtx") ) { symmetrize = Xt_X; } else if( !myStrcmpi(STR,"x*xt") || !myStrcmpi(STR,"xxt") ) { symmetrize = X_Xt; } else { myErrMsgTxt("Second argument expected: 'xt*x' , 'x*xt' , '+' , or [].\n"); } } else { myErrMsgTxt("Second argument expected: 'xt*x' , 'x*xt' , '+' , or [].\n"); } for( oid = 0 ; oid < nlhs ; oid++ ){ if( ! mxIsChar(prhs[oid+2]) ){ myErrMsgTxt("Valids arguments are: 'id' 'eigval' 'eigvec' 'log' 'sqrt' 'exp' 'error'.\n"); } mxGetString( prhs[oid+2], STR, 100 ); if( !myStrcmpi(STR,"id") ) { outs[oid] = ID; } else if( !myStrcmpi(STR,"inv") || !myStrcmpi(STR,"inverse") ) { outs[oid] = INVERSE; } else if( !myStrcmpi(STR,"det") ) { outs[oid] = DET; } else if( !myStrcmpi(STR,"trace") ) { outs[oid] = TRACE; } else if( !myStrcmpi(STR,"evec") || !myStrcmpi(STR,"v") || !myStrcmpi(STR,"eigenvec") || !myStrcmpi(STR,"eigvec") || !myStrcmpi(STR,"eigenvectors") ) { outs[oid] = EIGVECS; } else if( !myStrcmpi(STR,"eval") || !myStrcmpi(STR,"d") || !myStrcmpi(STR,"eigenval") || !myStrcmpi(STR,"eigval") || !myStrcmpi(STR,"eigenvalues") ) { outs[oid] = EIGVALS; } else if( !myStrcmpi(STR,"diag") || !myStrcmpi(STR,"dd") ) { outs[oid] = EIGVALSDIAG; } else if( !myStrcmpi(STR,"error") ) { outs[oid] = MAXDIFF; } else if( !myStrcmpi(STR,"sqrt") || !myStrcmpi(STR,"sqrtm") ) { outs[oid] = SQRT; } else if( !myStrcmpi(STR,"log") || !myStrcmpi(STR,"logm") ) { outs[oid] = LOG; } else if( !myStrcmpi(STR,"exp") || !myStrcmpi(STR,"expm") ) { outs[oid] = EXP; } else { myErrMsgTxt("Valids arguments are: 'id' 'inv' 'det' 'trace' 'eigval' 'eigvec' 'log' 'sqrt' 'exp' 'error'.\n"); } } X = mxGetPr( mxX ); ndims = myGetSizes( mxX , Odims ); for( oid = 0 ; oid < nlhs ; oid++ ){ switch( outs[oid] ){ case ID: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case INVERSE: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case DET: Odims[dim1-1] = 1; Odims[dim2-1] = 1; plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); Odims[dim1-1] = N; Odims[dim2-1] = N; break; case TRACE: Odims[dim1-1] = 1; Odims[dim2-1] = 1; plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); Odims[dim1-1] = N; Odims[dim2-1] = N; break; case EIGVALS: Odims[dim2-1] = 1; plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); Odims[dim2-1] = N; break; case EIGVECS: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case EIGVALSDIAG: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case MAXDIFF: Odims[dim1-1] = 1; Odims[dim2-1] = 1; plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); Odims[dim1-1] = N; Odims[dim2-1] = N; break; case EXP: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case LOG: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case SQRT: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; case evalFUN: plhs[oid] = mxCreateNumericArray( ndims , Odims , mxREAL_CLASS , mxREAL ); break; } } K1 = 1; for( k1 = 0 ; k1 < dim1-1 ; k1++ ){ K1 *= Odims[k1]; } K2 = 1; for( k2 = dim1 ; k2 < dim2-1 ; k2++ ){ K2 *= Odims[k2]; } K3 = 1; for( k3 = dim2 ; k3 < ndims ; k3++ ){ K3 *= Odims[k3]; } for( k3 = 0 ; k3 < K3 ; k3++ ){ for( k2 = 0 ; k2 < K2 ; k2++ ){ for( k1 = 0 ; k1 < K1 ; k1++ ){ if( K1 == 1 && K2 == 1 ){ memcpy( Xk , X + k3*NN , NN*sizeof( real ) ); } else { for( jj = 0 ; jj < N ; jj++ ){ for( ii = 0 ; ii < N ; ii++ ){ Xk[ ii + N*jj ] = X[ k1 + K1*( ii + N*( k2 + K2*( jj + N*k3 ))) ]; } } } switch( symmetrize ){ case NONE: memcpy( XX , Xk , NN*sizeof( real ) ); break; case X_Xt: XX[0] = Xk[0]*Xk[0] + Xk[2]*Xk[2]; XX[1] = Xk[1]*Xk[0] + Xk[3]*Xk[2]; XX[2] = Xk[0]*Xk[1] + Xk[2]*Xk[3]; XX[3] = Xk[1]*Xk[1] + Xk[3]*Xk[3]; break; case Xt_X: XX[0] = Xk[0]*Xk[0] + Xk[1]*Xk[1]; XX[1] = Xk[2]*Xk[0] + Xk[3]*Xk[1]; XX[2] = Xk[0]*Xk[2] + Xk[1]*Xk[3]; XX[3] = Xk[2]*Xk[2] + Xk[3]*Xk[3]; break; case PLUS: XX[0] = Xk[0]; XX[1] = XX[2] = ( Xk[1] + Xk[2] )/2.0; XX[3] = Xk[3]; break; } D_computed = 0; V_computed = 0; ORDER_computed = 0; D_sorted = 0; V_sorted = 0; for( oid = 0 ; oid < nlhs ; oid++ ){ switch( outs[oid] ){ case ID: memcpy( Ok , XX , NN*sizeof( real ) ); O = mxGetPr( plhs[oid] ); ToOutput2x2; break; case INVERSE: det = XX[0]*XX[3] - XX[1]*XX[2]; det = 1.0/det; Ok[0] = XX[3] *det; Ok[1] = -XX[1] *det; Ok[2] = -XX[2] *det; Ok[3] = XX[0] *det; O = mxGetPr( plhs[oid] ); ToOutput2x2; break; case DET: Ok[0] = XX[0]*XX[3] - XX[1]*XX[2]; O = mxGetPr( plhs[oid] ); ToOutput1x1; break; case TRACE: Ok[0] = XX[0] + XX[3]; O = mxGetPr( plhs[oid] ); ToOutput1x1; break; case EIGVALS: if( !D_computed ){ EigenValues2x2( XX , D ); D_computed = 1; } if( !ORDER_computed ){ GetOrder( D, ORDER ); ORDER_computed = 1; } if( !D_sorted ){ SortEigenValues( D, ORDER , DS ); D_sorted = 1; } memcpy( Ok , DS , N*sizeof( real ) ); O = mxGetPr( plhs[oid] ); ToOutput2x1; break; case EIGVALSDIAG: if( !D_computed ){ EigenValues2x2( XX , D ); D_computed = 1; } if( !ORDER_computed ){ GetOrder( D, ORDER ); ORDER_computed = 1; } if( !D_sorted ){ SortEigenValues( D, ORDER , DS ); D_sorted = 1; } Ok[0] = DS[0]; Ok[3] = DS[1]; Ok[1] = Ok[2] = 0; O = mxGetPr( plhs[oid] ); ToOutput2x2; break; case EIGVECS: if( !D_computed ){ EigenValues2x2( XX , D ); D_computed = 1; } if( !V_computed ){ EigenVectors2x2( XX , D , V); V_computed = 1; } if( !ORDER_computed ){ GetOrder( D, ORDER ); ORDER_computed = 1; } if( !V_sorted ){ SortEigenVectors( V, ORDER , VS); V_sorted = 1; } memcpy( Ok , VS , NN*sizeof( real ) ); O = mxGetPr( plhs[oid] ); ToOutput2x2; break; // case MAXDIFF: // if( !D_computed ){ EigenValuesSym3x3( XX , D ); D_computed = 1; } // if( !V_computed ){ EigenVectorsSym3x3( XX , D , V); V_computed = 1; } // // Ok[0] = V[0]*V[0]*D[0] + V[3]*V[3]*D[1] + V[6]*V[6]*D[2]; // Ok[1] = V[1]*V[0]*D[0] + V[4]*V[3]*D[1] + V[7]*V[6]*D[2]; // Ok[2] = V[2]*V[0]*D[0] + V[5]*V[3]*D[1] + V[8]*V[6]*D[2]; // // Ok[3] = V[0]*V[1]*D[0] + V[3]*V[4]*D[1] + V[6]*V[7]*D[2]; // Ok[4] = V[1]*V[1]*D[0] + V[4]*V[4]*D[1] + V[7]*V[7]*D[2]; // Ok[5] = V[2]*V[1]*D[0] + V[5]*V[4]*D[1] + V[8]*V[7]*D[2]; // // Ok[6] = V[0]*V[2]*D[0] + V[3]*V[5]*D[1] + V[6]*V[8]*D[2]; // Ok[7] = V[1]*V[2]*D[0] + V[4]*V[5]*D[1] + V[7]*V[8]*D[2]; // Ok[8] = V[2]*V[2]*D[0] + V[5]*V[5]*D[1] + V[8]*V[8]*D[2]; // // Ok[0] = MAX9( fabs( Ok[0] - XX[0] ) , // fabs( Ok[1] - XX[1] ) , // fabs( Ok[2] - XX[2] ) , // fabs( Ok[3] - XX[3] ) , // fabs( Ok[4] - XX[4] ) , // fabs( Ok[5] - XX[5] ) , // fabs( Ok[6] - XX[6] ) , // fabs( Ok[7] - XX[7] ) , // fabs( Ok[8] - XX[8] ) ); // // O = mxGetPr( plhs[oid] ); // ToOutput1x1; // break; // // // case SQRT: // if( !D_computed ){ EigenValuesSym3x3( XX , D ); D_computed = 1; } // if( !V_computed ){ EigenVectorsSym3x3( XX , D , V); V_computed = 1; } // // fD[0] = sqrt( D[0] ); // fD[1] = sqrt( D[1] ); // fD[2] = sqrt( D[2] ); // // FillOk; // O = mxGetPr( plhs[oid] ); // ToOutput3x3; // break; // // // case LOG: // if( !D_computed ){ EigenValuesSym3x3( XX , D ); D_computed = 1; } // if( !V_computed ){ EigenVectorsSym3x3( XX , D , V); V_computed = 1; } // // fD[0] = log( D[0] ); // fD[1] = log( D[1] ); // fD[2] = log( D[2] ); // // FillOk; // O = mxGetPr( plhs[oid] ); // ToOutput3x3; // break; #define r eval[0] #define e eval[1] #define er eval[2] case EXP: r = XX[0] - XX[3]; r = 4*XX[1]*XX[2] + r*r; if( r >= 0 ){ r = sqrt(r); e = exp( ( XX[0] + XX[3] - r )/2 )/r/2.0; er = exp(r); Ok[0] = e * ( XX[3] - XX[0] + r + er*(XX[0]-XX[3]+r) ); Ok[1] = e * XX[1] * ( er - 1 ) * 2; Ok[2] = e * XX[2] * ( er - 1 ) * 2; Ok[3] = e * ( XX[0] - XX[3] + r + er*(XX[3]-XX[0]+r) ); } else { r = sqrt( -r ); e = exp( ( XX[0] + XX[3] )/2 )/r; er = sin(r/2); Ok[0] = e * ( r*cos(r/2) + ( XX[0]-XX[3] )*er ); Ok[1] = 2 * XX[1] * e * er; Ok[2] = 2 * XX[2] * e * er; Ok[3] = e * ( r*cos(r/2) + ( XX[3]-XX[0] )*er ); } O = mxGetPr( plhs[oid] ); ToOutput2x2; break; // case evalFUN: // O = mxGetPr( plhs[oid] ) + k*NN; // if( !D_computed ){ EigenValuesSym3x3( XX , D ); D_computed = 1; } // if( !V_computed ){ EigenVectorsSym3x3( XX , D , V); V_computed = 1; } // // fD[0] = exp( D[0] ); // fD[1] = exp( D[1] ); // fD[2] = exp( D[2] ); // // mexCallMATLAB(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[], const char *name) // // FillO // break; } } }}} EXIT: myFreeALLOCATES(); }
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize n; float *b , *x; ldl_p chol; mwSize i; mwIndex *jld; s_hlevel *H; int nlevels; mxArray *C; /* Input validation */ if (nrhs !=2) mexErrMsgTxt("Wrong number of input arguments"); if (!mxIsCell(H_IN)) mexErrMsgTxt("First argument must be a Hierarchy cell"); if (!mxIsSingle(b_IN)) mexErrMsgTxt("Second argument must be a non-sparse single precision vector"); if ( (mxGetN(b_IN)!=1)) mexErrMsgTxt("Second argument must be a column vector"); n = mxGetM(b_IN); nlevels = (int) MAX(mxGetM(H_IN),mxGetN(H_IN)); H = malloc(nlevels*sizeof(s_hlevel)); if (nlevels>1) { C = mxGetCell(H_IN,nlevels-2); H[nlevels-2].islast = (boolean) *(mxGetPr(mxGetField(C,0,"islast"))); if (H[nlevels-2].islast) nlevels = nlevels-1; } for (i=0; i<nlevels; i++) { C = mxGetCell(H_IN,i); H[i].islast = (boolean) *(mxGetPr(mxGetField(C,0,"islast"))); H[i].iterative = (boolean) *(mxGetPr(mxGetField(C,0,"iterative"))); if (i<(nlevels-1)) { H[i].cI = (mIndex *) mxGetPr(mxGetField(C,0,"cI")); H[i].nc = (mSize) *(mxGetPr(mxGetField(C,0,"nc"))); H[i].invD = (float *) mxGetPr(mxGetField(C,0,"invD")); H[i].dc = (boolean) *(mxGetPr(mxGetField(C,0,"dc"))); H[i].repeat = (int) *(mxGetPr(mxGetField(C,0,"repeat"))); H[i].lws1 = (float *) mxGetPr(mxGetField(C,0,"lws1")); H[i].lws2 = (float *) mxGetPr(mxGetField(C,0,"lws2")); H[i].sws1 = (float *) mxGetPr(mxGetField(C,0,"sws1")); H[i].sws2 = (float *) mxGetPr(mxGetField(C,0,"sws2")); H[i].sws3 = (float *) mxGetPr(mxGetField(C,0,"sws3")); } if (i==0) H[i].laplacian = (boolean) *(mxGetPr(mxGetField(C,0,"laplacian"))); H[i].A.a = (float *) mxGetPr(mxGetField(mxGetField(C,0,"A"),0,"a")); H[i].A.ia = (mIndex *) mxGetPr(mxGetField(mxGetField(C,0,"A"),0,"ia")); H[i].A.ja = (mIndex *) mxGetPr(mxGetField(mxGetField(C,0,"A"),0,"ja")); H[i].A.n = (mSize) *(mxGetPr(mxGetField(mxGetField(C,0,"A"),0,"n"))); H[i].A.issym = (boolean) *(mxGetPr(mxGetField(mxGetField(C,0,"A"),0,"issym"))); if (i==(nlevels-1)){ if (!H[i].iterative){ H[i].chol.ld.a = (double *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ld"),0,"a")); H[i].chol.ld.ia = (mIndex *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ld"),0,"ia")); H[i].chol.ld.ja = (mIndex *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ld"),0,"ja")); H[i].chol.ld.n = (mSize ) *(mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ld"),0,"n"))); H[i].chol.ldT.a = (double *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ldT"),0,"a")); H[i].chol.ldT.ia = (mIndex *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ldT"),0,"ia")); H[i].chol.ldT.ja = (mIndex *) mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ldT"),0,"ja")); H[i].chol.ldT.n = (mSize ) *(mxGetPr(mxGetField(mxGetField(mxGetField(C,0,"chol"),0,"ldT"),0,"n"))); H[i].chol.p = (mIndex *) mxGetPr(mxGetField(mxGetField(C,0,"chol"),0,"p")); H[i].chol.invp = (mIndex *) mxGetPr(mxGetField(mxGetField(C,0,"chol"),0,"invp")); } else { H[i].invD = (float *) mxGetPr(mxGetField(C,0,"invD")); H[i].lws1 = (float *) mxGetPr(mxGetField(C,0,"lws1")); H[i].lws2 = (float *) mxGetPr(mxGetField(C,0,"lws2")); H[i].sws1 = (float *) mxGetPr(mxGetField(C,0,"sws1")); H[i].sws2 = (float *) mxGetPr(mxGetField(C,0,"sws2")); H[i].sws3 = (float *) mxGetPr(mxGetField(C,0,"sws3")); } } } b = (float *) mxGetPr(b_IN); x_OUT = mxCreateNumericArray(1,&n,mxSINGLE_CLASS,mxREAL); x = (float *) mxGetPr(x_OUT); preconditioner( H, b, 0, 1,x); free(H); return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int dim, m, n, l, ntot, dims[3]; float *data1, *data2, *data20, *data21, *data22, *data23,*wx, *wy, *wz; double spline, nx, ny, nz, offx, offy, offz, mx, my, mz; size_t sizebuf; if (nrhs == 6) { spline = mxGetScalar(prhs[5]); } else if (nrhs == 5) { spline = 3; } else { mexPrintf("[Gxx Gyx Gzx Gxy Gyy Gzy Gxz Gyz Gzz] = " "BsplCos2ValsMaskZero(COEFFx, COEFFy, COEFFz, " "[nx ny nz], [offx offy offz], [mx my mz], MASK, deg);\n"); mexPrintf("[in]\n"); mexPrintf("\tCOEFFx COEFFy COEFFz: bspline coefficients - " "single type\n"); mexPrintf("\t[nx ny nz] : output dimension\n"); mexPrintf("\t[offx offy offz] : offset of the origin\n"); mexPrintf("\t[mx my mz] : magnification factor for " "each direction\n"); mexPrintf("\tMASK : MASK, non zeros"); mexPrintf("\tdeg : (opt) spline basis degree " "{default: 3}\n"); mexPrintf("[out]\n"); mexPrintf("\tGx Gy Gz, x y z : gradient values\n"); return; } if (mxIsSingle(prhs[0]) != 1) { mexErrMsgTxt("First argument must be of single type\n"); return; } /* Retrieve the input data */ data1 = mxGetData(prhs[0]); if (mxGetNumberOfDimensions(prhs[0]) == 2) { m = mxGetDimensions(prhs[0])[0]; n = mxGetDimensions(prhs[0])[1]; l = 1; } else if (mxGetNumberOfDimensions(prhs[0]) == 3) { m = mxGetDimensions(prhs[0])[0]; n = mxGetDimensions(prhs[0])[1]; l = mxGetDimensions(prhs[0])[2]; } else { mexErrMsgTxt("First argument must be 2D or 3D\n"); return; } ntot = mxGetNumberOfElements(prhs[1]); dim = ntot; sizebuf = mxGetElementSize(prhs[1]); if (ntot == 2) { nx = *((double*)mxGetData(prhs[1])); ny = *((double*)(mxGetData(prhs[1]) + sizebuf)); dims[0] = (int)nx; dims[1] = (int)ny; } else if (ntot == 3) { nx = *((double*)mxGetData(prhs[1])); ny = *((double*)(mxGetData(prhs[1]) + sizebuf)); nz = *((double*)(mxGetData(prhs[1]) + 2*sizebuf)); dims[0] = (int)nx; dims[1] = (int)ny; dims[2] = (int)nz; } else { mexErrMsgTxt("Second argument should be either [nx ny nz] or " "[nx ny]\n"); return; } ntot = mxGetNumberOfElements(prhs[2]); sizebuf = mxGetElementSize(prhs[2]); if (ntot == 2) { offx = *((double*)mxGetData(prhs[2])); offy = *((double*)(mxGetData(prhs[2]) + sizebuf)); } else if (ntot == 3) { offx = *((double*)mxGetData(prhs[2])); offy = *((double*)(mxGetData(prhs[2]) + sizebuf)); offz = *((double*)(mxGetData(prhs[2]) + 2*sizebuf)); } else { mexErrMsgTxt("Third argument should be either [offx offy offz]" " or [offx offy]\n"); return; } ntot = mxGetNumberOfElements(prhs[3]); sizebuf = mxGetElementSize(prhs[3]); if (ntot == 2) { mx = *((double*)mxGetData(prhs[3])); my = *((double*)(mxGetData(prhs[3]) + sizebuf)); } else if (ntot == 3) { mx = *((double*)mxGetData(prhs[3])); my = *((double*)(mxGetData(prhs[3]) + sizebuf)); mz = *((double*)(mxGetData(prhs[3]) + 2*sizebuf)); } else { mexErrMsgTxt("Fourth argument should be either [mx my mz] or" " [mx my]\n"); return; } ntot = mxGetNumberOfElements(prhs[4]); if (ntot == 0) { } else if (ntot == 2) { wx = (float*)mxGetData(mxGetCell(prhs[4], 0)); wy = (float*)mxGetData(mxGetCell(prhs[4], 1)); } else if (ntot == 3) { wx = (float*)mxGetData(mxGetCell(prhs[4], 0)); wy = (float*)mxGetData(mxGetCell(prhs[4], 1)); wz = (float*)mxGetData(mxGetCell(prhs[4], 2)); } else { mexErrMsgTxt("Fifth argument should be {}, {wx wy wz} or " "{wx wy}\n"); return; } /* Create an mxArray for the output data */ if (dim == 3) { if (nlhs == 4) { plhs[0] = mxCreateNumericArray( mxGetNumberOfElements(prhs[1]), dims, mxSINGLE_CLASS, mxREAL); plhs[1] = mxCreateNumericArray( mxGetNumberOfElements(prhs[1]), dims, mxSINGLE_CLASS, mxREAL); plhs[2] = mxCreateNumericArray( mxGetNumberOfElements(prhs[1]), dims, mxSINGLE_CLASS, mxREAL); plhs[3] = mxCreateNumericArray( mxGetNumberOfElements(prhs[1]), dims, mxSINGLE_CLASS, mxREAL); data20 = mxGetData(plhs[0]); data21 = mxGetData(plhs[1]); data22 = mxGetData(plhs[2]); data23 = mxGetData(plhs[3]); if (ntot == 0) /* no warp */ { BatchInterpolatedAll3DZero ( data20, data21, data22, data23, data1, m, n, l, nx, offx, mx, ny, offy, my, nz, offz, mz, (long)spline); } else { BatchInterpolatedAll3DZeroWarp ( data20, data21, data22, data23, data1, m, n, l, nx, offx, mx, wx, ny, offy, my, wy, nz, offz, mz, wz, (long)spline); } } else { plhs[0] = mxCreateNumericArray( mxGetNumberOfElements(prhs[1]), dims, mxSINGLE_CLASS, mxREAL); data2 = mxGetData(plhs[0]); if (ntot == 0) /* no warp */ { BatchInterpolatedValue3DZero(data2, data1, m, n, l, nx, offx, mx, ny, offy, my, nz, offz, mz, (long)spline); } else { BatchInterpolatedValue3DZeroWarp(data2, data1, m, n, l, nx, offx, mx, wx, ny, offy, my, wy, nz, offz, mz, wz, (long)spline); } } } else { if (nlhs == 3) { plhs[0] = mxCreateNumericArray( mxGetNumberOfElements(prhs[1]), dims, mxSINGLE_CLASS, mxREAL); plhs[1] = mxCreateNumericArray( mxGetNumberOfElements(prhs[1]), dims, mxSINGLE_CLASS, mxREAL); plhs[2] = mxCreateNumericArray( mxGetNumberOfElements(prhs[1]), dims, mxSINGLE_CLASS, mxREAL); data20 = mxGetData(plhs[0]); data21 = mxGetData(plhs[1]); data22 = mxGetData(plhs[2]); if (ntot == 0) /* no warp */ { BatchInterpolatedValue2DZero(data20,data1, m, n, nx, offx, mx, ny, offy, my, (long)spline); BatchInterpolatedGradX2DZero(data21,data1, m, n, nx, offx, mx, ny, offy, my, (long)spline); BatchInterpolatedGradY2DZero(data22,data1, m, n, nx, offx, mx, ny, offy, my, (long)spline); } else { BatchInterpolatedValue2DZeroWarp(data20, data1, m, n, nx, offx, mx, wx, ny, offy, my,wy, (long)spline); BatchInterpolatedGradX2DZeroWarp(data21, data1, m, n, nx, offx, mx, wx, ny, offy, my,wy, (long)spline); BatchInterpolatedGradY2DZeroWarp(data22, data1, m, n, nx, offx, mx, wx, ny, offy, my,wy, (long)spline); } } else { plhs[0] = mxCreateNumericArray( mxGetNumberOfElements(prhs[1]), dims, mxSINGLE_CLASS, mxREAL); data2 = mxGetData(plhs[0]); if (ntot == 0) /* no warp */ { BatchInterpolatedValue2DZero(data2, data1, m, n, nx, offx, mx, ny, offy, my, (long)spline); } else { BatchInterpolatedValue2DZeroWarp(data2, data1, m, n, nx, offx, mx, wx, ny, offy, my,wy, (long)spline); } } } }
// Create object from MATLAB struct variable. // mx_shear is a struct containing the following fields: // * fftPlanMany (array of forward FFT R2C plans, one multiplan per scale) // * ifftPlanMany (array of inverse FFT C2R plans, one multiplan per scale) // * fftPlanOne (one FFT R2C plan for a single image) // * filter (cell array of filters, one cell element per scale) bool ShearDictionary::loadFromMx(const mxArray* mx_shear, GPUmat* gm) { if( hasData() ) { mexErrMsgTxt( "Method ShearDictionary::loadFromMx() should only be called once" ); return false; } // Get fields mxArray* mx_filter = mxGetField( mx_shear, 0, "filter" ); mxArray* mx_fftPlanMany = mxGetField( mx_shear, 0, "fftPlanMany" ); mxArray* mx_ifftPlanMany = mxGetField( mx_shear, 0, "ifftPlanMany" ); mxArray* mx_fftPlanOne= mxGetField( mx_shear, 0, "fftPlanOne" ); // Check size of first element mxArray* mx_filter_elem = mxGetCell(mx_filter, 0); // Get attributes GPUtype firstElem = gm->gputype.getGPUtype(mx_filter_elem); m_type = gm->gputype.getType(firstElem); if( m_type != gpuCFLOAT && m_type != gpuCDOUBLE ) { mexErrMsgTxt("Filters should be complex of type GPUsingle or GPUdouble"); return false; } m_nFilterLen = gm->gputype.getSize(firstElem)[0]; // Check number of elements int numScales = (int)mxGetNumberOfElements(mx_filter); m_anNumDirections.resize(numScales); m_GPUtypeData.resize(numScales); // Check dimensions and get pointers for (int j = 0; j < numScales; j++) { mx_filter_elem = mxGetCell(mx_filter, (mwIndex)j); m_GPUtypeData[j] = gm->gputype.getGPUtype(mx_filter_elem); // Check filter type gpuTYPE_t type = gm->gputype.getType( m_GPUtypeData[j] ); if( type != m_type ) { mexErrMsgTxt("Filters should be of GPUsingle or GPUdouble and type should be consistent"); return false; } // Check filter dimensions int numDims = gm->gputype.getNdims(m_GPUtypeData[j]); const int *dims = gm->gputype.getSize(m_GPUtypeData[j]); if (numDims>2) m_anNumDirections[j] = dims[2]; else m_anNumDirections[j] = 1; if (dims[1] != (m_nFilterLen/2+1) || dims[0] != m_nFilterLen ) { mexErrMsgTxt("Filters should have same dimensions"); return false; } } // Get pointers to FFT plans m_fftPlanMany = (cufftHandle*)mxGetData( mx_fftPlanMany ); m_ifftPlanMany = (cufftHandle*)mxGetData( mx_ifftPlanMany ); m_fftPlanOne = *(cufftHandle*)mxGetData( mx_fftPlanOne ); // Set GPUmat environment m_gm = gm; return true; }
/* read in input variables and run the algorithm */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int orient, img, i, j, c, x, y; mxArray *f; c = 0; /* about active basis */ numOrient = ROUND(mxGetScalar(prhs[c++])); locationShiftLimit = ROUND(mxGetScalar(prhs[c++])); orientShiftLimit = ROUND(mxGetScalar(prhs[c++])); subsample = ROUND(mxGetScalar(prhs[c++])); numElement = ROUND(mxGetScalar(prhs[c++])); /* about input images */ numImage = ROUND(mxGetScalar(prhs[c++])); sizex = ROUND(mxGetScalar(prhs[c++])); sizey = ROUND(mxGetScalar(prhs[c++])); SUM1map = mxCalloc(numImage*numOrient, sizeof(float*)); for (img=0; img<numImage; img++) for (orient=0; orient<numOrient; orient++) { i = orient*numImage+img; f = mxGetCell(prhs[c], i); SUM1map[i] = mxGetPr(f); } c++; /* about Gabor filters */ halfFilterSize = ROUND(mxGetScalar(prhs[c++])); Correlation = mxCalloc(numOrient*numOrient, sizeof(double*)); for (orient=0; orient<numOrient; orient++) { for (j=0; j<numOrient; j++) { f = mxGetCell(prhs[c], j*numOrient+orient); Correlation[j*numOrient+orient] = mxGetPr(f); } } c++; allSymbol = mxCalloc(numOrient, sizeof(double*)); for (orient=0; orient<numOrient; orient++) { f = mxGetCell(prhs[c], orient); allSymbol[orient] = mxGetPr(f); } c++; /* about exponential model */ numStoredPoint = ROUND(mxGetScalar(prhs[c++])); storedlambda = mxGetPr(prhs[c++]); storedExpectation = mxGetPr(prhs[c++]); storedLogZ = mxGetPr(prhs[c++]); /* learned parameters of active basis */ selectedOrient = mxGetPr(prhs[c++]); selectedx = mxGetPr(prhs[c++]); selectedy = mxGetPr(prhs[c++]); selectedlambda = mxGetPr(prhs[c++]); selectedLogZ = mxGetPr(prhs[c++]); /* templates of images */ commonTemplate = mxGetPr(prhs[c++]); deformedTemplate = mxCalloc(numImage, sizeof(float*)); for (img=0; img<numImage; img++) { f = mxGetCell(prhs[c], img); deformedTemplate[img] = mxGetPr(f); } c++; for (x=1; x<=sizex; x++) for (y=1; y<=sizey; y++) commonTemplate[px(x, y, sizex, sizey)] = 0.; for (img=0; img<numImage; img++) { for (x=1; x<=sizex; x++) for (y=1; y<=sizey; y++) deformedTemplate[img][px(x, y, sizex, sizey)] = 0.; } /* MAX1 maps are smaller than SUM1 maps */ sizexSubsample = floor((double)sizex/subsample); sizeySubsample = floor((double)sizey/subsample); /* run the shared sketch algorithm */ StoreShift(); InitializeMAX1map(); PursueElement(); /* free matrices to avoid memory leak */ free_matrix(pooledMax1map, numOrient, sizexSubsample*sizeySubsample); free_matrix(MAX1map, numImage*numOrient, sizexSubsample*sizeySubsample); free_matrix(trackMap, numImage*numOrient, sizexSubsample*sizeySubsample); free_matrix(xShift, numOrient, numShift); free_matrix(yShift, numOrient, numShift); free_matrix(orientShifted, numOrient, numShift); }
void mcaMonitorEventHandler(struct event_handler_args arg) { union db_access_val *pBuf; struct mca_channel* PCHNL = (struct mca_channel*)arg.usr; double *myDblPr; chtype RequestType; int i,Cnt; mxArray* mymxArray; pBuf = (union db_access_val *)arg.dbr; //mexPrintf("MCA Monitor Event Handler Called\n"); PCHNL->MonitorEventCount++; Cnt = ca_element_count(arg.chid); RequestType = dbf_type_to_DBR(ca_field_type(arg.chid)); // Closest to the native if(RequestType==DBR_STRING) { if(Cnt==1) { mxDestroyArray(PCHNL->CACHE); // clear mxArray that pointed to by PCHNL->CACHE PCHNL->CACHE = mxCreateString((char*)((pBuf)->strval)); // Create new array with current string value mexMakeArrayPersistent(PCHNL->CACHE); } else { for(i=0;i<Cnt;i++) { mymxArray = mxGetCell(PCHNL->CACHE,i); mxDestroyArray(mymxArray); mymxArray = mxCreateString( (char*) (&(pBuf->strval)+i) ); mexMakeArrayPersistent(mymxArray); mxSetCell(PCHNL->CACHE,i,mymxArray); } } } else { myDblPr = mxGetPr(PCHNL->CACHE); switch(RequestType) { case DBR_INT: // As defined in db_access.h DBR_INT = DBR_SHORT = 1 for (i = 0; i<Cnt;i++) myDblPr[i]= (double)(*(&((pBuf)->intval)+i)); break; case DBR_FLOAT: for (i = 0; i<Cnt;i++) myDblPr[i]= (double)(*(&((pBuf)->fltval)+i)); break; case DBR_ENUM: for (i = 0; i<Cnt;i++) myDblPr[i]= (double)(*(&((pBuf)->enmval)+i)); break; case DBR_CHAR: for (i = 0; i<Cnt;i++) myDblPr[i]= (double)(*(&((pBuf)->charval)+i)); break; case DBR_LONG: for (i = 0; i<Cnt;i++) myDblPr[i]= (double)(*(&((pBuf)->longval)+i)); break; case DBR_DOUBLE: for (i = 0; i<Cnt;i++) myDblPr[i]= (double)(*(&((pBuf)->doubleval)+i)); break; } } if(PCHNL->MonitorCBString) { mexEvalString(PCHNL->MonitorCBString); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { mxArray *blk_cell_pr; double *A, *B, *AI, *BI, *blksize; mwIndex *irA, *jcA, *irB, *jcB; int *cumblksize, *blknnz; int mblk, isspA, isspB, iscmpA; mwIndex subs[2]; mwSize nsubs=2; int m, n, n2, nsub, k, index, numblk, NZmax, type; double r2; /* CHECK FOR PROPER NUMBER OF ARGUMENTS */ if (nrhs < 2){ mexErrMsgTxt("mexsvec: requires at least 2 input arguments."); } if (nlhs > 1){ mexErrMsgTxt("mexsvec: requires 1 output argument."); } /* CHECK THE DIMENSIONS */ mblk = mxGetM(prhs[0]); if (mblk > 1) { mexErrMsgTxt("mexsvec: blk can have only 1 row."); } m = mxGetM(prhs[1]); n = mxGetN(prhs[1]); if (m != n) { mexErrMsgTxt("mexsvec: matrix must be square."); } subs[0] = 0; subs[1] = 1; index = mxCalcSingleSubscript(prhs[0],nsubs,subs); blk_cell_pr = mxGetCell(prhs[0],index); numblk = mxGetN(blk_cell_pr); blksize = mxGetPr(blk_cell_pr); if (numblk == 1) { n2 = n*(n+1)/2; } else { cumblksize = mxCalloc(numblk+1,sizeof(int)); blknnz = mxCalloc(numblk+1,sizeof(int)); cumblksize[0] = 0; blknnz[0] = 0; n = 0; n2 = 0; for (k=0; k<numblk; ++k) { nsub = (int) blksize[k]; n += nsub; n2 += nsub*(nsub+1)/2; cumblksize[k+1] = n; blknnz[k+1] = n2; } } /***** assign pointers *****/ A = mxGetPr(prhs[1]); isspA = mxIsSparse(prhs[1]); iscmpA = mxIsComplex(prhs[1]); if (isspA) { irA = mxGetIr(prhs[1]); jcA = mxGetJc(prhs[1]); NZmax = mxGetNzmax(prhs[1]); } else { NZmax = n2; } if (iscmpA) { AI = mxGetPi(prhs[1]); } if ((numblk > 1) & (!isspA)) { mexErrMsgTxt("mexsvec: matrix must be sparse for numblk > 1"); } if (nrhs > 2) { if (mxGetM(prhs[2])>1) { isspB = (int)*mxGetPr(prhs[2]); } else if (NZmax < n2/2) { isspB = 1; } else { isspB = 0; } } else { if (NZmax < n2/2) { isspB = 1; } else { isspB = 0; } } if (nrhs > 3) { type = (int)*mxGetPr(prhs[3]); } else { type = 0; } /***** create return argument *****/ if (isspB) { if (iscmpA) { plhs[0] = mxCreateSparse(n2,1,NZmax,mxCOMPLEX); } else { plhs[0] = mxCreateSparse(n2,1,NZmax,mxREAL); } B = mxGetPr(plhs[0]); irB = mxGetIr(plhs[0]); jcB = mxGetJc(plhs[0]); jcB[0] = 0; } else { if (iscmpA) { plhs[0] = mxCreateDoubleMatrix(n2,1,mxCOMPLEX); } else { plhs[0] = mxCreateDoubleMatrix(n2,1,mxREAL); } B = mxGetPr(plhs[0]); } if (iscmpA) { BI = mxGetPi(plhs[0]); } /***** Do the computations in a subroutine *****/ r2 = sqrt(2); if (type == 0) { if (iscmpA) { if (numblk == 1) { svec1cmp(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI); } else { svec2cmp(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI); } } else { if (numblk == 1) { svec1(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB); } else { svec2(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB); } } } else { if (iscmpA) { if (numblk == 1) { svec3cmp(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI); } else { svec4cmp(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB,AI,BI); } } else { if (numblk == 1) { svec3(n,r2,A,irA,jcA,isspA,B,irB,jcB,isspB); } else { svec4(n,numblk,cumblksize,blknnz,r2,A,irA,jcA,isspA,B,irB,jcB,isspB); } } } return; }
// Sample factor vectors // Function written from perspective of sampling user factor vectors with cross-topics // Switch roles of user-item inputs to sample item factor vectors void sampleTopicFactorVectors(uint32_t* items, double* resids, const mxArray* exampsByUser, int KU, int KM, int numUsers, int numItems, double invSigmaSqd, ptrdiff_t numTopicFacs, double* LambdaU, double* muU, double* c, double* d, uint32_t* zU, uint32_t* zM){ // Array of random number generators gsl_rng** rngs = getRngArray(); // Extract internals of jagged arrays uint32_t** userExamps; mwSize* userLens; unpackJagged(exampsByUser, &userExamps, &userLens, numUsers); ptrdiff_t numTopicFacsSqd = numTopicFacs*numTopicFacs; ptrdiff_t numTopicFacsTimesNumItems = numTopicFacs*numItems; ptrdiff_t numTopicFacsTimesNumUsers = numTopicFacs*numUsers; // BLAS constants char uplo[] = "U"; char trans[] = "N"; char diag[] = "N"; ptrdiff_t oneInt = 1; double oneDbl = 1; double zeroDbl = 0; // Compute muBase = LambdaU*muU double* muBase = mxMalloc(numTopicFacs*sizeof(*muBase)); dsymv(uplo, &numTopicFacs, &oneDbl, LambdaU, &numTopicFacs, muU, &oneInt, &zeroDbl, muBase, &oneInt); // Allocate memory for new mean and precision parameters double** muNew[MAX_NUM_THREADS]; double** LambdaNew[MAX_NUM_THREADS]; for(int thread = 0; thread < MAX_NUM_THREADS; thread++){ muNew[thread] = mxMalloc(KM*sizeof(**muNew)); LambdaNew[thread] = mxMalloc(KM*sizeof(**LambdaNew)); for(int i = 0; i < KM; i++){ muNew[thread][i] = mxMalloc(numTopicFacs*sizeof(***muNew)); LambdaNew[thread][i] = mxMalloc(numTopicFacsSqd*sizeof(***LambdaNew)); } } #pragma omp parallel for for(int u = 0; u < numUsers; u++){ int thread = omp_get_thread_num(); for(int i = 0; i < KM; i++){ // Initialize new mean to muBase dcopy(&numTopicFacs, muBase, &oneInt, muNew[thread][i], &oneInt); // Initialize new precision to LambdaU dcopy(&numTopicFacsSqd, LambdaU, &oneInt, LambdaNew[thread][i], &oneInt); } // Iterate over user's examples mxArray* exampsArray = mxGetCell(exampsByUser, u); mwSize len = mxGetN(exampsArray); uint32_t* examps = (uint32_t*) mxGetData(exampsArray); for(int j = 0; j < len; j++){ uint32_t e = examps[j]-1; int m = items[e]-1; int userTop = zU[e]-1; int itemTop = zM[e]-1; // Item vector for this rated item double* dVec = d + m*numTopicFacs + userTop*numTopicFacsTimesNumItems; // Compute posterior sufficient statistics for factor vector // Add resid * dVec/sigmaSqd to muNew double resid = resids[e]; resid *= invSigmaSqd; daxpy(&numTopicFacs, &resid, dVec, &oneInt, muNew[thread][itemTop], &oneInt); // Add (dVec * dVec^t)/sigmaSqd to LambdaNew // Exploit symmetric structure of LambdaNew dsyr(uplo, &numTopicFacs, &invSigmaSqd, dVec, &oneInt, LambdaNew[thread][itemTop], &numTopicFacs); } for(int i = 0; i < KM; i++){ // Compute upper Cholesky factor of LambdaNew ptrdiff_t info; dpotrf(uplo, &numTopicFacs, LambdaNew[thread][i], &numTopicFacs, &info); // Solve for (LambdaNew)^-1*muNew using Cholesky factor dpotrs(uplo, &numTopicFacs, &oneInt, LambdaNew[thread][i], &numTopicFacs, muNew[thread][i], &numTopicFacs, &info); // Sample vector of N(0,1) variables gsl_rng* rng = rngs[thread]; double* cVec = c + u*numTopicFacs + i*numTopicFacsTimesNumUsers; for(int f = 0; f < numTopicFacs; f++) cVec[f] = gsl_ran_gaussian(rng, 1); // Solve for (chol(LambdaNew,'U'))^-1*N(0,1) dtrtrs(uplo, trans, diag, &numTopicFacs, &oneInt, LambdaNew[thread][i], &numTopicFacs, cVec, &numTopicFacs, &info); // Add muNew to aVec daxpy(&numTopicFacs, &oneDbl, muNew[thread][i], &oneInt, cVec, &oneInt); } } // Clean up mxFree(userExamps); mxFree(userLens); mxFree(muBase); for(int thread = 0; thread < MAX_NUM_THREADS; thread++){ for(int i = 0; i < KM; i++){ mxFree(muNew[thread][i]); mxFree(LambdaNew[thread][i]); } mxFree(muNew[thread]); mxFree(LambdaNew[thread]); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // printf("start of file \n"); // Get array_sizes const mxArray* mx_array_sizes = mexGetVariablePtr("global", "array_sizes"); if (mx_array_sizes == NULL) { mexErrMsgTxt("array_sizes not defined"); } unsigned array_sizes = (unsigned)mxGetScalar(mx_array_sizes); // Get iteration const mxArray* mx_iteration = mexGetVariablePtr("caller", "iteration"); if (mx_iteration == NULL) { mexErrMsgTxt("iteration not defined"); } double iteration = mxGetScalar(mx_iteration); // Get protection_time const mxArray* mx_protection_time = mexGetVariablePtr("caller", "protection_time"); if (mx_protection_time == NULL) { mexErrMsgTxt("protection_time not defined"); } double protection_time = mxGetScalar(mx_protection_time); // Get join_probability const mxArray* mx_join_probability = mexGetVariablePtr("caller", "join_probability"); if (mx_join_probability == NULL) { mexErrMsgTxt("join_probability not defined"); } double join_probability = mxGetScalar(mx_join_probability); // Get threshold_join_nodes const mxArray* mx_threshold_join_nodes = mexGetVariablePtr("caller", "threshold_join_nodes"); if (mx_threshold_join_nodes == NULL) { mexErrMsgTxt("threshold_join_nodes not defined"); } double threshold_join_nodes = mxGetScalar(mx_threshold_join_nodes); // Get time const mxArray* mx_time = mexGetVariablePtr("global", "time"); if (mx_time == NULL) { mexErrMsgTxt("time not defined"); } double time = mxGetScalar(mx_time); unsigned width_cell_store = mxGetN(prhs[1]); unsigned no_cells = mxGetM(prhs[2]); unsigned no_FEM_elements = mxGetM(prhs[5]); unsigned length_FEM_node_positions = mxGetM(prhs[6]); double* initial_cell_store = mxGetPr(prhs[1]); double* initial_cells_per_node = mxGetPr(prhs[3]); double* initial_Dpp = mxGetPr(prhs[4]); double* initial_FEM_elements = mxGetPr(prhs[5]); double* initial_previous_FEM_node_positions = mxGetPr(prhs[6]); double* initial_node_positions = mxGetPr(prhs[7]); double* initial_time_nodes_created = mxGetPr(prhs[8]); plhs[0] = mxCreateCellMatrix(no_cells, 1); plhs[1] = mxCreateDoubleMatrix(array_sizes, width_cell_store, mxREAL); plhs[2] = mxCreateCellMatrix(no_cells, 1); plhs[3] = mxCreateDoubleMatrix(array_sizes, 1, mxREAL); plhs[4] = mxCreateDoubleMatrix(length_FEM_node_positions, 1, mxREAL); plhs[5] = mxCreateDoubleMatrix(no_FEM_elements, 3, mxREAL); plhs[6] = mxCreateDoubleMatrix(length_FEM_node_positions, 2, mxREAL); plhs[7] = mxCreateDoubleMatrix(array_sizes, 2, mxREAL); plhs[8] = mxCreateDoubleMatrix(array_sizes, 1, mxREAL); plhs[9] = mxCreateDoubleMatrix(1, 1, mxREAL); double* final_cell_store = mxGetPr(plhs[1]); double* final_cells_per_node = mxGetPr(plhs[3]); double* final_Dpp = mxGetPr(plhs[4]); double* final_FEM_elements = mxGetPr(plhs[5]); double* final_previous_FEM_node_positions = mxGetPr(plhs[6]); double* final_node_positions = mxGetPr(plhs[7]); double* final_time_nodes_created = mxGetPr(plhs[8]); double* no_join_nodes_this_iteration = mxGetPr(plhs[9]); *no_join_nodes_this_iteration = 0; // set output matrices equal to input matrices for(unsigned current_node=0;current_node<array_sizes;current_node++){ final_cells_per_node[current_node] = initial_cells_per_node[current_node]; final_time_nodes_created[current_node] = initial_time_nodes_created[current_node]; for(unsigned dim=0;dim<2;dim++){ final_node_positions[current_node+array_sizes*dim] = initial_node_positions[current_node+array_sizes*dim]; } for(unsigned i=0;i<width_cell_store;i++){ final_cell_store[current_node+i*array_sizes] = initial_cell_store[current_node+i*array_sizes]; } } for(unsigned current_element=0;current_element<no_FEM_elements;current_element++){ for(unsigned i=0;i<3;i++){ final_FEM_elements[current_element+no_FEM_elements*i] = initial_FEM_elements[current_element+no_FEM_elements*i]; } } for(unsigned current_FEM_node=0;current_FEM_node<length_FEM_node_positions;current_FEM_node++){ final_Dpp[current_FEM_node] = initial_Dpp[current_FEM_node]; for(unsigned dim=0;dim<2;dim++){ final_previous_FEM_node_positions[current_FEM_node+length_FEM_node_positions*dim] = initial_previous_FEM_node_positions[current_FEM_node+length_FEM_node_positions*dim]; } } // set output cells equal to input cells for(unsigned current_cell=0; current_cell<no_cells; current_cell++) { mxArray* mx_initial_cell_nodes = mxGetCell(prhs[2], current_cell); unsigned no_cell_nodes = mxGetN(mx_initial_cell_nodes); double* initial_cell_nodes = mxGetPr(mx_initial_cell_nodes); mxArray* mx_final_cell_nodes = mxCreateDoubleMatrix(1, no_cell_nodes, mxREAL); double* final_cell_nodes = mxGetPr(mx_final_cell_nodes); mxArray* mx_initial_cell_elements = mxGetCell(prhs[0], current_cell); double* initial_cell_elements = mxGetPr(mx_initial_cell_elements); mxArray* mx_final_cell_elements = mxCreateDoubleMatrix(1, no_cell_nodes, mxREAL); double* final_cell_elements = mxGetPr(mx_final_cell_elements); for(unsigned i=0; i<no_cell_nodes;i++){ final_cell_nodes[i] = initial_cell_nodes[i]; final_cell_elements[i] = initial_cell_elements[i]; } mxSetCell(plhs[2], current_cell, mx_final_cell_nodes); mxSetCell(plhs[0], current_cell, mx_final_cell_elements); } bool join_logical; // loop over all cells for(unsigned current_cell_ci=0; current_cell_ci<no_cells; current_cell_ci++) { join_logical = false; // printf("start of main loop \n"); unsigned current_cell_mi = current_cell_ci+1; mxArray* mx_cell_nodes = mxGetCell(plhs[2], current_cell_ci); double* cell_nodes = mxGetPr(mx_cell_nodes); unsigned no_cell_nodes = mxGetN(mx_cell_nodes); // only proceed if there are more than 3 cell nodes if(no_cell_nodes > 3){ // loop over the nodes of the current cell for(unsigned current_node_local=0; current_node_local<no_cell_nodes; current_node_local++) { double rand_number = rand()/((double)RAND_MAX); // only proceed with p(join_probability) if(rand_number < join_probability){ // find current node and clockwise node in matlab and c indicies unsigned current_node_global_mi = (unsigned)cell_nodes[current_node_local]; unsigned current_node_global_ci = current_node_global_mi-1; unsigned clockwise_node_local = (current_node_local+1)%no_cell_nodes; unsigned clockwise_node_global_mi = (unsigned)cell_nodes[clockwise_node_local]; unsigned clockwise_node_global_ci = clockwise_node_global_mi - 1; // extract the positions of the current node and clockwise node from the node positions matrix double current_node_position[2], clockwise_node_position[2]; for(unsigned dim=0;dim<2;dim++) { current_node_position[dim] = final_node_positions[current_node_global_ci + dim*array_sizes]; clockwise_node_position[dim] = final_node_positions[clockwise_node_global_ci + dim*array_sizes]; } // find the current edge length double current_edge_length = findStraightLineDistanceBetweenTwoNodes(current_node_position, clockwise_node_position); // only proceed if edge length is less than threshold, and nodes have not been created very // recently if(current_edge_length < threshold_join_nodes && (time-final_time_nodes_created[current_node_global_ci])>protection_time && (time-final_time_nodes_created[clockwise_node_global_ci])>protection_time){ // printf("hello \n"); // look for a cell that shares the edge - we need this for a T1 swap bool cell_with_same_edge_found = false; int cell_with_same_edge_mi = -1; unsigned counter_1 = 0; // loop over all cells containing current_node_global for(unsigned i=0;i<final_cells_per_node[current_node_global_ci];i++){ unsigned temp_cell_1_mi = (unsigned)final_cell_store[current_node_global_ci + i*array_sizes]; // if not current_cell, loop over all cells containing clockwise_node_global if(temp_cell_1_mi != current_cell_mi && !cell_with_same_edge_found){ for(unsigned j=0;j<final_cells_per_node[clockwise_node_global_ci];j++){ unsigned temp_cell_2_mi = (unsigned)final_cell_store[clockwise_node_global_ci + j*array_sizes]; // if cell containing clockwise_node_global is also a cell containing current_node_global, // but not current_cell, then it is cell_with_same_edge; if(temp_cell_2_mi == temp_cell_1_mi){ cell_with_same_edge_mi = temp_cell_1_mi; cell_with_same_edge_found = true; break; } } } } if(!cell_with_same_edge_found){ join_logical = true; (*no_join_nodes_this_iteration)++; // printf("doing a join \n"); double new_node_position[2]; for(unsigned dim=0;dim<2;dim++) { new_node_position[dim] = (current_node_position[dim] + clockwise_node_position[dim])/2; } // find two unused nodes to put new nodes in unsigned new_node_ci = 0; while(final_cells_per_node[new_node_ci]>0){ new_node_ci++; } unsigned new_node_mi = new_node_ci+1; assert(new_node_mi <= array_sizes); // store new node position for(unsigned dim=0;dim<2;dim++){ final_node_positions[new_node_ci+dim*array_sizes] = new_node_position[dim]; } // set time new nodes created to current time final_time_nodes_created[new_node_ci] = time; // edit current cell nodes to contain new node instead of previous two nodes mxArray* mx_cell_nodes_edited = mxCreateDoubleMatrix(1, no_cell_nodes-1, mxREAL); double* cell_nodes_edited = mxGetPr(mx_cell_nodes_edited); int temp_counter = -1; for(unsigned temp_current_node_local=0;temp_current_node_local<no_cell_nodes;temp_current_node_local++){ unsigned temp_current_node_global_mi = (unsigned)cell_nodes[temp_current_node_local]; if(temp_current_node_global_mi==current_node_global_mi){ temp_counter++; cell_nodes_edited[temp_counter]=new_node_mi; } else if(temp_current_node_global_mi==clockwise_node_global_mi){} else{ temp_counter++; cell_nodes_edited[temp_counter]=temp_current_node_global_mi; } } mxSetCell(plhs[2], current_cell_ci, mx_cell_nodes_edited); // printf("edited current cell \n"); final_cells_per_node[new_node_ci] = 1; final_cell_store[new_node_ci] = current_cell_mi; if(final_cells_per_node[current_node_global_ci] > 1.1){ for(unsigned i=0;i<final_cells_per_node[current_node_global_ci];i++){ unsigned temp_cell_mi = (unsigned)final_cell_store[current_node_global_ci + i*array_sizes]; if(temp_cell_mi!=current_cell_mi){ unsigned temp_cell_ci = temp_cell_mi-1; mxArray* mx_cell_nodes_temp_cell = mxGetCell(plhs[2], temp_cell_ci); double* cell_nodes_temp_cell = mxGetPr(mx_cell_nodes_temp_cell); unsigned no_cell_nodes_temp_cell = mxGetN(mx_cell_nodes_temp_cell); mxArray* mx_cell_nodes_temp_cell_edited = mxCreateDoubleMatrix(1, no_cell_nodes_temp_cell, mxREAL); double* cell_nodes_temp_cell_edited = mxGetPr(mx_cell_nodes_temp_cell_edited); for(unsigned temp_current_node_local=0;temp_current_node_local<no_cell_nodes_temp_cell;temp_current_node_local++){ unsigned temp_current_node_global_mi = (unsigned)cell_nodes_temp_cell[temp_current_node_local]; if(temp_current_node_global_mi==current_node_global_mi){ cell_nodes_temp_cell_edited[temp_current_node_local] = new_node_mi; } else{ cell_nodes_temp_cell_edited[temp_current_node_local] = temp_current_node_global_mi; } } mxSetCell(plhs[2], temp_cell_ci, mx_cell_nodes_temp_cell_edited); final_cells_per_node[new_node_ci]++; unsigned matrix_index = (unsigned)(new_node_ci+array_sizes*(final_cells_per_node[new_node_ci]-1)); final_cell_store[matrix_index] = temp_cell_mi; } } // printf("edited cells with node 1 \n"); } if(final_cells_per_node[clockwise_node_global_ci] > 1.1){ for(unsigned i=0;i<final_cells_per_node[clockwise_node_global_ci];i++){ unsigned temp_cell_mi = (unsigned)final_cell_store[clockwise_node_global_ci + i*array_sizes]; if(temp_cell_mi!=current_cell_mi){ unsigned temp_cell_ci = temp_cell_mi-1; // edit stretch cell 1 by adding in two new nodes in place of current node global mxArray* mx_cell_nodes_temp_cell = mxGetCell(plhs[2], temp_cell_ci); double* cell_nodes_temp_cell = mxGetPr(mx_cell_nodes_temp_cell); unsigned no_cell_nodes_temp_cell = mxGetN(mx_cell_nodes_temp_cell); mxArray* mx_cell_nodes_temp_cell_edited = mxCreateDoubleMatrix(1, no_cell_nodes_temp_cell, mxREAL); double* cell_nodes_temp_cell_edited = mxGetPr(mx_cell_nodes_temp_cell_edited); for(unsigned temp_current_node_local=0;temp_current_node_local<no_cell_nodes_temp_cell;temp_current_node_local++){ unsigned temp_current_node_global_mi = (unsigned)cell_nodes_temp_cell[temp_current_node_local]; if(temp_current_node_global_mi==clockwise_node_global_mi){ cell_nodes_temp_cell_edited[temp_current_node_local] = new_node_mi; } else{ cell_nodes_temp_cell_edited[temp_current_node_local] = temp_current_node_global_mi; } } mxSetCell(plhs[2], temp_cell_ci, mx_cell_nodes_temp_cell_edited); // add stretch cell 1 to cells_per_node and cell_store for new_node and new_node_2 final_cells_per_node[new_node_ci]++; unsigned matrix_index = (unsigned)(new_node_ci+array_sizes*(final_cells_per_node[new_node_ci]-1)); final_cell_store[matrix_index] = temp_cell_mi; } } printf("edited cells with node 2 \n"); } // reset cells per node and cell store for current_node_global and clockwise_node_global. // they should no longer be part of any cells, unless something has gone horribly wrong. final_cells_per_node[current_node_global_ci] = 0; final_cells_per_node[clockwise_node_global_ci] = 0; for(unsigned i=0;i<width_cell_store;i++){ final_cell_store[current_node_global_ci+i*array_sizes] = 0; final_cell_store[clockwise_node_global_ci+i*array_sizes] = 0; } for(unsigned dim=0;dim<2;dim++){ final_node_positions[current_node_global_ci+dim*array_sizes] = 0; final_node_positions[clockwise_node_global_ci+dim*array_sizes] = 0; } } } } if(join_logical){break;} } } if(join_logical){break;} } }