//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[]) { /* Declaration of input and output arguments. */ double *x, *u, **p, *dx, *y, *t; int i, np, nu, nx; const mxArray *auxvar = NULL; /* Cell array of additional data. */ if (nrhs < 3) { mexErrMsgIdAndTxt("IDNLGREY:ODE_FILE:InvalidSyntax", "At least 3 inputs expected (t, u, x)."); } /* Determine if auxiliary variables were passed as last input. */ if ((nrhs > 3) && (mxIsCell(prhs[nrhs-1]))) { /* Auxiliary variables were passed as input. */ auxvar = prhs[nrhs-1]; np = nrhs - 4; /* Number of parameters (could be 0). */ } else { /* Auxiliary variables were not passed. */ np = nrhs - 3; /* Number of parameters. */ } /* Determine number of inputs and states. */ nx = mxGetNumberOfElements(prhs[1]); /* Number of states. */ nu = mxGetNumberOfElements(prhs[2]); /* Number of inputs. */ /* Obtain double data pointers from mxArrays. */ t = mxGetPr(prhs[0]); /* Current time value (scalar). */ x = mxGetPr(prhs[1]); /* States at time t. */ u = mxGetPr(prhs[2]); /* Inputs at time t. */ p = mxCalloc(np, sizeof(double*)); for (i = 0; i < np; i++) { p[i] = mxGetPr(prhs[3+i]); /* Parameter arrays. */ } /* Create matrix for the return arguments. */ plhs[0] = mxCreateDoubleMatrix(nx, 1, mxREAL); plhs[1] = mxCreateDoubleMatrix(NY, 1, mxREAL); dx = mxGetPr(plhs[0]); /* State derivative values. */ y = mxGetPr(plhs[1]); /* Output values. */ /* Call the state and output update functions. Note: You may also pass other inputs that you might need, such as number of states (nx) and number of parameters (np). You may also omit unused inputs (such as auxvar). For example, you may want to use orders nx and nu, but not time (t) or auxiliary data (auxvar). You may write these functions as: compute_dx(dx, nx, nu, x, u, p); compute_y(y, nx, nu, x, u, p); */ /* Call function for state derivative update. */ compute_dx(dx, t[0], x, u, p, auxvar); /* Call function for output update. */ compute_y(y, t[0], x, u, p, auxvar); /* Clean up. */ mxFree(p); }
//Main Function void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) { //Input Args double *f, *A = NULL, *b = NULL, *lb = NULL, *ub = NULL, *y0 = NULL; double *sdpDIM = NULL, *SDP_pr = NULL; //Return Args double *x, *pval, *dval, *exitflag, *iter, *pdflag; //Options (most get defaults written in) int maxiter = 1500; int reuse=4,rpos=0,drho=1,ndim,sdpnmax=1; double penalty,rho,dbound,dlbound,zbar,r0,mu0,ylow,yhigh,gaptol,pnormtol,maxtrust,steptol,inftol,infptol; double lpb=1.0, datanorm[3], *dreuse, *fixed = NULL; //Internal Vars size_t nlincon = 0, ndec = 0, ncones = 0, nfix = 0; size_t lincon_nz = 0; size_t i, j; size_t nLB = 0, nUB = 0; int *temp_ir = NULL, *temp_jc = NULL; double *temp_pr = NULL; const char *onames[2] = {"pval","dval"}; const char *fnames[11] = {"iter","pdflag","r","mu","pstep","dstep","pnorm","ynorm","tracex","reuse","rho"}; double evaltime, *X = NULL; int iters = 0, status, indcell = 0; //DSDP Vars DSDP dsdp; SDPCone sdpcone = NULL; LPCone lpcone = NULL; BCone bcone = NULL; DSDPTerminationReason reason; DSDPSolutionType pdfeasible; //Sparse Indicing mwIndex *A_ir, *A_jc; //Version Return if(nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString(DSDP_VERSION); return; } //Check Inputs checkInputs(prhs,nrhs); //Get pointers to Input variables f = mxGetPr(pF); ndec = mxGetNumberOfElements(pF); if(!mxIsEmpty(pA)) { A = mxGetPr(pA); A_ir = mxGetIr(pA); A_jc = mxGetJc(pA); b = mxGetPr(pB); nlincon = mxGetM(pA); lincon_nz = A_jc[mxGetN(pA)]; } if(nrhs > eLB && !mxIsEmpty(pLB)) lb = mxGetPr(pLB); if(nrhs > eUB && !mxIsEmpty(pUB)) ub = mxGetPr(pUB); if(nrhs > eSDP && !mxIsEmpty(pSDP)) { if(mxIsCell(pSDP)) ncones = mxGetNumberOfElements(pSDP); else ncones = 1; } if(nrhs > eY0 && !mxIsEmpty(pY0)) y0 = mxGetPr(pY0); if(nrhs > eOPTS && !mxIsEmpty(pOPTS) && mxGetField(pOPTS,0,"fixed") && !mxIsEmpty(mxGetField(pOPTS,0,"fixed"))) { fixed = mxGetPr(mxGetField(pOPTS,0,"fixed")); nfix = mxGetM(mxGetField(pOPTS,0,"fixed")); } //Create Outputs plhs[0] = mxCreateDoubleMatrix(ndec,1, mxREAL); plhs[1] = mxCreateStructMatrix(1,1,2,onames); mxSetField(plhs[1],0,onames[0],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[1],0,onames[1],mxCreateDoubleMatrix(1,1, mxREAL)); plhs[2] = mxCreateDoubleMatrix(1,1, mxREAL); x = mxGetPr(plhs[0]); pval = mxGetPr(mxGetField(plhs[1],0,onames[0])); dval = mxGetPr(mxGetField(plhs[1],0,onames[1])); exitflag = mxGetPr(plhs[2]); //Info Output plhs[3] = mxCreateStructMatrix(1,1,11,fnames); mxSetField(plhs[3],0,fnames[0],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[1],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[2],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[3],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[4],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[5],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[6],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[7],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[8],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[9],mxCreateDoubleMatrix(1,1, mxREAL)); mxSetField(plhs[3],0,fnames[10],mxCreateDoubleMatrix(1,1, mxREAL)); iter = mxGetPr(mxGetField(plhs[3],0,fnames[0])); pdflag = mxGetPr(mxGetField(plhs[3],0,fnames[1])); dreuse = mxGetPr(mxGetField(plhs[3],0,"reuse")); if(nlhs > 4) plhs[4] = mxCreateCellMatrix(ncones+(int)(nlincon>0)+(int)(nfix>0),1); //Set Defaults maxtime = 1000; printLevel = 0; //Create DSDP Problem DSDP_ERR( DSDPCreate((int)ndec,&dsdp), "Error Creating DSDP Problem"); //Set Monitor DSDP_ERR( DSDPSetMonitor(dsdp,DSDPMonitor,0), "Error Setting DSDP Monitor"); //Set Dual Objective for (i=0;i<ndec;i++){ DSDP_ERR( DSDPSetDualObjective(dsdp,(int)i+1,f[i]), "Error Adding Objective Coefficients"); } //Check finite bounds for allocation if(lb || ub) for(i=0;i<ndec;i++) { if(lb) if(!mxIsInf(lb[i])) nLB++; if(ub) if(!mxIsInf(ub[i])) nUB++; } //Set Bounds as BCone if(nLB || nUB) { DSDP_ERR( DSDPCreateBCone(dsdp, &bcone), "Error creating BCone"); DSDP_ERR( BConeAllocateBounds(bcone, (int)(nLB+nUB)), "Error allocating bounds"); for(i=0;i<ndec;i++) { if(nLB > 0 && !mxIsInf(lb[i])) DSDP_ERR( BConeSetLowerBound(bcone, (int)i+1, lb[i]), "Error setting lower bound"); if(nUB > 0 && !mxIsInf(ub[i])) DSDP_ERR( BConeSetUpperBound(bcone, (int)i+1, ub[i]), "Error setting upper bound"); } } //Set Linear Inequality Constraints as LPCone if(nlincon) { int M = (int)mxGetM(pA); int N = (int)mxGetN(pA); DSDP_ERR( DSDPCreateLPCone(dsdp, &lpcone), "Error creating LPCone (inequalities)"); //Create Memory to store A*x <= b in dsdp and integer format temp_jc = mxCalloc(N+2,sizeof(int)); temp_ir = mxCalloc(lincon_nz+M,sizeof(int)); temp_pr = mxCalloc(lincon_nz+M,sizeof(double)); //Copy over linear A for(i=0;i<=(size_t)N;i++) temp_jc[i] = (int)A_jc[i]; for(i=0;i<lincon_nz;i++) { temp_ir[i] = (int)A_ir[i]; temp_pr[i] = A[i]; } //Append linear rhs (b) temp_jc[N+1] = temp_jc[N] + M; for(i=lincon_nz,j=0;j<(size_t)M;j++) { if(b[j] != 0) { temp_ir[i] = (int)j; temp_pr[i++] = b[j]; } else temp_jc[N+1]--; } #ifdef DEBUG mexPrintf("---- Inequality Constraints ----\n"); for(i=0;i<=(size_t)(N+1);i++) mexPrintf("jc[%d] = %d\n",i,temp_jc[i]); for(i=0;i<lincon_nz+M;i++) mexPrintf("ir[%d] = %d, pr[%d] = %f\n",i,temp_ir[i],i,temp_pr[i]); #endif //Set LP Cone Data DSDP_ERR( LPConeSetData2(lpcone, M, temp_jc, temp_ir, temp_pr), "Error setting LP Cone data (inequality)" ); //Optionally set X data if(nlhs > 4) { mxSetCell(plhs[4],indcell,mxCreateDoubleMatrix(M,1,mxREAL)); DSDP_ERR( LPConeSetXVec(lpcone,mxGetPr(mxGetCell(plhs[4],indcell++)),M), "Error setting LP Cone X data" ); } } //Set Semidefinite Constraints as SDPCone if(ncones) { //Create the cone structure, specifying each constraint as a block DSDP_ERR( DSDPCreateSDPCone(dsdp,(int)ncones,&sdpcone), "Error creating SDPCone"); //Add each constraint cone for(i=0;i<ncones;i++) { if(ncones == 1 && !mxIsCell(pSDP)) { if(nlhs > 4) { mxSetCell(plhs[4],indcell,mxCreateDoubleMatrix(mxGetM(pSDP),1,mxREAL)); X = mxGetPr(mxGetCell(plhs[4],indcell++)); } ndim = addSDPCone(sdpcone,pSDP,(int)i,X); } else { if(nlhs > 4) { mxSetCell(plhs[4],indcell,mxCreateDoubleMatrix(mxGetM(mxGetCell(pSDP,i)),1,mxREAL)); X = mxGetPr(mxGetCell(plhs[4],indcell++)); } ndim = addSDPCone(sdpcone,mxGetCell(pSDP,i),(int)i,X); } //Update max dim if(sdpnmax < ndim) sdpnmax = ndim; } } //Set y0 if (y0) for (i=0;i<ndec;i++) { DSDP_ERR( DSDPSetY0(dsdp,(int)i+1,y0[i]), "Error setting Y0"); } //Determine whether to reuse schur complement matrix (dsdp authors' heuristic) if(ndec == 1) reuse = 1/sdpnmax; else reuse = ((int)ndec-2)/sdpnmax; if (ndec<50 && reuse==0) reuse=1; if (reuse>=1) reuse++; reuse=reuse*reuse; if (ndec<2000 && ndec>10) reuse=10; if (ndec>12) reuse=12; //Get DSDP Default Options DSDP_ERR( DSDPGetR(dsdp,&r0), "Error Getting R"); DSDP_ERR( DSDPGetPenaltyParameter(dsdp,&penalty), "Error Getting Penalty Parameter"); DSDP_ERR( DSDPGetPotentialParameter(dsdp,&rho), "Error Getting Potential Parameter"); DSDP_ERR( DSDPGetDualBound(dsdp,&dbound), "Error Getting Dual Bound"); DSDP_ERR( DSDPGetGapTolerance(dsdp,&gaptol), "Error Getting Gap Tolerance"); DSDP_ERR( DSDPGetRTolerance(dsdp,&inftol), "Error Getting R Tolerance"); DSDP_ERR( DSDPGetBarrierParameter(dsdp,&mu0), "Error Getting Barrier Parameter"); DSDP_ERR( DSDPGetMaxTrustRadius(dsdp,&maxtrust), "Error Getting Max Trust Radius"); DSDP_ERR( DSDPGetStepTolerance(dsdp,&steptol), "Error Getting Step Tolerance"); DSDP_ERR( DSDPGetPTolerance(dsdp,&infptol), "Error Getting P Tolerance"); DSDP_ERR( DSDPGetPNormTolerance(dsdp,&pnormtol), "Error Getting PNorm Tolerance"); //Get Data Norms to establish y bounds DSDP_ERR( DSDPGetDataNorms(dsdp, datanorm), "Error Getting Data Norms"); DSDP_ERR( DSDPGetYBounds(dsdp,&ylow,&yhigh), "Error Getting Y Bounds"); if (datanorm[0]==0){DSDP_ERR( DSDPSetYBounds(dsdp,-1.0,1.0), "Error Setting Y Bounds");} //Get User Options (overwrites defaults above) if(nrhs > eOPTS && !mxIsEmpty(pOPTS)) { //OPTI Options GetIntegerOption(pOPTS,"maxiter",&maxiter); GetDoubleOption(pOPTS,"maxtime",&maxtime); GetIntegerOption(pOPTS,"display",&printLevel); //DSDP Options GetDoubleOption(pOPTS,"r0",&r0); GetDoubleOption(pOPTS,"penalty",&penalty); GetDoubleOption(pOPTS,"rho",&rho); GetDoubleOption(pOPTS,"dbound",&dbound); GetDoubleOption(pOPTS,"gaptol",&gaptol); GetDoubleOption(pOPTS,"rtol",&inftol); GetDoubleOption(pOPTS,"mu0",&mu0); GetDoubleOption(pOPTS,"maxtrust",&maxtrust); GetDoubleOption(pOPTS,"steptol",&steptol); GetDoubleOption(pOPTS,"ptol",&infptol); GetDoubleOption(pOPTS,"pnormtol",&pnormtol); GetIntegerOption(pOPTS,"reuse",&reuse); GetIntegerOption(pOPTS,"rpos",&rpos); GetIntegerOption(pOPTS,"drho",&drho); //Check and set DSDP options without valid defaults if(mxGetField(pOPTS,0,"zbar") && !mxIsEmpty(mxGetField(pOPTS,0,"zbar"))) { GetDoubleOption(pOPTS,"zbar",&zbar); DSDP_ERR( DSDPSetZBar(dsdp,zbar), "Error Setting Z Bar"); } if(mxGetField(pOPTS,0,"dlbound") && !mxIsEmpty(mxGetField(pOPTS,0,"dlbound"))) { GetDoubleOption(pOPTS,"dlbound",&dlbound); DSDP_ERR( DSDPSetDualLowerBound(dsdp,dlbound), "Error Setting Dual Lower Bound"); } if(mxGetField(pOPTS,0,"ybound") && !mxIsEmpty(mxGetField(pOPTS,0,"ybound"))) { GetDoubleOption(pOPTS,"ybound",&yhigh); ylow = -yhigh; DSDP_ERR( DSDPSetYBounds(dsdp,ylow,yhigh), "Error Setting Y Bounds"); } } //Set DSDP Options with Defaults DSDP_ERR( DSDPSetMaxIts(dsdp,maxiter), "Error Setting Max Iterations"); DSDP_ERR( DSDPSetR0(dsdp,r0), "Error Setting Option R0 "); DSDP_ERR( DSDPSetPenaltyParameter(dsdp,penalty), "Error Setting Penalty Parameter"); DSDP_ERR( DSDPSetPotentialParameter(dsdp,rho), "Error Setting Potential Parameter"); DSDP_ERR( DSDPSetDualBound(dsdp,dbound), "Error Setting Dual Bound"); DSDP_ERR( DSDPSetGapTolerance(dsdp,gaptol), "Error Setting Gap Tolerance"); DSDP_ERR( DSDPSetRTolerance(dsdp,inftol), "Error Setting R Tolerance"); DSDP_ERR( DSDPSetBarrierParameter(dsdp,mu0), "Error Setting Barrier Parameter"); DSDP_ERR( DSDPSetMaxTrustRadius(dsdp,maxtrust), "Error Setting Max Trust Radius"); DSDP_ERR( DSDPSetStepTolerance(dsdp,steptol), "Error Setting Step Tolerance") DSDP_ERR( DSDPSetPTolerance(dsdp,infptol), "Error Setting P Tolerance"); DSDP_ERR( DSDPSetPNormTolerance(dsdp,pnormtol), "Error Setting PNorm Tolerance"); if(reuse < 0) reuse = 0; if(reuse > 15) reuse = 15; DSDP_ERR( DSDPReuseMatrix(dsdp,reuse), "Error Setting Reuse Matrix"); //Set Other DSDP Options DSDP_ERR( DSDPUsePenalty(dsdp,rpos), "Error Setting Use Penalty"); DSDP_ERR( DSDPUseDynamicRho(dsdp,drho), "Error Setting Dynamic Rho"); if (lpb<0.1) lpb=0.1; if(lpcone) DSDP_ERR( LPConeScaleBarrier(lpcone,lpb), "Error Setting LPCone Scale Barrier"); //Set Fixed Variables if(fixed != NULL) { if(nlhs > 4) { mxSetCell(plhs[4],indcell,mxCreateDoubleMatrix(nfix,1,mxREAL)); X = mxGetPr(mxGetCell(plhs[4],indcell++)); } else X = NULL; DSDP_ERR( DSDPSetFixedVariables(dsdp, fixed, &fixed[nfix], X, (int)nfix), "Error Setting Fixed Variables"); } //Print Header if(printLevel) { mexPrintf("\n------------------------------------------------------------------\n"); mexPrintf(" This is DSDP v%s\n",DSDP_VERSION); mexPrintf(" Authors: Steve Benson, Yinyu Ye and Xiong Zhang\n\n"); mexPrintf(" Problem Properties:\n"); mexPrintf(" # Decision Variables: %4d\n",ndec); mexPrintf(" # Linear Inequalities: %4d ",nlincon); if(nlincon) mexPrintf("[%d nz]\n",lincon_nz); else mexPrintf("\n"); mexPrintf(" # Semidefinite Cones: %4d\n",ncones); mexPrintf("------------------------------------------------------------------\n"); } //Start timer start = clock(); //Call DSDP Setup to initialize problem DSDP_ERR( DSDPSetup(dsdp), "Error setting up DSDP Problem, likely out of memory"); //Now Solve the Problem status = DSDPSolve(dsdp); //Stop Timer end = clock(); evaltime = ((double)(end-start))/CLOCKS_PER_SEC; //Determine Stop Reason if(status == 0) { DSDP_ERR( DSDPStopReason(dsdp,&reason), "Error retrieving post-solve stop reason"); } else if(status == DSDP_MAX_TIME || status == DSDP_USER_TERMINATION) reason = status; else { DSDP_ERR( status, "Error solving DSDP Problem!");} //Computer X and Get Solution Type if (reason!=DSDP_INFEASIBLE_START) DSDP_ERR( DSDPComputeX(dsdp), "Error computing post-solve x"); DSDP_ERR( DSDPGetSolutionType(dsdp,&pdfeasible), "Error collecting post-solve solution type"); //Copy Dual Solution DSDP_ERR( DSDPGetY(dsdp,x,(int)ndec), "Error returning Solution Vector"); //Collect Output Statistics DSDPGetIts(dsdp,&iters); DSDPGetDObjective(dsdp,dval); DSDPGetPObjective(dsdp,pval); DSDPGetR(dsdp,mxGetPr(mxGetField(plhs[3],0,"r"))); DSDPGetBarrierParameter(dsdp,mxGetPr(mxGetField(plhs[3],0,"mu"))); DSDPGetStepLengths(dsdp,mxGetPr(mxGetField(plhs[3],0,"pstep")),mxGetPr(mxGetField(plhs[3],0,"dstep"))); DSDPGetPnorm(dsdp,mxGetPr(mxGetField(plhs[3],0,"pnorm"))); DSDPGetYMaxNorm(dsdp,mxGetPr(mxGetField(plhs[3],0,"ynorm"))); DSDPGetTraceX(dsdp,mxGetPr(mxGetField(plhs[3],0,"tracex"))); DSDPGetPotentialParameter(dsdp,mxGetPr(mxGetField(plhs[3],0,"rho"))); *dreuse = (double)reuse; //Assign to MATLAB *iter = (double)iters; *exitflag = (double)reason; *pdflag = (double)pdfeasible; //Print Header if(printLevel){ //Detail termination reason switch(reason) { //Success case DSDP_CONVERGED: mexPrintf("\n *** DSDP CONVERGED ***\n"); break; case DSDP_UPPERBOUND: mexPrintf("\n *** DSDP CONVERGED: Dual Objective exceeds its bound***\n"); break; //Error case DSDP_SMALL_STEPS: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Terminated due to Small Steps ***\n"); break; case DSDP_MAX_IT: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Maximum Iterations Reached ***\n"); break; case DSDP_MAX_TIME: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Maximum Time Reached ***\n"); break; case DSDP_INFEASIBLE_START: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Infeasible Starting Point ***\n"); break; case DSDP_USER_TERMINATION: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: User Exited ***\n"); break; //Here is ok too? default: mexPrintf("\n *** DSDP FINISHED ***\n"); break; } //Detail solution status if(reason == DSDP_CONVERGED || reason == DSDP_UPPERBOUND) { switch(pdfeasible) { //Success case DSDP_PDFEASIBLE: mexPrintf(" Solution Status: Both Primal and Dual are Feasible and Bounded\n"); break; //Error case DSDP_UNBOUNDED: mexPrintf(" Solution Status: Dual Unbounded, Primal Infeasible\n"); break; case DSDP_INFEASIBLE: mexPrintf(" Solution Status: Primal Unbounded, Dual Infeasible\n"); break; case DSDP_PDUNKNOWN: default: mexPrintf(" Solution Status: Unknown - Check Dual Bounds\n"); break; } } if(reason==DSDP_CONVERGED) mexPrintf("\n Final Primal Objective: %2.5g\n Final Dual Objective: %2.5g\n In %5d iterations\n %5.2f seconds\n",*pval,*dval,iters,evaltime); mexPrintf("------------------------------------------------------------------\n\n"); } //Free DSDP Problem DSDP_ERR( DSDPDestroy(dsdp), "Error Destroying DSDP Problem"); //Free Temporary memory if(temp_jc) {mxFree(temp_jc); temp_jc = NULL;} if(temp_ir) {mxFree(temp_ir); temp_ir = NULL;} if(temp_pr) {mxFree(temp_pr); temp_pr = NULL;} }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { MatlabCPPInitialize(false); // Check for proper number of arguments if ( (nrhs < NR_IN) || (nrhs > NR_IN + NR_IN_OPT) || \ (nlhs < NR_OUT) || (nlhs > NR_OUT + NR_OUT_OPT) ) { mexErrMsgTxt("Wrong number of arguments."); } // fetch the input (we support matrices and cell arrays) std::vector< Eigen::VectorXd > theta_unary; std::vector< Eigen::VectorXd > theta_pair; if (!mxIsCell(THETA_UNARY_IN)) { GetMatlabPotentialFromMatrix(THETA_UNARY_IN, theta_unary); GetMatlabPotentialFromMatrix(THETA_PAIR_IN, theta_pair); } else { GetMatlabPotential(THETA_UNARY_IN, theta_unary); GetMatlabPotential(THETA_PAIR_IN, theta_pair); } Eigen::MatrixXi edges; GetMatlabMatrix(EDGES_IN, edges); double beta = mxGetScalar(BETA_IN); TreeInference inf = TreeInference(theta_unary, theta_pair, edges); inf.run(beta); LOGZ_OUT = mxCreateNumericMatrix(1, 1, mxDOUBLE_CLASS, mxREAL); double* logz_p = mxGetPr(LOGZ_OUT); logz_p[0] = inf.getLogPartitionSum(); // return marginals (if input was provided as a matrix, also return // marginals in a matrix) if (nlhs > 1) { std::vector< Eigen::VectorXd >& mu_unary = inf.getUnaryMarginals(); if (!mxIsCell(THETA_UNARY_IN)) { size_t num_states = mxGetM(THETA_UNARY_IN); size_t num_vars = mxGetN(THETA_UNARY_IN); MARGINALS_UNARY_OUT = mxCreateNumericMatrix( num_states, num_vars, mxDOUBLE_CLASS, mxREAL); double* mu_res_p = mxGetPr(MARGINALS_UNARY_OUT); for (size_t v_idx=0; v_idx<mu_unary.size(); v_idx++) { for (size_t idx=0; idx<mu_unary[v_idx].size(); idx++) { mu_res_p[v_idx*num_states+idx] = mu_unary[v_idx](idx); } } } else { mwSize dim_0 = static_cast<mwSize>(mu_unary.size()); MARGINALS_UNARY_OUT = mxCreateCellArray(1, &dim_0); for (size_t v_idx=0; v_idx<mu_unary.size(); v_idx++) { mxArray* m = mxCreateNumericMatrix( static_cast<int>(mu_unary[v_idx].size()), 1, mxDOUBLE_CLASS, mxREAL); double* mu_res_p = mxGetPr(m); for (size_t idx=0; idx<mu_unary[v_idx].size(); idx++) { mu_res_p[idx] = mu_unary[v_idx](idx); } mxSetCell(MARGINALS_UNARY_OUT, v_idx, m); } } } // return pairwise marginals if (nlhs > 2) { std::vector< Eigen::VectorXd >& mu_pair = inf.getPairwiseMarginals(); if (!mxIsCell(THETA_UNARY_IN)) { size_t num_states = mxGetM(THETA_PAIR_IN); size_t num_edges = mxGetN(THETA_PAIR_IN); MARGINALS_PAIR_OUT = mxCreateNumericMatrix( num_states, num_edges, mxDOUBLE_CLASS, mxREAL); double* mu_res_p = mxGetPr(MARGINALS_PAIR_OUT); for (size_t e_idx=0; e_idx<mu_pair.size(); e_idx++) { for (size_t idx=0; idx<mu_pair[e_idx].size(); idx++) { mu_res_p[e_idx*num_states+idx] = mu_pair[e_idx](idx); } } } else { mxAssert(0, "not implemented yet!"); // TODO: not implemented yet, see above! // see unary case above! } } MatlabCPPExit(); }
/* [graphs, count] = mexgspan (G, minsup, maxpat); */ void mexFunction (int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) { if (nlhs > 3) { mexPrintf ("Too many left hand side parameters.\n"); return; } if (nrhs != 4 && nrhs != 10) { mexErrMsgTxt ("Wrong number of right hand side parameters (must be 4 or 10).\n"); return; } if (mxIsCell (prhs[0]) == 0) { mexErrMsgTxt ("G must be a cellarray of graph structures.\n"); return; } unsigned int minsup = (unsigned int) mxGetScalar (prhs[1]); if (mxGetM (prhs[2]) != 1 || mxGetN (prhs[2]) != 2) { mexErrMsgTxt ("size_req must be a (1,2) real vector.\n"); return; } double* size_req = (double *) mxGetPr (prhs[2]); unsigned int maxpat_min = (unsigned int) size_req[0]; unsigned int maxpat_max = (unsigned int) size_req[1]; unsigned int directed = (unsigned int) mxGetScalar (prhs[3]); if (directed > 1) { mexErrMsgTxt ("Parameter 'directed' must be zero or 1.\n"); return; } GSPAN::gSpan gspan; /* In case we should do graph boosting, we have to do some extra setup * work, such as initializing the known labels of the graphs and their * weights. */ if (nrhs == 10) { double boostTau = (double) mxGetScalar (prhs[6]); if (boostTau < 0.0) { mexErrMsgTxt ("Boost tau parameter must be >= 0.0.\n"); return; } unsigned int boostN = (unsigned int) mxGetScalar (prhs[7]); double* boostYptr = (double *) mxGetPr (prhs[4]); double* boostWeightsPtr = (double *) mxGetPr (prhs[5]); unsigned int boostYlen = mxGetM (prhs[4]); std::vector<double> boostY; std::vector<double> boostWeights; for (unsigned int n = 0 ; n < boostYlen ; ++n) { boostY.push_back (boostYptr[n]); boostWeights.push_back (boostWeightsPtr[n]); } unsigned int boostMax = (unsigned int) mxGetScalar (prhs[8]); unsigned int boostType = (unsigned int) mxGetScalar (prhs[9]); gspan.boost_setup (boostN, boostTau, boostMax, boostY, boostWeights, boostType); } /* Start the actual gspan algorithm. Before the graphs are converted from * the Matlab structures to Taku's graph object format. */ gspan.run_graphs (prhs[0], nlhs, plhs, minsup, maxpat_min, maxpat_max, false, false, (directed == 1) ? true : false); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if(nrhs < 3) mexErrMsgTxt("Minimum of three inputs required."); if (nlhs > 1) mexErrMsgTxt("Too many output arguments."); for (int i = 1 ; i < nrhs-2 ; ++i) { if (mxIsEmpty(prhs[i]) || (!mxIsChar(prhs[i]) && ((mxGetClassID(prhs[i]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[i]) || (mxGetNumberOfElements(prhs[i]) != 1)))) mexErrMsgTxt("Metadata's label or index must be set by a non-empty string or an integer respectively."); } if ((mxGetClassID(prhs[nrhs-2]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[nrhs-2]) || (mxGetNumberOfElements(prhs[nrhs-2]) != 1)) mexErrMsgTxt("The index for the metadata's value must be set by a single integer"); bool invalidData = false; if (mxIsCell(prhs[nrhs-1])) { if (mxGetNumberOfElements(prhs[nrhs-1]) != 1) invalidData = true; } else if (mxIsChar(prhs[nrhs-1])) { if (mxGetM(prhs[nrhs-1]) != 1) invalidData = true; } else if ((mxGetClassID(prhs[nrhs-1]) != mxDOUBLE_CLASS) || mxIsComplex(prhs[nrhs-1]) || (mxGetNumberOfElements(prhs[nrhs-1]) != 1)) invalidData = true; if (invalidData) mexErrMsgTxt("Unsupported metadata's value or the number of elements is greater than 1."); btk::Acquisition::Pointer acq = btk_MOH_get_object<btk::Acquisition>(prhs[0]); btk::MetaData::Iterator it; btk::MetaData::Pointer parent = btkMXExtractMetaDataIterator(&it, nrhs-3, prhs, acq->GetMetaData()); if (!(*it)->HasInfo()) mexErrMsgTxt("No metadata's info."); size_t index = static_cast<size_t>(mxGetScalar(prhs[nrhs-2])) - 1; if (index >= (*it)->GetInfo()->GetValues().size()) mexErrMsgTxt("Invalid index to extract one metadata's value."); const mxArray* data = 0; if (mxIsCell(prhs[nrhs-1])) { data = mxGetCell(prhs[nrhs-1], 0); if (!data || !mxIsChar(data)) mexErrMsgTxt("Error in the value's format: only a string is accepted in cell."); } else data = prhs[nrhs-1]; if (mxIsChar(data)) { size_t strlen_ = (mxGetM(data) * mxGetN(data) * sizeof(mxChar)) + 1; char* d = (char*)mxMalloc(strlen_); mxGetString(data, d, strlen_); (*it)->GetInfo()->SetValue(static_cast<int>(index), d); mxFree(d); } else (*it)->GetInfo()->SetValue(static_cast<int>(index), mxGetScalar(data)); if (nlhs > 0) plhs[0] = btkMXCreateMetaDataStructure(acq->GetMetaData()); };
/* mexRays computes the following RAY features ; distance (ray1), orientation (ray3), norm (ray4) * @param name of the input image. * @param sigma specifies the standard deviation of the edge filter. * @param angle specifies the angle at which the features should be computed. * @param edge_low_threshold low threshold used for the canny edge detection. * @param edge_high_threshold high threshold used for the canny edge detection. */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mwSize nElements,j; mwSize number_of_dims; double start_angle; double end_angle; double step_angle; int strLength; mxArray *tmp; char *pImageName; // Check for proper number of input and output arguments if ((nrhs != 4) && (nrhs != 6)) { mexErrMsgTxt("Four or six input arguments required."); } if (nlhs > 1){ mexErrMsgTxt("Too many output arguments."); } // Check data type of input argument if (!(mxIsCell(prhs[0]))) { mexErrMsgTxt("First input argument must be of type cell."); } if (!(mxIsDouble(prhs[1]))) { mexErrMsgTxt("Second input argument must be of type double."); } if (!(mxIsDouble(prhs[2]))) { mexErrMsgTxt("Third input argument must be of type double."); } if (!(mxIsDouble(prhs[3]))) { mexErrMsgTxt("Fourth input argument must be of type double."); } if ((nrhs > 4) && !(mxIsDouble(prhs[4]))) { mexErrMsgTxt("Fifth input argument must be of type double."); } if ((nrhs > 5) && !(mxIsDouble(prhs[5]))) { mexErrMsgTxt("Sixth input argument must be of type double."); } mexPrintf("Loading input parameters\n"); // Get image name tmp = mxGetCell(prhs[0],0); strLength = mxGetN(tmp)+1; pImageName = (char*)mxCalloc(strLength, sizeof(char)); mxGetString(tmp,pImageName,strLength); start_angle=*((double *)mxGetPr(prhs[1])); end_angle=*((double *)mxGetPr(prhs[2])); step_angle=*((double *)mxGetPr(prhs[3])); double low_th = 15000; double high_th = 30000; if(nrhs > 5) { low_th = *((double *)mxGetPr(prhs[4])); high_th = low_th + 10000; if(nrhs > 6) high_th = *((double *)mxGetPr(prhs[5])); } mexPrintf("computeRays\n"); IplImage** rays2 = 0; computeDistanceDifferenceRays(pImageName, start_angle, end_angle, step_angle, rays2, 0, F_CANNY, true, low_th, high_th); /* int nAngles = (end_angle-start_angle)/step_angle; IplImage** rays1 = new IplImage*[nAngles]; IplImage** rays3 = 0; IplImage** rays4 = 0; //IplImage** rays3 = new IplImage*[nAngles]; //IplImage** rays4 = new IplImage*[nAngles]; double angle = 0; for(int a = 0;a<nAngles;a++) { computeRays((const char*)pImageName, sigma, angle, &rays1[a],&rays3[a],&rays4[a],F_CANNY,true,low_th,high_th); angle =+ step_angle; } // Release images mexPrintf("Cleaning\n"); for(int a = 0;a<nAngles;a++) { cvReleaseImage(&rays1); cvReleaseImage(&rays3); cvReleaseImage(&rays4); } */ mxFree(pImageName); }
// 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); } }
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; }
static PyObject* mat2py(const mxArray *a) { size_t ndims = mxGetNumberOfDimensions(a); const mwSize *dims = mxGetDimensions(a); mxClassID cls = mxGetClassID(a); size_t nelem = mxGetNumberOfElements(a); char *data = (char*) mxGetData(a); char *imagData = (char*) mxGetImagData(a); if (debug) mexPrintf("cls = %d, nelem = %d, ndims = %d, dims[0] = %d, dims[1] = %d\n", cls, nelem, ndims, dims[0], dims[1]); if (cls == mxCHAR_CLASS) { char *str = mxArrayToString(a); PyObject *o = PyString_FromString(str); mxFree(str); return o; } else if (mxIsStruct(a)) { PyObject *o = PyDict_New(); PyObject *list; PyObject *pyItem; mxArray *item; int i, j; const char *fieldName; int nfields = mxGetNumberOfFields(a); if (debug) mexPrintf("nfields = %d, nelem = %d\n", nfields, nelem); for(i = 0; i < nfields; i++) { fieldName = mxGetFieldNameByNumber(a, i); list = PyList_New(nelem); for(j = 0; j < nelem; j++) { item = mxGetFieldByNumber(a, j, i); if(item == NULL) { Py_DECREF(list); Py_DECREF(o); mexErrMsgIdAndTxt("matpy:NullFieldValue", "Null field in struct"); } pyItem = mat2py(item); if(pyItem == NULL) { Py_DECREF(list); Py_DECREF(o); mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type in struct"); } PyList_SetItem(list, j, pyItem); } PyDict_SetItemString(o, fieldName, list); } Py_DECREF(list); return o; } PyObject *list = PyList_New(nelem); const char *dtype = NULL; if (mxIsCell(a)) { dtype = "object"; for (int i = 0; i < nelem; i++) { PyObject *item = mat2py(mxGetCell(a, i)); if(NULL != item) { PyList_SetItem(list, i, item); } else // Failure { Py_DECREF(list); mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type in a cell"); } } return list; } else { if (imagData == NULL) { #define CASE(cls,c_type,d_type,py_ctor) case cls: for (int i = 0; i < nelem; i++) { \ dtype=d_type; \ PyObject *item = py_ctor(*((c_type*) data)); \ if (debug) mexPrintf("Setting %d to %f (item = 0x%08X)\n", i, (double) *((c_type*) data), item); \ data += sizeof(c_type); \ if (PyList_SetItem(list, i, item) == -1) PyErr_Print(); } \ break switch(cls) { CASE(mxLOGICAL_CLASS, bool, "bool", PyBool_FromLong); CASE(mxDOUBLE_CLASS, double, "float64", PyFloat_FromDouble); CASE(mxSINGLE_CLASS, float, "float32", PyFloat_FromDouble); CASE(mxINT8_CLASS, char, "int8", PyInt_FromLong); CASE(mxUINT8_CLASS, unsigned char, "uint8", PyInt_FromLong); CASE(mxINT16_CLASS, short, "int16", PyInt_FromLong); CASE(mxUINT16_CLASS, unsigned short, "uint16", PyInt_FromLong); CASE(mxINT32_CLASS, int, "int32", PyInt_FromLong); CASE(mxUINT32_CLASS, unsigned int, "uint32", PyLong_FromLongLong); CASE(mxINT64_CLASS, long long, "int64", PyLong_FromLongLong); CASE(mxUINT64_CLASS, unsigned long long, "uint64", PyLong_FromUnsignedLongLong); default: mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type"); } } else { #undef CASE #define CASE(cls,c_type,d_type) case cls: for (int i = 0; i < nelem; i++) { \ dtype = d_type; \ PyObject *item = PyComplex_FromDoubles(*((c_type*) data), *((c_type*) imagData)); \ data += sizeof(c_type); \ imagData += sizeof(c_type); \ PyList_SetItem(list, i, item); } \ break switch(cls) { CASE(mxDOUBLE_CLASS, double, "complex128"); CASE(mxSINGLE_CLASS, float, "complex64"); CASE(mxINT8_CLASS, char, "complex64"); CASE(mxUINT8_CLASS, unsigned char, "complex64"); CASE(mxINT16_CLASS, short, "complex64"); CASE(mxUINT16_CLASS, unsigned short, "complex64"); CASE(mxINT32_CLASS, int, "complex128"); CASE(mxUINT32_CLASS, unsigned int, "complex128"); CASE(mxINT64_CLASS, long long, "complex128"); CASE(mxUINT64_CLASS, unsigned long long, "complex128"); default: mexErrMsgIdAndTxt("matpy:UnsupportedVariableType", "Unsupported variable type"); } } }
void 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, CONSTmxArray *prhs[]) { static Boolean firstTime=1,deferAvailable; long priorityLevel=-1; double a; Stuff stuff; Boolean isString,oldMatlabBackgrounding; plhs; InitMEX(); isString=nrhs>0 && (mxIsChar(prhs[0]) || mxIsCell(prhs[0])); if(nlhs>1 || nrhs<1 || nrhs>2 || (isString && nlhs>0))PrintfExit("Usage:\n\n%s",useRush); switch(nrhs){ case 2: a=mxGetScalar(prhs[1]); if(a!=0 && a!=0.5 && a!=1 && a!=2 && a!=3 && a!=4 && a!=5 && a!=6 && a!=7) PrintfExit("Illegal priorityLevel %.1f. Must be 0, 0.5, 1, 2, 3, 4, 5, 6, or 7. Usage:\n%s",a,useRush); priorityLevel=a; if(a==0.5)priorityLevel=-1; case 1: if(!isString){ // special case: get an array of timings double s,s0; long j; stuff.getTimes=mxGetScalar(prhs[0]); if(stuff.getTimes<1) PrintfExit("The first argument must be either a string (or strings) or a number."); plhs[0]=mxCreateDoubleMatrix(1,stuff.getTimes,mxREAL); if(plhs[0]==NULL)PrintfExit("Couldn't allocate %ld element array.",stuff.getTimes); stuff.mxTimes=plhs[0]; stuff.iterations=10000; s=Seconds(); s=Seconds(); s0=Seconds()-s; s=Seconds(); for(j=0;j<stuff.iterations;j++) ; s=Seconds()-s-s0; stuff.iterations=(0.001-s0)*stuff.iterations/s; // That many iterations plus a call to Seconds() should take 1 ms. }else stuff.getTimes=0; break; } if(1){ // concatenate array or cell array of strings int error=0; mxArray *out,*in; in=(mxArray *)prhs[0]; error=mexCallMATLAB(1,&out,1,&in,"CatStr"); // Psychtoolbox:PsychOneliners:CatStr.m stuff.mxString=out; }else{ stuff.mxString=prhs[0]; } stuff.trapErrors=1; stuff.error=0; #if TARGET_OS_MAC if(CanControlMatlabBackgrounding()){ oldMatlabBackgrounding=MatlabBackgrounding(0); }else{ if(firstTime){ // Backgrounding is dangerous. Matlab would give time to another process while priority is raised. // Checking the enabled flag (on the disk) is slow, so we only do it once if backgrounding's off. But // if it's on, we give an error, and check again next time. if(IsMatlabBackgroundingEnabled()){ PrintfExit("Rush: please turn off Matlab's \"Backgrounding\" Preference, in the File menu.\n"); }else firstTime=0; } } #endif mexEvalString("lasterr('');"); Rush(priorityLevel,&fun,&stuff); if(CanControlMatlabBackgrounding())MatlabBackgrounding(oldMatlabBackgrounding); if(stuff.error)mexErrMsgTxt("mexCallMATLAB error during Rush"); // never happens { // if there's a message in LASTERR, print it as an error, with a preface int nlhs=1,nrhs=0,error=0; mxArray *plhs[1]={NULL},*prhs[1]={NULL}; char string[512]="Error during Rush: ",*errorMsg; errorMsg=string+strlen(string); error=mexCallMATLAB(nlhs,plhs,nrhs,prhs,"lasterr"); error=mxGetString(plhs[0],errorMsg,sizeof(string)-strlen(string)); if(strlen(errorMsg)>0)mexErrMsgTxt(string); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mxArray *srcmat; int ndim, *dimsize, eltsize; const int *dims; int ndimdest, *destdims, *destdimsize; char *src, *dest; int *rep; int i,nrep; int extra_rep = 1; int empty; if(nrhs < 2) mexErrMsgTxt("Usage: xrepmat(A, [N M ...])"); srcmat = prhs[0]; if(mxIsSparse(srcmat)) { mexErrMsgTxt("Sorry, can't handle sparse matrices yet."); } if(mxIsCell(srcmat)) { mexErrMsgTxt("Sorry, can't handle cell arrays yet."); } ndim = mxGetNumberOfDimensions(srcmat); dims = mxGetDimensions(srcmat); eltsize = mxGetElementSize(srcmat); /* compute dimension sizes */ dimsize = mxCalloc(ndim, sizeof(int)); dimsize[0] = eltsize*dims[0]; for(i=1;i<ndim;i++) dimsize[i] = dimsize[i-1]*dims[i]; /* determine repetition vector */ ndimdest = ndim; if(nrhs == 2) { nrep = mxGetN(prhs[1]); if(nrep > ndimdest) ndimdest = nrep; rep = mxCalloc(ndimdest, sizeof(int)); for(i=0;i<nrep;i++) { double repv = mxGetPr(prhs[1])[i]; rep[i] = (int)repv; } if(nrep == 1) { /* special behavior */ nrep = 2; rep[1] = rep[0]; } } else { nrep = nrhs-1; if(nrep > ndimdest) ndimdest = nrep; rep = mxCalloc(ndimdest, sizeof(int)); for(i=0;i<nrep;i++) { rep[i] = (int)*mxGetPr(prhs[i+1]); } } for(i=nrep;i<ndimdest;i++) rep[i] = 1; /* compute output size */ destdims = mxCalloc(ndimdest, sizeof(int)); for(i=0;i<ndim;i++) destdims[i] = dims[i]*rep[i]; for(;i<ndimdest;i++) { destdims[i] = rep[i]; extra_rep *= rep[i]; } destdimsize = mxCalloc(ndim, sizeof(int)); destdimsize[0] = eltsize*destdims[0]; for(i=1;i<ndim;i++) destdimsize[i] = destdimsize[i-1]*destdims[i]; /* for speed, array should be uninitialized */ plhs[0] = mxCreateNumericArray(ndimdest, destdims, mxGetClassID(srcmat), mxIsComplex(srcmat)?mxCOMPLEX:mxREAL); /* if any rep[i] == 0, output should be empty array. Added by KPM 11/13/02. */ empty = 0; for (i=0; i < nrep; i++) { if (rep[i]==0) empty = 1; } if (empty) return; src = (char*)mxGetData(srcmat); dest = (char*)mxGetData(plhs[0]); repmat(dest,src,ndim,destdimsize,dimsize,dims,rep); if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep); if(mxIsComplex(srcmat)) { src = (char*)mxGetPi(srcmat); dest = (char*)mxGetPi(plhs[0]); repmat(dest,src,ndim,destdimsize,dimsize,dims,rep); if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep); } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { MatlabCPPInitialize(false); // Check for proper number of arguments if ( (nrhs < NR_IN) || (nrhs > NR_IN + NR_IN_OPT) || \ (nlhs < NR_OUT) || (nlhs > NR_OUT + NR_OUT_OPT) ) { mexErrMsgTxt("Wrong number of arguments."); } // fetch the input (we support matrices and cell arrays) std::vector< Eigen::VectorXd > theta_unary; std::vector< Eigen::VectorXd > theta_pair; if (!mxIsCell(THETA_UNARY_IN)) { GetMatlabPotentialFromMatrix(THETA_UNARY_IN, theta_unary); GetMatlabPotentialFromMatrix(THETA_PAIR_IN, theta_pair); } else { GetMatlabPotential(THETA_UNARY_IN, theta_unary); GetMatlabPotential(THETA_PAIR_IN, theta_pair); } Eigen::MatrixXi edges; GetMatlabMatrix(EDGES_IN, edges); // decomposition: cell array of edge index vectors std::vector< std::vector<size_t> > decomposition; size_t num = mxGetNumberOfElements(DECOMPOSITION_IN); decomposition.resize(num); for (size_t d_idx=0; d_idx<num; d_idx++) { const mxArray* v = mxGetCell(DECOMPOSITION_IN, d_idx); size_t num_edges = mxGetM(v); decomposition[d_idx].resize(num_edges); const double* ptr = mxGetPr(v); for (size_t e_idx=0; e_idx<num_edges; e_idx++) { decomposition[d_idx][e_idx] = static_cast<size_t>(ptr[e_idx]); } } // parse options MexSmoothDDOptions options; if (nrhs >= 5) { bool opts_parsed = options.parse(OPTIONS_IN); if (!opts_parsed) { MatlabCPPExit(); return; } } // set algorithm & parameters according to options SmoothDualDecomposition* sdd; /*if (options.solver == SOLVER_FISTADESCENT) { sdd = new SmoothDualDecompositionFistaDescent(theta_unary, theta_pair, edges, decomposition); } if (options.solver == SOLVER_FISTA) { sdd = new SmoothDualDecompositionFista(theta_unary, theta_pair, edges, decomposition); } else if (options.solver == SOLVER_GRADIENTDESCENT) { sdd = new SmoothDualDecompositionGradientDescent(theta_unary, theta_pair, edges, decomposition); } else if (options.solver == SOLVER_NESTEROV) { sdd = new SmoothDualDecompositionNesterov(theta_unary, theta_pair, edges, decomposition); } else { mxAssert(0, "Solver not found. Should not happen!"); }*/ // TODO sdd = new SmoothDualDecompositionFistaDescent(theta_unary, theta_pair, edges, decomposition); //sdd = new SmoothDualDecompositionLBFGS(theta_unary, theta_pair, edges, decomposition); sdd->setMaximumNumberOfIterations(options.num_max_iter); sdd->setEpsilonGradientNorm(options.eps_gnorm); // run the computations sdd->run(options.rho); // return marginals (if input was provided as a matrix, also return // marginals in a matrix) std::vector< Eigen::VectorXd >& mu_unary = sdd->getUnaryMarginals(); if (!mxIsCell(THETA_UNARY_IN)) { size_t num_states = mxGetM(THETA_UNARY_IN); size_t num_vars = mxGetN(THETA_UNARY_IN); MARGINALS_UNARY_OUT = mxCreateNumericMatrix( num_states, num_vars, mxDOUBLE_CLASS, mxREAL); double* mu_res_p = mxGetPr(MARGINALS_UNARY_OUT); for (size_t v_idx=0; v_idx<mu_unary.size(); v_idx++) { for (size_t idx=0; idx<mu_unary[v_idx].size(); idx++) { mu_res_p[v_idx*num_states+idx] = mu_unary[v_idx](idx); } } } else { mwSize dim_0 = static_cast<mwSize>(mu_unary.size()); MARGINALS_UNARY_OUT = mxCreateCellArray(1, &dim_0); for (size_t v_idx=0; v_idx<mu_unary.size(); v_idx++) { mxArray* m = mxCreateNumericMatrix( static_cast<int>(mu_unary[v_idx].size()), 1, mxDOUBLE_CLASS, mxREAL); double* mu_res_p = mxGetPr(m); for (size_t idx=0; idx<mu_unary[v_idx].size(); idx++) { mu_res_p[idx] = mu_unary[v_idx](idx); } mxSetCell(MARGINALS_UNARY_OUT, v_idx, m); } } // return history /*if (nlhs > 1) { std::vector<double> history_obj = lpqp.getHistoryObjective(); std::vector<double> history_obj_qp = lpqp.getHistoryObjectiveQP(); std::vector<double> history_obj_lp = lpqp.getHistoryObjectiveLP(); std::vector<double> history_obj_decoded = lpqp.getHistoryObjectiveDecoded(); std::vector<size_t> history_iteration = lpqp.getHistoryIteration(); std::vector<double> history_beta = lpqp.getHistoryBeta(); std::vector< Eigen::VectorXi > history_decoded = lpqp.getHistoryDecoded(); const char *field_names[] = {"obj", "obj_qp", "obj_lp", "obj_decoded", "iteration", "beta", "decoded"}; mwSize dims[2]; dims[0] = 1; dims[1] = history_obj.size(); HISTORY_OUT = mxCreateStructArray(2, dims, sizeof(field_names)/sizeof(*field_names), field_names); int field_obj, field_obj_qp, field_obj_lp, field_obj_decoded, field_iteration, field_beta, field_decoded; field_obj = mxGetFieldNumber(HISTORY_OUT, "obj"); field_obj_qp = mxGetFieldNumber(HISTORY_OUT, "obj_qp"); field_obj_lp = mxGetFieldNumber(HISTORY_OUT, "obj_lp"); field_obj_decoded = mxGetFieldNumber(HISTORY_OUT, "obj_decoded"); field_iteration = mxGetFieldNumber(HISTORY_OUT, "iteration"); field_beta = mxGetFieldNumber(HISTORY_OUT, "beta"); field_decoded = mxGetFieldNumber(HISTORY_OUT, "decoded"); for (size_t i=0; i<history_obj.size(); i++) { mxArray *field_value; field_value = mxCreateDoubleMatrix(1,1,mxREAL); *mxGetPr(field_value) = history_obj[i]; mxSetFieldByNumber(HISTORY_OUT, i, field_obj, field_value); field_value = mxCreateDoubleMatrix(1,1,mxREAL); *mxGetPr(field_value) = history_obj_qp[i]; mxSetFieldByNumber(HISTORY_OUT, i, field_obj_qp, field_value); field_value = mxCreateDoubleMatrix(1,1,mxREAL); *mxGetPr(field_value) = history_obj_lp[i]; mxSetFieldByNumber(HISTORY_OUT, i, field_obj_lp, field_value); field_value = mxCreateDoubleMatrix(1,1,mxREAL); *mxGetPr(field_value) = history_obj_decoded[i]; mxSetFieldByNumber(HISTORY_OUT, i, field_obj_decoded, field_value); field_value = mxCreateDoubleMatrix(1,1,mxREAL); *mxGetPr(field_value) = static_cast<double>(history_iteration[i]); mxSetFieldByNumber(HISTORY_OUT, i, field_iteration, field_value); field_value = mxCreateDoubleMatrix(1,1,mxREAL); *mxGetPr(field_value) = history_beta[i]; mxSetFieldByNumber(HISTORY_OUT, i, field_beta, field_value); if (options.with_decoded_history) { field_value = mxCreateDoubleMatrix(history_decoded[i].size(),1,mxREAL); double* decoded_res_p = mxGetPr(field_value); for (size_t idx=0; idx<history_decoded[i].size(); idx++) { decoded_res_p[idx] = static_cast<double>(history_decoded[i][idx]); } mxSetFieldByNumber(HISTORY_OUT, i, field_decoded, field_value); } } }*/ // return pairwise marginals if (nlhs > 1) { std::vector< Eigen::VectorXd >& mu_pair = sdd->getPairwiseMarginals(); if (!mxIsCell(THETA_UNARY_IN)) { size_t num_states = mxGetM(THETA_PAIR_IN); size_t num_edges = mxGetN(THETA_PAIR_IN); MARGINALS_PAIR_OUT = mxCreateNumericMatrix( num_states, num_edges, mxDOUBLE_CLASS, mxREAL); double* mu_res_p = mxGetPr(MARGINALS_PAIR_OUT); for (size_t e_idx=0; e_idx<mu_pair.size(); e_idx++) { for (size_t idx=0; idx<mu_pair[e_idx].size(); idx++) { mu_res_p[e_idx*num_states+idx] = mu_pair[e_idx](idx); } } } else { mwSize dim_0 = static_cast<mwSize>(mu_pair.size()); MARGINALS_PAIR_OUT = mxCreateCellArray(1, &dim_0); for (size_t e_idx=0; e_idx<mu_pair.size(); e_idx++) { mxArray* m = mxCreateNumericMatrix( static_cast<int>(mu_pair[e_idx].size()), 1, mxDOUBLE_CLASS, mxREAL); double* mu_res_p = mxGetPr(m); for (size_t idx=0; idx<mu_pair[e_idx].size(); idx++) { mu_res_p[idx] = mu_pair[e_idx](idx); } mxSetCell(MARGINALS_PAIR_OUT, e_idx, m); } } } delete sdd; MatlabCPPExit(); }
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; } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { if ((nrhs == 0) || !mxIsChar(prhs[0])) { mexErrMsgTxt("BotParamClient: first argument must be command string"); } if ((nrhs < 2) || !mxIsChar(prhs[1])) { mexErrMsgTxt("BotParamClient: second argument must be key"); } std::string command = ::getString(prhs[0]); std::transform(command.begin(), command.end(), command.begin(), ::tolower); std::string key = ::getString(prhs[1]); if ((nrhs > 3) || ((nrhs == 3) && !::isSetCommand(command))) { mexErrMsgTxt("BotParamClient: too many input arguments"); } if (isSetCommand(command) && (nrhs != 3)) { mexErrMsgTxt("BotParamClient: need value argument"); } BotParam* param = BotParamClient::instance().getUnderlyingBotParam(); if (param == NULL) { mexErrMsgTxt("BotParamClient: no param client; is server running?"); } bool hasKey = (0 != bot_param_has_key(param, key.c_str())); if (!hasKey && !isSetCommand(command) && (command != "haskey")) { mexErrMsgTxt("BotParamClient: invalid key"); } if (command == "haskey") { plhs[0] = mxCreateLogicalMatrix(1,1); mxLogical* out = mxGetLogicals(plhs[0]); out[0] = hasKey; } else if (command == "subkeys") { char** subkeysRaw = bot_param_get_subkeys(param, key.c_str()); std::vector<std::string> subkeys; for (char** subkeyPtr = subkeysRaw; *subkeyPtr != NULL; ++subkeyPtr) { subkeys.push_back(std::string(*subkeyPtr)); } bot_param_str_array_free(subkeysRaw); plhs[0] = mxCreateCellMatrix(1,subkeys.size()); for (size_t i = 0; i < subkeys.size(); ++i) { mxSetCell(plhs[0], i, mxCreateString(subkeys[i].c_str())); } } else if (command == "getnum") { int len = bot_param_get_array_len(param, key.c_str()); std::vector<double> vals; if (len <= 0) { double val; if (bot_param_get_double(param, key.c_str(), &val) != 0) { mexErrMsgTxt("BotParamClient: cannot find numeric"); } vals.push_back(val); } else { vals.resize(len); if (bot_param_get_double_array(param, key.c_str(), vals.data(), len) != len) { mexErrMsgTxt("BotParamClient: non-numeric value(s)"); } } plhs[0] = mxCreateDoubleMatrix(1,vals.size(),mxREAL); double* ptr = mxGetPr(plhs[0]); for (size_t i = 0; i < vals.size(); ++i) { ptr[i] = vals[i]; } } else if (command == "getbool") { int len = bot_param_get_array_len(param, key.c_str()); std::vector<bool> vals; if (len <= 0) { int val; if (bot_param_get_boolean(param, key.c_str(), &val) != 0) { mexErrMsgTxt("BotParamClient: cannot find bool"); } vals.push_back(val!=0); } else { int valsRaw[len]; if (bot_param_get_boolean_array(param, key.c_str(), valsRaw, len) != len) { mexErrMsgTxt("BotParamClient: non-boolean value(s)"); } for (int i = 0; i < len; ++i) { vals.push_back(valsRaw[i]!=0); } } plhs[0] = mxCreateLogicalMatrix(1,vals.size()); mxLogical* out = mxGetLogicals(plhs[0]); for (size_t i = 0; i < vals.size(); ++i) { out[i] = vals[i]; } } else if (command == "getstr") { int len = bot_param_get_array_len(param, key.c_str()); std::vector<std::string> vals; if (len <= 0) { char* val = NULL; if (bot_param_get_str(param, key.c_str(), &val) != 0) { mexErrMsgTxt("BotParamClient: cannot find string"); } vals.push_back(std::string(val)); free(val); } else { char** valsRaw = bot_param_get_str_array_alloc(param, key.c_str()); for (char** valsPtr = valsRaw; *valsPtr != NULL; ++valsPtr) { vals.push_back(std::string(*valsPtr)); } bot_param_str_array_free(valsRaw); } plhs[0] = mxCreateCellMatrix(1,vals.size()); for (size_t i = 0; i < vals.size(); ++i) { mxSetCell(plhs[0], i, mxCreateString(vals[i].c_str())); } } else if (command == "setstr") { bot_param::set_t msg = constructSetMessage(param, key); std::string value; if (mxIsCell(prhs[2])) { int len = mxGetNumberOfElements(prhs[2]); for (int i = 0; i < len; ++i) { mxArray* cellVal = mxGetCell(prhs[2],i); if (!mxIsChar(cellVal)) { mexErrMsgTxt("BotParamClient: invalid string value argument"); } std::string curVal = ::getString(cellVal); value += (curVal + std::string(",")); } if (value.size() > 0) { value = value.substr(0,value.size()-1); } msg.entries[0].is_array = true; } else { if (!mxIsChar(prhs[2])) { mexErrMsgTxt("BotParamClient: invalid string value argument"); } value = ::getString(prhs[2]); } msg.entries[0].value = value; BotParamClient::instance().getLcm()->publish("PARAM_SET", &msg); } else if (command == "setnum") { if (!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2])) { mexErrMsgTxt("BotParamClient: third argument must be real value array"); } bot_param::set_t msg = constructSetMessage(param, key); std::string value; int len = mxGetNumberOfElements(prhs[2]); double* valArray = mxGetPr(prhs[2]); for (int i = 0; i < len; ++i) { std::ostringstream oss; oss << valArray[i] << ","; value += oss.str(); } if (value.size() > 0) { value = value.substr(0,value.size()-1); } msg.entries[0].value = value; msg.entries[0].is_array = (len > 1); BotParamClient::instance().getLcm()->publish("PARAM_SET", &msg); } else if (command == "print") { bot_param_write(param, stderr); } else { mexErrMsgTxt("BotParamClient: command must be haskey, subkeys, getnum, getbool, getstr, or setstr"); } }
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; }
// Function definitions. // ----------------------------------------------------------------- void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int argc = 0; const char **argv; mwIndex i; int k, ncell; int j = 0; // Count inputs and check for char type for( k=0; k<nrhs; k++ ) { if( mxIsCell( prhs[k] ) ) { argc += ncell = mxGetNumberOfElements( prhs[k] ); for( i=0; i<ncell; i++ ) if( !mxIsChar( mxGetCell( prhs[k], i ) ) ) mexErrMsgTxt("Input cell element is not char"); } else { argc++; if( !mxIsChar( prhs[k] ) ) mexErrMsgTxt("Input argument is not char"); } } // Construct argv argv = (const char **) mxCalloc( argc, sizeof(char *) ); for( k=0; k<nrhs; k++ ) { if( mxIsCell( prhs[k] ) ) { ncell = mxGetNumberOfElements( prhs[k] ); for( i=0; i<ncell; i++ ) argv[j++] = mxArrayToString( mxGetCell( prhs[k], i ) ); } else { argv[j++] = mxArrayToString( prhs[k] ); } } /* for(j = 0; j < argc; j++) { mexPrintf("Input %d = <%s>\n", j, argv[j]); } */ try { // list of ctl filenames and associated parameters CTLOperations ctl_operations; CTLParameters global_ctl_parameters; ctl_operation_t new_ctl_operation; // list of input images on which to operate std::list<const char *> input_image_files; char output_path[MAXPATHLEN + 1]; Compression compression = Compression::compressionNamed("PIZ"); format_t desired_format; format_t actual_format; float input_scale = 0.0; float output_scale = 0.0; bool force_overwrite_output_file = FALSE; bool noalpha = FALSE; int start_argc = argc; new_ctl_operation.filename = NULL; while (argc > 0) { if (!strncmp(argv[0], "-help", 2)) { if (argc > 1) { usagePrompt(argv[1]); } else { usagePrompt(NULL); } return; } else if (!strncmp(argv[0], "-input_scale", 2)) { if (argc == 1) { mexPrintf( "The -input_scale option requires an " "additional option specifying a scale\nvalue for the " "input file. see '-help scale' for additional " "details.\n"); return; } else { char *end = NULL; input_scale = strtof(argv[1], &end); if (end != NULL && *end != 0) { mexPrintf( "Unable to parse '%s' as a floating " "point number for the '-input_scale'\nargument\n", argv[1]); return; } argv++; argc--; } } else if (!strncmp(argv[0], "-output_scale", 2)) { if (argc == 1) { mexPrintf( "The -output_scale option requires an " "additional option specifying a scale\nvalue for the " "output file. see '-help scale' for additional " "details.\n"); return; } else { char *end = NULL; output_scale = strtof(argv[1], &end); if (end != NULL && *end != 0) { mexPrintf( "Unable to parse '%s' as a floating " "point number for the '-output_scale'\nargument\n", argv[1]); return; } argv++; argc--; } } else if (!strncmp(argv[0], "-ctl", 3)) { if (argc == 1) { mexPrintf( "the -ctl option requires an additional " "option specifying a file containing a\nctl script.\n" "see '-help ctl' for more details.\n"); return; } if (new_ctl_operation.filename != NULL) { ctl_operations.push_back(new_ctl_operation); } new_ctl_operation.local.clear(); new_ctl_operation.filename = argv[1]; argv++; argc--; } else if (!strncmp(argv[0], "-format", 5)) { if (argc == 1) { mexPrintf( "the -format option requires an additional " "argument specifying the destination file\nformat. " "this may be one of the following: 'dpx10', 'dpx16', " "'aces', 'tiff8',\n'tiff16', or 'exr'.\nSee '-help " "format' for more details.\n"); return; } desired_format = find_format(argv[1]," for parameter '-format'.\nSee '-help format' for more details."); argv++; argc--; } else if (!strncmp(argv[0], "-compression", 3)) { if (argc == 1) { mexPrintf( "the -compression option requires an additional " "argument specifying a compression scheme to be " "used.\n See '-help compression' for more details.\n"); return; } char scheme[8]; memset(scheme, '\0', 8); for(int i = 0; i < 8 && argv[1][i]; ++i) { scheme[i] = toupper(argv[1][i]); } compression = Compression::compressionNamed(scheme); if (!strcmp(compression.name, Compression::no_compression.name)) { mexPrintf("Unrecognized compression scheme '%s'. Turning off compression.\n", scheme); } argv++; argc--; } else if (!strcmp(argv[0], "-param1") || !strcmp(argv[0], "-p1")) { if (argc < 3) { mexPrintf( "the -param1 option requires two additional " "arguments specifying the\nparameter name and value." "\nSee '-help param' for more details.\n"); return; } if (new_ctl_operation.filename == NULL) { THROW(Iex::ArgExc, "the -param1 argument must occur *after* a -ctl option."); } new_ctl_operation.local.push_back(get_ctl_parameter(&argv, &argc, start_argc, "local", 1)); } else if (!strcmp(argv[0], "-param2") || !strcmp(argv[0], "-p2")) { if (argc < 4) { mexPrintf( "the -param2 option requires three additional " "arguments specifying the\nparameter name and value." "\nSee '-help param' for more details.\n"); return; } if (new_ctl_operation.filename == NULL) { THROW(Iex::ArgExc, "the -param2 argument must occur *after* a -ctl option."); } new_ctl_operation.local.push_back(get_ctl_parameter(&argv, &argc, start_argc, "local", 3)); } else if (!strcmp(argv[0], "-param3") || !strcmp(argv[0], "-p3")) { if (argc < 5) { mexPrintf( "the -param3 option requires four additional " "arguments specifying the\nparameter name and value." "\nSee '-help param' for more details.\n"); return; } if (new_ctl_operation.filename == NULL) { THROW(Iex::ArgExc, "the -param3 argument must occur *after* a -ctl option."); } new_ctl_operation.local.push_back(get_ctl_parameter(&argv, &argc, start_argc, "local", 3)); } else if (!strcmp(argv[0], "-global_param1") || !strcmp(argv[0], "-gp1")) { if (argc < 3) { mexPrintf("the -global_param1 option requires two " "additional arguments specifying the\nparameter " "name and value.\nSee '-help param' for more " "details.\n"); return; } global_ctl_parameters.push_back(get_ctl_parameter(&argv, &argc, start_argc, "global", 1)); } else if (!strcmp(argv[0], "-global_param2") || !strcmp(argv[0], "-gp2")) { if (argc < 4) { mexPrintf("the -global_param2 option requires three " "additional arguments specifying the\nparameter " "name and value.\nSee '-help param' for more " "details.\n"); return; } global_ctl_parameters.push_back(get_ctl_parameter(&argv, &argc, start_argc, "global", 2)); } else if (!strcmp(argv[0], "-global_param3") || !strcmp(argv[0], "-gp3")) { if (argc < 5) { mexPrintf("the -global_param3 option requires four " "additional arguments specifying the\nparameter " "name and value.\nSee '-help param' for more " "details.\n"); return; } global_ctl_parameters.push_back(get_ctl_parameter(&argv, &argc, start_argc, "global", 2)); } else if (!strncmp(argv[0], "-verbose", 2)) { verbosity++; } else if (!strncmp(argv[0], "-quiet", 2)) { verbosity--; } else if (!strncmp(argv[0], "-force", 5)) { force_overwrite_output_file = TRUE; } else if (!strncmp(argv[0], "-noalpha", 2)) { noalpha = TRUE; } else if (!strncmp(argv[0], "-", 1)) { mexPrintf( "unrecognized option %s. see -help for a list " "of available options.\n", argv[0]); return; } else { input_image_files.push_back(argv[0]); } argv++; argc--; } // end while if (new_ctl_operation.filename != NULL) { ctl_operations.push_back(new_ctl_operation); } if (input_image_files.size() < 2) { mexPrintf( "one or more source filenames and a destination " "file or directory must be\nprovided. if more than one " "source filenames is provided then the last argument\nmust " "be a directory. see -help for more details.\n"); return; } char *output_slash = NULL; const char *outputFile = input_image_files.back(); input_image_files.pop_back(); struct stat file_status; if (stat(outputFile, &file_status) >= 0) { if (S_ISDIR(file_status.st_mode)) { memset(output_path, 0, sizeof(output_path)); strncpy(output_path, outputFile, MAXPATHLEN); outputFile = output_path; output_slash = output_path + strlen(output_path); if (*output_slash != '/') { *(output_slash++) = '/'; *output_slash = 0; } } else if (S_ISREG(file_status.st_mode)) { if (input_image_files.size() > 1) { mexPrintf( "When providing more than one source " "image the destination must be a\ndirectory.\n"); return; } else { if (!force_overwrite_output_file) { mexPrintf( "The destination file %s already exists.\n" "Cravenly refusing to overwrite unless you supply " "the -force option.\n", outputFile); return; } else { // File exists, but we treat it as if it doesn't (see // if(output_slash==NULL) {...} down below... output_slash = NULL; } } } else { mexPrintf( "Specified destination is something other than " "a file or directory. That's\nprobably a bad idea.\n"); return; } } else { if (errno != ENOENT) { mexPrintf("Unable to get information about %s (%s).\n", outputFile, strerror(errno)); return; } if (input_image_files.size() != 1) { mexPrintf( "When specifying more than one source file " "you must specify the destination as\na directory " "that already exists.\nUnable to stat '%s' (%s)\n", outputFile, strerror(errno)); return; } } if (output_slash == NULL) { // This is the case when our outputFile is a single file. We do a bunch // of sanity checking between the extension of the specified file // (if any) and the -format option (if any). char *dot = (char *) strrchr(outputFile, '.'); if (dot == NULL && desired_format.ext == NULL) { mexPrintf( "You have not explicitly provided an output " "format, and the output file name\ndoes not not contain " "an extension. Please add an extension to the output " "file\nor use the -format option to specify the desired " "output format.\n"); return; } else if (dot != NULL) { if (desired_format.ext == NULL) { actual_format = find_format(dot + 1, " specified implicitly (by " "the extension) for\noutput file " "format. Please fix this or use\n" "the -format option to specify " "the desired output format.\n"); } else { // HACK aces format file type check const char *ext = desired_format.ext; static const char exrext[] = "exr"; if (!strcmp(ext, "aces")) ext = exrext; if (strcmp(ext, dot + 1) && !force_overwrite_output_file) { mexPrintf( "You have specified a destination file " "type with the -format option, but the\noutput " "file extension does not match the format " "specified by the -format option.\nCravenly " "refusing to do this unless you specify the " "-force option (which\nwill make the -format " "option take priority).\n"); return; } actual_format = desired_format; } } } if (verbosity > 1) { mexPrintf("global ctl parameters:\n"); CTLParameters temp_ctl_parameters; temp_ctl_parameters = global_ctl_parameters; while (temp_ctl_parameters.size() > 0) { ctl_parameter_t new_ctl_parameter = temp_ctl_parameters.front(); temp_ctl_parameters.pop_front(); mexPrintf("%17s:", new_ctl_parameter.name); for (int i = 0; i < new_ctl_parameter.count; i++) { mexPrintf(" %f", new_ctl_parameter.value[i]); } mexPrintf("\n"); } mexPrintf("\n"); } while (input_image_files.size() > 0) { const char *inputFile = input_image_files.front(); if (output_slash != NULL) { const char *input_slash = strrchr(inputFile, '/'); if (input_slash == NULL) { input_slash = (char *) inputFile; } else { input_slash++; } strcpy(output_slash, input_slash); char *dot = (char *) strrchr(outputFile, '.'); if (dot != NULL) { dot++; if (desired_format.ext != NULL) { // HACK aces format file type check const char *ext = desired_format.ext; static const char exrext[] = "exr"; if (!strcmp(ext, "aces")) ext = exrext; strcpy(dot, ext); actual_format = desired_format; } else { actual_format = find_format(dot, " (determined from destination file extension)."); } } } if (force_overwrite_output_file) { if (unlink(outputFile) < 0) { if (errno != ENOENT) { mexPrintf("Unable to remove existing file named " "'%s' (%s).\n", outputFile, strerror(errno)); return; } } } if (access(outputFile, F_OK) >= 0) { mexPrintf("Cravenly refusing to overwrite the file '%s'.\n", outputFile); return; } actual_format.squish = noalpha; transform(inputFile, outputFile, input_scale, output_scale, &actual_format, &compression, ctl_operations, global_ctl_parameters); input_image_files.pop_front(); } } catch (std::exception &e) { mexPrintf("exception thrown (oops...): %s\n", e.what()); } /* if( argc ) { for( j=argc-1; j>=0; j-- ) mxFree( argv[j] ); mxFree( argv ); } */ }
void formatMatrix(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* if (nlhs < 1) { mexWarnMsgTxt("formatMatrix did not get an output argument, so not doing any real work. Specify an output argument to do real work."); RETURN_NULL(); }*/ if (nrhs != 1 || !mxIsCell(*prhs) || !mxGetNumberOfDimensions(*prhs)) mexErrMsgTxt("formatMatrix: needs one input argument of type cell"); const int m = mxGetM(*prhs), n = mxGetN(*prhs); int i,j; static long outbuf_len = 1024*1024; // preallocate 1MB char *outbuf = (char *)mxCalloc(outbuf_len, sizeof(char)), *outbufPtr = outbuf; // preallocate 1MB for output if (!outbuf) mexErrMsgTxt("formatMatrix: failed to allocate 1MB for output txt"); for (i = 0; i < m; ++i) { for (j = 0; j < n; ++j) { int subs[2] = { i, j }; char buf[4096]; mxArray *cell = mxGetCell(*prhs, mxCalcSingleSubscript(*prhs, 2, subs)); if (!cell) { mxFree(outbuf); mexErrMsgTxt("formatMatrix: A cell element in the cell array could not be retrieved!"); } void *data = mxGetData(cell); if (!data) { // can happen on empty array mxFree(outbuf); mexErrMsgTxt("formatMatrix: A cell element in the cell array is empty/null -- all elements need to contain data!"); } switch(mxGetClassID(cell)) { case mxCHAR_CLASS: mxGetString(cell, buf, sizeof(buf)); buf[sizeof(buf)-1] = 0; break; case mxINT8_CLASS: sprintf(buf, "%hhd", *(char *)mxGetData(cell)); break; case mxUINT8_CLASS: sprintf(buf, "%hhu", *(unsigned char *)mxGetData(cell)); break; case mxINT16_CLASS: sprintf(buf, "%hd", *(short *)mxGetData(cell)); break; case mxUINT16_CLASS: sprintf(buf, "%hu", *(unsigned short *)mxGetData(cell)); break; case mxINT32_CLASS: sprintf(buf, "%d", *(int *)mxGetData(cell)); break; case mxUINT32_CLASS: sprintf(buf, "%u", *(unsigned int *)mxGetData(cell)); break; case mxSINGLE_CLASS: sprintf(buf, "%g", *(float *)mxGetData(cell)); break; case mxDOUBLE_CLASS: sprintf(buf, "%g", *(double *)mxGetData(cell)); break; default: mxFree(outbuf); mexErrMsgTxt("formatMatrix: Unknown cell type encountered!"); } long lenSoFar = outbufPtr - outbuf; if (lenSoFar + (strlen(buf)*3+4) >= outbuf_len) { // reallocate if ran out of space void * tmp = mxRealloc(outbuf, outbuf_len*=2); if (!tmp) { mxFree(outbuf); mexErrMsgTxt("formatMatrix: Out of space in output text buffer and failed to allocate more!"); } outbuf = (char *)tmp; outbufPtr = outbuf + lenSoFar; } // it's 1 cell per line.... *outbufPtr++ = ' '; *outbufPtr++ = ' '; outbufPtr += UrlEncode(outbufPtr, buf); *outbufPtr++ = '\n'; } } // return the text.. if (plhs[0]) mxDestroyArray(plhs[0]); plhs[0] = mxCreateString(outbuf); mxFree(outbuf); }
int isFunctionHandle( const mxArray* const M ) { if ( M == NULL ) return 0; if ( mxIsCell(M) ) return 0; if ( mxIsChar(M) ) return 0; if ( mxIsComplex(M) ) return 0; if ( mxIsDouble(M) ) return 0; if ( mxIsEmpty(M) ) return 0; if ( mxIsInt8(M) ) return 0; if ( mxIsInt16(M) ) return 0; if ( mxIsInt32(M) ) return 0; if ( mxIsLogical(M) ) return 0; if ( mxIsLogicalScalar(M) ) return 0; if ( mxIsLogicalScalarTrue(M) ) return 0; if ( mxIsNumeric(M) ) return 0; if ( mxIsSingle(M) ) return 0; if ( mxIsSparse(M) ) return 0; if ( mxIsStruct(M) ) return 0; if ( mxIsUint8(M) ) return 0; if ( mxIsUint16(M) ) return 0; if ( mxIsUint32(M) ) return 0; // assume to be a function handle iff it is nothing else return 1; }
mxArray* ParseChildNodes(pugi::xml_node& node) { mxArray *children = NULL; pugi::xml_attribute tempAttr = node.first_attribute(); if (HasChildNodes(node) || tempAttr != NULL) { mxArray *attributes = ParseAttributes(node); std::vector<std::string> distinctNames; std::vector<std::string> allChildNodeNames; std::vector<pugi::xml_node> childNodes; std::size_t numChildNodes; childNodes = GetChildNodes(node); numChildNodes = childNodes.size(); for (int i = 0; i < numChildNodes; i++) { allChildNodeNames.push_back(childNodes.at(i).name()); } distinctNames = GetDistinctNodeNames(allChildNodeNames); /* Patch for bypassing the variable-length arrays problems of modern C++ compilers */ std::vector<const char*> distinctChildNodeNames; std::transform(distinctNames.begin(), distinctNames.end(), std::back_inserter(distinctChildNodeNames), [](const std::string & str) { // initialize empty char array char *output = new char[str.size()+1]; std::strcpy(output, str.c_str()); return output; }); std::vector<std::string> processedNames; children = mxCreateStructMatrix(1, 1, (int)distinctNames.size(), &distinctChildNodeNames[0]); for (int idx = 0; idx < childNodes.size(); idx++) { pugi::xml_node theChild = childNodes.at(idx); std::string type = node_types[theChild.type()]; std::string temp = theChild.name(); std::string val = theChild.value(); const char *namey[1] = {}; namey[0] = temp.c_str(); mxArray *glhf = mxGetField(children, 0, namey[0]); int indexOfMatchingItem = mxGetFieldNumber(children, namey[0]); if (!(strcmp(type.c_str(), "pcdata") == 0) && !(strcmp(type.c_str(), "comment") == 0) && !(strcmp(type.c_str(), "cdata") == 0)) { //XML allows the same elements to be defined multiple times, put each in a different cell if (std::find(processedNames.begin(), processedNames.end(), temp) != processedNames.end()) { if ( glhf != NULL ) { if (!mxIsCell(glhf)) { mxArray *temp = glhf; glhf = mxCreateCellMatrix(1, 2); mxSetCell(glhf, 0, temp); mxSetCell(glhf, 1, ParseChildNodes(theChild)); mxSetCell(children, indexOfMatchingItem, glhf); } else { std::size_t numberItemsInCell = mxGetN(glhf); mxArray *temp = glhf; glhf = mxCreateCellMatrix(1, numberItemsInCell + 1); for (int i = 0; i < numberItemsInCell; i++) { mxSetCell(glhf, i, mxGetCell(temp, i)); } mxSetCell(glhf, numberItemsInCell, ParseChildNodes(theChild)); mxSetCell(children, indexOfMatchingItem, glhf); } } } //add previously unknown (new) element to the structure else { mxSetCell(children, indexOfMatchingItem, ParseChildNodes(theChild)); } processedNames.push_back(temp); } else { const char *typeFieldNames[1] = {"Text"}; std::string value = theChild.value(); mxArray *matValue = mxCreateString(value.c_str()); if (strcmp(type.c_str(), "cdata") == 0) { typeFieldNames[0] = "CDATA"; } else if (strcmp(type.c_str(), "comment") == 0) { typeFieldNames[0] = "Comment"; } children = mxCreateStructMatrix(1, 1, 1, typeFieldNames); mxSetFieldByNumber(children, 0, 0, matValue); processedNames.push_back(temp); } } if (attributes != NULL) { const char *attrFieldName = "Attributes"; mxAddField(children, attrFieldName); mxSetField(children, 0, attrFieldName, attributes); } } return children; }
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); } return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { double *A, *y; mwIndex *irA, *jcA, *iry, *jcy; double *ytmp, *Ay; int isspA, isspy, options; int m1, n1, m2, n2, j, jm1; int i, r, k, istart, iend, kstart, kend; double tmp; /* CHECK THE DIMENSIONS */ if (mxIsCell(prhs[0]) | mxIsCell(prhs[1])) { mexErrMsgTxt(" mexMatvec: A, x must be a double array"); } if (nrhs <2) { mexErrMsgTxt(" mexMatvec: must have at least 2 inputs"); } if (nlhs > 2) { mexErrMsgTxt("mexMatvec: requires 1 output argument"); } if (nrhs == 2) { options = 0; } else { options = (int) *mxGetPr(prhs[2]); } /***** assign pointers *****/ A = mxGetPr(prhs[0]); m1 = mxGetM(prhs[0]); n1 = mxGetN(prhs[0]); isspA = mxIsSparse(prhs[0]); if (isspA) { irA = mxGetIr(prhs[0]); jcA = mxGetJc(prhs[0]); } isspy = mxIsSparse(prhs[1]); m2 = mxGetM(prhs[1]); n2 = mxGetN(prhs[1]); if (n2 > 1) { mexErrMsgTxt("mexMatvec: 2ND input must be a column vector"); } if (isspy) { iry = mxGetIr(prhs[1]); jcy = mxGetJc(prhs[1]); ytmp = mxGetPr(prhs[1]); /***** copy ytmp to y *****/ y = mxCalloc(m2,sizeof(double)); kstart = jcy[0]; kend = jcy[1]; for (k=kstart; k<kend; k++) { r = iry[k]; y[r] = ytmp[k]; } } else { y = mxGetPr(prhs[1]); } if (options == 0 & n1 != m2) { mexErrMsgTxt("mexMatvec: 1ST and 2ND input not compatible."); } else if (options & m1 != m2) { mexErrMsgTxt("mexMatvec: 1ST and 2ND input not compatible."); } /***** create return argument *****/ if (options==0) { plhs[0] = mxCreateDoubleMatrix(m1,1,mxREAL); } else { plhs[0] = mxCreateDoubleMatrix(n1,1,mxREAL); } Ay = mxGetPr(plhs[0]); /***** main body *****/ if (options==0) { if (!isspA) { for (j=0; j<n1; j++){ jm1 = j*m1; tmp = y[j]; if (tmp !=0) { saxpymat(A,jm1,0,m1,tmp,Ay,0); } } } else { for (j=0; j<n1; j++){ tmp = y[j]; if (tmp != 0) { istart = jcA[j]; iend = jcA[j+1]; for (i=istart; i<iend; i++) { r = irA[i]; Ay[r] += tmp*A[i]; } } } } } else { if (!isspA) { for (j=0; j<n1; j++){ jm1 = j*m1; Ay[j] = realdotde(A,jm1,y,m1); } } else { for (j=0; j<n1; j++){ istart = jcA[j]; iend = jcA[j+1]; tmp = 0; for (i=istart; i<iend; i++) { r = irA[i]; tmp += y[r]*A[i]; } Ay[j] = tmp; } } } return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mxArray* tmp; /* ================ */ /* Check the INPUTS */ /* ================ */ #if DO_CHECK > 0 if( nrhs != 4 ) mexErrMsgIdAndTxt("InvalidInput:nrhs", "Require 4 inputs."); if ( !mxIsStruct(prhs[0]) ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY", "'DICTIONARY' must be a struct"); #endif mxArray* IC = mxGetField( prhs[0], 0, "IC" ); mxArray* EC = mxGetField( prhs[0], 0, "EC" ); mxArray* ISO = mxGetField( prhs[0], 0, "ISO" ); #if DO_CHECK > 0 if ( !mxIsStruct(IC) || !mxIsStruct(EC) || !mxIsStruct(ISO) ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY", "'DICTIONARY' format is wrong"); #endif // Parse "DICTIONARY.nV" tmp = mxGetField( prhs[0], 0, "nV" ); #if DO_CHECK > 0 if( !mxIsDouble(tmp) || mxIsComplex(tmp) || mxGetNumberOfElements(tmp)!=1 ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.nV","'DICTIONARY.nV' must be a real scalar"); #endif nV = mxGetScalar( tmp ); // Parse "DICTIONARY.EC.nE" tmp = mxGetField( EC, 0, "nE" ); #if DO_CHECK > 0 if( !mxIsDouble(tmp) || mxIsComplex(tmp) || mxGetNumberOfElements(tmp)!=1 ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.EC.nE","'DICTIONARY.EC.nE' must be a real scalar"); #endif nE = mxGetScalar( tmp ); // Parse "DICTIONARY.IC.n" tmp = mxGetField( IC, 0, "n" ); #if DO_CHECK > 0 if( !mxIsDouble(tmp) || mxIsComplex(tmp) || mxGetNumberOfElements(tmp)!=1 ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.IC.n","'DICTIONARY.IC.n' must be a real scalar"); #endif n = mxGetScalar( tmp ); // Parse "DICTIONARY.IC.fiber" tmp = mxGetField( IC, 0, "fiber" ); #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.IC.fiber","'DICTIONARY.IC.fiber' must be a n*1 vector (uint32)"); #endif ICf = (UINT32_T*) mxGetData( tmp ); // Parse "DICTIONARY.IC.len" tmp = mxGetField( IC, 0, "len" ); #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"single") ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.IC.len","'DICTIONARY.IC.len' must be a n*1 vector (single)"); #endif ICl = (float*) mxGetData(tmp); // Parse "DICTIONARY.IC.v", "DICTIONARY.IC.o" tmp = mxGetField( IC, 0, "v" ); #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.IC.v","'DICTIONARY.IC.v' must be a n*1 vector (uint32)"); #endif ICv = (UINT32_T*) mxGetData(tmp); tmp = mxGetField( IC, 0, "o" ); #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint16") ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.IC.o","'DICTIONARY.IC.o' must be a n*1 vector (uint16)"); #endif ICo = (UINT16_T*) mxGetData(tmp); // Parse "DICTIONARY.EC.v","DICTIONARY.EC.o" tmp = mxGetField( EC, 0, "v" ); #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.EC.v","'DICTIONARY.EC.v' must be a n*1 vector (uint32)"); #endif ECv = (UINT32_T*) mxGetData(tmp); tmp = mxGetField( EC, 0, "o" ); #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint16") ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.EC.o","'DICTIONARY.EC.o' must be a n*1 vector (uint16)"); #endif ECo = (UINT16_T*) mxGetData(tmp); // Parse "DICTIONARY.ISO.v" tmp = mxGetField( ISO, 0, "v" ); #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") ) mexErrMsgIdAndTxt("InvalidInput:DICTIONARY.ISO.v","'DICTIONARY.ISO.v' must be a n*1 vector (uint32)"); #endif ISOv = (UINT32_T*) mxGetData(tmp); // Parse "KERNELS.nS" tmp = mxGetField( prhs[1], 0, "nS" ); #if DO_CHECK > 0 if( !mxIsDouble(tmp) || mxIsComplex(tmp) || mxGetNumberOfElements(tmp)!=1 ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.nS","'KERNELS.nS' must be a real scalar"); #endif nS = mxGetScalar( tmp ); // Parse "KERNELS.wmr", "KERNELS.wmh" and "KERNELS.iso" mxArray* wmr = mxGetField( prhs[1], 0, "wmr" ); #if nIC>=1 #if DO_CHECK > 0 if ( !mxIsCell(wmr) ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmr","'KERNELS.wmr' must be a cell array"); if( !mxIsClass(mxGetCell(wmr,0),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmr","'KERNELS.wmr' must contain single"); #endif wmrSFP0 = (float*) mxGetData( mxGetCell(wmr,0) ); #endif #if nIC>=2 #if DO_CHECK > 0 if( !mxIsClass(mxGetCell(wmr,1),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmr","'KERNELS.wmr' must contain single"); #endif wmrSFP1 = (float*) mxGetData( mxGetCell(wmr,1) ); #endif #if nIC>=3 #if DO_CHECK > 0 if( !mxIsClass(mxGetCell(wmr,2),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmr","'KERNELS.wmr' must contain single"); #endif wmrSFP2 = (float*) mxGetData( mxGetCell(wmr,2) ); #endif #if nIC>=4 #if DO_CHECK > 0 if( !mxIsClass(mxGetCell(wmr,3),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmr","'KERNELS.wmr' must contain single"); #endif wmrSFP3 = (float*) mxGetData( mxGetCell(wmr,3) ); #endif #if nEC>=1 mxArray* wmh = mxGetField( prhs[1], 0, "wmh" ); #if DO_CHECK > 0 if ( !mxIsCell(wmh) ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmh","'KERNELS.wmh' must be a cell array"); if( !mxIsClass(mxGetCell(wmh,0),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmh","'KERNELS.wmh' must contain single"); #endif wmhSFP0 = (float*) mxGetData( mxGetCell(wmh,0) ); #if nEC>=2 #if DO_CHECK > 0 if( !mxIsClass(mxGetCell(wmh,1),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmh","'KERNELS.wmh' must contain single"); #endif wmhSFP1 = (float*) mxGetData( mxGetCell(wmh,1) ); #endif #if nEC>=3 #if DO_CHECK > 0 if( !mxIsClass(mxGetCell(wmh,2),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmh","'KERNELS.wmh' must contain single"); #endif wmhSFP2 = (float*) mxGetData( mxGetCell(wmh,2) ); #endif #if nEC>=4 #if DO_CHECK > 0 if( !mxIsClass(mxGetCell(wmh,3),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.wmh","'KERNELS.wmh' must contain single"); #endif wmhSFP3 = (float*) mxGetData( mxGetCell(wmh,3) ); #endif #endif #if nISO>=1 mxArray* iso = mxGetField( prhs[1], 0, "iso" ); #if DO_CHECK > 0 if ( !mxIsCell(iso) ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.iso","'KERNELS.iso' must be a cell array"); if( !mxIsClass(mxGetCell(iso,0),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.iso","'KERNELS.iso' must contain single"); #endif isoSFP0 = (float*) mxGetData( mxGetCell(iso,0) ); #if nISO>=2 #if DO_CHECK > 0 if( !mxIsClass(mxGetCell(iso,1),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.iso","'KERNELS.iso' must contain single"); #endif isoSFP1 = (float*) mxGetData( mxGetCell(iso,1) ); #endif #if nISO>=3 #if DO_CHECK > 0 if( !mxIsClass(mxGetCell(iso,2),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.iso","'KERNELS.iso' must contain single"); #endif isoSFP2 = (float*) mxGetData( mxGetCell(iso,2) ); #endif #if nISO>=4 #if DO_CHECK > 0 if( !mxIsClass(mxGetCell(iso,3),"single") ) mexErrMsgIdAndTxt("InvalidInput:KERNELS.iso","'KERNELS.iso' must contain single"); #endif isoSFP3 = (float*) mxGetData( mxGetCell(iso,3) ); #endif #endif // Parse "x" #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(prhs[2]) != 2 || mxGetN(prhs[2]) != 1 || !mxIsClass(prhs[2],"double") ) mexErrMsgIdAndTxt("InvalidInput:x","'x' must be a n*1 vector (double)"); #endif x = (double*) mxGetData( prhs[2] ); if ( nIC > 0 ) nF = ( mxGetM(prhs[2]) - nE*nEC - nV*nISO) / nIC; else nF = 0; // parse "THREADS" #if DO_CHECK > 0 if ( !mxIsStruct(prhs[3]) ) mexErrMsgIdAndTxt("InvalidInput:THREADS", "'THREADS' must be a struct"); #endif tmp = mxGetField( prhs[3], 0, "IC" ); #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") ) mexErrMsgIdAndTxt("InvalidInput:THREADS.IC","'THREADS.IC' must be a n*1 vector (uint32)"); #endif ICthreads = (UINT32_T*) mxGetData( tmp ); tmp = mxGetField( prhs[3], 0, "EC" ); #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") ) mexErrMsgIdAndTxt("InvalidInput:THREADS.EC","'THREADS.EC' must be a n*1 vector (uint32)"); #endif ECthreads = (UINT32_T*) mxGetData( tmp ); tmp = mxGetField( prhs[3], 0, "ISO" ); #if DO_CHECK > 0 if ( mxGetNumberOfDimensions(tmp) != 2 || mxGetN(tmp) != 1 || !mxIsClass(tmp,"uint32") ) mexErrMsgIdAndTxt("InvalidInput:THREADS.ISO","'THREADS.ISO' must be a n*1 vector (uint32)"); #endif ISOthreads = (UINT32_T*) mxGetData( tmp ); /* =============== */ /* Set the OUTPUTS */ /* =============== */ #if DO_CHECK > 0 if( nlhs != 1 ) mexErrMsgIdAndTxt("InvalidOutput:nlhs", "Required 1 output."); #endif const int outDims[2] = { nS*nV, 1 }; plhs[0] = mxCreateNumericArray(2, outDims, mxDOUBLE_CLASS, mxREAL); Y = (double*)mxGetData( plhs[0] ); /* ================================================== */ /* Run SEPARATE THREADS to perform the multiplication */ /* ================================================== */ pthread_t threads[nTHREADS]; for(int t=0; t<nTHREADS ; t++) pthread_create( &threads[t], NULL, computeProductBlock, (void *) (long int)t ); for(int t=0; t<nTHREADS ; t++) pthread_join( threads[t], NULL ); return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { unsigned n; double *x, *x0, opt_f; nlopt_result ret; mxArray *x_mx, *mx; user_function_data d, dpre, *dfc = NULL, *dh = NULL; nlopt_opt opt = NULL; CHECK(nrhs == 2 && nlhs <= 3, "wrong number of arguments"); /* options = prhs[0] */ CHECK(mxIsStruct(prhs[0]), "opt must be a struct"); /* x0 = prhs[1] */ CHECK(mxIsDouble(prhs[1]) && !mxIsComplex(prhs[1]) && (mxGetM(prhs[1]) == 1 || mxGetN(prhs[1]) == 1), "x must be real row or column vector"); n = mxGetM(prhs[1]) * mxGetN(prhs[1]), x0 = mxGetPr(prhs[1]); CHECK(opt = make_opt(prhs[0], n), "error initializing nlopt options"); d.neval = 0; d.verbose = (int) struct_val_default(prhs[0], "verbose", 0); d.opt = opt; /* function f = prhs[1] */ mx = struct_funcval(prhs[0], "min_objective"); if (!mx) mx = struct_funcval(prhs[0], "max_objective"); CHECK(mx, "either opt.min_objective or opt.max_objective must exist"); if (mxIsChar(mx)) { CHECK(mxGetString(mx, d.f, FLEN) == 0, "error reading function name string (too long?)"); d.nrhs = 1; d.xrhs = 0; } else { d.prhs[0] = mx; strcpy(d.f, "feval"); d.nrhs = 2; d.xrhs = 1; } d.prhs[d.xrhs] = mxCreateDoubleMatrix(1, n, mxREAL); if ((mx = struct_funcval(prhs[0], "pre"))) { CHECK(mxIsChar(mx) || mxIsFunctionHandle(mx), "pre must contain function handles or function names"); if (mxIsChar(mx)) { CHECK(mxGetString(mx, dpre.f, FLEN) == 0, "error reading function name string (too long?)"); dpre.nrhs = 2; dpre.xrhs = 0; } else { dpre.prhs[0] = mx; strcpy(dpre.f, "feval"); dpre.nrhs = 3; dpre.xrhs = 1; } dpre.verbose = d.verbose > 2; dpre.opt = opt; dpre.neval = 0; dpre.prhs[dpre.xrhs] = d.prhs[d.xrhs]; dpre.prhs[d.xrhs+1] = mxCreateDoubleMatrix(1, n, mxREAL); d.dpre = &dpre; if (struct_funcval(prhs[0], "min_objective")) nlopt_set_precond_min_objective(opt, user_function,user_pre,&d); else nlopt_set_precond_max_objective(opt, user_function,user_pre,&d); } else { dpre.nrhs = 0; if (struct_funcval(prhs[0], "min_objective")) nlopt_set_min_objective(opt, user_function, &d); else nlopt_set_max_objective(opt, user_function, &d); } if ((mx = mxGetField(prhs[0], 0, "fc"))) { int j, m; double *fc_tol; CHECK(mxIsCell(mx), "fc must be a Cell array"); m = mxGetM(mx) * mxGetN(mx);; dfc = (user_function_data *) mxCalloc(m, sizeof(user_function_data)); fc_tol = struct_arrval(prhs[0], "fc_tol", m, NULL); for (j = 0; j < m; ++j) { mxArray *fc = mxGetCell(mx, j); CHECK(mxIsChar(fc) || mxIsFunctionHandle(fc), "fc must contain function handles or function names"); if (mxIsChar(fc)) { CHECK(mxGetString(fc, dfc[j].f, FLEN) == 0, "error reading function name string (too long?)"); dfc[j].nrhs = 1; dfc[j].xrhs = 0; } else { dfc[j].prhs[0] = fc; strcpy(dfc[j].f, "feval"); dfc[j].nrhs = 2; dfc[j].xrhs = 1; } dfc[j].verbose = d.verbose > 1; dfc[j].opt = opt; dfc[j].neval = 0; dfc[j].prhs[dfc[j].xrhs] = d.prhs[d.xrhs]; CHECK(nlopt_add_inequality_constraint(opt, user_function, dfc + j, fc_tol ? fc_tol[j] : 0) > 0, "nlopt error adding inequality constraint"); } } if ((mx = mxGetField(prhs[0], 0, "h"))) { int j, m; double *h_tol; CHECK(mxIsCell(mx), "h must be a Cell array"); m = mxGetM(mx) * mxGetN(mx);; dh = (user_function_data *) mxCalloc(m, sizeof(user_function_data)); h_tol = struct_arrval(prhs[0], "h_tol", m, NULL); for (j = 0; j < m; ++j) { mxArray *h = mxGetCell(mx, j); CHECK(mxIsChar(h) || mxIsFunctionHandle(h), "h must contain function handles or function names"); if (mxIsChar(h)) { CHECK(mxGetString(h, dh[j].f, FLEN) == 0, "error reading function name string (too long?)"); dh[j].nrhs = 1; dh[j].xrhs = 0; } else { dh[j].prhs[0] = h; strcpy(dh[j].f, "feval"); dh[j].nrhs = 2; dh[j].xrhs = 1; } dh[j].verbose = d.verbose > 1; dh[j].opt = opt; dh[j].neval = 0; dh[j].prhs[dh[j].xrhs] = d.prhs[d.xrhs]; CHECK(nlopt_add_equality_constraint(opt, user_function, dh + j, h_tol ? h_tol[j] : 0) > 0, "nlopt error adding equality constraint"); } } x_mx = mxCreateDoubleMatrix(mxGetM(prhs[1]), mxGetN(prhs[1]), mxREAL); x = mxGetPr(x_mx); memcpy(x, x0, sizeof(double) * n); ret = nlopt_optimize(opt, x, &opt_f); mxFree(dh); mxFree(dfc); mxDestroyArray(d.prhs[d.xrhs]); if (dpre.nrhs > 0) mxDestroyArray(dpre.prhs[d.xrhs+1]); nlopt_destroy(opt); plhs[0] = x_mx; if (nlhs > 1) { plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL); *(mxGetPr(plhs[1])) = opt_f; } if (nlhs > 2) { plhs[2] = mxCreateDoubleMatrix(1, 1, mxREAL); *(mxGetPr(plhs[2])) = (int) ret; } }
//Check all inputs for size and type errors void checkInputs(const mxArray *prhs[], int nrhs) { size_t ndec, m, i; const mxArray *fxd; double *val; //Correct number of inputs if(nrhs < 3) mexErrMsgTxt("You must supply at least 3 arguments to dsdp (f, A, b)"); //Check we have an objective if(mxIsEmpty(pF)) mexErrMsgTxt("You must supply an objective function via f!"); //Check we have some constraints if(nrhs >= (eSDP+1) && mxIsEmpty(pA) && mxIsEmpty(pLB) && mxIsEmpty(pUB) && mxIsEmpty(pSDP)) mexErrMsgTxt("You must supply constraints to this solver!"); else if(nrhs == (eUB+1) && mxIsEmpty(pA) && mxIsEmpty(pLB) && mxIsEmpty(pUB)) mexErrMsgTxt("You must supply constraints to this solver!"); else if(nrhs == (eB+1) && (mxIsEmpty(pA) || mxIsEmpty(pB))) mexErrMsgTxt("You must supply constraints to this solver!"); //Check options is a structure if(nrhs > eOPTS && !mxIsStruct(pOPTS)) mexErrMsgTxt("The options argument must be a structure"); //Get Sizes ndec = mxGetNumberOfElements(pF); //Check linear constraints if(!mxIsEmpty(pA)) { //Check types if(!mxIsSparse(pA) || mxIsComplex(pA) || !mxIsDouble(pA)) mexErrMsgTxt("A must be real, sparse, double matrix"); if(mxIsSparse(pB) || mxIsComplex(pB) || !mxIsDouble(pB)) mexErrMsgTxt("b must be real, dense, double column vector"); //Check sizes if(mxGetN(pA) != ndec) mexErrMsgTxt("A does not have the same number of columns as decision variables!"); if(mxGetM(pA) != mxGetNumberOfElements(pB)) mexErrMsgTxt("A and b do not have the same number of rows!"); } //Check bounds if(nrhs > eLB && !mxIsEmpty(pLB)) { if(mxIsSparse(pLB) || mxIsComplex(pLB) || !mxIsDouble(pLB)) mexErrMsgTxt("lb must be real, dense, double column vector"); if(mxGetNumberOfElements(pLB) != ndec) mexErrMsgTxt("lb is not the same length as f!"); } if(nrhs > eUB && !mxIsEmpty(pUB)) { if(mxIsSparse(pUB) || mxIsComplex(pUB) || !mxIsDouble(pUB)) mexErrMsgTxt("ub must be real, dense, double column vector"); if(mxGetNumberOfElements(pUB) != ndec) mexErrMsgTxt("ub is not the same length as f!"); } //Check sdcones if(nrhs > eSDP && !mxIsEmpty(pSDP)) { if(mxIsCell(pSDP)) { for(i=0;i<mxGetNumberOfElements(pSDP);i++) checkCone(mxGetCell(pSDP,i),ndec,i); } else checkCone(pSDP,ndec,1); } //Check y0 if(nrhs > eY0 && !mxIsEmpty(pY0)) { if(mxIsSparse(pY0) || mxIsComplex(pY0) || !mxIsDouble(pY0)) mexErrMsgTxt("y0 must be real, dense, double column vector"); if(mxGetNumberOfElements(pY0) != ndec) mexErrMsgTxt("y0 is not the same length as f!"); } //Check fixed vars option if(nrhs > eOPTS && !mxIsEmpty(pOPTS) && mxGetField(pOPTS,0,"fixed") && !mxIsEmpty(mxGetField(pOPTS,0,"fixed"))) { fxd = mxGetField(pOPTS,0,"fixed"); //Check Type if(mxIsSparse(fxd) || mxIsComplex(fxd) || !mxIsDouble(fxd)) mexErrMsgTxt("The fixed option must be a real, dense, double matrix"); val = mxGetPr(fxd); m = mxGetM(fxd); if(mxGetN(fxd) != 2) mexErrMsgTxt("The fixed option must contain 2 columns"); if(m > ndec) mexErrMsgTxt("The fixed option must not contain more rows than decision variables"); for(i=0;i<m;i++) { if(val[i] <= 0 || val[i] > ndec) mexErrMsgTxt("A variable index in the fixed option is <= 0 or > ndec"); if(mxIsNaN(val[i+m]) || mxIsInf(val[i+m])) mexErrMsgTxt("A variable value in the fixed option is NaN or Inf"); } } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const mxArray *srcmat; int ndim, eltsize; mwSize *dimsize; const mwSize *dims; int ndimdest; mwSize *destdims, *destdimsize; char *src, *dest; mwSize *rep; int i,nrep; int extra_rep = 1; int empty; double *outp, *inp; mwSize m,n,numel; if(nrhs < 2) mexErrMsgTxt("Usage: repmat(A, [M N ...])"); srcmat = prhs[0]; if(0) { /* testing code, please ignore */ /* plhs[0] = mxCreateNumericArrayE(ndim, dims, mxGetClassID(srcmat), mxIsComplex(srcmat)?mxCOMPLEX:mxREAL); */ m = mxGetM(srcmat); n = mxGetN(srcmat); plhs[0] = mxCreateDoubleMatrixE(m, n, mxREAL); outp = mxGetPr(plhs[0]); inp = mxGetPr(srcmat); numel = mxGetNumberOfElements(srcmat); memcpy(outp, inp, numel*sizeof(double)); /* plhs[0] = mxCreateNumericMatrixE(dims[0], dims[1], mxGetClassID(srcmat), mxIsComplex(srcmat)?mxCOMPLEX:mxREAL); plhs[0] = mxCreateNumericMatrix(0, 0, mxGetClassID(srcmat), mxIsComplex(srcmat)?mxCOMPLEX:mxREAL); */ return; } if(!mxIsNumeric(srcmat) || mxIsSparse(srcmat) || mxIsCell(srcmat) || mxIsStruct(srcmat)) { /* call Matlab's repmat */ mexCallMATLAB(nlhs,plhs,nrhs,(mxArray**)prhs,"xrepmat");return; /* mexErrMsgTxt("Sorry, can't handle sparse matrices yet."); */ } ndim = mxGetNumberOfDimensions(srcmat); dims = mxGetDimensions(srcmat); eltsize = mxGetElementSize(srcmat); /* compute dimension sizes */ dimsize = (mwSize*)mxCalloc(ndim, sizeof(mwSize)); dimsize[0] = eltsize*dims[0]; for(i=1;i<ndim;i++) dimsize[i] = dimsize[i-1]*dims[i]; /* determine repetition vector */ ndimdest = ndim; if(nrhs == 2) { /* prhs[1] is a vector of reps */ nrep = mxGetN(prhs[1]); if(nrep > ndimdest) ndimdest = nrep; rep = (mwSize*)mxCalloc(ndimdest, sizeof(mwSize)); for(i=0;i<nrep;i++) { double repv = mxGetPr(prhs[1])[i]; rep[i] = (mwSize)repv; } #if ALWAYS_2D if(nrep == 1) { /* special behavior */ nrep = 2; rep[1] = rep[0]; } #endif } else { /* concatenate all prhs's */ int ri=0; nrep = 0; for(i=0;i<nrhs-1;i++) { nrep += mxGetNumberOfElements(prhs[i+1]); } if(nrep > ndimdest) ndimdest = nrep; rep = (mwSize*)mxCalloc(ndimdest, sizeof(mwSize)); for(i=0;i<nrhs-1;i++) { double *p = mxGetPr(prhs[i+1]); int j, sz = mxGetNumberOfElements(prhs[i+1]); for(j=0;j<sz;j++) rep[ri++] = (mwSize)p[j]; } } for(i=nrep;i<ndimdest;i++) rep[i] = 1; /* compute output size */ destdims = (mwSize*)mxCalloc(ndimdest, sizeof(mwSize)); for(i=0;i<ndim;i++) destdims[i] = dims[i]*rep[i]; for(;i<ndimdest;i++) { destdims[i] = rep[i]; extra_rep *= rep[i]; } destdimsize = (mwSize*)mxCalloc(ndim, sizeof(mwSize)); destdimsize[0] = eltsize*destdims[0]; for(i=1;i<ndim;i++) destdimsize[i] = destdimsize[i-1]*destdims[i]; /* for speed, array should be uninitialized */ plhs[0] = mxCreateNumericArrayE(ndimdest, destdims, mxGetClassID(srcmat), mxIsComplex(srcmat)?mxCOMPLEX:mxREAL); /* if any rep[i] == 0, output should be empty array. Added by KPM 11/13/02. */ empty = 0; for (i=0; i < nrep; i++) { if (rep[i]==0) empty = 1; } if (empty) return; src = (char*)mxGetData(srcmat); dest = (char*)mxGetData(plhs[0]); repmat(dest,src,ndim,destdimsize,dimsize,dims,rep); if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep); if(mxIsComplex(srcmat)) { src = (char*)mxGetPi(srcmat); dest = (char*)mxGetPi(plhs[0]); repmat(dest,src,ndim,destdimsize,dimsize,dims,rep); if(ndimdest > ndim) memrep(dest,destdimsize[ndim-1],extra_rep); } }
MP_Dict_c * mp_create_dict_from_mxDict(const mxArray *mxDict) { const char *func = "mp_create_dict_from_mxDict"; const char *fieldName; map<string,string,mp_ltstring> *paramMap; MP_Dict_c *dict = NULL; mxArray *mxBlockCell,*mxBlock,*mxTmp; mwSize mwNumDimension; const mwSize *mwDimension; size_t numFields; int nBlocks; int iIndexDimension,iDimension; char *fieldValue; double *dTable = NULL; string szDataString,szReturnString; if (NULL==mxDict) { mp_error_msg(func,"input is NULL\n"); return(NULL); } // Check that the input dictionary structure has the right fields mxBlockCell = mxGetField(mxDict,0,"block"); if (NULL==mxBlockCell) { mp_error_msg(func,"the dict.block field is missing\n"); return(NULL); } nBlocks = (int)mxGetNumberOfElements(mxBlockCell); if (0==nBlocks) { mp_error_msg(func,"the number of blocks should be at least one\n"); return(NULL); } if(!mxIsCell(mxBlockCell)) { mp_error_msg(func,"the dict.block is not a cell array\n"); return(NULL); } // Reach all blocks for (int i = 0; i < nBlocks; i++ ) { mxBlock = mxGetCell(mxBlockCell,i); if (NULL==mxBlock) { // This should never happen mp_error_msg(func,"dict.block{%d} could not be retrieved\n",i+1); // Clean the house if(NULL!=dict) delete dict; return(NULL); } numFields = mxGetNumberOfFields(mxBlock); if (0==numFields) { mp_error_msg(func,"the number of fields %d should be at least one in dict.block{%d}\n",numFields,i+1); // Clean the house if(NULL!=dict) delete dict; return(NULL); } // Reach all fields of the block and put them in a map paramMap = new map<string, string, mp_ltstring>(); if(NULL==paramMap) { mp_error_msg(func,"could not allocate paramMap\n"); // Clean the house if(NULL!=dict) delete dict; return(NULL); } for (unsigned int j= 0; j <numFields ; j++) { fieldName = mxGetFieldNameByNumber(mxBlock,j); if (fieldName == NULL) { mp_error_msg(func,"field number %d in dict.block{%d} could not be retrieved\n",j+1,i+1); // Clean the house if(NULL!=dict) delete dict; return(NULL); } // Retrieve the field value mxTmp = mxGetField(mxBlock,0,fieldName); if(mxTmp == NULL) { mp_error_msg(func,"value of field number %d in dict.block{%d} could not be retrieved\n",j+1,i+1); // Clean the house if(NULL!=dict) delete dict; return(NULL); } if(mxIsDouble(mxTmp)) { // Retrieve the dimension of the double mwNumDimension = mxGetNumberOfDimensions(mxTmp); mwDimension = mxGetDimensions(mxTmp); iDimension = 1; for(iIndexDimension = 0; iIndexDimension < (int)mwNumDimension; iIndexDimension++) iDimension *= mwDimension[iIndexDimension]; // Add the dimension of a double iDimension = iDimension * sizeof(double); // Getting the storage field if((dTable = (MP_Real_t*)malloc(iDimension)) == NULL) { mp_error_msg(func,"The double storage has not been allocaed\n"); return(NULL); } // Loading the mxArray if(!mp_get_anywave_datas_from_mxAnywaveTable(mxBlock,dTable)) { mp_error_msg(func,"A double value has been found but could not be retrieved\n"); // Clean the house if(NULL!=dict) delete dict; return(NULL); } // Store it in the map and free (*paramMap)["doubledata"] = string((char *)dTable, iDimension); } else { fieldValue = mxArrayToString(mxTmp); if(fieldValue == NULL) { mp_error_msg(func,"string value of field number %d in dict.block{%d} could not be retrieved\n",j+1,i+1); // Clean the house if(NULL!=dict) delete dict; return(NULL); } // Store it in the map and free (*paramMap)[string(fieldName)]=string(fieldValue); mxFree(fieldValue); fieldValue = NULL; } } // Retrieve the block creator MP_Block_c* (*blockCreator)( MP_Signal_c *setSignal, map<string, string, mp_ltstring> * paramMap ) = NULL; blockCreator = MP_Block_Factory_c::get_block_creator((*paramMap)["type"].c_str()); if (NULL == blockCreator) { mp_error_msg(func,"the block factory does not contain type %s of dict.block{%d}\n",(*paramMap)["type"].c_str(),i+1); // Clean the house if(NULL!=dict) delete dict; delete paramMap; return(NULL); } // Create the block MP_Block_c *block = blockCreator(NULL, paramMap); if (NULL == block) { mp_error_msg(func,"the dict.block{%d}, of type %s was not successfully created\n",i+1,(*paramMap)["type"].c_str()); // Clean the house if(NULL!=dict) delete dict; delete paramMap; return(NULL); } // Create the dictionary if needed (i.e. when adding first block) if (NULL==dict) { dict = MP_Dict_c::init(); if (NULL==dict) { mp_error_msg(func,"Failed to create an empty dictionary\n"); delete paramMap; delete block; return(NULL); } } // Add the block to the dictionary dict->add_block(block); if(dTable) free(dTable); delete paramMap; } return(dict); }
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; }