qp.c
上传用户:xfjled
上传日期:2007-05-06
资源大小:150k
文件大小:7k
源码类别:

matlab例程

开发平台:

Matlab

  1. // Filename: qp.c
  2. // 
  3. // Description: MATLAB interface for LOQO Optimiser
  4. // 
  5. // Comments: Quadratic and Linear Programming
  6. // 
  7. // Author: Steve Gunn (S.R.Gunn@ecs.soton.ac.uk)
  8. //         Modified from code by R. Vanderbei.
  9. #include <math.h>
  10. #include <stdio.h>
  11. #include "mex.h"
  12. #include "pr_loqo.h"
  13. #define Inf 1e30
  14. void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
  15. {
  16.     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;
  17.     double *tmpdp=NULL;
  18.     double big=Inf;
  19.     unsigned int neq=0;
  20.     long nmat=0, mmat=0;
  21.     long how=0;
  22.     int i;
  23.     unsigned int verb = 0;
  24.     double sigfig_max = 8;
  25.     int counter_max = 100000;
  26.     double margin = 0.95;
  27.     double bound = 10; 
  28.     int restart = 0;
  29.     static char *str[] = {
  30. "STILL_RUNNING",
  31. "OPTIMAL_SOLUTION",
  32. "SUBOPTIMAL_SOLUTION",
  33. "ITERATION_LIMIT",
  34. "PRIMAL_INFEASIBLE",
  35. "DUAL_INFEASIBLE",
  36. "PRIMAL_AND_DUAL_INFEASIBLE",
  37. "INCONSISTENT",
  38. "PRIMAL_UNBOUNDED",
  39. "DUAL_UNBOUNDED",
  40. "TIME_LIMIT"};
  41.     if (nrhs > 9 || nrhs < 1) {
  42.     mexErrMsgTxt("Usage: [x,lambda,how] = qp(H,c,A,b,l,u,x0,neqcstr,verbosity)");
  43.     return;
  44.     }
  45.     switch (nrhs) {
  46.     case 9:
  47. if (mxGetM(prhs[8]) != 0 || mxGetN(prhs[8]) != 0) {
  48.     if (!mxIsNumeric(prhs[8]) || mxIsComplex(prhs[8]) 
  49.      ||  mxIsSparse(prhs[8])
  50.      || !(mxGetM(prhs[8])==1 && mxGetN(prhs[8])==1)) {
  51.  mexErrMsgTxt("Ninth argument (display) must be "
  52.       "an integer scalar.");
  53.  return;
  54.     }
  55.     verb = (unsigned int)*mxGetPr(prhs[8]);
  56.     }
  57.     case 8:
  58. if (mxGetM(prhs[7]) != 0 || mxGetN(prhs[7]) != 0) {
  59.     if (!mxIsNumeric(prhs[7]) || mxIsComplex(prhs[7]) 
  60.      ||  mxIsSparse(prhs[7])
  61.      || !(mxGetM(prhs[7])==1 && mxGetN(prhs[7])==1)) {
  62.  mexErrMsgTxt("Eighth argument (neqcstr) must be "
  63.       "an integer scalar.");
  64.  return;
  65.     }
  66.     neq = (unsigned int)*mxGetPr(prhs[7]);
  67.     }
  68.     case 7:
  69. if (mxGetM(prhs[6]) != 0 || mxGetN(prhs[6]) != 0) {
  70. if (!mxIsNumeric(prhs[6]) || mxIsComplex(prhs[6]) 
  71.  ||  mxIsSparse(prhs[6])
  72.  || !mxIsDouble(prhs[6]) 
  73.  ||  mxGetN(prhs[6])!=1 ) {
  74.  mexErrMsgTxt("Seventh argument (x0) must be "
  75.   "a column vector.");
  76.  return;
  77. }
  78. x0 = mxGetPr(prhs[6]);
  79. nmat = mxGetM(prhs[6]);
  80.         }
  81.     case 6:
  82.     if (mxGetM(prhs[5]) != 0 || mxGetN(prhs[5]) != 0) {
  83.     if (!mxIsNumeric(prhs[5]) || mxIsComplex(prhs[5]) 
  84.      ||  mxIsSparse(prhs[5])
  85.      || !mxIsDouble(prhs[5]) 
  86.      ||  mxGetN(prhs[5])!=1 ) {
  87.  mexErrMsgTxt("Sixth argument (u) must be "
  88.       "a column vector.");
  89.  return;
  90.     }
  91.     if (nmat != 0 && nmat != mxGetM(prhs[5])) {
  92.  mexErrMsgTxt("Dimension error (arg 6 and later).");
  93.  return;
  94.     }
  95.     u = mxGetPr(prhs[5]);
  96. nmat = mxGetM(prhs[5]);
  97.     }
  98.     case 5:
  99.     if (mxGetM(prhs[4]) != 0 || mxGetN(prhs[4]) != 0) {
  100.     if (!mxIsNumeric(prhs[4]) || mxIsComplex(prhs[4]) 
  101.      ||  mxIsSparse(prhs[4])
  102.      || !mxIsDouble(prhs[4]) 
  103.      ||  mxGetN(prhs[4])!=1 ) {
  104.  mexErrMsgTxt("Fifth argument (l) must be "
  105.       "a column vector.");
  106.  return;
  107.     }
  108.     if (nmat != 0 && nmat != mxGetM(prhs[4])) {
  109.  mexErrMsgTxt("Dimension error (arg 5 and later).");
  110.  return;
  111.     }
  112.     l = mxGetPr(prhs[4]);
  113. nmat = mxGetM(prhs[4]);
  114.     }
  115.     case 4:
  116. if (mxIsEmpty(prhs[3]))
  117. { // No Constraints
  118. mmat = 0;
  119. }
  120. else
  121. { // Constraints
  122. if (mxGetM(prhs[3]) != 0 || mxGetN(prhs[3]) != 0) {
  123. if (!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) 
  124.  ||  mxIsSparse(prhs[3])
  125.  || !mxIsDouble(prhs[3]) 
  126.  ||  mxGetN(prhs[3])!=1 ) {
  127.  mexErrMsgTxt("Fourth argument (b) must be "
  128.   "a column vector.");
  129.  return;
  130. }
  131. if (mmat != 0 && mmat != mxGetM(prhs[3])) {
  132.  mexErrMsgTxt("Dimension error (arg 4 and later).");
  133.  return;
  134. }
  135. b = mxGetPr(prhs[3]);
  136. }
  137. }
  138.     case 3:
  139. if (mxIsEmpty(prhs[2]))
  140. { // No Constraints
  141. if (mmat != 0) {
  142. mexErrMsgTxt("Dimension error (arg 3 and later).");
  143. return;
  144. }
  145. }
  146. else
  147. { // Constraints
  148. if (mxGetM(prhs[2]) != 0 || mxGetN(prhs[2]) != 0) {
  149. if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) 
  150.  || mxIsSparse(prhs[2]) ) {
  151.  mexErrMsgTxt("Third argument (A) must be "
  152.   "a matrix.");
  153.  return;
  154. }
  155. if (mmat != 0 && mmat != mxGetM(prhs[2])) {
  156.  mexErrMsgTxt("Dimension error (arg 3 and later).");
  157.  return;
  158. }
  159. if (nmat != 0 && nmat != mxGetN(prhs[2])) {
  160.  mexErrMsgTxt("Dimension error (arg 3 and later).");
  161.  return;
  162. }
  163. mmat = mxGetM(prhs[2]);
  164. nmat = mxGetN(prhs[2]);
  165. A = mxGetPr(prhs[2]);
  166. }
  167. }
  168. tmpdp = (double *)malloc((nmat+mmat)*sizeof(double));
  169. for(i=0;i<nmat;i++) tmpdp[i] = (l[i] < -Inf ? -Inf : l[i]);
  170. l = tmpdp;
  171. tmpdp = (double *)malloc((nmat+mmat)*sizeof(double));
  172. for(i=0;i<nmat;i++) tmpdp[i] = (u[i] > Inf ? Inf : u[i]);
  173. u = tmpdp;
  174. /* Equality constraints */
  175. for(i=nmat;i<(int)(nmat+neq);i++) { l[i] = u[i] = 0; }
  176. /* InEquality constraints */
  177. for(i=nmat + neq;i<nmat+mmat;i++) { l[i] = -Inf; u[i] = 0; }
  178.     case 2:
  179.     if (mxGetM(prhs[1]) != 0 || mxGetN(prhs[1]) != 0) {
  180.     if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) 
  181.      ||  mxIsSparse(prhs[1])
  182.      || !mxIsDouble(prhs[1]) 
  183.      ||  mxGetN(prhs[1])!=1 ) {
  184.  mexErrMsgTxt("Second argument (c) must be "
  185.       "a column vector.");
  186.  return;
  187.     }
  188.     if (nmat != 0 && nmat != mxGetM(prhs[1])) {
  189.  mexErrMsgTxt("Dimension error (arg 2 and later).");
  190.  return;
  191.     }
  192.     c = mxGetPr(prhs[1]);
  193.     nmat = mxGetM(prhs[1]);
  194.     }
  195.     case 1:
  196. if (mxIsEmpty(prhs[0]))
  197. { // Linear Program
  198. H = (double *)calloc(nmat*nmat,sizeof(double));
  199. }
  200. else
  201. { // Quadratic Program
  202.         if (mxGetM(prhs[0]) != 0 || mxGetN(prhs[0]) != 0) {
  203. if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) 
  204.  || mxIsSparse(prhs[0]) ) {
  205.  mexErrMsgTxt("First argument (H) must be "
  206.   "a matrix.");
  207.  return;
  208. }
  209. if (nmat != 0 && nmat != mxGetM(prhs[0])) {
  210.  mexErrMsgTxt("Dimension error (arg 1 and later).");
  211.  return;
  212. }
  213. if (nmat != 0 && nmat != mxGetN(prhs[0])) {
  214.  mexErrMsgTxt("Dimension error (arg 1 and later).");
  215.  return;
  216. }
  217. nmat = mxGetN(prhs[0]);
  218. Q = mxGetPr(prhs[0]);
  219. H = (double *)calloc(nmat*nmat,sizeof(double));
  220. for(i=0;i<nmat*nmat;i++) H[i] = Q[i];
  221. }
  222. }
  223.     break;
  224.     }
  225.     if (nlhs > 3 || nlhs < 1) {
  226.     mexErrMsgTxt("Usage: [x,lambda,how] = qp(H,c,A,b,l,u,x0,neqcstr,verbosity)");
  227.     return;
  228.     }
  229. primal = (double *)calloc((3*nmat),sizeof(double));
  230. dual = (double *)calloc((mmat+2*nmat),sizeof(double));
  231.     how = pr_loqo(nmat, mmat, c, H, A, b, l, u, primal, dual, verb, sigfig_max, counter_max, margin, bound, restart);
  232.     switch (nlhs) {
  233.     case 3:
  234.     plhs[2] = mxCreateString(str[how]);
  235.     case 2:
  236.     plhs[1] = mxCreateDoubleMatrix(mmat, 1, mxREAL);
  237.     lambda = mxGetPr(plhs[1]);
  238. for(i=0; i<mmat; i++) lambda[i] = dual[i];
  239.     case 1:
  240.     plhs[0] = mxCreateDoubleMatrix(nmat, 1, mxREAL);
  241.     x = mxGetPr(plhs[0]);
  242. for(i=0; i<nmat; i++) x[i] = primal[i];
  243.     break;
  244.     }
  245. /* Free up memory */
  246. free(l);
  247. free(u);
  248. free(primal);
  249. free(dual);
  250. free(H);
  251. }