// 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; }
//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 user_function_data fun; double *x0, *ydata = NULL, *lb = NULL, *ub = NULL, *A = NULL, *b = NULL, *Aeq = NULL, *beq = NULL; //Options int maxIter = 500; double info[LM_INFO_SZ]; double opts[LM_OPTS_SZ]={J_INIT_MU, J_STOP_THRESH, J_STOP_THRESH, J_STOP_THRESH, LM_DIFF_DELTA}; //Outputs Args double *x, *fval, *exitflag, *iter, *feval; double *pcovar = NULL; //Internal Vars size_t ndec, ndat; int i, status, havJac = 0, conMode = 0; int nineq=0, neq=0; double *covar = NULL; double *Apr, *bpr; double *llb, *lub; citer = 1; iterF.enabled = false; if (nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString(LM_VERSION); return; } //Check user inputs & get constraint information checkInputs(prhs,nrhs,&conMode); //Get Sizes ndec = mxGetNumberOfElements(prhs[2]); ndat = mxGetNumberOfElements(prhs[3]); //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; } fun.prhs[fun.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //x0 fun.print = 0; //Check and Get Gradient Function Handle if(!mxIsEmpty(prhs[1])) { havJac = 1; if (mxIsChar(prhs[1])) { CHECK(mxGetString(prhs[1], fun.g, FLEN) == 0,"error reading gradient name string"); fun.nrhs_g = 1; fun.xrhs_g = 0; } else { fun.prhs_g[0] = (mxArray*)prhs[1]; 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(prhs[2]); ydata = mxGetPr(prhs[3]); fun.ydata = ydata; //Get Bounds if(conMode & 1) { //LB if(!mxIsEmpty(prhs[4])){ llb = mxGetPr(prhs[4]); lb = mxCalloc(ndec,sizeof(double)); memcpy(lb,llb,ndec*sizeof(double)); for(i=0;i<ndec;i++) { if(mxIsInf(lb[i])) lb[i] = -DBL_MAX; } } else { lb = mxCalloc(ndec,sizeof(double)); for(i=0;i<ndec;i++) lb[i] = -DBL_MAX; } //UB if(nrhs > 5 && !mxIsEmpty(prhs[5])){ lub = mxGetPr(prhs[5]); ub = mxCalloc(ndec,sizeof(double)); memcpy(ub,lub,ndec*sizeof(double)); for(i=0;i<ndec;i++) { if(mxIsInf(ub[i])) ub[i] = DBL_MAX; } } else { ub = mxCalloc(ndec,sizeof(double)); for(i=0;i<ndec;i++) ub[i] = DBL_MAX; } } //Get Linear Inequality Constraints if(conMode & 2) { nineq = (int)mxGetM(prhs[7]); Apr = mxGetPr(prhs[6]); bpr = mxGetPr(prhs[7]); //Need to flip >= to <= A = mxCalloc(ndec*nineq,sizeof(double)); b = mxCalloc(nineq,sizeof(double)); for(i=0;i<ndec*nineq;i++) A[i] = -Apr[i]; for(i=0;i<nineq;i++) b[i] = -bpr[i]; } //Get Linear Equality Constraints if(conMode & 4) { Aeq = mxGetPr(prhs[8]); beq = mxGetPr(prhs[9]); neq = (int)mxGetM(prhs[9]); } //Get Options if specified if(nrhs > 10) { if(mxGetField(prhs[10],0,"maxiter")) maxIter = (int)*mxGetPr(mxGetField(prhs[10],0,"maxiter")); if(mxGetField(prhs[10],0,"display")) fun.print = (int)*mxGetPr(mxGetField(prhs[10],0,"display")); if(mxGetField(prhs[10],0,"iterfun") && !mxIsEmpty(mxGetField(prhs[10],0,"iterfun"))) { iterF.prhs[0] = (mxArray*)mxGetField(prhs[10],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)); //Create Covariance Matrix if Required if(nlhs>4) covar=mxCalloc(ndec*ndec,sizeof(double)); //Print Header if(fun.print) { mexPrintf("\n------------------------------------------------------------------\n"); mexPrintf(" This is LEVMAR v2.5\n"); mexPrintf(" Author: Manolis Lourakis\n MEX Interface J. Currie 2011\n\n"); mexPrintf(" Problem Properties:\n"); mexPrintf(" # Decision Variables: %4d\n",ndec); mexPrintf(" # Data Points: %4d\n",ndat); mexPrintf("------------------------------------------------------------------\n"); } //Solve based on constraints switch(conMode) { case MIN_UNCONSTRAINED: //mexPrintf("Unc Problem\n"); if(havJac) status = dlevmar_der(func, jac, x, ydata, (int)ndec, (int)ndat, maxIter, opts, info, NULL, covar, &fun); else status = dlevmar_dif(func, x, ydata, (int)ndec, (int)ndat, maxIter, opts, info, NULL, covar, &fun); break; case MIN_CONSTRAINED_BC: //mexPrintf("Box Constrained Problem\n"); if(havJac) status = dlevmar_bc_der(func, jac, x, ydata, (int)ndec, (int)ndat, lb, ub, NULL, maxIter, opts, info, NULL, covar, &fun); else status = dlevmar_bc_dif(func, x, ydata, (int)ndec, (int)ndat, lb, ub, NULL, maxIter, opts, info, NULL, covar, &fun); break; case MIN_CONSTRAINED_LIC: //mexPrintf("Linear Inequality Problem\n"); if(havJac) status = dlevmar_lic_der(func, jac, x, ydata, (int)ndec, (int)ndat, A, b, nineq, maxIter, opts, info, NULL, covar, &fun); else status = dlevmar_lic_dif(func, x, ydata, (int)ndec, (int)ndat, A, b, nineq, maxIter, opts, info, NULL, covar, &fun); break; case MIN_CONSTRAINED_BLIC: //mexPrintf("Boxed Linear Inequality Problem\n"); if(havJac) status = dlevmar_blic_der(func, jac, x, ydata, (int)ndec, (int)ndat, lb, ub, A, b, nineq, maxIter, opts, info, NULL, covar, &fun); else status = dlevmar_blic_dif(func, x, ydata, (int)ndec, (int)ndat, lb, ub, A, b, nineq, maxIter, opts, info, NULL, covar, &fun); break; case MIN_CONSTRAINED_LEC: //mexPrintf("Linear Equality Problem\n"); if(havJac) status = dlevmar_lec_der(func, jac, x, ydata, (int)ndec, (int)ndat, Aeq, beq, neq, maxIter, opts, info, NULL, covar, &fun); else status = dlevmar_lec_dif(func, x, ydata, (int)ndec, (int)ndat, Aeq, beq, neq, maxIter, opts, info, NULL, covar, &fun); break; case MIN_CONSTRAINED_BLEC: //mexPrintf("Boxed Linear Equality Problem\n"); if(havJac) status = dlevmar_blec_der(func, jac, x, ydata, (int)ndec, (int)ndat, lb, ub, Aeq, beq, neq, NULL, maxIter, opts, info, NULL, covar, &fun); else status = dlevmar_blec_dif(func, x, ydata, (int)ndec, (int)ndat, lb, ub, Aeq, beq, neq, NULL, maxIter, opts, info, NULL, covar, &fun); break; case MIN_CONSTRAINED_LEIC: //mexPrintf("Linear Inequality + Equality Problem\n"); if(havJac) status = dlevmar_leic_der(func, jac, x, ydata, (int)ndec, (int)ndat, Aeq, beq, neq, A, b, nineq, maxIter, opts, info, NULL, covar, &fun); else status = dlevmar_leic_dif(func, x, ydata, (int)ndec, (int)ndat, Aeq, beq, neq, A, b, nineq, maxIter, opts, info, NULL, covar, &fun); break; case MIN_CONSTRAINED_BLEIC: //mexPrintf("Boxed Linear Inequality + Equality Problem\n"); if(havJac) status = dlevmar_bleic_der(func, jac, x, ydata, (int)ndec, (int)ndat, lb, ub, Aeq, beq, neq, A, b, nineq, maxIter, opts, info, NULL, covar, &fun); else status = dlevmar_bleic_dif(func, x, ydata, (int)ndec, (int)ndat, lb, ub, Aeq, beq, neq, A, b, nineq, maxIter, opts, info, NULL, covar, &fun); break; default: mexErrMsgTxt("Unknown constraint configuration"); } //Save Status & Iterations *fval = info[1]; *exitflag = getStatus(info[6]); *iter = (double)status; *feval = (double)citer; //Save Covariance if Required if(nlhs > 5) { plhs[5] = mxCreateDoubleMatrix(ndec, ndec, mxREAL); pcovar = mxGetPr(plhs[5]); memcpy(pcovar,covar,ndec*ndec*sizeof(double)); } //Print Header if(fun.print){ //Termination Detected if(*exitflag == 1) mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n"); else if(*exitflag == 0) mexPrintf("\n *** MAXIMUM ITERATIONS REACHED ***\n"); else if(*exitflag == -1) mexPrintf("\n *** TERMINATION: TOLERANCE TOO SMALL ***\n"); else if(*exitflag == -2) mexPrintf("\n *** TERMINATION: ROUTINE ERROR ***\n"); if(*exitflag==1) mexPrintf(" Final SSE: %12.5g\n In %3.0f iterations\n",*fval,*iter); mexPrintf("------------------------------------------------------------------\n\n"); } //Clean Up if(lb) mxFree(lb); if(ub) mxFree(ub); if(covar) mxFree(covar); if(A) mxFree(A); if(b) mxFree(b); }
// 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); }
// Function definitions. // ----------------------------------------------------------------- void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Input Args double *x0; //Outputs Args double *x, *fval, *exitflag, *iter, *feval; //Internal Vars size_t ndec; int printLevel = 0; //M1QN3 Vars int m = 5, n, indic, ndz; int uiparm[2] = {1,0}; //user integer array [citer, printLevel] double *g, dxmin = 1e-8, df1, epsg = 1e-6, *dz; char *normtype = "dfn"; int impres = 0, io = 0, omode = 0, reverse = 0; int imode[3] = {0,0,0}; //DIS, cold start, no SIMUL with indic = 1 int iz[5]; float *rzs = NULL; double *dzs = NULL; //dummy args //Defaults int maxfev = 1500; int maxiter = 1000; maxtime = 1000; iterF.enabled = false; if (nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString(M1QN3_VERSION); return; } //Check user inputs checkInputs(prhs,nrhs); //Get Sizes ndec = mxGetNumberOfElements(pX0); //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 //Get Gradient Function Handle 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 x0 = mxGetPr(pX0); //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,"maxtime")) maxtime = *mxGetPr(mxGetField(pOPTS,0,"maxtime")); if(mxGetField(pOPTS,0,"tolafun")) epsg = *mxGetPr(mxGetField(pOPTS,0,"tolafun")); //not function tolerance (gradient) if(mxGetField(pOPTS,0,"nupdates")) m = (int)*mxGetPr(mxGetField(pOPTS,0,"nupdates")); //number of l-bfgs updates 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"); mexPrintf(" This is M1QN3 v%s\n",M1QN3_VERSION); mexPrintf(" Authors: Jean Charles Gilbert, Claude Lemarechal, INRIA\n MEX Interface J. Currie 2012\n\n"); mexPrintf(" Problem Properties:\n"); mexPrintf(" # Decision Variables: %4d\n",ndec); mexPrintf("------------------------------------------------------------------\n"); } //Assign Arguments n = (int)ndec; indic = 4; g = (double*)mxCalloc(n,sizeof(double)); //allocate memory for gradient ndz = 4*n + m*(2*n + 1); dz = (double*)mxCalloc(ndz,sizeof(double)); //Start timer start = clock(); //Initialization Call SIMUL(&indic, &n, x, fval, g, uiparm, NULL, NULL); //Set df1 (initial estiamte of f reduction) df1 = *fval; //MEX Options uiparm[0] = 1; uiparm[1] = printLevel; //Call Algorithm M1QN3(SIMUL,EUCLID,CTONBE,CTCABE,&n,x,fval,g,&dxmin,&df1,&epsg,normtype, &impres,&io,imode,&omode,&maxiter,&maxfev,iz,dz,&ndz,&reverse,&indic, uiparm,rzs,dzs); //Save Status & Iterations *exitflag = (double)omode; *iter = maxiter; *feval = maxfev; //Check if maxtime exceeded if(((double)(end-start))/CLOCKS_PER_SEC > maxtime) *exitflag = 8; //Print Header if(printLevel){ //Termination Detected switch((int)*exitflag) { //Success case 1: mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** gradient convergence |gk|/|g1| < epsg ***\n"); break; //Error case 5: mexPrintf("\n *** MAXIMUM FUNCTION EVALUATIONS REACHED ***\n"); break; case 4: mexPrintf("\n *** MAXIMUM ITERATIONS REACHED ***\n"); break; case 8: mexPrintf("\n *** MAXIMUM TIME REACHED ***\n"); break; case 2: mexPrintf("\n *** ERROR: one of the input arguments is not well initialized ***\n"); break; case 3: mexPrintf("\n *** ERROR: the line-search is blocked on tmax = 10^20 ***\n"); break; case 6: mexPrintf("\n *** ERROR: stop dxmin during the line-search ***\n"); break; case 7: mexPrintf("\n *** ERROR: either (g,d) is nonnegative or (y,s) is nonpositive ***\n"); break; //Early Exit case 0: mexPrintf("\n *** TERMINATION: USER EXITED ***\n"); break; //Other Error default: mexPrintf("\n *** ERROR: internal error code %d ***\n",omode); break; } if(*exitflag==1) mexPrintf("\n Final fval: %12.5g\n In %3.0f iterations\n",*fval,*iter); mexPrintf("------------------------------------------------------------------\n\n"); } //Free Memory mxFree(g); mxFree(dz); }
// Function definitions. // ----------------------------------------------------------------- void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Outputs Args double *x, *fval, *exitflag, *iter; //Internal Vars double *mptr; size_t ndec, ndat; int i, havJac = 0; //LMDIF + LMDER Vars int m; //len data int n; //len x double *x0; //initial guess + sol double *fvec; //final fvec double ftol = 1e-7; //function tolerance double xtol = 1e-7; //iterate tolerance double gtol = 1e-7; //gradient tolerance int maxfev = 1500; //max fevals double epsfcn = mxGetEps(); //FD max error double *diag; //scaling (ignored in mode 1) int mode = 1; //internal scaling double factor = 100; //used for initial step bound int nprint = -1; //no printing int info = 0; //output status int nfev = 0; //number of fevals int njev = 0; //number of jevals double *fjac; //final jacobian int ldfjac; //ld of jac int *ipvt; //permutation double *qtf; //qt * fvec double *wa1, *wa2, *wa3, *wa4; //work vectors if (nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString(""); //no version info? return; } //Check user inputs checkInputs(prhs,nrhs); //Set Defaults citer = 1; printLevel = 0; iterF.enabled = false; maxtime = 1000; //Get Sizes ndec = mxGetNumberOfElements(prhs[2]); ndat = mxGetNumberOfElements(prhs[3]); //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; } fun.prhs[fun.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //x0 //Check and Get Gradient Function Handle if(!mxIsEmpty(prhs[1])) { havJac = 1; if (mxIsChar(prhs[1])) { CHECK(mxGetString(prhs[1], grad.f, FLEN) == 0,"error reading gradient name string"); grad.nrhs = 1; grad.xrhs = 0; } else { grad.prhs[0] = (mxArray*)prhs[1]; strcpy(grad.f, "feval"); grad.nrhs = 2; grad.xrhs = 1; } grad.prhs[grad.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //x0 } //Get x0 + data x0 = mxGetPr(prhs[2]); ydata = mxGetPr(prhs[3]); //Get Options if specified if(nrhs > 4) { if(mxGetField(prhs[4],0,"display")) printLevel = (int)*mxGetPr(mxGetField(prhs[4],0,"display")); if(mxGetField(prhs[4],0,"maxfeval")) maxfev = (int)*mxGetPr(mxGetField(prhs[4],0,"maxfeval")); if(mxGetField(prhs[4],0,"maxtime")) maxtime = *mxGetPr(mxGetField(prhs[4],0,"maxtime")); if(mxGetField(prhs[4],0,"tolrfun")) ftol = *mxGetPr(mxGetField(prhs[4],0,"tolrfun")); if(mxGetField(prhs[4],0,"iterfun") && !mxIsEmpty(mxGetField(prhs[4],0,"iterfun"))) { iterF.prhs[0] = (mxArray*)mxGetField(prhs[4],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); x = mxGetPr(plhs[0]); fval = mxGetPr(plhs[1]); exitflag = mxGetPr(plhs[2]); iter = mxGetPr(plhs[3]); //Copy initial guess to x memcpy(x,x0,ndec*sizeof(double)); //Print Header if(printLevel) { mexPrintf("\n------------------------------------------------------------------\n"); if(havJac) mexPrintf(" This is LM_DER\n"); else mexPrintf(" This is LM_DIF\n"); mexPrintf(" Authors: Burton S. Garbow, Kenneth E. Hillstrom, Jorge J. More\n MEX Interface J. Currie 2011\n\n"); mexPrintf(" Problem Properties:\n"); mexPrintf(" # Decision Variables: %4d\n",ndec); mexPrintf(" # Data Points: %4d\n",ndat); mexPrintf("------------------------------------------------------------------\n"); } //Assign Arguments m = (int)ndat; ldfjac = m; n = (int)ndec; diag = mxCalloc(ndec,sizeof(double)); fvec = mxCalloc(ndat,sizeof(double)); fjac = mxCalloc(ndec*ndat,sizeof(double)); ipvt = mxCalloc(ndec,sizeof(int)); qtf = mxCalloc(ndec,sizeof(double)); //Get Work Memory mptr = mxCalloc(3*ndec+ndat,sizeof(double)); i = 0; wa1 = &mptr[i]; i += (int)ndec; wa2 = &mptr[i]; i += (int)ndec; wa3 = &mptr[i]; i += (int)ndec; wa4 = &mptr[i]; //Start Timer start = clock(); //Call Algorithm based on Derivatives if(havJac) LMDER(jacfunc,&m,&n,x,fvec,fjac,&ldfjac,&ftol,&xtol,>ol,&maxfev,diag,&mode,&factor,&nprint,&info,&nfev,&njev,ipvt,qtf,wa1,wa2,wa3,wa4); else LMDIF(func,&m,&n,x,fvec,&ftol,&xtol,>ol,&maxfev,&epsfcn,diag,&mode,&factor,&nprint,&info,&nfev,fjac,&ldfjac,ipvt,qtf,wa1,wa2,wa3,wa4); //Calculate final Rnorm *fval = 0; for(i=0;i<m;i++) *fval += fvec[i]*fvec[i]; //Check if maxtime exceeded if(((double)(end-start))/CLOCKS_PER_SEC > maxtime) info = 15; //Save Status & Iterations *exitflag = getStatus(info); *iter = (double)nfev; //Print Header if(printLevel){ //Termination Detected switch((int)info) { //Success case 1: mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** Both actual and predicted relative reductions in the sum of squares are at most ftol ***\n"); break; case 2: mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** Relative error between two consecutive iterates is at most xtol ***\n"); break; case 3: mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** Reductions in the sum of squares are at most ftol AND relative error between two consecutive iterates is at most xtol ***\n"); break; case 4: mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** The cosine of the angle between fvec and any column of the jacobian is at most gtol in absolute value ***\n"); break; //Error case 0: mexPrintf("\n *** ERROR: IMPROPER INPUT PARAMETERS ***\n"); break; case 5: mexPrintf("\n *** MAXIMUM FUNCTION EVALUATIONS REACHED ***\n"); break; case 15: mexPrintf("\n *** MAXIMUM TIME REACHED ***\n"); break; //Early Exit case 6: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: ftol is too small (OPTI setting tolfun). No further improvement in the sum of squares is possible ***\n"); break; case 7: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: xtol is too small (OPTI hard-codes 1e-7). No further improvement in the approximate solution x is possible ***\n"); break; case 8: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: gtol is too small (OPTI hard-codes 1e-7). Fvec is orthogonal to the columns of the jacobian to machine precision ***\n"); break; case -1: mexPrintf("\n *** TERMINATION: USER EXITED ***\n"); break; } if(*exitflag==1) mexPrintf("\n Final SSE: %12.5g\n In %3.0f function evaluations\n",*fval,*iter); mexPrintf("------------------------------------------------------------------\n\n"); } //Free Memory if(diag) mxFree(diag); if(fvec) mxFree(fvec); if(fjac) mxFree(fjac); if(ipvt) mxFree(ipvt); if(qtf) mxFree(qtf); if(mptr) mxFree(mptr); }
void mexFunction(int nlhs, mxArray *plhs[ ], int nrhs, const mxArray *prhs[ ]) { int i,j,pos; int *ptr_int; double *ptr_double; double *ptr_matlab; #if MUMPS_ARITH == MUMPS_ARITH_z double *ptri_matlab; #endif mwSize tmp_m,tmp_n; /* C pointer for input parameters */ size_t inst_address; mwSize n,m,ne, netrue ; int inst,job; mwIndex *irn_in,*jcn_in; /* variable for multiple and sparse rhs */ int posrhs; mwSize nbrhs,ldrhs, nz_rhs; mwIndex *irhs_ptr, *irhs_sparse; double *rhs_sparse; #if MUMPS_ARITH == MUMPS_ARITH_z double *im_rhs_sparse; #endif DMUMPS_STRUC_C *dmumps_par; int dosolve = 0; int donullspace = 0; int doanal = 0; if(nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString("4.10.0"); return; } EXTRACT_FROM_MATLAB_TOVAL(JOB,job); dosolve = (job == 3 || job == 5 || job == 6); doanal = (job == 1 || job == 4 || job == 6); if(job == -1){ DMUMPS_alloc(&dmumps_par); EXTRACT_FROM_MATLAB_TOVAL(SYM,dmumps_par->sym); dmumps_par->job = -1; dmumps_par->par = 1; dmumps_c(dmumps_par); dmumps_par->nz = -1; dmumps_par->nz_alloc = -1; }else{ EXTRACT_FROM_MATLAB_TOVAL(INST,inst_address); ptr_int = (int *) inst_address; dmumps_par = (DMUMPS_STRUC_C *) ptr_int; if(job == -2){ dmumps_par->job = -2; dmumps_c(dmumps_par); DMUMPS_free(&dmumps_par); }else{ /* check of input arguments */ n = mxGetN(A_IN); m = mxGetM(A_IN); if (!mxIsSparse(A_IN) || n != m ) mexErrMsgTxt("Input matrix must be a sparse square matrix"); jcn_in = mxGetJc(A_IN); ne = jcn_in[n]; irn_in = mxGetIr(A_IN); dmumps_par->n = (int)n; if(dmumps_par->n != n) mexErrMsgTxt("Input is too big; will not work...barfing out\n"); if(dmumps_par->sym != 0) netrue = (n+ne)/2; else netrue = ne; if(dmumps_par->nz_alloc < netrue || dmumps_par->nz_alloc >= 2*netrue){ MYFREE(dmumps_par->jcn); MYFREE(dmumps_par->irn); MYFREE(dmumps_par->a); MYMALLOC((dmumps_par->jcn),(int)netrue,int); MYMALLOC((dmumps_par->irn),(int)netrue,int); MYMALLOC((dmumps_par->a),(int)netrue,double2); dmumps_par->nz_alloc = (int)netrue; if (dmumps_par->nz_alloc != netrue) mexErrMsgTxt("Input is too big; will not work...barfing out\n"); } if(dmumps_par->sym == 0){ /* if analysis already performed then we only need to read numerical values Note that we suppose that matlab did not change the internal format of the matrix between the 2 calls */ if(doanal){ /* || dmumps_par->info[22] == 0 */ for(i=0;i<dmumps_par->n;i++){ for(j=jcn_in[i];j<jcn_in[i+1];j++){ (dmumps_par->jcn)[j] = i+1; (dmumps_par->irn)[j] = ((int)irn_in[j])+1; } } } dmumps_par->nz = (int)ne; if( dmumps_par->nz != ne) mexErrMsgTxt("Input is too big; will not work...barfing out\n"); #if MUMPS_ARITH == MUMPS_ARITH_z ptr_matlab = mxGetPr(A_IN); for(i=0;i<dmumps_par->nz;i++){ ((dmumps_par->a)[i]).r = ptr_matlab[i]; } ptr_matlab = mxGetPi(A_IN); if(ptr_matlab){ for(i=0;i<dmumps_par->nz;i++){ ((dmumps_par->a)[i]).i = ptr_matlab[i]; } }else{ for(i=0;i<dmumps_par->nz;i++){ ((dmumps_par->a)[i]).i = 0.0; } } #else ptr_matlab = mxGetPr(A_IN); for(i=0;i<dmumps_par->nz;i++){ (dmumps_par->a)[i] = ptr_matlab[i]; } #endif }else{ /* in the symmetric case we do not need to check doanal */ pos = 0; ptr_matlab = mxGetPr(A_IN); #if MUMPS_ARITH == MUMPS_ARITH_z ptri_matlab = mxGetPi(A_IN); #endif for(i=0;i<dmumps_par->n;i++){ for(j=jcn_in[i];j<jcn_in[i+1];j++){ if(irn_in[j] >= i){ if(pos >= netrue) mexErrMsgTxt("Input matrix must be symmetric"); (dmumps_par->jcn)[pos] = i+1; (dmumps_par->irn)[pos] = (int)irn_in[j]+1; #if MUMPS_ARITH == MUMPS_ARITH_z ((dmumps_par->a)[pos]).r = ptr_matlab[j]; if(ptri_matlab){ ((dmumps_par->a)[pos]).i = ptri_matlab[j]; }else{ ((dmumps_par->a)[pos]).i = 0.0; } #else (dmumps_par->a)[pos] = ptr_matlab[j]; #endif pos++; } } } dmumps_par->nz = pos; } EXTRACT_FROM_MATLAB_TOVAL(JOB,dmumps_par->job); EXTRACT_FROM_MATLAB_TOARR(ICNTL,dmumps_par->icntl,int,40); EXTRACT_FROM_MATLAB_TOARR(CNTL,dmumps_par->cntl,double,15); EXTRACT_FROM_MATLAB_TOPTR(PERM_IN,(dmumps_par->perm_in),int,((int)n)); EXTRACT_FROM_MATLAB_TOPTR(COLSCA,(dmumps_par->colsca),double,((int)n)); EXTRACT_FROM_MATLAB_TOPTR(ROWSCA,(dmumps_par->rowsca),double,((int)n)); dmumps_par->size_schur = (int)mxGetN(VAR_SCHUR); EXTRACT_FROM_MATLAB_TOPTR(VAR_SCHUR,(dmumps_par->listvar_schur),int,dmumps_par->size_schur); if(!dmumps_par->listvar_schur) dmumps_par->size_schur = 0; ptr_matlab = mxGetPr (RHS); /* * To follow the "spirit" of the matlab/scilab interfaces, treat case of null * space separately. In that case, we initialize lrhs and nrhs automatically * allocate the space needed, and do not rely on what is provided by the user * in component RHS, that is not touched. * * Note that at the moment the user should not call the solution step combined * with the factorization step when he/she sets icntl[25-1] to a non-zero value. * Hence we suppose infog[28-1] is available and we can use it. * * For users of scilab/matlab, it would still be nice to be able to set ICNTL(25)=-1, * and use JOB=6. If we want to make this functionality available, we should * call separately job=2 and job=3 even if job=5 or 6 and set nbrhs (and allocate * space correctly) between job=2 and job=3 calls to MUMPS. * */ if ( dmumps_par->icntl[25-1] == -1 && dmumps_par->infog[28-1] > 0 ) { dmumps_par->nrhs=dmumps_par->infog[28-1]; donullspace = dosolve; } else if ( dmumps_par->icntl[25-1] > 0 && dmumps_par->icntl[25-1] <= dmumps_par->infog[28-1] ) { dmumps_par->nrhs=1; donullspace = dosolve; } else { donullspace=0; } if (donullspace) { nbrhs=dmumps_par->nrhs; ldrhs=n; dmumps_par->lrhs=(int)n; MYMALLOC((dmumps_par->rhs),((dmumps_par->n)*(dmumps_par->nrhs)),double2); } else if((!dosolve) || ptr_matlab[0] == -9999 ) { /* rhs not already provided, or not used */ /*JY: Case where dosolve is true and ptr_matlab[0]=-9999, this could cause problems: * 1/ RHS was not initialized while it should have been * 2/ RHS was explicitely initialized to -9999 but is not allocated of the right size */ EXTRACT_CMPLX_FROM_MATLAB_TOPTR(RHS,(dmumps_par->rhs),double,1); }else{
// Function definitions. // ----------------------------------------------------------------- void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //Input Args user_function_data fun, grad; iter_fun_data iterF; double *x0, *lb, *ub; //Options int printLevel = 0, maxIter = 1000, nupdate = 5, maxFeval = 1500; double ftol = 1e-7, pgtol = 1e-5, maxtime = 1000; iterF.enabled = false; //Outputs Args double *x, *fval, *exitflag, *iter, *feval; //Internal Vars size_t ndec; int iiter, nfeval; if (nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString(LBFGSB_VERSION); return; } //Check user inputs checkInputs(prhs,nrhs); try { //Get Size ndec = mxGetNumberOfElements(prhs[4]); //Get Function Handles 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; } if (mxIsChar(prhs[1])) { CHECK(mxGetString(prhs[1], grad.f, FLEN) == 0,"error reading gradient name string"); grad.nrhs = 1; grad.xrhs = 0; } else { grad.prhs[0] = (mxArray*)prhs[1]; strcpy(grad.f, "feval"); grad.nrhs = 2; grad.xrhs = 1; } fun.prhs[fun.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //x0 grad.prhs[grad.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //Get Bounds + x0 lb = mxGetPr(prhs[2]); ub = mxGetPr(prhs[3]); x0 = mxGetPr(prhs[4]); //Get Options if specified if(nrhs > 5) { GetIntegerOption(prhs[5], "display", &printLevel); GetIntegerOption(prhs[5], "maxiter", &maxIter); GetIntegerOption(prhs[5], "maxfeval", &maxFeval); GetIntegerOption(prhs[5], "nupdate", &nupdate); GetDoubleOption(prhs[5], "tolrfun", &ftol); GetDoubleOption(prhs[5], "tolrfun", &ftol); GetDoubleOption(prhs[5], "pgtol", &pgtol); GetDoubleOption(prhs[5], "maxtime", &maxtime); if(mxGetField(prhs[5],0,"iterfun") && !mxIsEmpty(mxGetField(prhs[5],0,"iterfun"))) { iterF.prhs[0] = (mxArray*)mxGetField(prhs[5],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]); //Create Class for Peter's L-BFGS-B Interface lbfgsb_program solver(&fun,&grad,&iterF,ndec,lb,ub,x0,x,fval,iter,printLevel,maxIter,maxFeval,maxtime,ftol,nupdate,pgtol); //Run the Solver int exitStatus = solver.runSolver(iiter,nfeval,*fval); //Save Status & Iterations *exitflag = (double)exitStatus; *iter = (double)iiter; *feval = (double)nfeval; } catch (std::exception& error) { mexErrMsgTxt(error.what()); } }
//Main Function void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) { //Input Args double *f, *blin = NULL, *lb = NULL, *ub = NULL, *y0 = NULL; //Return Args double *x, *pval, *dval, *exitflag, *iter, *pinf, *dinf, *realgap, *xzgap; //Options (most get defaults written in) int maxiter = 1500; //Internal Vars size_t ndec = 0, nlincon = 0, lincon_nz = 0, total_dim = 0, ncones = 0; size_t i, j; const char *onames[2] = {"pval","dval"}; const char *fnames[5] = {"iter","pinf","dinf","realgap","xzgap"}; double evaltime; int status = -1, nb = 0, linoffset = 0, indlb = 1, indub = 1, nLB = 0, nUB = 0; mwIndex *jc; //CSDP Problem Data struct blockmatrix C; double *b, *y, *xx, objconstant = 0.0; struct constraintmatrix *constraints; struct blockmatrix X, Z; struct sparseblock *blockptr; struct paramstruc params; //Version Return if(nrhs < 1) { if(nlhs < 1) printSolverInfo(); else plhs[0] = mxCreateString(CSDP_VERSION); return; } //Check Inputs checkInputs(prhs,nrhs); //Get pointers to Input variables f = mxGetPr(pF); ndec = mxGetNumberOfElements(pF); if(!mxIsEmpty(pA)) { blin = mxGetPr(pB); nlincon = mxGetM(pA); jc = mxGetJc(pA); lincon_nz = jc[ndec]; } if(nrhs > eLB && !mxIsEmpty(pLB)) { lb = mxGetPr(pLB); //Ensure we have at least one finite bound for(i=0,j=0;i<ndec;i++) if(mxIsInf(lb[i])) j++; if(j==ndec) lb = NULL; } if(nrhs > eUB && !mxIsEmpty(pUB)) { ub = mxGetPr(pUB); //Ensure we have at least one finite bound for(i=0,j=0;i<ndec;i++) if(mxIsInf(ub[i])) j++; if(j==ndec) ub = NULL; } if(nrhs > eSDP && !mxIsEmpty(pSDP)) { if(mxIsCell(pSDP)) ncones = mxGetNumberOfElements(pSDP); else ncones = 1; } if(nrhs > eY0 && !mxIsEmpty(pY0)) y0 = mxGetPr(pY0); //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,5,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)); iter = mxGetPr(mxGetField(plhs[3],0,fnames[0])); pinf = mxGetPr(mxGetField(plhs[3],0,fnames[1])); dinf = mxGetPr(mxGetField(plhs[3],0,fnames[2])); realgap = mxGetPr(mxGetField(plhs[3],0,fnames[3])); xzgap = mxGetPr(mxGetField(plhs[3],0,fnames[4])); //Set Defaults citer = 0; maxtime = 1000; printLevel = 0; //Allocate Initial Storage for the Problem b = (double*)malloc((ndec+1)*sizeof(double)); //objective vector //C matrices [LB UB LIN SD] nb = (int)ncones+(int)(nlincon>0)+(int)(lb!=NULL)+(int)(ub!=NULL); #ifdef DEBUG mexPrintf("Number of blocks (including bounds, linear and sdcones): %d\n",nb); #endif C.nblocks = nb; C.blocks = (struct blockrec*)malloc((nb+1)*sizeof(struct blockrec)); //+1 due to fortran index if(C.blocks == NULL) mexErrMsgTxt("Error allocating memory for C matrices"); //Constraints (i.e. 1 per decision variable) constraints = (struct constraintmatrix*)malloc((ndec+1)*sizeof(struct constraintmatrix)); //+1 due to fortran index if(constraints == NULL) { free(C.blocks); mexErrMsgTxt("Error allocating memory for A matrices"); } for(i=1;i<=ndec;i++) constraints[i].blocks=NULL; //initially set as NULL //Copy in and negate objective vector for(i=0;i<ndec;i++) b[i+1] = -f[i]; //Create Bounds if Present if(lb || ub) linoffset += addBounds(C,lb,ub,ndec,&nLB,&nUB); //Create Linear Cone (diagonal) if present if(nlincon) { //Initialize C C.blocks[linoffset+1].blockcategory = DIAG; C.blocks[linoffset+1].blocksize = (int)nlincon; C.blocks[linoffset+1].data.vec = (double*)malloc((nlincon+1)*sizeof(double)); if(C.blocks[linoffset+1].data.vec == NULL) mexErrMsgTxt("Error allocating memory for LP C diagonal"); #ifdef DEBUG mexPrintf("LP C[%d] Vector size: %d\n",linoffset+1,nlincon); #endif //Copy Elements for(i=0;i<nlincon;i++) { C.blocks[linoffset+1].data.vec[i+1] = -blin[i]; #ifdef DEBUG mexPrintf(" C vec[%d] = %f\n",i+1,-blin[i]); #endif } linoffset++; } #ifdef DEBUG mexPrintf("\nBlock offset after bounds + linear con: %d\n\n",linoffset); #endif //Setup Semidefinite C matrices (note all full matrices, dense, in order from 1) for(i=1;i<=ncones;i++) { //Single Cone if(ncones == 1 && !mxIsCell(pSDP)) total_dim += addCMatrix(C,pSDP,(int)i+linoffset); //Multiple Cones else total_dim += addCMatrix(C,mxGetCell(pSDP,i-1),(int)i+linoffset); } //Add Linear Dims total_dim += nLB+nUB+nlincon; #ifdef DEBUG mexPrintf("\nTotal dimension of all cones: %d\n\n",total_dim); #endif //Setup Each Constraint (for each decision var) (in order from 1) indlb = 1; indub = 1; for(i=1;i<=ndec;i++) { //For each Semidefinte A matrix (sparse triu, in reverse order, i.e. [SD, LP, UB, LB]) for(j=ncones;j>0;j--) { //Create an A matrix blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock)); if(blockptr==NULL) { sprintf(msgbuf,"Error allocating memory for Semidefinite A[%d,%d]",i,j+linoffset); mexErrMsgTxt(msgbuf); } //Single Cone if(ncones == 1 && !mxIsCell(pSDP)) addAMatrix(blockptr,pSDP,(int)i,(int)j+linoffset); //Multiple Cones else addAMatrix(blockptr,mxGetCell(pSDP,j-1),(int)i,(int)j+linoffset); //Insert A matrix into constraint list blockptr->next=constraints[i].blocks; constraints[i].blocks=blockptr; } //Linear Inequality Constraints if(nlincon) { //Create an A matrix blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock)); if(blockptr==NULL) { sprintf(msgbuf,"Error allocating memory for LP A[%d]",i); mexErrMsgTxt(msgbuf); } //Insert LP A entries j = 1 + (int)(nUB > 0) + (int)(nLB > 0); insertLPVector(blockptr, pA, (int)i, (int)j); //Insert A matrix into constraint list blockptr->next=constraints[i].blocks; constraints[i].blocks=blockptr; } //Upper Bounds if(nUB) { //Create an A matrix blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock)); if(blockptr==NULL) { sprintf(msgbuf,"Error allocating memory for UB A[%d]",i); mexErrMsgTxt(msgbuf); } //Insert Bound A matrix entries if(nLB > 0) indub += insertBound(blockptr,ub,nUB,(int)i,2,indub,1.0); //block 2 ([LB,UB,..] 1.0 for ub) else indub += insertBound(blockptr,ub,nUB,(int)i,1,indub,1.0); //block 1 (first block, 1.0 for ub) //Insert A matrix into constraint list blockptr->next=constraints[i].blocks; constraints[i].blocks=blockptr; } //Lower Bounds if(nLB) { //Create an A matrix blockptr=(struct sparseblock*)malloc(sizeof(struct sparseblock)); if(blockptr==NULL) { sprintf(msgbuf,"Error allocating memory for LB A[%d]",i); mexErrMsgTxt(msgbuf); } //Insert Bound A matrix entries indlb += insertBound(blockptr,lb,nLB,(int)i,1,indlb,-1.0); //block 1 (always first block, -1.0 for lb) //Insert A matrix into constraint list blockptr->next=constraints[i].blocks; constraints[i].blocks=blockptr; } } // //Set y0 // if (y0) // for (i=0;i<ndec;i++) { // DSDP_ERR( DSDPSetY0(dsdp,(int)i+1,y0[i]), "Error setting Y0"); // } // //Get CSDP Default Options initparams(¶ms,&printLevel); //Set OPTI default printLevel (none) printLevel = 0; //Get User Options (overwrites defaults above) if(nrhs > eOPTS && !mxIsEmpty(pOPTS)) { //OPTI Options GetIntegerOption(pOPTS,"maxiter",¶ms.maxiter); GetDoubleOption(pOPTS,"maxtime",&maxtime); GetIntegerOption(pOPTS,"display",&printLevel); GetDoubleOption(pOPTS,"objconstant",&objconstant); //CSDP Options GetDoubleOption(pOPTS,"axtol",¶ms.axtol); GetDoubleOption(pOPTS,"atytol",¶ms.atytol); GetDoubleOption(pOPTS,"objtol",¶ms.objtol); GetDoubleOption(pOPTS,"pinftol",¶ms.pinftol); GetDoubleOption(pOPTS,"dinftol",¶ms.dinftol); GetDoubleOption(pOPTS,"minstepfrac",¶ms.minstepfrac); GetDoubleOption(pOPTS,"maxstepfrac",¶ms.maxstepfrac); GetDoubleOption(pOPTS,"minstepp",¶ms.minstepp); GetDoubleOption(pOPTS,"minstepd",¶ms.minstepd); GetIntegerOption(pOPTS,"usexzgap",¶ms.usexzgap); GetIntegerOption(pOPTS,"tweakgap",¶ms.tweakgap); GetIntegerOption(pOPTS,"affine",¶ms.affine); GetDoubleOption(pOPTS,"perturbobj",¶ms.perturbobj); //Optionally write problem to a SDPA sparse file if(mxGetField(pOPTS,0,"writeprob") && !mxIsEmpty(mxGetField(pOPTS,0,"writeprob")) && mxIsChar(mxGetField(pOPTS,0,"writeprob"))) { mxGetString(mxGetField(pOPTS,0,"writeprob"),msgbuf,1024); write_prob(msgbuf,(int)total_dim,(int)ndec,C,b,constraints); } } //Print Header if(printLevel) { mexPrintf("\n------------------------------------------------------------------\n"); mexPrintf(" This is CSDP v%s\n",CSDP_VERSION); mexPrintf(" Author: Brian Borchers\n MEX Interface J. Currie 2013\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(); //Find Initial Solution initsoln((int)total_dim,(int)ndec,C,b,constraints,&X,&y,&Z); //Solve the problem status=easy_sdp((int)total_dim,(int)ndec,C,b,constraints,objconstant,params,&X,&y,&Z,pval,dval,pinf,dinf,realgap,xzgap); //Stop Timer end = clock(); evaltime = ((double)(end-start))/CLOCKS_PER_SEC; //Copy and negate solution for(i=0;i<ndec;i++) x[i] = -y[i+1]; //Assign other MATLAB outputs *iter = (double)citer-1; *exitflag = (double)status; //Print Header if(printLevel){ //Detail termination reason switch(status) { //Success case 0: mexPrintf("\n *** CSDP CONVERGED ***\n"); break; //Infeasible case 1: mexPrintf("\n *** TERMINATION: Primal Infeasible ***\n"); break; case 2: mexPrintf("\n *** TERMINATION: Dual Infeasible ***\n"); break; //Partial Success case 3: mexPrintf("\n *** TERMINATION: PARTIAL SUCESS ***\n *** A Solution is found but full accuracy was not achieved ***\n"); break; //Error case 4: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Maximum Iterations Reached ***\n"); break; case CSDP_MAX_TIME: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Maximum Time Reached ***\n"); break; case 5: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Stuck at edge of primal feasibility ***\n"); break; case 6: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Stuck at edge of dual infeasibility ***\n"); break; case 7: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Lack of progress ***\n"); break; case 8: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: X, Z, or O was singular ***\n"); break; case 9: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Detected NaN or Inf values ***\n"); break; case 10: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Easy-SDP General Failure ***\n"); break; case 11: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Failed C Check - Check Symmetry! ***\n"); break; case 12: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: Failed Constraints Check ***\n"); break; case CSDP_USER_TERMINATION: mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: User Exited ***\n"); break; //Here is ok too? default: mexPrintf("\n *** CSDP FINISHED ***\n"); break; } if(status==0 || status==3) mexPrintf("\n Final Primal Objective: %2.5g\n Final Dual Objective: %2.5g\n In %5d iterations\n %5.2f seconds\n",*pval,*dval,citer-1,evaltime); mexPrintf("------------------------------------------------------------------\n\n"); } //Optionally write solution to a SDPA sparse file if(nrhs > eOPTS && !mxIsEmpty(pOPTS) && mxGetField(pOPTS,0,"writesol") && !mxIsEmpty(mxGetField(pOPTS,0,"writesol")) && mxIsChar(mxGetField(pOPTS,0,"writesol"))) { mxGetString(mxGetField(pOPTS,0,"writesol"),msgbuf,1024); write_sol(msgbuf,(int)total_dim,(int)ndec,X,y,Z); } //Optionally retrieve X if(nlhs > 4) { plhs[4] = mxCreateCellMatrix(X.nblocks,1); for(i=0;i<X.nblocks;i++) { //Set Block Values if(X.blocks[i+1].blockcategory == DIAG) { mxSetCell(plhs[4],i,mxCreateDoubleMatrix(X.blocks[i+1].blocksize,1,mxREAL)); //create vector xx = mxGetPr(mxGetCell(plhs[4],i)); for(j=0;j<X.blocks[i+1].blocksize;j++) xx[j] = X.blocks[i+1].data.vec[j+1]; } else { mxSetCell(plhs[4],i,mxCreateDoubleMatrix(X.blocks[i+1].blocksize,X.blocks[i+1].blocksize,mxREAL)); //create matrix xx = mxGetPr(mxGetCell(plhs[4],i)); for(j=0;j<(X.blocks[i+1].blocksize*X.blocks[i+1].blocksize);j++) xx[j] = X.blocks[i+1].data.mat[j]; } } } //Free CSDP Problem (including all allocated memory) free_prob((int)total_dim,(int)ndec,C,b,constraints,X,y,Z); }