Beispiel #1
0
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] = qp(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<nmat;i++) tmpdp[i] = (l[i] < -Inf ? -Inf : l[i]);
		l = tmpdp;
		tmpdp = (double *)malloc((nmat+mmat)*sizeof(double));
		for(i=0;i<nmat;i++) tmpdp[i] = (u[i] > Inf ? Inf : u[i]);
		u = tmpdp;

		for(i=nmat;i<(int)(nmat+neq);i++) { l[i] = u[i] = 0; }

		for(i=nmat + neq;i<nmat+mmat;i++) { l[i] = -Inf; u[i] = 0; }
    case 2:
	    if (mxGetM(prhs[1]) != 0 || mxGetN(prhs[1]) != 0) {
		    if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) 
		     ||  mxIsSparse(prhs[1])
		     || !mxIsDouble(prhs[1]) 
		     ||  mxGetN(prhs[1])!=1 ) {
			 mexErrMsgTxt("Second argument (c) must be "
				      "a column vector.");
			 return;
		    }
		    if (nmat != 0 && nmat != mxGetM(prhs[1])) {
			 mexErrMsgTxt("Dimension error (arg 2 and later).");
			 return;
		    }
		    c = mxGetPr(prhs[1]);
		    nmat = mxGetM(prhs[1]);
	    }
    case 1:
		if (mxIsEmpty(prhs[0]))
		{ 
			H = (double *)calloc(nmat*nmat,sizeof(double));
		}
		else
		{
	        if (mxGetM(prhs[0]) != 0 || mxGetN(prhs[0]) != 0) {
				if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) 
				 || mxIsSparse(prhs[0]) ) {
				 mexErrMsgTxt("First argument (H) must be "
						  "a matrix.");
				 return;
				}
				if (nmat != 0 && nmat != mxGetM(prhs[0])) {
				 mexErrMsgTxt("Dimension error (arg 1 and later).");
				 return;
				}
				if (nmat != 0 && nmat != mxGetN(prhs[0])) {
				 mexErrMsgTxt("Dimension error (arg 1 and later).");
				 return;
				}
				nmat = mxGetN(prhs[0]);
				Q = mxGetPr(prhs[0]);
				H = (double *)calloc(nmat*nmat,sizeof(double));
				for(i=0;i<nmat*nmat;i++) H[i] = Q[i];
			}
		}
	    break;
    }

    if (nlhs > 3 || nlhs < 1) {
	    mexErrMsgTxt("Usage: [x,lambda,how] = qp(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<mmat; i++) lambda[i] = dual[i];
    case 1:
	    plhs[0] = mxCreateDoubleMatrix(nmat, 1, mxREAL);
	    x = mxGetPr(plhs[0]);
		for(i=0; i<nmat; i++) x[i] = primal[i];
	    break;
    }

	/* Free up memory */
	free(l);
	free(u);
	free(primal);
	free(dual);
	free(H);

}
Beispiel #2
0
double *optimize_qp2(
QP *qp,
double *epsilon_crit,
long nx, /* Maximum number of variables in QP */
double *threshold,
LEARN_PARM *learn_parm)
/* start the optimizer and return the optimal values */
{
  register long i,j,result;
  double margin,obj_before,obj_after;
  double sigdig,dist,epsilon_loqo;
  int iter;
 
  if(!primal1) { /* allocate memory at first call */
    primal1=(double *)my_malloc(sizeof(double)*nx*3);
    dual1=(double *)my_malloc(sizeof(double)*(nx*2+1));
  }
  
  if(verbosity3>=4) { /* really verbose */
    printf("\n\n");
    for(i=0;i<qp->opt_n;i++) {
      printf("%f: ",qp->opt_g0[i]);
      for(j=0;j<qp->opt_n;j++) {
	printf("%f ",qp->opt_g[i*qp->opt_n+j]);
      }
      printf(": a%ld=%.10f < %f",i,qp->opt_xinit[i],qp->opt_up[i]);
      printf(": y=%f\n",qp->opt_ce[i]);
    }
    for(j=0;j<qp->opt_m;j++) {
      printf("EQ-%ld: %f*a0",j,qp->opt_ce[j]);
      for(i=1;i<qp->opt_n;i++) {
	printf(" + %f*a%ld",qp->opt_ce[i],i);
      }
      printf(" = %f\n\n",-qp->opt_ce0[0]);
    }
}

  obj_before=0; /* calculate objective before optimization */
  for(i=0;i<qp->opt_n;i++) {
    obj_before+=(qp->opt_g0[i]*qp->opt_xinit[i]);
    obj_before+=(0.5*qp->opt_xinit[i]*qp->opt_xinit[i]*qp->opt_g[i*qp->opt_n+i]);
    for(j=0;j<i;j++) {
      obj_before+=(qp->opt_xinit[j]*qp->opt_xinit[i]*qp->opt_g[j*qp->opt_n+i]);
    }
  }

  result=STILL_RUNNING;
  qp->opt_ce0[0]*=(-1.0);
  /* Run pr_loqo. If a run fails, try again with parameters which lead */
  /* to a slower, but more robust setting. */
  for(margin=init_margin,iter=init_iter;
      (margin<=0.9999999) && (result!=OPTIMAL_SOLUTION);) {
    sigdig=-log10(opt_precision2);

    result=pr_loqo((int)qp->opt_n,(int)qp->opt_m,
		   (double *)qp->opt_g0,(double *)qp->opt_g,
		   (double *)qp->opt_ce,(double *)qp->opt_ce0,
		   (double *)qp->opt_low,(double *)qp->opt_up,
		   (double *)primal1,(double *)dual1, 
		   (int)(verbosity3-2),
		   (double)sigdig,(int)iter, 
		   (double)margin,(double)(qp->opt_up[0])/4.0,(int)0);

    if(isnan(dual1[0])) {     /* check for choldc problem */
      if(verbosity3>=2) {
	printf("NOTICE: Restarting PR_LOQO with more conservative parameters.\n");
      }
      if(init_margin<0.80) { /* become more conservative in general */
	init_margin=(4.0*margin+1.0)/5.0;
      }
      margin=(margin+1.0)/2.0;
      (opt_precision2)*=10.0;   /* reduce precision */
      if(verbosity3>=2) {
	printf("NOTICE: Reducing precision of PR_LOQO.\n");
      }
    }
    else if(result!=OPTIMAL_SOLUTION) {
      iter+=2000; 
      init_iter+=10;
      (opt_precision2)*=10.0;   /* reduce precision */
      if(verbosity3>=2) {
	printf("NOTICE: Reducing precision of PR_LOQO due to (%ld).\n",result);
      }      
    }
  }

  if(qp->opt_m)         /* Thanks to Alex Smola for this hint */
    model_b=dual1[0];
  else
    model_b=0;

  /* Check the precision of the alphas. If results of current optimization */
  /* violate KT-Conditions, relax the epsilon on the bounds on alphas. */
  epsilon_loqo=1E-10;
  for(i=0;i<qp->opt_n;i++) {
    dist=-model_b*qp->opt_ce[i]; 
    dist+=(qp->opt_g0[i]+1.0);
    for(j=0;j<i;j++) {
      dist+=(primal1[j]*qp->opt_g[j*qp->opt_n+i]);
    }
    for(j=i;j<qp->opt_n;j++) {
      dist+=(primal1[j]*qp->opt_g[i*qp->opt_n+j]);
    }
    /*  printf("LOQO: a[%d]=%f, dist=%f, b=%f\n",i,primal1[i],dist,dual1[0]); */
    if((primal1[i]<(qp->opt_up[i]-epsilon_loqo)) && (dist < (1.0-(*epsilon_crit)))) {
      epsilon_loqo=(qp->opt_up[i]-primal1[i])*2.0;
    }
    else if((primal1[i]>(0+epsilon_loqo)) && (dist > (1.0+(*epsilon_crit)))) {
      epsilon_loqo=primal1[i]*2.0;
    }
  }

  for(i=0;i<qp->opt_n;i++) {  /* clip alphas to bounds */
    if(primal1[i]<=(0+epsilon_loqo)) {
      primal1[i]=0;
    }
    else if(primal1[i]>=(qp->opt_up[i]-epsilon_loqo)) {
      primal1[i]=qp->opt_up[i];
    }
  }

  obj_after=0;  /* calculate objective after optimization */
  for(i=0;i<qp->opt_n;i++) {
    obj_after+=(qp->opt_g0[i]*primal1[i]);
    obj_after+=(0.5*primal1[i]*primal1[i]*qp->opt_g[i*qp->opt_n+i]);
    for(j=0;j<i;j++) {
      obj_after+=(primal1[j]*primal1[i]*qp->opt_g[j*qp->opt_n+i]);
    }
  }

  /* if optimizer returned NAN values, reset and retry with smaller */
  /* working set. */
  if(isnan(obj_after) || isnan(model_b)) {
    for(i=0;i<qp->opt_n;i++) {
      primal1[i]=qp->opt_xinit[i];
    }     
    model_b=0;
    if(learn_parm->svm_maxqpsize>2) {
      learn_parm->svm_maxqpsize--;  /* decrease size of qp-subproblems */
    }
  }

  if(obj_after >= obj_before) { /* check whether there was progress */
    (opt_precision2)/=100.0;
    precision_violations2++;
    if(verbosity3>=2) {
      printf("NOTICE: Increasing Precision of PR_LOQO.\n");
    }
  }

  if(precision_violations2 > 500) { 
    (*epsilon_crit)*=10.0;
    precision_violations2=0;
    if(verbosity3>=1) {
      printf("\nWARNING: Relaxing epsilon on KT-Conditions.\n");
    }
  }	  

  (*threshold)=model_b;

  if(result!=OPTIMAL_SOLUTION) {
    printf("\nERROR: PR_LOQO did not converge. \n");
    return(qp->opt_xinit);
  }
  else {
    return(primal1);
  }
}