void get_P1(const mxArray *model, int *pm, double **P1, double **P1_inf) { int m, i, init; m = mxGetM(model); if(pm) *pm = m; *P1 = mxGetPr(model); /*** Determine initialization ***/ for(i=0, init=false; i<m*m; i++) if(mxIsInf((*P1)[i])) { init = true; break; } if(init) { /*** Make a copy first ***/ double *P1new = g_P1 = (double *)mxCalloc(m*m, sizeof(double)); *P1_inf = g_P1_inf = (double *)mxCalloc(m*m, sizeof(double)); for(i=0; i<m*m; i++) { P1new[i] = (*P1)[i]; if(mxIsInf(P1new[i])) { P1new[i] = 0; (*P1_inf)[i] = 1; } else (*P1_inf)[i] = 0; } *P1 = P1new; } else *P1_inf = (double *)0; }
// Function definitions. // ----------------------------------------------------------------- int getBoundType (double& lb, double& ub) { bool haslb = !mxIsInf(lb); bool hasub = !mxIsInf(ub); int btype = haslb + 3*hasub - 2*(haslb && hasub); lb = haslb ? lb : 0; ub = hasub ? ub : 0; return btype; }
double* Options::loadUpperBounds(int n, const mxArray* ptr, double posinfty) { double* ub; // The return value. // Load the upper bounds on the variables. const mxArray* p = mxGetField(ptr,0,"ub"); if (p) { // Load the upper bounds and check to make sure they are valid. int N = Iterate::getMatlabData(p,ub); if (N != n) throw MatlabException("Upper bounds array must have one element for each optimization variable"); // Convert MATLAB's convention of infinity to BONMIN's convention // of infinity. for (int i = 0; i < n; i++) if (mxIsInf(ub[i])) ub[i] = posinfty; } else { // If the upper bounds have not been specified, set them to // positive infinity. ub = new double[n]; for (int i = 0; i < n; i++) ub[i] = posinfty; } return ub; }
//Insert Bound Vector int insertBound(struct sparseblock *blockptr, double *bnd, int nBND, int con_num, int block, int ind, double coeff) { //Assign Sizes blockptr->blocknum = block; blockptr->blocksize = nBND; blockptr->constraintnum = con_num; blockptr->next = NULL; blockptr->nextbyblock = NULL; //Check we have a finite constraint on this variable if(!mxIsInf(bnd[con_num-1])) { blockptr->numentries = 1; //Allocate LB A Memory (+1s due to Fortran index) blockptr->entries = (double*)malloc((1+1)*sizeof(double)); if(blockptr->entries == NULL) { if(coeff==-1.0) sprintf(msgbuf,"Error allocating entries memory for LB[%d, block %d]",con_num, block); else sprintf(msgbuf,"Error allocating entries memory for UB[%d, block %d]",con_num, block); mexErrMsgTxt(msgbuf); } blockptr->iindices = (unsigned*)malloc((1+1)*sizeof(unsigned)); if(blockptr->iindices == NULL) { if(coeff==-1.0) sprintf(msgbuf,"Error allocating iindices memory for LB[%d, block %d]",con_num, block); else sprintf(msgbuf,"Error allocating iindices memory for UB[%d, block %d]",con_num, block); mexErrMsgTxt(msgbuf); } blockptr->jindices = (unsigned*)malloc((1+1)*sizeof(unsigned)); if(blockptr->jindices == NULL) { if(coeff==-1.0) sprintf(msgbuf,"Error allocating jindices memory for LB[%d, block %d]",con_num, block); else sprintf(msgbuf,"Error allocating jindices memory for UB[%d, block %d]",con_num, block); mexErrMsgTxt(msgbuf); } //Fill in entry blockptr->entries[1] = coeff; blockptr->iindices[1] = ind; //don't use con_num incase leading elements are inf (lb = [-Inf,0] .. etc) blockptr->jindices[1] = ind; #ifdef DEBUG if(coeff==-1.0) mexPrintf("LB[%d, block %d] i: %d, j: %d, val: %f\n",con_num,block,ind,ind,coeff); else mexPrintf("UB[%d, block %d] i: %d, j: %d, val: %f\n",con_num,block,ind,ind,coeff); #endif } //Else skip entry else { blockptr->numentries = 0; blockptr->entries = NULL; blockptr->iindices = NULL; blockptr->jindices = NULL; } return blockptr->numentries; }
/* * egarch_core.c - * This is a helper function and is part of the UCSD_GARCH toolbox * You can compile it and should work on any platform. * * Author: Kevin Sheppard * [email protected] * Revision: 3 Date: 3/1/2005 */ void egarch_core(double *data, double *parameters, double *back_cast, double *upper, int p, int o, int q, int m, mwSize T, double *ht, double *logHt, double *stdData, double *absStdData) { mwIndex i; int j; double exp_back_cast, vol, subconst, eLB, hLB; exp_back_cast=exp(back_cast[0]); subconst = 0.797884560802865; for (j=0; j<m; j++) { /* uses the estimated cov for starting values*/ logHt[j]=back_cast[0]; ht[j]=exp_back_cast; vol = sqrt(ht[j]); stdData[j] = data[j]/vol; absStdData[j] = fabs(stdData[j])-subconst; } eLB = exp_back_cast/10000; hLB = back_cast[0] - log(10000); for (i=m; i<T; i++) { logHt[i]=parameters[0]; for (j=0; j<p; j++) { logHt[i] += parameters[j+1] * absStdData[i-1-j]; } for (j=0; j<o; j++) { logHt[i] += parameters[j+p+1] * stdData[i-1-j]; } for (j=0; j<q; j++) { logHt[i] += parameters[j+p+o+1] * logHt[i-1-j]; } /* Compute the stanardized residuals*/ ht[i]=exp(logHt[i]); if (ht[i]<eLB) { ht[i]=eLB; logHt[i] = hLB; } /*Should have a check that not to big*/ if (ht[i]>upper[0]) { if(mxIsInf(ht[i])) { ht[i] = upper[0]; } else { ht[i]= upper[0] + logHt[i]; } logHt[i] = log(upper[0]); } vol = sqrt(ht[i]); stdData[i] = data[i]/vol; absStdData[i] = fabs(stdData[i])-subconst; } }
/* * c o n t a i n s I n f */ BooleanType containsInf( const real_t* const data, uint_t dim ) { uint_t i; if ( data == 0 ) return BT_FALSE; for ( i = 0; i < dim; ++i ) if ( mxIsInf(data[i]) == 1 ) return BT_TRUE; return BT_FALSE; }
void numeric(double dbl, json_object **jo){ int intgr = round(dbl); if(mxIsNaN(dbl) || mxIsInf(dbl)){ *jo = NULL; } else{ if(fabs(dbl-(double)intgr) > 1e-18){ *jo = json_object_new_double(dbl); } else{ *jo = json_object_new_int(intgr); } } }
/* Function: mdlOutputs ======================================================= * Abstract: */ static void mdlOutputs(SimStruct *S, int_T tid) { InputRealPtrsType u = ssGetInputPortRealSignalPtrs(S,0); Data *y = ssGetOutputPortSignal(S,0); if (*u[0] > 127 || mxIsInf(*u[0])) { y->value = 127; y->res = LO_RES; } else if (*u[0] < 1.0 && *u[0] > -1.0) { y->value = (int8_T) (127.0 * *u[0]); y->res = HI_RES; } else { y->value = (int8_T) *u[0]; y->res = LO_RES; } }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *pitch, *wave, pitchRate; int fs, pitchLen, waveLen; cAudio myAudio; /* Check for proper number of arguments */ if (nrhs!=3){ char message[200]; strcpy(message, mexFunctionName()); strcat(message, " requires 3 input arguments: pitch, pitchRate, fs."); mexErrMsgTxt(message); } /* Dimensions of the input matrix */ pitchLen = mxGetM(PITCH)*mxGetN(PITCH); /* Assign pointers to the various parameters */ pitch = mxGetPr(PITCH); pitchRate = mxGetScalar(PITCHRATE); fs = (int)mxGetScalar(FS); /* If some of the elements are nan/inf, change them to 0 */ double *pitch2=(double *)malloc(pitchLen*sizeof(double)); memcpy(pitch2, pitch, pitchLen*sizeof(double)); for (int i=0; i<pitchLen; i++) if (mxIsNaN(pitch[i])||mxIsInf(pitch[i])) pitch2[i]=0.0; /* Create a matrix for the return argument */ waveLen=(int)floor(fs*pitchLen/pitchRate+0.5); WAVE = mxCreateDoubleMatrix(waveLen, 1, mxREAL); wave = mxGetPr(WAVE); myAudio.pitch2wave(pitch2, pitchLen, pitchRate, fs, wave, waveLen); free(pitch2); }
// Function definitions. // ----------------------------------------------------------------- void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Input Args user_function_data fun; double *x0; double *ydata; double *lb, *ub; //Outputs Args double *x, *fval, *exitflag, *iter, *feval; //Internal Vars size_t ndec, ndat, i, j; int havJac = 0; int printLevel = 0; double *bounds = NULL; //NL2SOL Vars int n; //len data int p; //len x int *iv; //intermediate work array double *v; //intermediate work array int liv = 0, lv = 0; //lengths of intermediate arrays int uiparm[2] = {1,0}; //user integer array [citer, printLevel] int one = 1, two = 2; //Defaults int maxfev = 1500; int maxiter = 1000; double frtol = 1e-7; double fatol = 1e-5; iterF.enabled = false; if (nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString(NL2SOL_VERSION); return; } //Check user inputs checkInputs(prhs,nrhs); //Get Sizes ndec = mxGetNumberOfElements(pX0); ndat = mxGetNumberOfElements(pYDATA); //Get Objective Function Handle if (mxIsChar(pFUN)) { CHECK(mxGetString(pFUN, fun.f, FLEN) == 0,"error reading objective name string"); fun.nrhs = 1; fun.xrhs = 0; } else { fun.prhs[0] = (mxArray*)pFUN; strcpy(fun.f, "feval"); fun.nrhs = 2; fun.xrhs = 1; } fun.prhs[fun.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //x0 //Check and Get Gradient Function Handle if(!mxIsEmpty(pGRAD)) { havJac = 1; if (mxIsChar(pGRAD)) { CHECK(mxGetString(pGRAD, fun.g, FLEN) == 0,"error reading gradient name string"); fun.nrhs_g = 1; fun.xrhs_g = 0; } else { fun.prhs_g[0] = (mxArray*)pGRAD; strcpy(fun.g, "feval"); fun.nrhs_g = 2; fun.xrhs_g = 1; } fun.prhs_g[fun.xrhs_g] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //x0 } //Get x0 + data x0 = mxGetPr(pX0); ydata = mxGetPr(pYDATA); //Get bounds if specified if(nrhs > eUB && !mxIsEmpty(pUB)) { lb = mxGetPr(pLB); ub = mxGetPr(pUB); bounds = (double*)mxCalloc(2*ndec,sizeof(double)); //Copy bounds into nlsol b(2,p) array for(i=0,j=0; i<2*ndec; i+=2,j++) { if(mxIsInf(lb[j])) bounds[i] = -D1MACH(&two); else bounds[i] = lb[j]; if(mxIsInf(ub[j])) bounds[i+1] = D1MACH(&two); else bounds[i+1] = ub[j]; } } //Get Options if specified if(nrhs > eOPTS) { if(mxGetField(pOPTS,0,"display")) printLevel = (int)*mxGetPr(mxGetField(pOPTS,0,"display")); if(mxGetField(pOPTS,0,"maxfeval")) maxfev = (int)*mxGetPr(mxGetField(pOPTS,0,"maxfeval")); if(mxGetField(pOPTS,0,"maxiter")) maxiter = (int)*mxGetPr(mxGetField(pOPTS,0,"maxiter")); if(mxGetField(pOPTS,0,"tolrfun")) frtol = *mxGetPr(mxGetField(pOPTS,0,"tolrfun")); if(mxGetField(pOPTS,0,"tolafun")) fatol = *mxGetPr(mxGetField(pOPTS,0,"tolafun")); if(mxGetField(pOPTS,0,"iterfun") && !mxIsEmpty(mxGetField(pOPTS,0,"iterfun"))) { iterF.prhs[0] = (mxArray*)mxGetField(pOPTS,0,"iterfun"); strcpy(iterF.f, "feval"); iterF.enabled = true; iterF.prhs[1] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL); iterF.prhs[2] = mxCreateDoubleMatrix(1,1,mxREAL); iterF.prhs[3] = mxCreateDoubleMatrix(ndec,1,mxREAL); } } //Create Outputs plhs[0] = mxCreateDoubleMatrix(ndec,1, mxREAL); plhs[1] = mxCreateDoubleMatrix(1,1, mxREAL); plhs[2] = mxCreateDoubleMatrix(1,1, mxREAL); plhs[3] = mxCreateDoubleMatrix(1,1, mxREAL); plhs[4] = mxCreateDoubleMatrix(1,1, mxREAL); x = mxGetPr(plhs[0]); fval = mxGetPr(plhs[1]); exitflag = mxGetPr(plhs[2]); iter = mxGetPr(plhs[3]); feval = mxGetPr(plhs[4]); //Copy initial guess to x memcpy(x,x0,ndec*sizeof(double)); //Print Header if(printLevel) { mexPrintf("\n------------------------------------------------------------------\n"); if(havJac) { if(bounds) mexPrintf(" This is DN2GB (NL2SOL v%s)\n",NL2SOL_VERSION); else mexPrintf(" This is DN2G (NL2SOL v%s)\n",NL2SOL_VERSION); } else { if(bounds) mexPrintf(" This is DN2FB (NL2SNO v%s)\n",NL2SOL_VERSION); else mexPrintf(" This is DN2F (NL2SNO v%s)\n",NL2SOL_VERSION); } mexPrintf(" Authors: John Dennis, David Gay, Roy Welsch\n MEX Interface J. Currie 2012\n\n"); mexPrintf(" Problem Properties:\n"); mexPrintf(" # Decision Variables: %4d\n",ndec); mexPrintf(" # Data Points: %4d\n",ndat); mexPrintf("------------------------------------------------------------------\n"); } //Assign Arguments n = (int)ndat; p = (int)ndec; if(bounds) liv = 82 + 4*p; else liv = 82+p; if(bounds) lv = 105 + p*(n + 2*p + 21) + 2*n; else lv = 105 + p*(n + 2*p + 17) + 2*n; iv = (int*)mxCalloc(liv + 10,sizeof(int)); v = (double*)mxCalloc(lv + 10,sizeof(double)); //Set Options //DFAULT(iv,v); //set defaults (OLD v2.2) DIVSET(&one,iv,&liv,&lv,v); iv[13] = iv[14] = 0; //no covar iv[16] = maxfev; //limit on fevals + gevals iv[17] = maxiter; //max iter iv[18] = 0; //no iteration printing iv[19] = 0; //no default printing iv[20] = 0; //no output unit printing iv[21] = 0; //no x printing iv[22] = 0; //no summary printing iv[23] = 0; //no initial printing v[30] = fatol; v[31] = frtol; //MEX Options uiparm[1] = printLevel; //Start timer start = clock(); //Call Algorithm based on Derivatives if(havJac) { //NL2SOL(&n,&p,x,CALCR,CALCJ,iv,v,uiparm,ydata,&fun); if(bounds) DN2GB(&n,&p,x,bounds,CALCR,CALCJ,iv,&liv,&lv,v,uiparm,ydata,&fun); else DN2G(&n,&p,x,CALCR,CALCJ,iv,&liv,&lv,v,uiparm,ydata,&fun); } else { //#ifdef WIN64 // mexErrMsgTxt("Currently NL2SNO crashes when compiled on 64bit systems, try NL2SOL instead (supply a gradient)"); //#else //NL2SNO(&n,&p,x,CALCR,iv,v,uiparm,ydata,&fun); if(bounds) DN2FB(&n,&p,x,bounds,CALCR,iv,&liv,&lv,v,uiparm,ydata,&fun); else DN2F(&n,&p,x,CALCR,iv,&liv,&lv,v,uiparm,ydata,&fun); //#endif } //Final Rnorm *fval = 2*v[9]; //nl2sol uses 1/2 sum(resid^2) //Save Status & Iterations *exitflag = getStatus(iv[0]); *iter = (double)iv[30]; *feval = (double)uiparm[0]; //Print Header if(printLevel) { //Termination Detected switch((int)iv[0]) { //Success case 3: mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** x-convergence ***\n"); break; case 4: mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** relative function convergence ***\n"); break; case 5: mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** both x and relative function convergence ***\n"); break; case 6: mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** absolute function convergence ***\n"); break; //Error case 9: mexPrintf("\n *** MAXIMUM FUNCTION EVALUATIONS REACHED ***\n"); break; case 10: mexPrintf("\n *** MAXIMUM ITERATIONS REACHED ***\n"); break; case 13: mexPrintf("\n *** ERROR: f(x) cannot be computed at the initial x ***\n"); break; case 14: mexPrintf("\n *** ERROR: bad parameters passed to asses ***\n"); break; case 15: mexPrintf("\n *** ERROR: the jacobian cannot be computed at x ***\n"); break; case 16: mexPrintf("\n *** ERROR: internal parameter n or p out of range ***\n"); break; case 17: mexPrintf("\n *** ERROR: restart attempted with n or p changed ***\n"); break; case 50: mexPrintf("\n *** ERROR: internal parameter iv(1) is out of range ***\n"); break; //Early Exit case 7: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: singular convergence. the hessian near the current iterate appears to be singular or nearly so. ***\n"); break; case 8: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: false convergence. the iterates appear to be converging to a noncritical point. this may mean that the convergence tolerances are too small ***\n"); break; case 11: mexPrintf("\n *** TERMINATION: USER EXITED ***\n"); break; //Other Error default: mexPrintf("\n *** ERROR: internal error code %d ***\n",(int)iv[0]); break; } if(*exitflag==1) mexPrintf("\n Final SSE: %12.5g\n In %3.0f iterations\n",*fval,*iter); mexPrintf("------------------------------------------------------------------\n\n"); } //Free Memory if(iv) mxFree(iv); iv = NULL; if(v) mxFree(v); v = NULL; if(bounds) mxFree(bounds); bounds = NULL; }
//CALCR static void CALCR(int *n, int *p, double *x, int *nf, double *r, int *uiparm, double *ydata, void *ufparm) { bool havrnorm = false, stop = false; int i, stat; double *fval, rnorm = 0; clock_t end; double evaltime; //Get User Data user_function_data *fun = (user_function_data*)ufparm; fun->plhs[0] = NULL; memcpy(mxGetPr(fun->prhs[fun->xrhs]), x, *p * sizeof(double)); stat = mexCallMATLAB(1, fun->plhs, fun->nrhs, fun->prhs, fun->f); if(stat) mexErrMsgTxt("Error calling Objective Function!"); //Get Objective fval = mxGetPr(fun->plhs[0]); //Assign Objective + subtract ydata for(i=0; i<*n; i++) { r[i] = fval[i]-ydata[i]; //Check for out of bounds, will try a smaller step size if(mxIsInf(r[i]) || mxIsNaN(r[i])) *nf = 0; } // Clean up Ptr mxDestroyArray(fun->plhs[0]); //Iteration Printing if(uiparm[1] > 1) { //Get Execution Time end = clock(); evaltime = ((double)(end-start))/CLOCKS_PER_SEC; //Calculate Residual Norm rnorm = 0; havrnorm = true; for(i=0; i<*n; i++) rnorm += r[i]*r[i]; if(uiparm[0] == 1 || !(uiparm[0]%10)) mexPrintf(" feval time sse\n"); mexPrintf("%5d %5.2f %12.5g\n",uiparm[0],evaltime,rnorm); mexEvalString("drawnow;"); //flush draw buffer } //Iteration Callback if(iterF.enabled) { //Calculate sse if we don't have it if(!havrnorm) for(i=0; i<*n; i++) rnorm += r[i]*r[i];; iterF.plhs[0] = NULL; memcpy(mxGetData(iterF.prhs[1]), uiparm, sizeof(int)); memcpy(mxGetPr(iterF.prhs[2]), &rnorm, sizeof(double)); memcpy(mxGetPr(iterF.prhs[3]), x, *p * sizeof(double)); stat = mexCallMATLAB(1, iterF.plhs, 4, iterF.prhs, iterF.f); if(stat) mexErrMsgTxt("Error calling Callback Function!"); //Collect return argument stop = *(bool*)mxGetData(iterF.plhs[0]); // Clean up Ptr mxDestroyArray(iterF.plhs[0]); //Warn user stop not implemented if(stop) mexWarnMsgTxt("NL2SOL does not implement the stop feature of iterfun"); } uiparm[0]++; }
//Gateway routine void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Read input arguments char outputFormat[10]; char outputVarName[MAXVARNAMESIZE]; int outputVarSampsPerChan; double timeout; int numSampsPerChan; bool outputData; //Indicates whether to return an outputData argument mxClassID outputDataClass; uInt32 bufSize; bool writeDigitalLines; uInt32 bytesPerChan=0; TaskHandle taskID, *taskIDPtr; int32 status; //Get TaskHandle taskIDPtr = (TaskHandle*)mxGetData(mxGetProperty(prhs[0],0, "taskID")); taskID = *taskIDPtr; //Determine if this is a buffered read operation status = DAQmxGetBufInputBufSize(taskID, &bufSize); if (status) handleDAQmxError(status, "DAQmxGetBufInputBufSize"); //Handle input arguments if ((nrhs < 2) || mxIsEmpty(prhs[1]) || mxIsInf(mxGetScalar(prhs[1]))) { if (bufSize==0) numSampsPerChan = 1; else numSampsPerChan = DAQmx_Val_Auto; } else numSampsPerChan = (int) mxGetScalar(prhs[1]); if ((nrhs < 3) || mxIsEmpty(prhs[2])) { //Automatic determination of read type bool isLineBased = (bool) mxGetScalar(mxGetProperty(prhs[0],0,"isLineBasedDigital")); if ((bufSize==0) && isLineBased) //This is a non-buffered, line-based Task: return data as a double array outputDataClass = mxDOUBLE_CLASS; else { status = DAQmxGetReadDigitalLinesBytesPerChan(taskID,&bytesPerChan); //This actually returns the number of bytes required to represent one sample of Channel data if (status) handleDAQmxError(status, "DAQmxGetReadDigitalLinesBytesPerChan"); if (bytesPerChan <= 8) outputDataClass = mxUINT8_CLASS; else if (bytesPerChan <= 16) outputDataClass = mxUINT16_CLASS; else if (bytesPerChan <= 32) outputDataClass = mxUINT32_CLASS; else mexErrMsgTxt("It is not currently possible to read integer values from Task with greater than 32 lines per sample value"); } } else { mxGetString(prhs[2], outputFormat, 10); if (_strcmpi(outputFormat,"uint8")) outputDataClass = mxUINT8_CLASS; else if (_strcmpi(outputFormat,"uint16")) outputDataClass = mxUINT16_CLASS; else if (_strcmpi(outputFormat,"uint32")) outputDataClass = mxUINT32_CLASS; else if (_strcmpi(outputFormat,"double")) outputDataClass = mxDOUBLE_CLASS; else if (_strcmpi(outputFormat,"logical")) outputDataClass = mxLOGICAL_CLASS; else mexErrMsgTxt("The specified 'outputFormat' value (case-sensitive) is not recognized."); } if ((outputDataClass == mxDOUBLE_CLASS) || (outputDataClass == mxLOGICAL_CLASS)) { writeDigitalLines = true; if (bytesPerChan == 0) { status = DAQmxGetReadDigitalLinesBytesPerChan(taskID,&bytesPerChan); //This actually returns the number of bytes required to represent one sample of Channel data if (status) handleDAQmxError(status, "DAQmxGetReadDigitalLinesBytesPerChan"); } } else writeDigitalLines = false; if ((nrhs < 4) || mxIsEmpty(prhs[3]) || mxIsInf(mxGetScalar(prhs[3]))) timeout = DAQmx_Val_WaitInfinitely; else timeout = mxGetScalar(prhs[3]); if ((nrhs < 5) || mxIsEmpty(prhs[4])) //OutputVarSizeOrName argument { outputData = true; outputVarSampsPerChan = numSampsPerChan; //If value is DAQmx_Val_Auto, then the # of samples available will be queried before allocting array } else { outputData = mxIsNumeric(prhs[4]); if (outputData) { if (nlhs < 2) mexErrMsgTxt("There must be two output arguments specified if a preallocated MATLAB variable is not specified"); outputVarSampsPerChan = (int) mxGetScalar(prhs[4]); } else mxGetString(prhs[4], outputVarName, MAXVARNAMESIZE); } //Determin # of output channels uInt32 numChannels; DAQmxGetReadNumChans(taskID, &numChannels); //Reflects number of channels in Task, or the number of channels specified by 'ReadChannelsToRead' property //Determine output buffer/size (creating if needed) mxArray *outputDataBuf, *outputDataBufTrue; void *outputDataPtr; //float64 *outputDataPtr; if (outputData) { mwSize numRows; if (outputVarSampsPerChan == DAQmx_Val_Auto) { status = DAQmxGetReadAvailSampPerChan(taskID, (uInt32 *)&outputVarSampsPerChan); if (status) { handleDAQmxError(status, "DAQmxGetReadAvailSampPerChan"); return; } } if (writeDigitalLines) numRows = (mwSize) (outputVarSampsPerChan * bytesPerChan); else numRows = (mwSize) outputVarSampsPerChan; if (outputDataClass == mxDOUBLE_CLASS) { outputDataBuf = mxCreateNumericMatrix(numRows,numChannels,mxUINT8_CLASS,mxREAL); outputDataBufTrue = mxCreateDoubleMatrix(numRows,numChannels,mxREAL); } else outputDataBuf = mxCreateNumericMatrix(numRows,numChannels,outputDataClass,mxREAL); } else //I don't believe this is working { outputDataBuf = mexGetVariable("caller", outputVarName); outputVarSampsPerChan = mxGetM(outputDataBuf); //TODO: Add check to ensure WS variable is of correct class } outputDataPtr = mxGetData(outputDataBuf); //Read data int32 numSampsRead; int32 numBytesPerSamp; switch (outputDataClass) { case mxUINT8_CLASS: status = DAQmxReadDigitalU8(taskID, numSampsPerChan, timeout, fillMode, (uInt8*) outputDataPtr, outputVarSampsPerChan * numChannels, &numSampsRead, NULL); break; case mxUINT16_CLASS: status = DAQmxReadDigitalU16(taskID, numSampsPerChan, timeout, fillMode, (uInt16*) outputDataPtr, outputVarSampsPerChan * numChannels, &numSampsRead, NULL); break; case mxUINT32_CLASS: status = DAQmxReadDigitalU32(taskID, numSampsPerChan, timeout, fillMode, (uInt32*) outputDataPtr, outputVarSampsPerChan * numChannels, &numSampsRead, NULL); break; case mxLOGICAL_CLASS: case mxDOUBLE_CLASS: status = DAQmxReadDigitalLines(taskID, numSampsPerChan, timeout, fillMode, (uInt8*) outputDataPtr, outputVarSampsPerChan * numChannels * bytesPerChan, &numSampsRead, &numBytesPerSamp, NULL); break; default: mexErrMsgTxt("There must be two output arguments specified if a preallocated MATLAB variable is not specified"); } //Return output data if (!status) { //mexPrintf("Successfully read %d samples of data\n", numSampsRead); if (outputData) { if (nlhs > 0) { if (outputDataClass == mxDOUBLE_CLASS) { //Convert logical data to double type double *outputDataTruePtr = mxGetPr(outputDataBufTrue); for (size_t i=0;i < mxGetNumberOfElements(outputDataBuf);i++) *(outputDataTruePtr+i) = (double) *((uInt8 *)outputDataPtr+i); mxDestroyArray(outputDataBuf); plhs[0] = outputDataBufTrue; } else plhs[0] = outputDataBuf; } else mxDestroyArray(outputDataBuf); //If you don't read out, all the reading was done for naught } else //I don't believe this is working { mexErrMsgTxt("invalid branch"); mexPutVariable("caller", outputVarName, outputDataBuf); if (nlhs > 0) //Return empty value for output data plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); } if (nlhs > 1) //Return number of samples actually read { double *sampsReadOutput; plhs[1] = mxCreateDoubleScalar(0); sampsReadOutput = mxGetPr(plhs[1]); *sampsReadOutput = (double)numSampsRead; } } else //Read failed handleDAQmxError(status, mexFunctionName()); }
//Gateway routine //sampsPerChanWritten = writeAnalogData(task, writeData, timeout, autoStart, numSampsPerChan) void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //General vars char errMsg[512]; //Read input arguments float64 timeout; int numSampsPerChan; bool32 autoStart; TaskHandle taskID, *taskIDPtr; //Get TaskHandle taskIDPtr = (TaskHandle*)mxGetData(mxGetProperty(prhs[0],0, "taskID")); taskID = *taskIDPtr; if ((nrhs < 3) || mxIsEmpty(prhs[2])) timeout = 10.0; else { timeout = (float64) mxGetScalar(prhs[2]); if (mxIsInf(timeout)) timeout = DAQmx_Val_WaitInfinitely; } if ((nrhs < 4) || mxIsEmpty(prhs[3])) { int32 sampTimingType = 0; int32 status = DAQmxGetSampTimingType(taskID,&sampTimingType); if (status!=0) { mexErrMsgTxt("Failed to get sample timing type from DAQmx."); } autoStart = (sampTimingType==DAQmx_Val_OnDemand); } else autoStart = (bool32) mxGetScalar(prhs[3]); size_t numRows = mxGetM(prhs[1]); if ((nrhs < 5) || mxIsEmpty(prhs[4])) numSampsPerChan = numRows; else numSampsPerChan = (int) mxGetScalar(prhs[4]); //Verify correct input length //Write data int32 sampsWritten; int32 status; switch (mxGetClassID(prhs[1])) { case mxUINT16_CLASS: status = DAQmxWriteBinaryU16(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (uInt16*) mxGetData(prhs[1]), &sampsWritten, NULL); break; case mxINT16_CLASS: status = DAQmxWriteBinaryI16(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (int16*) mxGetData(prhs[1]), &sampsWritten, NULL); break; case mxDOUBLE_CLASS: status = DAQmxWriteAnalogF64(taskID, numSampsPerChan, autoStart, timeout, dataLayout, (float64*) mxGetData(prhs[1]), &sampsWritten, NULL); break; default: sprintf_s(errMsg,"Class of supplied writeData argument (%s) is not valid", mxGetClassName(prhs[1])); mexErrMsgTxt(errMsg); } //Handle output arguments and errors if (!status) { if (nlhs > 0) { plhs[0] = mxCreateDoubleScalar(0); double *sampsPerChanWritten = mxGetPr(plhs[0]); } //mexPrintf("Successfully wrote %d samples of data\n", sampsWritten); } else //Write failed handleDAQmxError(status, mexFunctionName()); }
/* ------------------------------------------------------------- The gateway routine. ------------------------------------------------------------- */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { int exitflag; /* status of the solution (output arg) */ long t; /* number of iterations (output arg) */ double *x; /* solution vector (output arg)*/ double *History; /* UB and LB history (output arg) */ int verb; /* verbosity (input arg)*/ long tmax; /* max number of iteration (input arg)*/ double tolrel; /* stopping condition (input arg) */ double tolabs; /* stopping condition (input arg) */ double *x0; /* initial solution (input arg)*/ double *f; /* vector f (input arg) */ double b; /* scalar b (input arg) */ uint16_T *I; /* vector of uint16_T (input arg) */ double *diag_H; /* diagonal of matrix H */ long i ; /* loop variable */ double *tmp_ptr; /*------------------------------------------------------------------- */ /* Take input arguments */ /* [...] = qpssvm_mex(H,f,b,I,x0,tmax,tolabs,tolrel,verb) */ /*------------------------------------------------------------------- */ if( nrhs != 9) mexErrMsgTxt("Incorrect number of input arguments."); /* matrix H */ matrix_H = mxGetPr(prhs[0]); dim = mxGetM(prhs[0]); if(dim != mxGetN(prhs[0])) mexErrMsgTxt("Matrix H mast be squared."); /* vector f */ f = mxGetPr(prhs[1]); if((MAX(mxGetM(prhs[1]),mxGetN(prhs[1])) != dim) || (MIN(mxGetM(prhs[1]),mxGetN(prhs[1])) != 1)) mexErrMsgTxt("Vector f is of wrong size."); /* vector b */ b = mxGetScalar(prhs[2]); /* vector I */ I = (uint16_T*)mxGetPr(prhs[3]); if((MAX(mxGetM(prhs[3]),mxGetN(prhs[3])) != dim) || (MIN(mxGetM(prhs[3]),mxGetN(prhs[3])) != 1)) mexErrMsgTxt("Vector I is of wrong size."); /* vector x0 */ x0 = mxGetPr(prhs[4]); if((MAX(mxGetM(prhs[4]),mxGetN(prhs[4])) != dim) || (MIN(mxGetM(prhs[4]),mxGetN(prhs[4])) != 1)) mexErrMsgTxt("Vector x0 is of wrong size."); /* maximal allowed number of iterations */ tmax = mxIsInf( mxGetScalar(prhs[5])) ? INT_MAX : (long)mxGetScalar(prhs[5]); /* abs. precision defining stopping cond*/ tolabs = mxGetScalar(prhs[6]); /* rel. precision defining stopping cond*/ tolrel = mxGetScalar(prhs[7]); /* verbosity parameter */ verb = (int)mxGetScalar(prhs[8]); /* verbosity on/off */ /* print input setting if required */ if( verb > 0 ) { mexPrintf("Settings of QP solver:\n"); mexPrintf("tmax : %d\n", tmax ); mexPrintf("tolabs : %f\n", tolabs ); mexPrintf("tolrel : %f\n", tolrel ); mexPrintf("dim : %d\n", dim ); mexPrintf("b : %f\n", b ); mexPrintf("verb : %d\n", verb ); } /*------------------------------------------------------------------- Inicialization ------------------------------------------------------------------- */ /* solution vector x [dim x 1] */ plhs[0] = mxCreateDoubleMatrix(dim,1,mxREAL); x = mxGetPr(plhs[0]); for(i=0; i < dim; i++ ) { x[i] = x0[i]; } /* make diagonal of the Hessian matrix */ diag_H = mxCalloc(dim, sizeof(double)); if( diag_H == NULL ) mexErrMsgTxt("Not enough memory."); /* to replace with memcpy(void *dest, const void *src, size_t n); */ for(i = 0; i < dim; i++ ) { diag_H[i] = matrix_H[dim*i+i]; } /* counter of access to matrix H */ access = dim; /*------------------------------------------------------------------- Call the QP solver. -------------------------------------------------------------------*/ /* exitflag = qpssvm_solver( &get_col, diag_H, f, b, I, x, dim, tmax, tolabs, tolrel, &t, &History, verb ); */ exitflag = qpssvm_imdm( &get_col, diag_H, f, b, I, x, dim, tmax, tolabs, tolrel, &t, &History, verb ); /*------------------------------------------------------------------- Set up output arguments [x,exitflag,t,access,History] = qpssvm_mex(...) ------------------------------------------------------------------- */ /* exitflag [1x1] */ plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(plhs[1])) = (double)exitflag; /* t [1x1] */ plhs[2] = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(plhs[2])) = (double)t; /* access [1x1] */ plhs[3] = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(plhs[3])) = (double)access; /* History [2 x (t+1)] */ plhs[4] = mxCreateDoubleMatrix(2,t+1,mxREAL); tmp_ptr = mxGetPr( plhs[4] ); for( i = 0; i <= t; i++ ) { tmp_ptr[INDEX(0,i,2)] = History[INDEX(0,i,2)]; tmp_ptr[INDEX(1,i,2)] = History[INDEX(1,i,2)]; } /*------------------------------------------------------------------- Free used memory ------------------------------------------------------------------- */ mxFree( History ); mxFree( diag_H ); return; }
/* ------------------------------------------------------------------- Main MEX function - interface to Matlab. [vec_x,exitflag,t,access,Nabla] = gsmo_mex(H,f,a,b,LB,UB,x0,Nabla0,tmax,tolKKT,verb); -------------------------------------------------------------------- */ void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray*prhs[] ) { int verb; uint32_t i; uint32_t MaxIter; double TolKKT; double *vec_x; /* output arg -- solution*/ double *vec_x0; double *diag_H; /* diagonal of matrix H */ double *f; /* vector f */ double *a; double b; double *LB; double *UB; double fval; /*------------------------------------------------------------------- */ /* Take input arguments */ /*------------------------------------------------------------------- */ if( nrhs != 10) mexErrMsgTxt("Incorrect number of input arguments."); mat_H = mxGetPr(prhs[0]); nVar = mxGetM(prhs[0]); f = mxGetPr(prhs[1]); a = mxGetPr(prhs[2]); b = mxGetScalar(prhs[3]); LB = mxGetPr(prhs[4]); UB = mxGetPr(prhs[5]); vec_x0 = mxGetPr(prhs[6]); MaxIter = mxIsInf( mxGetScalar(prhs[7])) ? INT_MAX : (long)mxGetScalar(prhs[7]); TolKKT = mxGetScalar(prhs[8]); verb = (int)(mxGetScalar(prhs[9])); if( verb > 0 ) { mexPrintf("Settings of QP solver\n"); mexPrintf("MaxIter : %d\n", MaxIter ); mexPrintf("TolKKT : %f\n", TolKKT ); mexPrintf("nVar : %d\n", nVar ); mexPrintf("verb : %d\n", verb ); } plhs[0] = mxCreateDoubleMatrix(nVar,1,mxREAL); vec_x = mxGetPr(plhs[0]); memcpy( vec_x, vec_x0, sizeof(double)*nVar ); diag_H = mxCalloc(nVar, sizeof(double)); if( diag_H == NULL ) mexErrMsgTxt("Not enough memory."); for(i = 0; i < nVar; i++ ) diag_H[i] = mat_H[nVar*i+i]; /*------------------------------------------------------------------- */ /* Call QP solver */ /*------------------------------------------------------------------- */ state = libqp_gsmo_solver( &get_col, diag_H, f, a, b, LB, UB, vec_x, nVar, MaxIter, TolKKT, NULL ); /*------------------------------------------------------------------- */ /* Generate outputs */ /*------------------------------------------------------------------- */ plhs[1] = mxCreateDoubleScalar(state.QP); plhs[2] = mxCreateDoubleScalar((double)state.exitflag); plhs[3] = mxCreateDoubleScalar((double)state.nIter); /*------------------------------------------------------------------- */ /* Clean up */ /*------------------------------------------------------------------- */ mxFree( diag_H ); }
/* ------------------------------------------------------------- MEX main function. ------------------------------------------------------------- */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { int verb; uint32_t MaxIter; uint32_t *vec_I; uint32_t nConstr; uint8_t *vec_S; double *vec_x; double TolRel; double TolAbs; double QP_TH; double *vec_x0; double *vec_f; double *vec_b; double *diag_H; long i ; libqp_state_T state; double *tmp; /*------------------------------------------------------------------- Get input arguments ------------------------------------------------------------------- */ if( nrhs != 12) mexErrMsgTxt("Incorrect number of input arguments."); mat_H = (mxArray*)prhs[0]; nVar = mxGetM(prhs[0]); diag_H = mxGetPr(prhs[1]); vec_f = mxGetPr(prhs[2]); vec_b = (double*)mxGetPr(prhs[3]); vec_I = (uint32_t*)mxGetPr(prhs[4]); vec_S = (uint8_t*)mxGetPr(prhs[5]); nConstr = LIBQP_MAX(mxGetN(prhs[3]),mxGetM(prhs[3])); vec_x0 = mxGetPr(prhs[6]); MaxIter = mxIsInf( mxGetScalar(prhs[7])) ? 0xFFFFFFFF : (uint32_t)mxGetScalar(prhs[7]); TolAbs = mxGetScalar(prhs[8]); TolRel = mxGetScalar(prhs[9]); QP_TH = mxGetScalar(prhs[10]); verb = (int)mxGetScalar(prhs[11]); /* print input setting if required */ if( verb > 0 ) { mexPrintf("Settings of LIBQP_SSVM solver:\n"); mexPrintf("MaxIter : %u\n", MaxIter ); mexPrintf("TolAbs : %f\n", TolAbs ); mexPrintf("TolRel : %f\n", TolRel ); mexPrintf("QP_TH : %f\n", QP_TH ); mexPrintf("nVar : %u\n", nVar ); mexPrintf("nConstr : %u\n", nConstr ); } /*------------------------------------------------------------------- Inicialization ------------------------------------------------------------------- */ /* create solution vector x [nVar x 1] */ plhs[0] = mxCreateDoubleMatrix(nVar,1,mxREAL); vec_x = mxGetPr(plhs[0]); memcpy( vec_x, vec_x0, sizeof(double)*nVar ); /*------------------------------------------------------------------- Call the QP solver. -------------------------------------------------------------------*/ if( mxIsSparse(mat_H)== true ) { col_buf0 = mxCalloc(nVar,sizeof(double)); if( col_buf0 == NULL) mexErrMsgTxt("Cannot allocate memory for col_buf0."); col_buf1 = mxCalloc(nVar,sizeof(double)); if( col_buf1 == NULL) mexErrMsgTxt("Cannot allocate memory for col_buf1."); /* tmp = get_col_sparse(nVar-1); for(i=0; i<nVar; i++) { mexPrintf("%d: %f\n",i,tmp[i]); vec_x[i] = tmp[i]; } */ state = libqp_splx_solver(&get_col_sparse, diag_H, vec_f, vec_b, vec_I, vec_S, vec_x, nVar, MaxIter, TolAbs, TolRel, QP_TH, NULL); mxFree(col_buf0); mxFree(col_buf1); } else { /* tmp = get_col(nVar-1); for(i=0; i<nVar; i++) { mexPrintf("%d: %f\n",i,tmp[i]); vec_x[i] = tmp[i]; } */ state = libqp_splx_solver(&get_col, diag_H, vec_f, vec_b, vec_I, vec_S, vec_x, nVar, MaxIter, TolAbs, TolRel, QP_TH, NULL); } /*------------------------------------------------------------------- Set output arguments [x,QP,QD,exitflag,nIter] = libqp_splx_mex(...) ------------------------------------------------------------------- */ plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(plhs[1])) = (double)state.QP; plhs[2] = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(plhs[2])) = (double)state.QD; plhs[3] = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(plhs[3])) = (double)state.exitflag; plhs[4] = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(plhs[4])) = (double)state.nIter; return; }
int Options::loadConstraintBounds (const mxArray* ptr, double*& cl, double*& cu, double neginfty, double posinfty, int &lin, int &nlin) { int m = 0; // The return value is the number of constraints. int tm; //Defaults lin = 0; nlin = 0; // LOAD CONSTRAINT BOUNDS. // If the user has specified constraints bounds, then she must // specify *both* the lower and upper bounds. const mxArray* pl = mxGetField(ptr,0,"cl"); const mxArray* pu = mxGetField(ptr,0,"cu"); const mxArray* prl = mxGetField(ptr,0,"rl"); //linear constraint bounds const mxArray* pru = mxGetField(ptr,0,"ru"); if (pl || pu || prl || pru) { // Check to make sure the constraint bounds are valid. if ((!pl ^ !pu) || (!prl ^ !pru)) throw MatlabException("You must specify both lower and upper bounds on the constraints"); if (pl && (!mxIsDouble(pl) || !mxIsDouble(pu) || (mxGetNumberOfElements(pl) != mxGetNumberOfElements(pu)))) throw MatlabException("The nonlinear constraints lower and upper bounds must both be double-precision arrays with the same number of elements"); if (prl && (!mxIsDouble(prl) || !mxIsDouble(pru) || (mxGetNumberOfElements(prl) != mxGetNumberOfElements(pru)))) throw MatlabException("The linear constraints lower and upper bounds must both be double-precision arrays with the same number of elements"); // Get the number of constraints. if(pl && prl) { lin = (int)mxGetNumberOfElements(prl); nlin = (int)mxGetNumberOfElements(pl); m = lin+nlin; } else if(pl) { lin = 0; nlin = (int)mxGetNumberOfElements(pl); m = nlin; } else { lin = (int)mxGetNumberOfElements(prl); nlin = 0; m = lin; } // Load the lower bounds on the constraints and convert MATLAB's // convention of infinity to IPOPT's convention of infinity. cl = new double[m]; cu = new double[m]; if(pl && prl) { tm = (int)mxGetNumberOfElements(pl); copymemory(mxGetPr(pl),cl,tm); copymemory(mxGetPr(pu),cu,tm); copymemory(mxGetPr(prl),&cl[tm],(int)mxGetNumberOfElements(prl)); copymemory(mxGetPr(pru),&cu[tm],(int)mxGetNumberOfElements(pru)); } else if(pl) { copymemory(mxGetPr(pl),cl,m); copymemory(mxGetPr(pu),cu,m); } else { copymemory(mxGetPr(prl),cl,m); copymemory(mxGetPr(pru),cu,m); } // Convert MATLAB's convention of infinity to IPOPT's convention // of infinity. for (int i = 0; i < m; i++) { if (mxIsInf(cl[i])) cl[i] = neginfty; if (mxIsInf(cu[i])) cu[i] = posinfty; } } return m; }
int get_IntgrOptions(const mxArray *options, cvmPbData thisPb, booleantype fwd, int lmm, int *maxord, booleantype *sld, booleantype *errmsg, long int *mxsteps, int *itol, realtype *reltol, double *Sabstol, double **Vabstol, double *hin, double *hmax, double *hmin, double *tstop, booleantype *rhs_s) { mxArray *opt; int q; long int i, m, n; double *tmp; char *fctName; char *fwd_fctName = "CVodeInit/CVodeReInit"; char *bck_fctName = "CVodeInitB/CVodeReInitB"; if (fwd) fctName = fwd_fctName; else fctName = bck_fctName; /* Set default values */ *maxord = (lmm == CV_ADAMS) ? 12 : 5; *sld = FALSE; *mxsteps = 0; *itol = CV_SS; *reltol = 1.0e-3; *Sabstol = 1.0e-6; *Vabstol = NULL; *hin = 0.0; *hmax = 0.0; *hmin = 0.0; *rhs_s = FALSE; Ng = 0; tstopSet = FALSE; mon = FALSE; *errmsg = TRUE; /* Return now if options was empty */ if (mxIsEmpty(options)) return(0); /* User data */ opt = mxGetField(options,0,"UserData"); if ( !mxIsEmpty(opt) ) { mxDestroyArray(mtlb_data); mtlb_data = mxDuplicateArray(opt); } /* Tolerances */ opt = mxGetField(options,0,"RelTol"); if ( !mxIsEmpty(opt) ) { *reltol = *mxGetPr(opt); if (*reltol < 0.0 ) { cvmErrHandler(-999, "CVODES", fctName, "RelTol is negative.", NULL); return(-1); } } opt = mxGetField(options,0,"AbsTol"); if ( !mxIsEmpty(opt) ) { m = mxGetM(opt); n = mxGetN(opt); if ( (n != 1) && (m != 1) ) { cvmErrHandler(-999, "CVODES", fctName, "AbsTol is not a scalar or a vector.", NULL); return(-1); } if ( m > n ) n = m; tmp = mxGetPr(opt); if (n == 1) { *itol = CV_SS; *Sabstol = *tmp; if (*Sabstol < 0.0) { cvmErrHandler(-999, "CVODES", fctName, "AbsTol is negative.", NULL); return(-1); } } else if (n == N) { *itol = CV_SV; *Vabstol = (double *) malloc(N*sizeof(double)); for(i=0;i<N;i++) { (*Vabstol)[i] = tmp[i]; if (tmp[i] < 0.0) { cvmErrHandler(-999, "CVODES", fctName, "AbsTol has a negative component.", NULL); return(-1); } } } else { cvmErrHandler(-999, "CVODES", fctName, "AbsTol does not contain N elements.", NULL); return(-1); } } /* Maximum number of steps */ opt = mxGetField(options,0,"MaxNumSteps"); if ( !mxIsEmpty(opt) ) { *mxsteps = (int)*mxGetPr(opt); if (*mxsteps < 0) { cvmErrHandler(-999, "CVODES", fctName, "MaxNumSteps is negative.", NULL); return(-1); } } /* Maximum order */ opt = mxGetField(options,0,"MaxOrder"); if ( !mxIsEmpty(opt) ) { q = (int)*mxGetPr(opt); if (q <= 0) { cvmErrHandler(-999, "CVODES", fctName, "MaxOrder must be positive.", NULL); return(-1); } if (q > *maxord) { cvmErrHandler(-999, "CVODES", fctName, "MaxOrder is too large for the Method specified.", NULL); return(-1); } *maxord = q; } /* Initial step size */ opt = mxGetField(options,0,"InitialStep"); if ( !mxIsEmpty(opt) ) { *hin = *mxGetPr(opt); } /* Maximum step size */ opt = mxGetField(options,0,"MaxStep"); if ( !mxIsEmpty(opt) ) { tmp = mxGetPr(opt); if (*tmp < 0.0) { cvmErrHandler(-999, "CVODES", fctName, "MaxStep is negative.", NULL); return(-1); } if ( mxIsInf(*tmp) ) *hmax = 0.0; else *hmax = *tmp; } /* Minimum step size */ opt = mxGetField(options,0,"MinStep"); if ( !mxIsEmpty(opt) ) { *hmin = *mxGetPr(opt); if (*hmin < 0.0) { cvmErrHandler(-999, "CVODES", fctName, "MinStep is negative.", NULL); return(-1); } } /* Stability Limit Detection */ opt = mxGetField(options,0,"StabilityLimDet"); if ( !mxIsEmpty(opt) ) { if (!mxIsLogical(opt)) { cvmErrHandler(-999, "CVODES", fctName, "StabilityLimDet is not a logical scalar.", NULL); return(-1); } if (mxIsLogicalScalarTrue(opt)) *sld = TRUE; else *sld = FALSE; } /* Monitor? */ opt = mxGetField(options,0,"MonitorFn"); if ( !mxIsEmpty(opt) ) { mon = TRUE; mxDestroyArray(mtlb_MONfct); mtlb_MONfct = mxDuplicateArray(opt); opt = mxGetField(options,0,"MonitorData"); if ( !mxIsEmpty(opt) ) { mxDestroyArray(mtlb_MONdata); mtlb_MONdata = mxDuplicateArray(opt); } } /* The remaining options are interpreted either for * forward problems only or backward problems only */ if (fwd) { /* FORWARD PROBLEM ONLY */ /* Disable error/warning messages? */ opt = mxGetField(options,0,"ErrorMessages"); if ( !mxIsEmpty(opt) ) { if (!mxIsLogical(opt)) { cvmErrHandler(-999, "CVODES", fctName, "ErrorMessages is not a logical scalar.", NULL); return(-1); } if (mxIsLogicalScalarTrue(opt)) *errmsg = TRUE; else *errmsg = FALSE; } /* Stopping time */ opt = mxGetField(options,0,"StopTime"); if ( !mxIsEmpty(opt) ) { *tstop = *mxGetPr(opt); tstopSet = TRUE; } /* Number of root functions */ opt = mxGetField(options,0,"NumRoots"); if ( !mxIsEmpty(opt) ) { Ng = (int)*mxGetPr(opt); if (Ng < 0) { cvmErrHandler(-999, "CVODES", fctName, "NumRoots is negative.", NULL); return(-1); } if (Ng > 0) { /* Roots function */ opt = mxGetField(options,0,"RootsFn"); if ( !mxIsEmpty(opt) ) { mxDestroyArray(mtlb_Gfct); mtlb_Gfct = mxDuplicateArray(opt); } else { cvmErrHandler(-999, "CVODES", fctName, "RootsFn required for NumRoots > 0", NULL); return(-1); } } } } else { /* BACKWARD PROBLEM ONLY */ /* Dependency on forward sensitivities */ opt = mxGetField(options,0,"SensDependent"); if ( !mxIsEmpty(opt) ) { if (!mxIsLogical(opt)) { cvmErrHandler(-999, "CVODES", fctName, "SensDependent is not a logical scalar.", NULL); return(-1); } if (mxIsLogicalScalarTrue(opt)) *rhs_s = TRUE; else *rhs_s = FALSE; } } /* We made it here without problems */ return(0); }
void assignmentoptimal(double *assignment, double *cost, double *distMatrixIn, int nOfRows, int nOfColumns) { double *distMatrix, *distMatrixTemp, *distMatrixEnd, *columnEnd, value, minValue; bool *coveredColumns, *coveredRows, *starMatrix, *newStarMatrix, *primeMatrix; int nOfElements, minDim, row, col; #ifdef CHECK_FOR_INF bool infiniteValueFound; double maxFiniteValue, infValue; #endif /* initialization */ *cost = 0; for(row=0; row<nOfRows; row++) #ifdef ONE_INDEXING assignment[row] = 0.0; #else assignment[row] = -1.0; #endif /* generate working copy of distance Matrix */ /* check if all matrix elements are positive */ nOfElements = nOfRows * nOfColumns; distMatrix = (double *)mxMalloc(nOfElements * sizeof(double)); distMatrixEnd = distMatrix + nOfElements; for(row=0; row<nOfElements; row++) { value = distMatrixIn[row]; if(mxIsFinite(value) && (value < 0)) mexErrMsgTxt("All matrix elements have to be non-negative."); distMatrix[row] = value; } #ifdef CHECK_FOR_INF /* check for infinite values */ maxFiniteValue = -1; infiniteValueFound = false; distMatrixTemp = distMatrix; while(distMatrixTemp < distMatrixEnd) { value = *distMatrixTemp++; if(mxIsFinite(value)) { if(value > maxFiniteValue) maxFiniteValue = value; } else infiniteValueFound = true; } if(infiniteValueFound) { if(maxFiniteValue == -1) /* all elements are infinite */ return; /* set all infinite elements to big finite value */ if(maxFiniteValue > 0) infValue = 10 * maxFiniteValue * nOfElements; else infValue = 10; distMatrixTemp = distMatrix; while(distMatrixTemp < distMatrixEnd) if(mxIsInf(*distMatrixTemp++)) *(distMatrixTemp-1) = infValue; } #endif /* memory allocation */ coveredColumns = (bool *)mxCalloc(nOfColumns, sizeof(bool)); coveredRows = (bool *)mxCalloc(nOfRows, sizeof(bool)); starMatrix = (bool *)mxCalloc(nOfElements, sizeof(bool)); primeMatrix = (bool *)mxCalloc(nOfElements, sizeof(bool)); newStarMatrix = (bool *)mxCalloc(nOfElements, sizeof(bool)); /* used in step4 */ /* preliminary steps */ if(nOfRows <= nOfColumns) { minDim = nOfRows; for(row=0; row<nOfRows; row++) { /* find the smallest element in the row */ distMatrixTemp = distMatrix + row; minValue = *distMatrixTemp; distMatrixTemp += nOfRows; while(distMatrixTemp < distMatrixEnd) { value = *distMatrixTemp; if(value < minValue) minValue = value; distMatrixTemp += nOfRows; } /* subtract the smallest element from each element of the row */ distMatrixTemp = distMatrix + row; while(distMatrixTemp < distMatrixEnd) { *distMatrixTemp -= minValue; distMatrixTemp += nOfRows; } } /* Steps 1 and 2a */ for(row=0; row<nOfRows; row++) for(col=0; col<nOfColumns; col++) if(distMatrix[row + nOfRows*col] == 0) if(!coveredColumns[col]) { starMatrix[row + nOfRows*col] = true; coveredColumns[col] = true; break; } } else /* if(nOfRows > nOfColumns) */ { minDim = nOfColumns; for(col=0; col<nOfColumns; col++) { /* find the smallest element in the column */ distMatrixTemp = distMatrix + nOfRows*col; columnEnd = distMatrixTemp + nOfRows; minValue = *distMatrixTemp++; while(distMatrixTemp < columnEnd) { value = *distMatrixTemp++; if(value < minValue) minValue = value; } /* subtract the smallest element from each element of the column */ distMatrixTemp = distMatrix + nOfRows*col; while(distMatrixTemp < columnEnd) *distMatrixTemp++ -= minValue; } /* Steps 1 and 2a */ for(col=0; col<nOfColumns; col++) for(row=0; row<nOfRows; row++) if(distMatrix[row + nOfRows*col] == 0) if(!coveredRows[row]) { starMatrix[row + nOfRows*col] = true; coveredColumns[col] = true; coveredRows[row] = true; break; } for(row=0; row<nOfRows; row++) coveredRows[row] = false; } /* move to step 2b */ step2b(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim); /* compute cost and remove invalid assignments */ computeassignmentcost(assignment, cost, distMatrixIn, nOfRows); /* free allocated memory */ mxFree(distMatrix); mxFree(coveredColumns); mxFree(coveredRows); mxFree(starMatrix); mxFree(primeMatrix); mxFree(newStarMatrix); return; }
/* Function: mdlCheckParameters ============================================= * Abstract: * Validate our parameters to verify they are okay. */ static void mdlCheckParameters(SimStruct *S) { int_T i; static char_T msg[100]; /* for RTW we do not need these variables */ #ifdef MATLAB_MEX_FILE const char *fname; mxArray *fval; int_T nfields; #endif /* Check 1st parameter: number of states */ { if ( !mxIsDouble(ssGetSFcnParam(S,0)) || mxIsEmpty(ssGetSFcnParam(S,0)) || mxGetNumberOfElements(ssGetSFcnParam(S,0))!=1 || mxGetScalar(ssGetSFcnParam(S,0))<=0 || mxIsNaN(*mxGetPr(ssGetSFcnParam(S,0))) || mxIsInf(*mxGetPr(ssGetSFcnParam(S,0))) || mxIsSparse(ssGetSFcnParam(S,0)) ) { ssSetErrorStatus(S,"lcp_sfun: Number of states must be of type double, not empty, scalar and finite."); return; } } /* Check 2nd parameter: sample time */ { if ( !mxIsDouble(ssGetSFcnParam(S,1)) || mxIsEmpty(ssGetSFcnParam(S,1)) || mxGetNumberOfElements(ssGetSFcnParam(S,1))!=1 || mxGetScalar(ssGetSFcnParam(S,1))<=0 || mxIsNaN(*mxGetPr(ssGetSFcnParam(S,1))) || mxIsInf(*mxGetPr(ssGetSFcnParam(S,1))) || mxIsSparse(ssGetSFcnParam(S,1)) ) { ssSetErrorStatus(S,"lcp_sfun: Sample time must be of type double, not empty, scalar and finite."); return; } } #ifdef MATLAB_MEX_FILE /* Check 3rd parameter: options */ if (ssGetSFcnParamsCount(S)==3) { if (!mxIsStruct(ssGetSFcnParam(S,2))) { ssSetErrorStatus(S, "lcp_sfun: Options must be in STRUCT format."); return; } else if (mxGetNumberOfElements(ssGetSFcnParam(S,2))>1) { ssSetErrorStatus(S,"lcp_sfun: Only one option structure is allowed."); return; } /* checking each option individually */ nfields = mxGetNumberOfFields(ssGetSFcnParam(S,2)); for (i=0; i<nfields; i++) { fname = mxGetFieldNameByNumber(ssGetSFcnParam(S,2), i); fval = mxGetField(ssGetSFcnParam(S,2), 0, fname); /* check for proper field names */ if (!( (strcmp(fname, "zerotol")==0) || (strcmp(fname, "maxpiv")==0) || (strcmp(fname, "lextol")==0) || (strcmp(fname, "nstepf")==0) || (strcmp(fname, "clock")==0) || (strcmp(fname, "verbose")==0) || (strcmp(fname, "routine")==0) || (strcmp(fname, "timelimit")==0) || (strcmp(fname, "normalize")==0) || (strcmp(fname, "normalizethres")==0) )) { strcpy(msg,""); strcat(msg, "lcp_sfun: The field '"); strcat(msg, fname); strcat(msg, "' is not allowed in the options structure."); ssSetErrorStatus(S, msg); return; } /* some options must be nonnegative */ if (strcmp(fname,"zerotol")==0 || strcmp(fname,"maxpiv")==0 || strcmp(fname,"timelimit")==0 || strcmp(fname,"lextol")==0 || (strcmp(fname,"nstepf")==0) || (strcmp(fname, "normalizethres")==0) ) { if (!mxIsDouble(fval) || mxIsEmpty(fval) || (mxGetM(fval)*mxGetN(fval))!=1 || (mxGetScalar(fval)<=0) ) { strcpy(msg,""); strcat(msg, "lcp_sfun: Option value '"); strcat(msg, fname); strcat(msg, "' must be of type double, nonempty, scalar, and nonnegative."); ssSetErrorStatus(S, msg); return; } } /* some can be zeros */ if (strcmp(fname,"clock")==0 || strcmp(fname,"verbose")==0 || strcmp(fname,"routine")==0 || strcmp(fname,"normalize")==0) { if (!mxIsDouble(fval) || mxIsEmpty(fval) || (mxGetM(fval)*mxGetN(fval))!=1 ) { strcpy(msg,""); strcat(msg, "lcp_sfun: Option value '"); strcat(msg, fname); strcat(msg, "' must be of type double, nonempty, scalar, and integer valued."); ssSetErrorStatus(S, msg); return; } } /* No NaN values allowed */ if ( mxIsNaN(*mxGetPr(fval)) ) { ssSetErrorStatus(S, "lcp_sfun: No 'NaN' are allowed in the options structure."); return; } /* Inf value allowed only for timelimit */ if ( strcmp(fname,"timelimit")!=0 && mxIsInf(*mxGetPr(fval)) ) { ssSetErrorStatus(S, "lcp_sfun: No 'Inf' terms allowed except for 'timelimit' option."); return; } } } #endif }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int i, j, k, M, N, NH, index, D, lambda, Coarsest_level, pwr; int dir, row; double *X, *Y, *lp, *hp; /****************************/ /* A very basic input check */ /****************************/ if ( nrhs != 4 ) mexErrMsgTxt("Four inputs required!"); else if ( nlhs > 1 ) mexErrMsgTxt("Too many output arguments!"); /*******************************************/ /* Get input matrix from MATLAB argument 1 */ /*******************************************/ M = mxGetM(prhs[0]); /* Number of rows */ N = mxGetN(prhs[0]); /* Number of columns */ X = mxGetPr(prhs[0]); /* The input M x N matrix */ /***************************************************************/ /* Get wavelet transform depth, lambda, from MATLAB argument 2 */ /***************************************************************/ lambda = (int) mxGetScalar(prhs[1]); if (mxIsInf(mxGetScalar(prhs[1]))) { /* If requested depth == Inf then */ Coarsest_level = 1; /* take as many steps as possible */ } else { pwr = pow(2,lambda); Coarsest_level = max((int) (N/ (float) pwr), 1); } /****************************************************/ /* Get wavelet filters from MATLAB argument 3 and 4 */ /****************************************************/ D = max(mxGetM(prhs[2]),mxGetN(prhs[2])); /* Filter length */ if (D != max(mxGetM(prhs[3]),mxGetN(prhs[3]))) mexErrMsgTxt("Filters must have same length. Pad with zeros!"); lp = mxGetPr(prhs[2]); /* Low pass filter */ hp = mxGetPr(prhs[3]); /* High pass filter */ /************************************************************/ /* Create output array. This will also be used as workspace */ /************************************************************/ plhs[0] = mxCreateDoubleMatrix(M, N, mxREAL); Y = mxGetPr(plhs[0]); /***************************************/ /* Outer loop of the wavelet transform */ /***************************************/ dir = 0; /* Alternate transform direction to save space */ while (N % 2 == 0 && N > Coarsest_level) { /* Transform for decreasing N */ dir = 1 - dir; if (dir == 1) { NH = mpwt (X, M, N, lp, hp, D, Y); /* One-step transform X -> Y */ } else { NH = mpwt (Y, M, N, lp, hp, D, X); /* One-step transform Y -> X */ for (k = NH; k < N; k++) { /* Copy partial result to Y */ index = k*M; for (row = 0; row < M; row++) { Y[index] = X[index]; index++; } } } N = NH; /* N = N/2 */ } if (dir == 0) { /* If last transform was backwards */ for (k = 0; k < N; k++) { index = k*M; for (row = 0; row < M; row++) { Y[index] = X[index]; /* then copy dc term to Y */ index++; } } } } /* END MATLAB GATEWAY ROUTINE */
//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"); } } }
//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;} }
// Function definitions. // ----------------------------------------------------------------- void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Input Args double *x0 = NULL, *lb = NULL, *ub = NULL, *A = NULL, *b = NULL; //Outputs Args double *x, *fval, *exitflag, *iter, *feval; //Internal Vars double *llb, *lub; size_t ndec; int i, exit_code; //PSwarm Vars double *sol = NULL; int lincon = 0; if (nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString(PSWARM_VERSION); return; } //Check user inputs checkInputs(prhs,nrhs,&lincon); //Set Defaults printLevel = 0; maxtime = 1000; noFeval = 0; ctrlCExit = false; iterF.enabled = false; //Reset Stats stats.solveriters = 0; stats.objfunctions = 0; stats.pollsteps = 0; stats.sucpollsteps = 0; //Set PSwarm Defaults opt.s = 42; opt.mu = 0.5; opt.nu = 0.5; opt.maxvfactor = 0.5; opt.maxiter = 1500; opt.maxf = 10000; opt.iweight = 0.9; opt.fweight = 0.4; opt.n2grd = 0.5; opt.blim = 10; opt.tol = 1e-5; opt.delta = Inf; opt.fdelta = 5.0; opt.idelta = 2.0; opt.ddelta = 0.5; opt.pollbasis = 0; opt.EpsilonActive = 0.1; opt.IPrint = 10; opt.vectorized = 0; //important, otherwise will pass whole swarm opt.outfcn = &iterfcn; //iteration + ctrl c //Get Sizes ndec = mxGetNumberOfElements(prhs[1]); //Get Objective Function Handle if (mxIsChar(prhs[0])) { CHECK(mxGetString(prhs[0], fun.f, FLEN) == 0,"error reading objective name string"); fun.nrhs = 1; fun.xrhs = 0; } else { fun.prhs[0] = (mxArray*)prhs[0]; strcpy(fun.f, "feval"); fun.nrhs = 2; fun.xrhs = 1; } //Get x0 x0 = mxGetPr(prhs[1]); //Get Bounds //LB if(!mxIsEmpty(prhs[2])){ llb = mxGetPr(prhs[2]); lb = mxCalloc(ndec,sizeof(double)); memcpy(lb,llb,ndec*sizeof(double)); for(i=0;i<ndec;i++) { if(mxIsInf(lb[i])) lb[i] = -1e19; } } else { lb = mxCalloc(ndec,sizeof(double)); for(i=0;i<ndec;i++) lb[i] = -1e19; } //UB if(nrhs > 3 && !mxIsEmpty(prhs[3])){ lub = mxGetPr(prhs[3]); ub = mxCalloc(ndec,sizeof(double)); memcpy(ub,lub,ndec*sizeof(double)); for(i=0;i<ndec;i++) { if(mxIsInf(ub[i])) ub[i] = 1e19; } } else { ub = mxCalloc(ndec,sizeof(double)); for(i=0;i<ndec;i++) ub[i] = 1e19; } //Get Linear Inequality Constraints if(nrhs > 4) { if(!mxIsEmpty(prhs[4]) && !mxIsEmpty(prhs[5])) { A = mxGetPr(prhs[4]); b = mxGetPr(prhs[5]); } } //Get Options if specified if(nrhs > 6) { if(mxGetField(prhs[6],0,"display")) printLevel = (int)*mxGetPr(mxGetField(prhs[6],0,"display")); if(mxGetField(prhs[6],0,"maxiter")) opt.maxiter = (int)*mxGetPr(mxGetField(prhs[6],0,"maxiter")); if(mxGetField(prhs[6],0,"maxtime")) maxtime = *mxGetPr(mxGetField(prhs[6],0,"maxtime")); if(mxGetField(prhs[6],0,"tolfun")) opt.tol = *mxGetPr(mxGetField(prhs[6],0,"tolfun")); if(mxGetField(prhs[6],0,"maxfeval")) opt.maxf = (int)*mxGetPr(mxGetField(prhs[6],0,"maxfeval")); if(mxGetField(prhs[6],0,"swarm_size")) opt.s = (int)*mxGetPr(mxGetField(prhs[6],0,"swarm_size")); if(mxGetField(prhs[6],0,"vectorized")) opt.vectorized = (int)*mxGetPr(mxGetField(prhs[6],0,"vectorized")); if(mxGetField(prhs[6],0,"mu")) opt.mu = *mxGetPr(mxGetField(prhs[6],0,"mu")); if(mxGetField(prhs[6],0,"nu")) opt.nu = *mxGetPr(mxGetField(prhs[6],0,"nu")); if(mxGetField(prhs[6],0,"iweight")) opt.iweight = *mxGetPr(mxGetField(prhs[6],0,"iweight")); if(mxGetField(prhs[6],0,"fweight")) opt.fweight = *mxGetPr(mxGetField(prhs[6],0,"fweight")); if(mxGetField(prhs[6],0,"delta")) opt.delta = *mxGetPr(mxGetField(prhs[6],0,"delta")); if(mxGetField(prhs[6],0,"idelta")) opt.idelta = *mxGetPr(mxGetField(prhs[6],0,"idelta")); if(mxGetField(prhs[6],0,"ddelta")) opt.ddelta = *mxGetPr(mxGetField(prhs[6],0,"ddelta")); if(mxGetField(prhs[6],0,"iterfun") && !mxIsEmpty(mxGetField(prhs[6],0,"iterfun"))) { iterF.prhs[0] = (mxArray*)mxGetField(prhs[6],0,"iterfun"); strcpy(iterF.f, "feval"); iterF.enabled = true; iterF.prhs[1] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL); iterF.prhs[2] = mxCreateDoubleMatrix(1,1,mxREAL); iterF.prhs[3] = mxCreateDoubleMatrix(ndec,1,mxREAL); } } //If not vectorized, we can create x now, otherwise must be done in callback if(!opt.vectorized) fun.prhs[fun.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //Create Outputs plhs[0] = mxCreateDoubleMatrix(ndec,1, mxREAL); plhs[1] = mxCreateDoubleMatrix(1,1, mxREAL); plhs[2] = mxCreateDoubleMatrix(1,1, mxREAL); plhs[3] = mxCreateDoubleMatrix(1,1, mxREAL); plhs[4] = mxCreateDoubleMatrix(1,1, mxREAL); x = mxGetPr(plhs[0]); fval = mxGetPr(plhs[1]); exitflag = mxGetPr(plhs[2]); iter = mxGetPr(plhs[3]); feval = mxGetPr(plhs[4]); //Print Header if(printLevel) { mexPrintf("\n------------------------------------------------------------------\n"); mexPrintf(" This is PSwarm v1.5\n"); mexPrintf(" Authors: A.I.F Vaz and L.N. Vicente\n\n"); mexPrintf(" Problem Properties:\n"); mexPrintf(" # Decision Variables: %4d\n",ndec); mexPrintf(" # Linear Constraints: %4d\n",lincon); mexPrintf("------------------------------------------------------------------\n"); } //Run PSwarm start = clock(); exit_code = PSwarm((int)ndec, &func, lb, ub, lincon, A, b, &sol, fval, x0); if(exit_code == 0) { //Copy Solution memcpy(x,sol,ndec*sizeof(double)); free(sol); *iter = (double)stats.solveriters; *feval = (double)stats.objfunctions; } //Save Status & Iterations *exitflag = getStatus(exit_code,stats.solveriters,stats.objfunctions); //Print Header if(printLevel){ //Termination Detected switch((int)*exitflag) { //Success case 1: mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** Normal Exit ***\n"); break; //Error case -1: mexPrintf("\n *** ERROR: Abnormal Exit ***\n"); break; case 0: if(stats.solveriters >= (opt.maxiter-5)) mexPrintf("\n *** MAXIMUM ITERATIONS REACHED ***\n"); else if(((double)(end-start))/CLOCKS_PER_SEC > maxtime) mexPrintf("\n *** MAXIMUM TIME EXCEEDED ***\n"); else mexPrintf("\n *** MAXIMUM FUNCTION EVALUATIONS REACHED ***\n"); break; //Early Exit case -2: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Failed to allocate memory ***\n"); break; case -3: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Unable to initialize population - check constraints are feasible ***\n"); break; case -5: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: User Exit (Ctrl C) ***\n"); break; } if(*exitflag==1) mexPrintf("\n Final Objective: %12.5g\n In %3d iterations and\n %4d function evaluations\n",*fval,stats.solveriters,stats.objfunctions); mexPrintf("------------------------------------------------------------------\n\n"); } //Free Memory if(lb) mxFree(lb); if(ub) mxFree(ub); }
/* here comes the main function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* default settings */ /* connectivity pattern: 2 */ const double DEF_clconn = 2.0; /* threshold 1 (consider also single voxel clusters) */ const double DEF_kthr = 1.0; /* setting pointers (for argument read-out) */ const double *clconn = NULL; const double *kthr = NULL; /* settings (internal) */ /* max directions */ unsigned int md = 2; /* cluster threshold */ unsigned int kthrl = 1; /* sizes and position */ const int *dim = NULL; int idim[3] = {1, 1, 1}; int tdim[3] = {1, 1, 1}; /* offset (must be variable, as copy might not require additional slices) */ unsigned int toff[3] = {1, 1, 1}; /* dimX, dimY, dimZ, dimXY, next position */ unsigned int dx = 0, dy = 0, dz = 0, dxy = 0, dxyz = 0, np = 0; /* data pointers */ /* (enlarged) copy */ unsigned char *copy = NULL; /* list of cluster voxels */ unsigned int clvoxcnt; unsigned int clnxtvox; signed int *clvox = NULL; /* list of cluster sizes and total number of clustered voxels */ unsigned int mxclnum = 0; unsigned int clnum = 0; unsigned int *clsiz = NULL; unsigned int cltvox = 0, cltvox2 = 0, cltvox3 = 0; /* clustered volume (internal) */ unsigned int *clvol = NULL; /* direction increments (as index differences) */ signed int dlxyz[26] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* next positions (signed!) */ signed int nextp = 0, nextpi = 0; /* counters */ signed char dc = 0; unsigned int cx = 0, cy = 0, cz = 0; /* output pointer(s) */ mxArray *ma = NULL; double *op = NULL, *sop = NULL; /* variable output text */ /* char vstr[256]; */ /* code starts here */ /* nr. of arguments check */ if ((nrhs < 1) || (nlhs > 4)) mexErrMsgTxt("Bad number of input/output arguments."); /* first argument class and size check */ if (!mxIsLogical(prhs[0]) || (mxGetNumberOfElements(prhs[0]) < 8) || (mxGetNumberOfDimensions(prhs[0]) > 3)) mexErrMsgTxt("Invalid argument type or dimension."); /* check connectivity flag */ if ((nrhs < 2) || !mxIsDouble(prhs[1]) || (mxGetNumberOfElements(prhs[1]) != 1)) clconn = &DEF_clconn; else { clconn = (const double*) mxGetPr(prhs[1]); if (mxIsNaN(*clconn) || mxIsInf(*clconn) || ((*clconn) < 1.0) || ((*clconn) > 5.0)) clconn = &DEF_clconn; } /* check threshold */ if ((nrhs < 3) || !mxIsDouble(prhs[2]) || (mxGetNumberOfElements(prhs[2]) != 1)) kthr = &DEF_kthr; else { kthr = (const double*) mxGetPr(prhs[2]); if (mxIsNaN(*kthr) || mxIsInf(*kthr) || ((*kthr) < 1.0) || ((*kthr) > (0.5 * mxGetNumberOfElements(prhs[0])))) kthr = &DEF_kthr; } kthrl = (unsigned int) *kthr; /* get & check argument content */ dim = mxGetDimensions(prhs[0]); idim[0] = dim[0]; idim[1] = dim[1]; if (mxGetNumberOfDimensions(prhs[0]) > 2) idim[2] = dim[2]; dx = idim[0]; dy = idim[1]; dz = idim[2]; dxy = dx * dy; dxyz = dxy * dz; mxclnum = (unsigned int) (((double) (dxyz + 3)) / 4.0); /* set connectivity flag -> max directions (opposite direction later) */ /* face connectivity -> three main directions */ if ((*clconn >= 1.0) && (*clconn < 1.5)) md = 3; /* edge connectivity -> add 6 edge diagonals */ else if ((*clconn >= 1.5) && (*clconn < 2.5)) md = 9; /* vertex connectivity -> add 4 3D diagonals */ else if ((*clconn >= 2.5) && (*clconn < 3.5)) md = 13; /* otherwise, leave at 2, we stay "in-plane" */ /* reserve space for next cluster list and cluster sizes */ clvox = (signed int *) mxCalloc(dxyz, sizeof(signed int)); if (clvox == NULL) mexErrMsgTxt("Error allocating next cluster voxel list."); clsiz = (unsigned int *) mxCalloc(mxclnum, sizeof(signed int)); if (clsiz == NULL) { mxFree(clvox); mexErrMsgTxt("Error allocating next cluster voxel list."); } /* increase numbers accordingly */ if (idim[0] > 1) dx += 2; else toff[0] = 0; if (idim[1] > 1) dy += 2; else toff[1] = 0; if (idim[2] > 1) dz += 2; else toff[2] = 0; /* compute new plane/vol numel */ dxy = dx * dy; dxyz = dxy * dz; /* reserve space for clustered volume (if needed) */ if (nlhs > 1) { clvol = (unsigned int *) mxCalloc(dxyz, sizeof(unsigned int)); if (clvol == NULL) { mxFree(clsiz); mxFree(clvox); mexErrMsgTxt("Error allocating clustered volume."); } } /* set temp dim array */ tdim[0] = dx; tdim[1] = dy; tdim[2] = dz; /* fill direction increment array */ np = 0; for (dc = 0; dc < md; ++dc) { if (((idim[0] > 1) || (dlx[dc] == 0)) && ((idim[1] > 1) || (dly[dc] == 0)) && (((idim[2] > 1) && (*clconn < 3.5)) || (dlz[dc] == 0))) { dlxyz[np] = dlx[dc] + dly[dc] * dx + dlz[dc] * dxy; dlxyz[np+1] = -dlxyz[np]; np += 2; } } if ((*clconn >= 4.5) && (idim[0] > 1) && (idim[1] > 1)) { for (dc = 3; dc < 5; ++dc) { dlxyz[np] = dlx[dc] + dly[dc] * dx + dlz[dc] * dxy; dlxyz[np+1] = -dlxyz[np]; np += 2; } } /* re-set */ md = np - 1; /* create temp. copy array */ copy = (unsigned char *) mxCalloc(dxyz, sizeof(unsigned char)); if (copy == NULL) { mxFree(clsiz); mxFree(clvox); mexErrMsgTxt("Error allocating temporary memory"); } /* copy into temporary array */ ff_copy_intopart(idim[0], idim[1], idim[2], (unsigned char *) mxGetPr(prhs[0]), tdim, copy, toff); /* preparations complete, now we can "search"... */ /* iterate while new points found */ for (np = 0; np < dxyz; ++np) { /* check voxel */ if (copy[np] == 1) { /* start new cluster */ clvoxcnt = 1; clvox[0] = np; /* remove from search volume */ copy[np] = 0; /* continue until no more neighbors found */ for (clnxtvox = 0; clnxtvox < clvoxcnt; ++clnxtvox) { /* check neighbors */ nextp = clvox[clnxtvox]; for (dc = md; dc >= 0; --dc) { /* check voxel with increment */ nextpi = nextp + dlxyz[dc]; if (copy[nextpi] == 1) { /* equally remove from search volume */ copy[nextpi] = 0; /* and add to list */ clvox[clvoxcnt++] = nextpi; } } } /* rest of code only if surpasses threshold */ if (clvoxcnt >= kthrl) { /* write to list of sizes and increase cluster number count */ clsiz[clnum++] = clvoxcnt; cltvox += clvoxcnt; /* write to output volume (if needed) */ if (nlhs > 1) { for (nextp = clvoxcnt - 1; nextp >= 0; --nextp) clvol[clvox[nextp]] = clnum; } } } } /* we're done with this */ mxFree(copy); /* create output argument #1 */ CREATE_MxN(plhs[0], 1, clnum); if (plhs[0] == NULL) { if (clvol != NULL) mxFree(clvol); mxFree(clsiz); mxFree(clvox); mexErrMsgTxt("Error creating output argument cs."); } /* if requested create other outputs first */ if (nlhs > 1) { plhs[1] = mxCreateNumericArray(3, idim, mxUINT32_CLASS, mxREAL); if (plhs[1] == NULL) { mxDestroyArray(plhs[0]); mxFree(clvol); mxFree(clsiz); mxFree(clvox); mexErrMsgTxt("Error creating output argument cv."); } } /* if requested create other outputs first */ if (nlhs > 2) { CREATE_MxN(plhs[2], cltvox, 4); if (plhs[2] == NULL) { mxDestroyArray(plhs[1]); mxDestroyArray(plhs[0]); mxFree(clvol); mxFree(clsiz); mxFree(clvox); mexErrMsgTxt("Error creating output argument l."); } } /* if requested create other outputs first */ if (nlhs > 3) { plhs[3] = mxCreateCellMatrix(1, clnum); if (plhs[3] == NULL) { mxDestroyArray(plhs[2]); mxDestroyArray(plhs[1]); mxDestroyArray(plhs[0]); mxFree(clvol); mxFree(clsiz); mxFree(clvox); mexErrMsgTxt("Error creating output argument c."); } /* put numeric array into each cell */ for (nextp = 0; nextp < clnum; ++nextp) { CREATE_MxN(ma, clsiz[nextp], 3); if (ma == NULL) { mxDestroyArray(plhs[3]); mxDestroyArray(plhs[2]); mxDestroyArray(plhs[1]); mxDestroyArray(plhs[0]); mxFree(clvol); mxFree(clsiz); mxFree(clvox); mexErrMsgTxt("Error creating output cell contents in argument c."); } mxSetCell(plhs[3], nextp, ma); } } /* copy cluster sizes into output */ op = (double *) mxGetPr(plhs[0]); for (nextp = 0; nextp < clnum; ++nextp) *op++ = (double) clsiz[nextp]; /* copy volume to output */ if (nlhs > 1) { ff_copy_frompart(dx, dy, clvol, idim, (unsigned int*) mxGetData(plhs[1]), toff); mxFree(clvol); clvol = (unsigned int *) mxGetPr(plhs[1]); } /* create list of voxels */ if (nlhs > 2) { /* get output pointer */ op = (double *) mxGetPr(plhs[2]); /* 2/3 * total count for fast indexing */ cltvox2 = 2 * cltvox; cltvox3 = 3 * cltvox; /* if required re-init counter */ if (nlhs > 3) { for (nextp = clnum - 1; nextp >= 0; --nextp) clvox[nextp] = 0; } dx = idim[0]; dy = idim[1]; dz = idim[2]; dxy = dx * dy; for (cz = 0; cz < dz; ++cz) { dxyz = dxy * cz; for (cy = 0; cy < dy; ++cy) { np = dxyz + cy * dx; for (cx = 0; cx < dx; ++cx) { clnum = *clvol++; if (clnum > 0) { op[cltvox3] = (double) clnum; op[cltvox2] = (double) (cz + 1); op[cltvox] = (double) (cy + 1); *op++ = (double) (cx + 1); if (nlhs > 3) { --clnum; sop = (double *) mxGetPr(mxGetCell(plhs[3], clnum)); sop[2 * clsiz[clnum] + clvox[clnum]] = (double) (cz + 1); sop[clsiz[clnum] + clvox[clnum]] = (double) (cy + 1); sop[clvox[clnum]++] = (double) (cx + 1); } } } } } } /* free other temp arrays */ mxFree(clsiz); mxFree(clvox); }
// [outputData, sampsPerChanRead] = readAnalogData(task, numSampsPerChan, outputFormat, timeout, outputVarSizeOrName) void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Read input arguments // Get the task handle mxArray *mxTaskID = mxGetProperty(prhs[0],0,"taskID"); mxClassID clsID = mxGetClassID(mxTaskID); localAssert(clsID==TASKHANDLE_MXCLASS); TaskHandle *taskIDPtr = (TaskHandle*)mxGetData(mxTaskID); TaskHandle taskID = *taskIDPtr; //Determine if this is a buffered read operation uInt32 bufSize = 0; int32 status = DAQmxGetBufInputBufSize(taskID,&bufSize); if (status) { handleDAQmxError(status,"DAQmxGetBufInputBufSize"); } // Handle input arguments int32 numSampsPerChan = 0; // this does take negative vals in the case of DAQmx_Val_Auto if ((nrhs < 2) || mxIsEmpty(prhs[1]) || mxIsInf(mxGetScalar(prhs[1]))) { if (bufSize==0) numSampsPerChan = 1; else numSampsPerChan = DAQmx_Val_Auto; } else { numSampsPerChan = (int) mxGetScalar(prhs[1]); } char outputFormat[10]; if ((nrhs < 3) || mxIsEmpty(prhs[2])) strcpy_s(outputFormat,"scaled"); else mxGetString(prhs[2], outputFormat, 10); double timeout; if ((nrhs < 4) || mxIsEmpty(prhs[3]) || mxIsInf(mxGetScalar(prhs[3]))) timeout = DAQmx_Val_WaitInfinitely; else timeout = mxGetScalar(prhs[3]); bool outputData; //Indicates whether to return an outputData argument int outputVarSampsPerChan = 0; // this CAN take negative values in case of DAQmx_Val_Auto char outputVarName[MAXVARNAMESIZE]; if ((nrhs < 5) || mxIsEmpty(prhs[4])) { outputData = true; outputVarSampsPerChan = numSampsPerChan; //If value is DAQmx_Val_Auto, then the # of samples available will be queried before allocting array } else { outputData = mxIsNumeric(prhs[4]); if (outputData) { if (nlhs < 2) { mexErrMsgTxt("There must be two output arguments specified if a preallocated MATLAB variable is not specified"); } outputVarSampsPerChan = (int) mxGetScalar(prhs[4]); } else { mxGetString(prhs[4],outputVarName,MAXVARNAMESIZE); } } //Determine output data type mxClassID outputDataClass; mxArray *mxRawDataArrayAI = mxGetProperty(prhs[0],0,"rawDataArrayAI"); //Stored in MCOS Task object as an empty array of the desired class! mxClassID rawDataClass = mxGetClassID(mxRawDataArrayAI); char errorMessage[30]; if (!_strcmpi(outputFormat,"scaled")) outputDataClass = mxDOUBLE_CLASS; else if (!_strcmpi(outputFormat,"native")) outputDataClass = rawDataClass; else { sprintf_s(errorMessage,"Unrecognized output format: %s\n",outputFormat); mexErrMsgTxt(errorMessage); } //Determine # of output channels uInt32 numChannels; DAQmxGetReadNumChans(taskID,&numChannels); //Reflects number of channels in Task, or the number of channels specified by 'ReadChannelsToRead' property //Determine output buffer/size (creating if needed) mxArray *mxOutputDataBuf = NULL; if (outputData) { if (outputVarSampsPerChan == DAQmx_Val_Auto) { uInt32 buf = 0; status = DAQmxGetReadAvailSampPerChan(taskID,&buf); if (status) { handleDAQmxError(status, mexFunctionName()); } outputVarSampsPerChan = buf; } //localAssert(outputVarSampsPerChan >= 0); localAssert(outputVarSampsPerChan > 0); mxOutputDataBuf = mxCreateNumericMatrix(outputVarSampsPerChan,numChannels,outputDataClass,mxREAL); } else { localAssert(false); ////I don't believe this is working //mxOutputDataBuf = mexGetVariable("caller", outputVarName); //outputVarSampsPerChan = mxGetM(mxOutputDataBuf); ////TODO: Add check to ensure WS variable is of correct class } void* outputDataPtr = mxGetData(mxOutputDataBuf); localAssert(outputDataPtr!=NULL); uInt32 arraySizeInSamps = outputVarSampsPerChan * numChannels; localAssert(mxGetNumberOfElements(mxOutputDataBuf)==(size_t)arraySizeInSamps); int32 numSampsPerChanRead; if (outputDataClass == mxDOUBLE_CLASS) //'scaled' // float64 should be double status = DAQmxReadAnalogF64(taskID,numSampsPerChan,timeout,fillMode, (float64*) outputDataPtr, arraySizeInSamps, &numSampsPerChanRead, NULL); else { //'raw' switch (outputDataClass) { case mxINT16_CLASS: status = DAQmxReadBinaryI16(taskID, numSampsPerChan, timeout, fillMode, (int16*) outputDataPtr, arraySizeInSamps, &numSampsPerChanRead, NULL); break; case mxINT32_CLASS: status = DAQmxReadBinaryI32(taskID, numSampsPerChan, timeout, fillMode, (int32*) outputDataPtr, arraySizeInSamps, &numSampsPerChanRead, NULL); break; case mxUINT16_CLASS: status = DAQmxReadBinaryU16(taskID, numSampsPerChan, timeout, fillMode, (uInt16*) outputDataPtr, arraySizeInSamps, &numSampsPerChanRead, NULL); break; case mxUINT32_CLASS: status = DAQmxReadBinaryU32(taskID, numSampsPerChan, timeout, fillMode, (uInt32*) outputDataPtr, arraySizeInSamps, &numSampsPerChanRead, NULL); break; } } //Return output data if (!status) { //mexPrintf("Successfully read %d samples of data\n", numSampsRead); if (outputData) { if (nlhs > 0) plhs[0] = mxOutputDataBuf; else mxDestroyArray(mxOutputDataBuf); //If you don't read out, all the reading was done for naught } else { //I don't believe this is working localAssert(false); //mexPutVariable("caller", outputVarName, mxOutputDataBuf); // //if (nlhs >= 0) //Return empty value for output data // plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL); } if (nlhs>1) { //Return number of samples actually read plhs[1] = mxCreateDoubleScalar(0.0); double *sampsReadOutput = mxGetPr(plhs[1]); *sampsReadOutput = (double)numSampsPerChanRead; } } else { //Read failed handleDAQmxError(status, mexFunctionName()); } }
/* ------------------------------------------------------------------- Main MEX function - interface to Matlab. -------------------------------------------------------------------- */ void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray*prhs[] ) { char solver[20]; /* solver identifier */ int exitflag; /* output arg */ int buf_len; /* real length of the solver identifier */ int verb; /* input argument -- verbosity */ long i ; /* loop variable */ long tmax; /* input arg - max number of iteration */ long t; /* output arg - number of iterations */ double tolrel; /* input arg */ double tolabs; /* input arg */ double tolKKT; /* input arg */ double *tmp_ptr; double *x; /* output arg -- solution*/ double *History; /* output arg */ double *diag_H; /* diagonal of matrix H */ double *f; /* vector f */ /*------------------------------------------------------------------- */ /* Take input arguments */ /*------------------------------------------------------------------- */ if( nrhs != 8) mexErrMsgTxt("Incorrect number of input arguments."); /* matrix H */ matrix_H = mxGetPr(prhs[0]); dim = mxGetM(prhs[0]); if(dim != mxGetN(prhs[0])) mexErrMsgTxt("Matrix H mast be squared."); /* vector f */ f = mxGetPr(prhs[1]); if((MAX(mxGetM(prhs[1]),mxGetN(prhs[1])) != dim) || (MIN(mxGetM(prhs[1]),mxGetN(prhs[1])) != 1)) mexErrMsgTxt("Vector f is of wrong size."); /* string identifier of QP solver to be used */ if( mxIsChar( prhs[2] ) != 1) mexErrMsgTxt("Solver must be a string."); buf_len = (mxGetM(prhs[2]) * mxGetN(prhs[2])) + 1; buf_len = (buf_len > 20) ? 20 : buf_len; mxGetString( prhs[2], solver, buf_len ); /* maximal allowed number of iterations */ tmax = mxIsInf( mxGetScalar(prhs[3])) ? INT_MAX : (long)mxGetScalar(prhs[3]); tolabs = mxGetScalar(prhs[4]); /* abs. precision defining stopping cond*/ tolrel = mxGetScalar(prhs[5]); /* rel. precision defining stopping cond*/ /* KKT cond. tolerance */ tolKKT = (double)mxGetScalar(prhs[6]); verb = (int)mxGetScalar(prhs[7]); /* verbosity on/off */ if( verb > 0 ) { mexPrintf("Settings of QP solver\n"); mexPrintf("solver : %s\n", solver ); mexPrintf("tmax : %d\n", tmax ); mexPrintf("tolabs : %f\n", tolabs ); mexPrintf("tolrel : %f\n", tolrel ); mexPrintf("tolKKT : %f\n", tolKKT ); mexPrintf("dim : %d\n", dim ); mexPrintf("verb : %d\n", verb ); } /*------------------------------------------------------------------- */ /* Inicialization */ /*------------------------------------------------------------------- */ /* output "solution" vector alpha [dim x 1] */ plhs[0] = mxCreateDoubleMatrix(dim,1,mxREAL); x = mxGetPr(plhs[0]); /* allocattes and precomputes diagonal of virtual K matrix */ diag_H = mxCalloc(dim, sizeof(double)); if( diag_H == NULL ) mexErrMsgTxt("Not enough memory."); for(i = 0; i < dim; i++ ) { diag_H[i] = matrix_H[dim*i+i]; } /* counter of access to matrix H */ access = dim; /*------------------------------------------------------------------- */ /* Call QP solver */ /*------------------------------------------------------------------- */ if ( strcmp( solver, "sca" ) == 0 ) { exitflag = gnnls_sca( &get_col, diag_H, f, dim, tmax, tolabs, tolrel, tolKKT, x, &t, &History, verb ); } else if ( strcmp( solver, "scas" ) == 0 ) { exitflag = gnnls_scas( &get_col, diag_H, f, dim, tmax, tolabs, tolrel, tolKKT, x, &t, &History, verb ); } else { mexErrMsgTxt("Unknown QP solver identifier!"); } /*------------------------------------------------------------------- */ /* Generate outputs */ /*------------------------------------------------------------------- */ /* exitflag [1x1] */ plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(plhs[1])) = (double)exitflag; /* t [1x1] */ plhs[2] = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(plhs[2])) = (double)t; /* access [1x1] */ plhs[3] = mxCreateDoubleMatrix(1,1,mxREAL); *(mxGetPr(plhs[3])) = (double)access; /* History [2 x (t+1)] */ plhs[4] = mxCreateDoubleMatrix(2,t+1,mxREAL); tmp_ptr = mxGetPr( plhs[4] ); for( i = 0; i <= t; i++ ) { tmp_ptr[INDEX(0,i,2)] = History[INDEX(0,i,2)]; tmp_ptr[INDEX(1,i,2)] = History[INDEX(1,i,2)]; } /*------------------------------------------------------------------- */ /* Free used memory */ /*------------------------------------------------------------------- */ mxFree( History ); mxFree( diag_H ); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* input parameters */ double WidT, PosT; double *T, *Pos, *Wid, *Amp, *x; /* output parameters */ double *y; /* working variables */ long nT, nx, nPdat, nIdat, nWdat; long idx, first, last, k, idxT; double alpha, beta, delta, deltaT; double left, right, WidS, Amplitude, pT, remT, Value, ValueOld; bool Verbose, InfEncountered, NaNEncountered, NegEncountered; /*int Harmonic; */ Verbose = false; /* Argument checks. */ if (nrhs!=7) mexErrMsgTxt("Wrong number of input parameters!"); if (nlhs!=1) mexErrMsgTxt("Wrong number of output parameters!"); /* Get all input arguments. */ T = mxGetPr(prhs[0]); PosT = mxGetScalar(prhs[1]) - 1; /* Matlab -> C array indices */ WidT = mxGetScalar(prhs[2]); Pos = mxGetPr(prhs[3]); Amp = mxGetPr(prhs[4]); Wid = mxGetPr(prhs[5]); x = mxGetPr(prhs[6]); /*Harmonic = 0;*/ /* Get vector lengths. */ nPdat = mxGetNumberOfElements(prhs[3]); nIdat = mxGetNumberOfElements(prhs[4]); nWdat = mxGetNumberOfElements(prhs[5]); if ((nPdat!=nIdat)||(nPdat!=nWdat)) mexErrMsgTxt("Pos, Amp, Wid must have the same number of elements!"); nT = mxGetNumberOfElements(prhs[0]); nx = mxGetNumberOfElements(prhs[6]); /* Allocate result array. */ plhs[0] = mxCreateDoubleMatrix(1,nx,mxREAL); y = mxGetPr(plhs[0]); delta = x[1]-x[0]; deltaT = 1; beta = delta/deltaT; /*if (Verbose) mexPrintf("begin of lisum1ic loop\n"); */ /* Loop over all peaks to add. */ InfEncountered = false; NaNEncountered = false; NegEncountered = false; for (k=0; k<nPdat; k++) { /* Skip if NaN or inf. */ if (mxIsNaN(Pos[k])||mxIsNaN(Amp[k])||mxIsNaN(Wid[k])) {NaNEncountered=true; continue;} if (mxIsInf(Pos[k])||mxIsInf(Amp[k])||mxIsInf(Wid[k])) {InfEncountered=true; continue;} /* Set to zero if negative width */ WidS = Wid[k]; if (WidS<0) {NegEncountered=true; WidS=0;} /* If width is zero, set it to a small value */ if (WidS<delta/100) WidS = delta/100; /* Scaling factor between template and spectrum abscissae */ alpha = WidT/WidS * beta; /* Left and right border of line in spectrum. */ left = (Pos[k]-x[0])/delta - PosT/alpha; left -= 0.5; /* Integration */ right = left + (nT-1)/alpha; /* Skip peak if completely outside. */ if ((left>=nx-1)||(right<=0)) continue; /* Chop if necessary. */ first = (long)((left<0) ? 0 : ceil(left)); last = (long)((right>nx-1) ? nx-1 : ceil(right)); /* scaled amplitude */ Amplitude = Amp[k]/beta; /*if (Harmonic>0) { */ /* Amplitude *= WidT/WidS; */ /* if (Harmonic>1) Amplitude *= WidT/WidS; */ /*} */ /*if (Verbose) */ /* mexPrintf(" setup> left %g right %g first %d last %d A %g\n",left,right,first,last,Amplitude); */ /* Loop over all points in spectrum to update. */ pT = alpha*(first-left); idxT = (long)(pT-alpha); remT = pT - alpha - idxT; ValueOld = (idxT<0) ? T[0] : (T[idxT]*(1-remT) + T[idxT+1]*remT); /*if (Verbose) mexPrintf(" start: pT %5f %11e ...\n",pT-alpha,ValueOld); */ for (idx=first; idx<last; idx++, pT+=alpha, ValueOld=Value) { idxT = (long)pT; remT = pT - idxT; Value = T[idxT]*(1-remT) + T[idxT+1]*remT; /*if (Verbose) */ /* mexPrintf(" idxS %4d pT %5f %11e - %-11e...",idx,pT,Value,ValueOld); */ y[idx] += Amplitude*(Value-ValueOld); /*if (Verbose) mexPrintf("added\n"); */ } idxT = (long)pT; remT = pT - idxT; Value = idxT<nT-2 ? T[idxT]*(1-remT) + T[idxT+1]*remT : T[nT-1]; /*if (Verbose) */ /* mexPrintf(" L:idxS %4d pT %5f %11e - %-11e...",idx,pT,Value,ValueOld); */ y[idx] += Amplitude*(Value-ValueOld); /*if (Verbose) mexPrintf("added\n"); */ } /* loop over all lines */ /*if (Verbose) mexPrintf("end of lisum1ic loop\n"); */ if (InfEncountered) mexPrintf("********** lisum1ic: Inf encountered!! Please report! **************\n"); if (NegEncountered) mexPrintf("********** lisum1ic: Negative width encountered!! Please report! **************\n"); } /* void mexFunction */
void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] ) { double C, TolRel, TolAbs, QPBound, trn_err, MaxTime; double *vec_C; double *ptr; uint32_t num_of_Cs; uint32_t i, j, BufSize; uint16_t Method; int verb; ocas_return_value_T ocas; /* timing variables */ double init_time; double total_time; total_time = get_time(); init_time = total_time; if(nrhs < 1) mexErrMsgTxt("Improper number of input arguments."); /* get input arguments */ if(mxIsChar(prhs[0]) == false) { /* [W,W0,stat] = svmocas_mex(X,X0,y,C,Method,TolRel,TolAbs,QPBound,BufSize,nData,MaxTime); */ if(nrhs < 4 || nrhs > 12) mexErrMsgTxt("Improper number of input arguments."); if(nrhs >= 12) verb = (int)mxGetScalar(prhs[11]); else verb = DEFAULT_VERB; data_X = (mxArray*)prhs[0]; if (!(mxIsDouble(data_X))) mexErrMsgTxt("Input argument X must be of type double."); if (mxGetNumberOfDimensions(data_X) != 2) mexErrMsgTxt("Input argument X must be two dimensional"); X0 = mxGetScalar(prhs[1]); data_y = (double*)mxGetPr(prhs[2]); if(LIBOCAS_MAX(mxGetM(prhs[2]),mxGetN(prhs[2])) != mxGetN(prhs[0])) mexErrMsgTxt("Length of vector y must equl to the number of columns of matrix X."); nDim = mxGetM(prhs[0]); if(verb) { mexPrintf("Input data statistics:\n" " # of examples : %d\n" " dimensionality : %d\n", mxGetN(data_X), nDim); if( mxIsSparse(data_X)== true ) mexPrintf(" density : %.2f%%\n", 100.0*(double)mxGetNzmax(data_X)/((double)nDim*(double)(mxGetN(data_X)))); else mexPrintf(" density : 100%% (full)\n"); } num_of_Cs = LIBOCAS_MAX(mxGetN(prhs[3]),mxGetM(prhs[3])); if(num_of_Cs == 1) { C = (double)mxGetScalar(prhs[3]); } else { vec_C = (double*)mxGetPr(prhs[3]); } if(nrhs >= 5) Method = (uint32_t)mxGetScalar(prhs[4]); else Method = DEFAULT_METHOD; if(nrhs >= 6) TolRel = (double)mxGetScalar(prhs[5]); else TolRel = DEFAULT_TOLREL; if(nrhs >= 7) TolAbs = (double)mxGetScalar(prhs[6]); else TolAbs = DEFAULT_TOLABS; if(nrhs >= 8) QPBound = (double)mxGetScalar(prhs[7]); else QPBound = DEFAULT_QPVALUE; if(nrhs >= 9) BufSize = (uint32_t)mxGetScalar(prhs[8]); else BufSize = DEFAULT_BUFSIZE; if(nrhs >= 10 && mxIsInf(mxGetScalar(prhs[9])) == false) nData = (uint32_t)mxGetScalar(prhs[9]); else nData = mxGetN(data_X); if(nData < 1 || nData > mxGetN(prhs[0])) mexErrMsgTxt("Improper value of argument nData."); if(num_of_Cs > 1 && num_of_Cs < nData) mexErrMsgTxt("Length of the vector C less than the number of examples."); if(nrhs >= 11) MaxTime = (double)mxGetScalar(prhs[10]); else MaxTime = DEFAULT_MAXTIME; } else { /* [W,W0,stat] = svmocas_mex(svmlight_data_file,X0,C,Method,TolRel,TolAbs,QPBound,BufSize,nData,MaxTime); */ char *fname; int fname_len; if(nrhs < 3 || nrhs > 11) mexErrMsgTxt("Improper number of input arguments."); if(nrhs >= 11) verb = (int)mxGetScalar(prhs[10]); else verb = DEFAULT_VERB; if(!mxIsChar(prhs[0])) mexErrMsgTxt("First input argument must be of type string."); fname_len = mxGetNumberOfElements(prhs[0]) + 1; fname = mxCalloc(fname_len, sizeof(char)); if (mxGetString(prhs[0], fname, fname_len) != 0) mexErrMsgTxt("Could not convert first input argument to string."); if( load_svmlight_file(fname,verb) == -1 || data_X == NULL || data_y == NULL) mexErrMsgTxt("Cannot load input file."); nDim = mxGetM(data_X); X0 = mxGetScalar(prhs[1]); /* C = (double)mxGetScalar(prhs[2]);*/ num_of_Cs = LIBOCAS_MAX(mxGetN(prhs[2]),mxGetM(prhs[2])); if(num_of_Cs == 1) { C = (double)mxGetScalar(prhs[2]); } else { vec_C = (double*)mxGetPr(prhs[2]); } if(verb) mexPrintf("Input data statistics:\n" " # of examples : %d\n" " dimensionality : %d\n" " density : %.2f%%\n", mxGetN(data_X), nDim, 100.0*(double)mxGetNzmax(data_X)/((double)nDim*(double)(mxGetN(data_X)))); if(nrhs >= 4) Method = (uint32_t)mxGetScalar(prhs[3]); else Method = DEFAULT_METHOD; if(nrhs >= 5) TolRel = (double)mxGetScalar(prhs[4]); else TolRel = DEFAULT_TOLREL; if(nrhs >= 6) TolAbs = (double)mxGetScalar(prhs[5]); else TolAbs = DEFAULT_TOLABS; if(nrhs >= 7) QPBound = (double)mxGetScalar(prhs[6]); else QPBound = DEFAULT_QPVALUE; if(nrhs >= 8) BufSize = (uint32_t)mxGetScalar(prhs[7]); else BufSize = DEFAULT_BUFSIZE; if(nrhs >= 9 && mxIsInf(mxGetScalar(prhs[8])) == false) nData = (uint32_t)mxGetScalar(prhs[8]); else nData = mxGetN(data_X); if(nData < 1 || nData > mxGetN(data_X)) mexErrMsgTxt("Improper value of argument nData."); if(num_of_Cs > 1 && num_of_Cs < nData) mexErrMsgTxt("Length of the vector C less than the number of examples."); if(nrhs >= 10) MaxTime = (double)mxGetScalar(prhs[9]); else MaxTime = DEFAULT_MAXTIME; } /*---------------------------------------------------------------- Print setting -------------------------------------------------------------------*/ if(verb) { mexPrintf("Setting:\n"); if( num_of_Cs == 1) mexPrintf(" C : %f\n", C); else mexPrintf(" C : different for each example\n"); mexPrintf(" bias : %.0f\n" " # of examples : %d\n" " solver : %d\n" " cache size : %d\n" " TolAbs : %f\n" " TolRel : %f\n" " QPValue : %f\n" " MaxTime : %f [s]\n" " verb : %d\n", X0, nData, Method,BufSize,TolAbs,TolRel, QPBound, MaxTime, verb); } /* learned weight vector */ plhs[0] = (mxArray*)mxCreateDoubleMatrix(nDim,1,mxREAL); W = (double*)mxGetPr(plhs[0]); if(W == NULL) mexErrMsgTxt("Not enough memory for vector W."); oldW = (double*)mxCalloc(nDim,sizeof(double)); if(oldW == NULL) mexErrMsgTxt("Not enough memory for vector oldW."); W0 = 0; oldW0 = 0; A0 = mxCalloc(BufSize,sizeof(A0[0])); if(A0 == NULL) mexErrMsgTxt("Not enough memory for vector A0."); /* allocate buffer for computing cutting plane */ new_a = (double*)mxCalloc(nDim,sizeof(double)); if(new_a == NULL) mexErrMsgTxt("Not enough memory for auxciliary cutting plane buffer new_a."); if(num_of_Cs > 1) { for(i=0; i < nData; i++) data_y[i] = data_y[i]*vec_C[i]; } if( mxIsSparse(data_X)== true ) { /* for i=1:nData, X(:,i) = X(:,i)*y(i); end*/ for(i=0; i < nData; i++) mul_sparse_col(data_y[i], data_X, i); /* init cutting plane buffer */ sparse_A.nz_dims = mxCalloc(BufSize,sizeof(uint32_t)); sparse_A.index = mxCalloc(BufSize,sizeof(sparse_A.index[0])); sparse_A.value = mxCalloc(BufSize,sizeof(sparse_A.value[0])); if(sparse_A.nz_dims == NULL || sparse_A.index == NULL || sparse_A.value == NULL) mexErrMsgTxt("Not enough memory for cutting plane buffer sparse_A."); init_time=get_time()-init_time; if(verb) { mexPrintf("Starting optimization:\n"); if(num_of_Cs == 1) { ocas = svm_ocas_solver( C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, &sparse_compute_W, &sparse_update_W, &sparse_add_new_cut, &sparse_compute_output, &qsort_data, &ocas_print, 0); } else { ocas = svm_ocas_solver_difC( vec_C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, &sparse_compute_W, &sparse_update_W, &sparse_add_new_cut, &sparse_compute_output, &qsort_data, &ocas_print, 0); } } else { if(num_of_Cs == 1) { ocas = svm_ocas_solver( C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, &sparse_compute_W, &sparse_update_W, &sparse_add_new_cut, &sparse_compute_output, &qsort_data, &ocas_print_null, 0); } else { ocas = svm_ocas_solver_difC( vec_C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, &sparse_compute_W, &sparse_update_W, &sparse_add_new_cut, &sparse_compute_output, &qsort_data, &ocas_print_null, 0); } } } else { ptr = mxGetPr(data_X); for(i=0; i < nData; i++) { for(j=0; j < nDim; j++ ) { ptr[LIBOCAS_INDEX(j,i,nDim)] = ptr[LIBOCAS_INDEX(j,i,nDim)]*data_y[i]; } } /* init cutting plane buffer */ full_A = mxCalloc(BufSize*nDim,sizeof(double)); if( full_A == NULL ) mexErrMsgTxt("Not enough memory for cutting plane buffer full_A."); init_time=get_time()-init_time; if(verb) { mexPrintf("Starting optimization:\n"); if(num_of_Cs == 1) ocas = svm_ocas_solver( C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, &full_compute_W, &full_update_W, &full_add_new_cut, &full_compute_output, &qsort_data, &ocas_print, 0); else ocas = svm_ocas_solver_difC( vec_C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, &full_compute_W, &full_update_W, &full_add_new_cut, &full_compute_output, &qsort_data, &ocas_print, 0); } else { if(num_of_Cs == 1) ocas = svm_ocas_solver( C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, &full_compute_W, &full_update_W, &full_add_new_cut, &full_compute_output, &qsort_data, &ocas_print_null, 0); else ocas = svm_ocas_solver_difC( vec_C, nData, TolRel, TolAbs, QPBound, MaxTime,BufSize, Method, &full_compute_W, &full_update_W, &full_add_new_cut, &full_compute_output, &qsort_data, &ocas_print_null, 0); } } if(verb) { mexPrintf("Stopping condition: "); switch( ocas.exitflag ) { case 1: mexPrintf("1-Q_D/Q_P <= TolRel(=%f) satisfied.\n", TolRel); break; case 2: mexPrintf("Q_P-Q_D <= TolAbs(=%f) satisfied.\n", TolAbs); break; case 3: mexPrintf("Q_P <= QPBound(=%f) satisfied.\n", QPBound); break; case 4: mexPrintf("Optimization time (=%f) >= MaxTime(=%f).\n", ocas.ocas_time, MaxTime); break; case -1: mexPrintf("Has not converged!\n" ); break; case -2: mexPrintf("Not enough memory for the solver.\n" ); break; } } total_time=get_time()-total_time; if(verb) { mexPrintf("Timing statistics:\n" " init_time : %f[s]\n" " qp_solver_time : %f[s]\n" " sort_time : %f[s]\n" " output_time : %f[s]\n" " add_time : %f[s]\n" " w_time : %f[s]\n" " print_time : %f[s]\n" " ocas_time : %f[s]\n" " total_time : %f[s]\n", init_time, ocas.qp_solver_time, ocas.sort_time, ocas.output_time, ocas.add_time, ocas.w_time, ocas.print_time, ocas.ocas_time, total_time); mexPrintf("Training error: %.4f%%\n", 100*(double)ocas.trn_err/(double)nData); } /* multiply data ba labels as it was at the begining */ if( mxIsSparse(data_X)== true ) { /* for i=1:nData, X(:,i) = X(:,i)*y(i); end*/ for(i=0; i < nData; i++) { mul_sparse_col(1/data_y[i], data_X, i); } } else { ptr = mxGetPr(data_X); for(i=0; i < nData; i++) { for(j=0; j < nDim; j++ ) { ptr[LIBOCAS_INDEX(j,i,nDim)] = ptr[LIBOCAS_INDEX(j,i,nDim)]/data_y[i]; } } } if(num_of_Cs > 1) { for(i=0; i < nData; i++) data_y[i] = data_y[i]/vec_C[i]; } plhs[1] = mxCreateDoubleScalar( W0 ); /* return ocas optimizer statistics */ /* typedef struct { uint32_t nIter; uint32_t nCutPlanes; double trn_err; double Q_P; double Q_D; double output_time; double sort_time; double solver_time; int8_t exitflag; } ocas_return_value_T; */ const char *field_names[] = {"nTrnErrors","Q_P","Q_D","nIter","nCutPlanes","exitflag", "init_time","output_time","sort_time","qp_solver_time","add_time", "w_time","print_time","ocas_time","total_time"}; mwSize dims[2] = {1,1}; plhs[2] = mxCreateStructArray(2, dims, (sizeof(field_names)/sizeof(*field_names)), field_names); mxSetField(plhs[2],0,"nIter",mxCreateDoubleScalar((double)ocas.nIter)); mxSetField(plhs[2],0,"nCutPlanes",mxCreateDoubleScalar((double)ocas.nCutPlanes)); mxSetField(plhs[2],0,"nTrnErrors",mxCreateDoubleScalar(ocas.trn_err)); mxSetField(plhs[2],0,"Q_P",mxCreateDoubleScalar(ocas.Q_P)); mxSetField(plhs[2],0,"Q_D",mxCreateDoubleScalar(ocas.Q_D)); mxSetField(plhs[2],0,"init_time",mxCreateDoubleScalar(init_time)); mxSetField(plhs[2],0,"output_time",mxCreateDoubleScalar(ocas.output_time)); mxSetField(plhs[2],0,"sort_time",mxCreateDoubleScalar(ocas.sort_time)); mxSetField(plhs[2],0,"qp_solver_time",mxCreateDoubleScalar(ocas.qp_solver_time)); mxSetField(plhs[2],0,"add_time",mxCreateDoubleScalar(ocas.add_time)); mxSetField(plhs[2],0,"w_time",mxCreateDoubleScalar(ocas.w_time)); mxSetField(plhs[2],0,"print_time",mxCreateDoubleScalar(ocas.print_time)); mxSetField(plhs[2],0,"ocas_time",mxCreateDoubleScalar(ocas.ocas_time)); mxSetField(plhs[2],0,"total_time",mxCreateDoubleScalar(total_time)); mxSetField(plhs[2],0,"exitflag",mxCreateDoubleScalar((double)ocas.exitflag)); return; }
void mexFunction( int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[] ) { char strFileName[MAXSTRING]; double record_offset; unsigned long file_size; FILE *fid=NULL; unsigned long nrecords = 0; char tval[6]; double recid; uint32_t timestamp = 0; int i; uint32_t offset; /*create empty outputs*/ for (i=0; i<nlhs; i++) { plhs[i] = mxCreateDoubleMatrix(0,0,mxREAL); } if (nrhs!=3) mexErrMsgTxt("Incorrect number of input arguments."); /* if (nlhs!=3) */ /* mexErrMsgTxt("Incorrect number of output arguments."); */ if (!mxIsChar(prhs[0])) mexErrMsgTxt("First argument should be a string"); if (!mxIsDouble(prhs[1])) mexErrMsgTxt("Second argument should be a double"); if (!mxIsDouble(prhs[2])) mexErrMsgTxt("Third argument should be a double"); mxGetString(prhs[0], strFileName, MAXSTRING); if ( (fid = fopen(strFileName, "rb")) == NULL ) mexErrMsgTxt("Unable to open file"); recid = mxGetScalar(prhs[2]); record_offset = mxGetScalar(prhs[1]); fseek(fid, 0, 2); file_size = ftell(fid); if (record_offset > file_size) mexErrMsgTxt("Invalid record offset"); fseek(fid, record_offset, 0); nrecords = 0; /*find the number of records in the file and store offsets*/ while (1) { if (fread(tval, 1, 6, fid)==6) { offset = ftell(fid)-6; if (mxIsInf(recid)==0 && (nrecords == recid)) { timestamp = *((uint32_t*)(&(tval[2]))); break; } nrecords++; fseek(fid, ((unsigned char*)tval)[0] * 3, SEEK_CUR); } else { if (nrecords == 0) { offset = record_offset; timestamp = 0; } else timestamp = *((uint32_t*)(&(tval[2]))); break; } } if (nlhs>0) plhs[0] = mxCreateDoubleScalar( nrecords ); if (nlhs>1) plhs[1] = mxCreateDoubleScalar( offset ); if (nlhs>2) plhs[2] = mxCreateDoubleScalar( timestamp ); fclose(fid); }