// Filename: loqo.c // // Description: MATLAB interface for LOQO Optimiser // // Comments: Quadratic and Linear Programming // // Author: Steve Gunn (S.R.Gunn@ecs.soton.ac.uk) #include #include #include "mex.h" #include "pr_loqo.h" #define Inf 1e30 void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) { double *c=NULL, *b=NULL, *A=NULL, *Q=NULL, *H=NULL, *l=NULL, *u=NULL, *x=NULL, *lambda=NULL, *x0=NULL, *primal=NULL, *dual=NULL; double *tmpdp=NULL; double big=Inf; unsigned int neq=0; long nmat=0, mmat=0; long how=0; int i; unsigned int verb = 0; double sigfig_max = 8; int counter_max = 100000; double margin = 0.95; double bound = 10; int restart = 0; static char *str[] = { "STILL_RUNNING", "OPTIMAL_SOLUTION", "SUBOPTIMAL_SOLUTION", "ITERATION_LIMIT", "PRIMAL_INFEASIBLE", "DUAL_INFEASIBLE", "PRIMAL_AND_DUAL_INFEASIBLE", "INCONSISTENT", "PRIMAL_UNBOUNDED", "DUAL_UNBOUNDED", "TIME_LIMIT"}; if (nrhs > 9 || nrhs < 1) { mexErrMsgTxt("Usage: [x,lambda,how] = loqo(H,c,A,b,l,u,x0,neqcstr,verbosity)"); return; } switch (nrhs) { case 9: if (mxGetM(prhs[8]) != 0 || mxGetN(prhs[8]) != 0) { if (!mxIsNumeric(prhs[8]) || mxIsComplex(prhs[8]) || mxIsSparse(prhs[8]) || !(mxGetM(prhs[8])==1 && mxGetN(prhs[8])==1)) { mexErrMsgTxt("Ninth argument (display) must be " "an integer scalar."); return; } verb = (unsigned int)*mxGetPr(prhs[8]); } case 8: if (mxGetM(prhs[7]) != 0 || mxGetN(prhs[7]) != 0) { if (!mxIsNumeric(prhs[7]) || mxIsComplex(prhs[7]) || mxIsSparse(prhs[7]) || !(mxGetM(prhs[7])==1 && mxGetN(prhs[7])==1)) { mexErrMsgTxt("Eighth argument (neqcstr) must be " "an integer scalar."); return; } neq = (unsigned int)*mxGetPr(prhs[7]); } case 7: if (mxGetM(prhs[6]) != 0 || mxGetN(prhs[6]) != 0) { if (!mxIsNumeric(prhs[6]) || mxIsComplex(prhs[6]) || mxIsSparse(prhs[6]) || !mxIsDouble(prhs[6]) || mxGetN(prhs[6])!=1 ) { mexErrMsgTxt("Seventh argument (x0) must be " "a column vector."); return; } x0 = mxGetPr(prhs[6]); nmat = mxGetM(prhs[6]); } case 6: if (mxGetM(prhs[5]) != 0 || mxGetN(prhs[5]) != 0) { if (!mxIsNumeric(prhs[5]) || mxIsComplex(prhs[5]) || mxIsSparse(prhs[5]) || !mxIsDouble(prhs[5]) || mxGetN(prhs[5])!=1 ) { mexErrMsgTxt("Sixth argument (u) must be " "a column vector."); return; } if (nmat != 0 && nmat != mxGetM(prhs[5])) { mexErrMsgTxt("Dimension error (arg 6 and later)."); return; } u = mxGetPr(prhs[5]); nmat = mxGetM(prhs[5]); } case 5: if (mxGetM(prhs[4]) != 0 || mxGetN(prhs[4]) != 0) { if (!mxIsNumeric(prhs[4]) || mxIsComplex(prhs[4]) || mxIsSparse(prhs[4]) || !mxIsDouble(prhs[4]) || mxGetN(prhs[4])!=1 ) { mexErrMsgTxt("Fifth argument (l) must be " "a column vector."); return; } if (nmat != 0 && nmat != mxGetM(prhs[4])) { mexErrMsgTxt("Dimension error (arg 5 and later)."); return; } l = mxGetPr(prhs[4]); nmat = mxGetM(prhs[4]); } case 4: if (mxIsEmpty(prhs[3])) { // No Constraints mmat = 0; } else { // Constraints if (mxGetM(prhs[3]) != 0 || mxGetN(prhs[3]) != 0) { if (!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) || mxIsSparse(prhs[3]) || !mxIsDouble(prhs[3]) || mxGetN(prhs[3])!=1 ) { mexErrMsgTxt("Fourth argument (b) must be " "a column vector."); return; } if (mmat != 0 && mmat != mxGetM(prhs[3])) { mexErrMsgTxt("Dimension error (arg 4 and later)."); return; } b = mxGetPr(prhs[3]); } } case 3: if (mxIsEmpty(prhs[2])) { // No Constraints if (mmat != 0) { mexErrMsgTxt("Dimension error (arg 3 and later)."); return; } } else { // Constraints if (mxGetM(prhs[2]) != 0 || mxGetN(prhs[2]) != 0) { if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2]) ) { mexErrMsgTxt("Third argument (A) must be " "a matrix."); return; } if (mmat != 0 && mmat != mxGetM(prhs[2])) { mexErrMsgTxt("Dimension error (arg 3 and later)."); return; } if (nmat != 0 && nmat != mxGetN(prhs[2])) { mexErrMsgTxt("Dimension error (arg 3 and later)."); return; } mmat = mxGetM(prhs[2]); nmat = mxGetN(prhs[2]); A = mxGetPr(prhs[2]); } } tmpdp = (double *)malloc((nmat+mmat)*sizeof(double)); for(i=0;i Inf ? Inf : u[i]); u = tmpdp; /* Equality constraints */ for(i=nmat;i<(int)(nmat+neq);i++) { l[i] = u[i] = 0; } /* InEquality constraints */ for(i=nmat + neq;i 3 || nlhs < 1) { mexErrMsgTxt("Usage: [x,lambda,how] = loqo(H,c,A,b,l,u,x0,neqcstr,verbosity)"); return; } primal = (double *)calloc((3*nmat),sizeof(double)); dual = (double *)calloc((mmat+2*nmat),sizeof(double)); how = pr_loqo(nmat, mmat, c, H, A, b, l, u, primal, dual, verb, sigfig_max, counter_max, margin, bound, restart); switch (nlhs) { case 3: plhs[2] = mxCreateString(str[how]); case 2: plhs[1] = mxCreateDoubleMatrix(mmat, 1, mxREAL); lambda = mxGetPr(plhs[1]); for(i=0; i