예제 #1
0
파일: QPSolver.cpp 프로젝트: jietan/src
bool QPSolver::solve(VectorXd& sol)
{
    bool ret = false;
#ifdef _WIN32
    VectorXd solution;
	preSolve();
	convertMatrixVectorFormat();
	MSKenv_t env;
	MSKtask_t task;
	MSKrescodee r;

	r = MSK_makeenv(&env, NULL, NULL, NULL, NULL);
	if (r == MSK_RES_OK)
	{
		r = MSK_linkfunctoenvstream(env, MSK_STREAM_LOG, NULL, printstr);
	}

	r = MSK_initenv(env);
	if (r == MSK_RES_OK)
	{
		r = MSK_maketask(env, mNumCon, mNumVar, &task);
		if (r == MSK_RES_OK)
		{
			r = MSK_linkfunctotaskstream(task, MSK_STREAM_LOG, NULL, printstr);
		}

		if (r == MSK_RES_OK)
			r = MSK_putmaxnumvar(task, mNumVar);
		if (r == MSK_RES_OK)
			r = MSK_putmaxnumcon(task, mNumCon);

		/* Append ¡¯NUMCON ¡¯ empty constraints .
		 The constraints will initially have no bounds . */
		if (r == MSK_RES_OK)
			r = MSK_append(task, MSK_ACC_CON, mNumCon);
		/* Append ¡¯NUMVAR ¡¯ variables .
		 The variables will initially be fixed at zero (x =0). */
		if (r == MSK_RES_OK)
			r = MSK_append(task, MSK_ACC_VAR, mNumVar);

		/* Optionally add a constant term to the objective . */
		if (r == MSK_RES_OK)
			r = MSK_putcfix(task, mConstant);

		for (int j = 0; j < mNumVar && r == MSK_RES_OK; ++j)
		{
			/* Set the linear term c_j in the objective .*/
			if (r == MSK_RES_OK)
				r = MSK_putcj(task, j, mCU[j]);
			/* Set the bounds on variable j.*/
			if (r == MSK_RES_OK)
			{
				if (mbLowerBounded[j] && mbUpperBounded[j])
				{
					if (mlb[j] == mub[j])
						r = MSK_putbound(task, MSK_ACC_VAR, j, MSK_BK_FX, mlb[j], mub[j]);
					else
					{
						CHECK(mlb[j] < mub[j]);
						r = MSK_putbound(task, MSK_ACC_VAR, j, MSK_BK_RA, mlb[j], mub[j]);
					}
				}
				else if (mbLowerBounded[j])
				{
					r = MSK_putbound(task, MSK_ACC_VAR, j , MSK_BK_LO, mlb[j], +MSK_INFINITY);
				}
				else if (mbUpperBounded[j])
				{
					r = MSK_putbound(task, MSK_ACC_VAR, j, MSK_BK_UP, -MSK_INFINITY, mub[j]);
				}	
				else
				{
					r = MSK_putbound(task, MSK_ACC_VAR, j, MSK_BK_FR, -MSK_INFINITY, +MSK_INFINITY);
				}
			}
			/* Input column j of A */
			if (r == MSK_RES_OK && mNumCon)
			{
				int currentColumnIdx = mAColumnStartIdx[j];
				int nextColumnIdx = mAColumnStartIdx[j + 1];
				r = MSK_putavec(task, MSK_ACC_VAR, j, nextColumnIdx - currentColumnIdx, &(mARowIdx[currentColumnIdx]), &(mAValues[currentColumnIdx]));
			}
		}
		/* Set the bounds on constraints .
		 for i=1, ... , NUMCON : blc [i] <= constraint i <= buc [i] */
		for (int i = 0; i < mNumCon && r == MSK_RES_OK; ++i)
		{
			if (mbConstraintLowerBounded[i] && mbConstraintUpperBounded[i])
			{
				if (mlbc[i] == mubc[i])
				{
					r = MSK_putbound(task, MSK_ACC_CON, i, MSK_BK_FX, mlbc[i], mubc[i]);
				}
				else 
				{
					r = MSK_putbound(task, MSK_ACC_CON, i, MSK_BK_RA, mlbc[i], mubc[i]);
				}
			}
			else if (mbConstraintLowerBounded[i])
			{
				r = MSK_putbound(task, MSK_ACC_CON, i, MSK_BK_LO, mlbc[i], +MSK_INFINITY);
			}
			else if (mbConstraintUpperBounded[i])
			{
				r = MSK_putbound(task, MSK_ACC_CON, i, MSK_BK_UP, -MSK_INFINITY, mubc[i]);
			}
			else
			{
				LOG(WARNING) << "Every constraint should not be free.";
			}
		}
		if (r == MSK_RES_OK)
		{
			/* Input the Q for the objective . */
			r = MSK_putqobj(task, mQValues.size(), &(mQSubi[0]), &(mQSubj[0]), &(mQValues[0]));
		}

		if (r == MSK_RES_OK)
		{
			MSKrescodee trmcode;

			r = MSK_optimizetrm(task, &trmcode);
			MSK_solutionsummary(task, MSK_STREAM_LOG);

			if (r == MSK_RES_OK)
			{
				MSKsolstae solsta;
				MSK_getsolutionstatus(task, MSK_SOL_ITR, NULL, &solsta);
				double* result = new double[mNumVar];
				switch (solsta)
				{
				case MSK_SOL_STA_OPTIMAL:
				case MSK_SOL_STA_NEAR_OPTIMAL:
					MSK_getsolutionslice(task, MSK_SOL_ITR, MSK_SOL_ITEM_XX, 0, mNumVar, result);
					LOG(INFO) << "Optimal primal solution";
                    ret = true;
					solution = VectorXd::Zero(mNumVar);
					for (int k = 0; k < mNumVar; ++k)
						solution[k] = result[k];
					break;
				case MSK_SOL_STA_DUAL_INFEAS_CER:
				case MSK_SOL_STA_PRIM_INFEAS_CER:
				case MSK_SOL_STA_NEAR_DUAL_INFEAS_CER:
				case MSK_SOL_STA_NEAR_PRIM_INFEAS_CER:
					LOG(WARNING) << "Primal or dual infeasibility certificate found.";
					break;
				case MSK_SOL_STA_UNKNOWN:
					LOG(WARNING) << "The status of the solution could not be determined.";
					break;
				default:
					LOG(WARNING) << "Other solution status.";
					break;

				}
				delete[] result;

			}
		}
		else
		{
			LOG(WARNING) << "Error while optimizing.";
		}
		if (r != MSK_RES_OK)
		{
			char symname[MSK_MAX_STR_LEN];
			char desc[MSK_MAX_STR_LEN];
			LOG(WARNING) << "An error occurred while optimizing.";
			MSK_getcodedesc(r, symname, desc);
			LOG(WARNING) << "Error " << symname << " - " << desc;
		
		}
       
	}
	MSK_deletetask(&task);
	MSK_deleteenv(&env);
    
	postSolve(solution, ret, sol);
#endif
	return ret;
}
예제 #2
0
int mosek_qp_optimize(double** G, double* delta, double* alpha, long k, double C, double *dual_obj) {
  long i,j,t;
  double *c;
  MSKlidxt *aptrb;
  MSKlidxt *aptre;
  MSKidxt *asub;
  double *aval;
  MSKboundkeye bkc[1];
  double blc[1];
  double buc[1];
  MSKboundkeye *bkx;
  double *blx;
  double *bux;
  MSKidxt *qsubi,*qsubj;
  double *qval;

  MSKenv_t env;
  MSKtask_t task;
  MSKrescodee r;
  /*double dual_obj;*/

  c = (double*) malloc(sizeof(double)*k);
  assert(c!=NULL);
  aptrb = (MSKlidxt*) malloc(sizeof(MSKlidxt)*k);
  assert(aptrb!=NULL);
  aptre = (MSKlidxt*) malloc(sizeof(MSKlidxt)*k);
  assert(aptre!=NULL);
  asub = (MSKidxt*) malloc(sizeof(MSKidxt)*k);
  assert(asub!=NULL);
  aval = (double*) malloc(sizeof(double)*k);
  assert(aval!=NULL);
  bkx = (MSKboundkeye*) malloc(sizeof(MSKboundkeye)*k);
  assert(bkx!=NULL);
  blx = (double*) malloc(sizeof(double)*k);
  assert(blx!=NULL);
  bux = (double*) malloc(sizeof(double)*k);
  assert(bux!=NULL);
  qsubi = (MSKidxt*) malloc(sizeof(MSKidxt)*(k*(k+1)/2));
  assert(qsubi!=NULL);  
  qsubj = (MSKidxt*) malloc(sizeof(MSKidxt)*(k*(k+1)/2));
  assert(qsubj!=NULL);  
  qval = (double*) malloc(sizeof(double)*(k*(k+1)/2));
  assert(qval!=NULL);  
  
  
  /* DEBUG */
  /*
  for (i=0;i<k;i++) {
    printf("delta: %.4f\n", delta[i]);
  }
  printf("G:\n"); 
  for (i=0;i<k;i++) {
    for (j=0;j<k;j++) {
      printf("%.4f ", G[i][j]);
    }
    printf("\n");
  }
  fflush(stdout);
  */
  /* DEBUG */


  for (i=0;i<k;i++) {
		c[i] = -delta[i];
		aptrb[i] = i;
		aptre[i] = i+1;
		asub[i] = 0;
		aval[i] = 1.0;
		bkx[i] = MSK_BK_LO;
		blx[i] = 0.0;
		bux[i] = MSK_INFINITY;
  }
  bkc[0] = MSK_BK_UP;
  blc[0] = -MSK_INFINITY;
  buc[0] = C;
	/*
  bkc[0] = MSK_BK_FX;
  blc[0] = C;
  buc[0] = C;  
	*/
  
  /* create mosek environment */
  r = MSK_makeenv(&env, NULL, NULL, NULL, NULL);

  /* check return code */
  if (r==MSK_RES_OK) {
    /* directs output to printstr function */
    MSK_linkfunctoenvstream(env, MSK_STREAM_LOG, NULL, printstr);
  }

  /* initialize the environment */
  r = MSK_initenv(env);

  if (r==MSK_RES_OK) {
    /* create the optimization task */
    r = MSK_maketask(env,1,k,&task);
	
    if (r==MSK_RES_OK) {
      r = MSK_linkfunctotaskstream(task, MSK_STREAM_LOG,NULL,printstr);
	  
      if (r==MSK_RES_OK) {
	r = MSK_inputdata(task,
			  1,k,
			  1,k,
			  c,0.0,
			  aptrb,aptre,
			  asub,aval,
			  bkc,blc,buc,
			  bkx,blx,bux);
						  
      }
	  
      if (r==MSK_RES_OK) {
	/* coefficients for the Gram matrix */
	t = 0;
	for (i=0;i<k;i++) {
	  for (j=0;j<=i;j++) {
	    qsubi[t] = i;
	    qsubj[t] = j;
			qval[t] = G[i][j];
	    t++;
	  }
	}
	    
	r = MSK_putqobj(task, k*(k+1)/2, qsubi,qsubj,qval);
      }
      

      /* DEBUG */
      /*
      printf("t: %ld\n", t);
      for (i=0;i<t;i++) {
	printf("qsubi: %d, qsubj: %d, qval: %.4f\n", qsubi[i], qsubj[i], qval[i]);
      }
      fflush(stdout);
      */
      /* DEBUG */

      /* set relative tolerance gap (DEFAULT = 1E-8)*/
      //MSK_putdouparam(task, MSK_DPAR_INTPNT_TOL_REL_GAP, 1E-10);
      MSK_putdouparam(task, MSK_DPAR_INTPNT_TOL_REL_GAP, 1E-14);

      if (r==MSK_RES_OK) {
	r = MSK_optimize(task);
      }
      
      if (r==MSK_RES_OK) {
	MSK_getsolutionslice(task,
			     MSK_SOL_ITR,
			     MSK_SOL_ITEM_XX,
			     0,
			     k,
			     alpha);
        /* print out alphas */
	/*
	for (i=0;i<k;i++) {
	  printf("alpha[%ld]: %.8f\n", i, alpha[i]); fflush(stdout);
	}
	*/
	/* output the objective value */
	MSK_getprimalobj(task, MSK_SOL_ITR, dual_obj);
	//printf("ITER DUAL_OBJ %.8g\n", -(*dual_obj)); fflush(stdout);
      }
      MSK_deletetask(&task);
    }
    MSK_deleteenv(&env);
  }
  
  
  /* free the memory */
  free(c);
  free(aptrb);
  free(aptre);
  free(asub);
  free(aval);
  free(bkx);
  free(blx);
  free(bux);
  free(qsubi);  
  free(qsubj);  
  free(qval);  
  
	if(r == MSK_RES_OK)
  	return(0);  
	else
		return(r);
}
예제 #3
0
/**********************
lap: the upper RHS of the symmetric graph laplacian matrix which will be transformed
	to the hessian of the non-linear part of the optimisation function
n: number of nodes (length of coords array)
ordering: array containing sequences of nodes for each level,
	ie, ordering[levels[i]] is first node of (i+1)th level
level_indexes: array of starting node for each level in ordering
	ie, levels[i] is index to first node of (i+1)th level
	also, levels[0] is number of nodes in first level
	and, levels[i]-levels[i-1] is number of nodes in ith level
	and, n - levels[num_divisions-1] is number of nodes in last level
num_divisions: number of divisions between levels, ie number of levels - 1
separation: the minimum separation between nodes on different levels
***********************/
MosekEnv *mosek_init_hier(float *lap, int n, int *ordering,
    int *level_indexes, int num_divisions,
    float separation)
{
    int count = 0;
    int i, j, num_levels = num_divisions + 1;
    int num_constraints;
    MosekEnv *mskEnv = GNEW(MosekEnv);
    DigColaLevel *levels;
    int nonzero_lapsize = (n * (n - 1)) / 2;
    /* vars for nodes (except x0) + dummy nodes between levels
     * x0 is fixed at 0, and therefore is not included in the opt problem
     * add 2 more vars for top and bottom constraints
     */
    mskEnv->num_variables = n + num_divisions + 1;

    logfile = fopen("quad_solve_log", "w");
    levels = assign_digcola_levels(ordering, n, level_indexes, num_divisions);
#ifdef DUMP_CONSTRAINTS
    print_digcola_levels(logfile, levels, num_levels);
#endif

    /* nonlinear coefficients matrix of objective function */
    /* int lapsize=mskEnv->num_variables+(mskEnv->num_variables*(mskEnv->num_variables-1))/2; */
    mskEnv->qval = N_GNEW(nonzero_lapsize, double);
    mskEnv->qsubi = N_GNEW(nonzero_lapsize, int);
    mskEnv->qsubj = N_GNEW(nonzero_lapsize, int);

    /* solution vector */
    mskEnv->xx = N_GNEW(mskEnv->num_variables, double);

    /* constraint matrix */
    separation /= 2.0;		/* separation between each node and it's adjacent constraint */
    num_constraints = get_num_digcola_constraints(levels,
				    num_levels) + num_divisions + 1;
    /* constraints of the form x_i - x_j >= sep so 2 non-zero entries per constraint in LHS matrix
     * except x_0 (fixed at 0) constraints which have 1 nz val each.
     */
#ifdef EQUAL_WIDTH_LEVELS
    num_constraints += num_divisions;
#endif
    /* pointer to beginning of nonzero sequence in a column */

    for (i = 0; i < n - 1; i++) {
	for (j = i; j < n - 1; j++) {
	    mskEnv->qval[count] = -2 * lap[count + n];
	    assert(mskEnv->qval[count] != 0);
	    mskEnv->qsubi[count] = j;
	    mskEnv->qsubj[count] = i;
	    count++;
	}
    }
#ifdef DUMP_CONSTRAINTS
    fprintf(logfile, "Q=[");
    int lapcntr = n;
    for (i = 0; i < mskEnv->num_variables; i++) {
	if (i != 0)
	    fprintf(logfile, ";");
	for (j = 0; j < mskEnv->num_variables; j++) {
	    if (j < i || i >= n - 1 || j >= n - 1) {
		fprintf(logfile, "0 ");
	    } else {
		fprintf(logfile, "%f ", -2 * lap[lapcntr++]);
	    }
	}
    }
    fprintf(logfile, "]\nQ=Q-diag(diag(Q))+Q'\n");
#endif
    fprintf(logfile, "\n");
    /* Make the mosek environment. */
    mskEnv->r = MSK_makeenv(&mskEnv->env, NULL, NULL, NULL, NULL);

    /* Check whether the return code is ok. */
    if (mskEnv->r == MSK_RES_OK) {
	/* Directs the log stream to the user
	 * specified procedure 'printstr'. 
	 */
	MSK_linkfunctoenvstream(mskEnv->env, MSK_STREAM_LOG, NULL,
				printstr);
    }

    /* Initialize the environment. */
    mskEnv->r = MSK_initenv(mskEnv->env);
    if (mskEnv->r == MSK_RES_OK) {
	/* Make the optimization task. */
	mskEnv->r =
	    MSK_maketask(mskEnv->env, num_constraints,
			 mskEnv->num_variables, &mskEnv->task);

	if (mskEnv->r == MSK_RES_OK) {
	    int c_ind = 0;
	    int c_var = n - 1;
	    mskEnv->r =
		MSK_linkfunctotaskstream(mskEnv->task, MSK_STREAM_LOG,
					 NULL, printstr);
	    /* Resize the task. */
	    if (mskEnv->r == MSK_RES_OK)
		mskEnv->r = MSK_resizetask(mskEnv->task, num_constraints, mskEnv->num_variables, 0,	/* no cones!! */
					   /* each constraint applies to 2 vars */
					   2 * num_constraints +
					   num_divisions, nonzero_lapsize);

	    /* Append the constraints. */
	    if (mskEnv->r == MSK_RES_OK)
		mskEnv->r = MSK_append(mskEnv->task, 1, num_constraints);

	    /* Append the variables. */
	    if (mskEnv->r == MSK_RES_OK)
		mskEnv->r =
		    MSK_append(mskEnv->task, 0, mskEnv->num_variables);
	    /* Put variable bounds. */
	    for (j = 0;
		 j < mskEnv->num_variables && mskEnv->r == MSK_RES_OK; ++j)
		mskEnv->r =
		    MSK_putbound(mskEnv->task, 0, j, MSK_BK_RA,
				 -MSK_INFINITY, MSK_INFINITY);
	    for (j = 0; j < levels[0].num_nodes && mskEnv->r == MSK_RES_OK;
		 j++) {
		int node = levels[0].nodes[j] - 1;
		if (node >= 0) {
		    INIT_sub_val(c_var,node);
		    mskEnv->r =
			MSK_putavec(mskEnv->task, 1, c_ind, 2, subi, vali);
		} else {
		    /* constraint for y0 (fixed at 0) */
		    mskEnv->r =
			MSK_putaij(mskEnv->task, c_ind, c_var, 1.0);
		}
		mskEnv->r =
		    MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_LO,
				 separation, MSK_INFINITY);
		c_ind++;
	    }
	    for (i = 0; i < num_divisions && mskEnv->r == MSK_RES_OK; i++) {
		c_var = n + i;
		for (j = 0;
		     j < levels[i].num_nodes && mskEnv->r == MSK_RES_OK;
		     j++) {
		    /* create separation constraint a>=b+separation */
		    int node = levels[i].nodes[j] - 1;
		    if (node >= 0) {	/* no constraint for fixed node */
			INIT_sub_val(node,c_var);
			mskEnv->r =
			    MSK_putavec(mskEnv->task, 1, c_ind, 2, subi,
					vali);
		    } else {
			/* constraint for y0 (fixed at 0) */
			mskEnv->r =
			    MSK_putaij(mskEnv->task, c_ind, c_var, -1.0);
		    }
		    mskEnv->r =
			MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_LO,
				     separation, MSK_INFINITY);
		    c_ind++;
		}
		for (j = 0;
		     j < levels[i + 1].num_nodes
		     && mskEnv->r == MSK_RES_OK; j++) {
		    int node = levels[i + 1].nodes[j] - 1;
		    if (node >= 0) {
			INIT_sub_val(c_var,node);
			mskEnv->r =
			    MSK_putavec(mskEnv->task, 1, c_ind, 2, subi,
					vali);
		    } else {
			/* constraint for y0 (fixed at 0) */
			mskEnv->r =
			    MSK_putaij(mskEnv->task, c_ind, c_var, 1.0);
		    }
		    mskEnv->r =
			MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_LO,
				     separation, MSK_INFINITY);
		    c_ind++;
		}
	    }
	    c_var = n + i;
	    for (j = 0; j < levels[i].num_nodes && mskEnv->r == MSK_RES_OK;
		 j++) {
		/* create separation constraint a>=b+separation */
		int node = levels[i].nodes[j] - 1;
		if (node >= 0) {	/* no constraint for fixed node */
		    INIT_sub_val(node,c_var);
		    mskEnv->r =
			MSK_putavec(mskEnv->task, 1, c_ind, 2, subi, vali);
		} else {
		    /* constraint for y0 (fixed at 0) */
		    mskEnv->r =
			MSK_putaij(mskEnv->task, c_ind, c_var, -1.0);
		}
		mskEnv->r =
		    MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_LO,
				 separation, MSK_INFINITY);
		c_ind++;
	    }
	    /* create constraints preserving the order of dummy vars */
	    for (i = 0; i < num_divisions + 1 && mskEnv->r == MSK_RES_OK;
		 i++) {
		int c_var = n - 1 + i, c_var2 = c_var + 1;
		INIT_sub_val(c_var,c_var2);
		mskEnv->r =
		    MSK_putavec(mskEnv->task, 1, c_ind, 2, subi, vali);
		mskEnv->r =
		    MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_LO, 0,
				 MSK_INFINITY);
		c_ind++;
	    }
#ifdef EQUAL_WIDTH_LEVELS
	    for (i = 1; i < num_divisions + 1 && mskEnv->r == MSK_RES_OK;
		 i++) {
		int c_var = n - 1 + i, c_var_lo = c_var - 1, c_var_hi =
		    c_var + 1;
		INIT_sub_val3(c_var_lo, c_var, c_var_h);
		mskEnv->r =
		    MSK_putavec(mskEnv->task, 1, c_ind, 3, subi, vali);
		mskEnv->r =
		    MSK_putbound(mskEnv->task, 1, c_ind, MSK_BK_FX, 0, 0);
		c_ind++;
	    }
#endif
	    assert(c_ind == num_constraints);
#ifdef DUMP_CONSTRAINTS
	    fprintf(logfile, "A=[");
	    for (i = 0; i < num_constraints; i++) {
		if (i != 0)
		    fprintf(logfile, ";");
		for (j = 0; j < mskEnv->num_variables; j++) {
		    double aij;
		    MSK_getaij(mskEnv->task, i, j, &aij);
		    fprintf(logfile, "%f ", aij);
		}
	    }
	    fprintf(logfile, "]\n");
	    fprintf(logfile, "b=[");
	    for (i = 0; i < num_constraints; i++) {
		fprintf(logfile, "%f ", separation);
	    }
	    fprintf(logfile, "]\n");
#endif
	    if (mskEnv->r == MSK_RES_OK) {
		/*
		 * The lower triangular part of the Q
		 * matrix in the objective is specified.
		 */
		mskEnv->r =
		    MSK_putqobj(mskEnv->task, nonzero_lapsize,
				mskEnv->qsubi, mskEnv->qsubj,
				mskEnv->qval);
	    }
	}
    }
    delete_digcola_levels(levels, num_levels);
    return mskEnv;
}
예제 #4
0
template <typename _Scalar> typename MosekOpt<_Scalar>::ReturnType
MosekOpt<_Scalar>::
update( bool verbose )
{
    if ( _task != NULL )
    {
        std::cerr << "[" << __func__ << "]: " << "update can only be called once! returning." << std::endl;
        return MSK_RES_ERR_UNKNOWN;
    }

    /* Create the optimization task. */
    if ( MSK_RES_OK == _r )
    {
        _r = MSK_maketask( _env, this->getConstraintCount(), this->getVarCount(), &_task );
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "could not create task with " << this->getVarCount() << " vars, and " << this->getConstraintCount() << " constraints" << std::endl;
    }

    // redirect output
    if ( MSK_RES_OK == _r )
    {
        _r = MSK_linkfunctotaskstream( _task, MSK_STREAM_LOG, NULL, mosekPrintStr );
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "could not create rewire output to mosekPrintStr(), continuing though..." << std::endl;
    }

    // Append _numCon empty constraints. The constraints will initially have no bounds.
    if ( MSK_RES_OK == _r )
    {
        if ( verbose ) std::cout << "my: MSK_appendcons(_task,"<< this->getConstraintCount() <<");" << std::endl;
        _r = MSK_appendcons( _task, this->getConstraintCount() );
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "could not append " << this->getConstraintCount() << " constraints" << std::endl;
    }

    // Append _numVar variables. The variables will initially be fixed at zero (x=0).
    if ( MSK_RES_OK == _r )
    {
        if ( verbose ) std::cout << "my: MSK_appendvars(_task," << this->getVarCount() <<");" << std::endl;
        _r = MSK_appendvars( _task, this->getVarCount() );
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "could not append " << this->getVarCount() << " variables" << std::endl;
    }

    // Optionally add a constant term to the objective.
    if ( MSK_RES_OK == _r )
    {
        if ( verbose ) std::cout << "my: MSK_putcfix(_task," << this->getObjectiveBias() << ");" << std::endl;
        _r = MSK_putcfix( _task, this->getObjectiveBias() );
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "could not add constant " << this->getObjectiveBias() << " to objective function" << std::endl;
    }

    // set Variables
    for ( size_t j = 0; (j < this->getVarCount()) && (MSK_RES_OK == _r); ++j )
    {
        // set Variable j's Bounds // blx[j] <= x_j <= bux[j]
        if ( MSK_RES_OK == _r )
        {
            _r = MSK_putvarbound( _task,
                                  j,                                                     /* Index of variable.*/
                                  MosekOpt<Scalar>::getBoundTypeCustom( this->getVarBoundType(j) ), /* Bound key.*/
                                  this->getVarLowerBound(j),                             /* Numerical value of lower bound.*/
                                  this->getVarUpperBound(j) );                           /* Numerical value of upper bound.*/

            if ( verbose ) std::cout << "my: MSK_putvarbound(_task," << j << "," << this->getVarBoundType(j) << "," << this->getVarLowerBound(j) << "," << this->getVarUpperBound(j) << ");" << std::endl;
        }

        // set Variable j's Type
        if ( MSK_RES_OK == _r )
        {
            _r = MSK_putvartype( _task, j, MosekOpt<Scalar>::getVarTypeCustom(this->getVarType(j)) );
        }

        // set Variable j's linear coefficient in the objective function
        if ( MSK_RES_OK == _r )
        {
            if ( verbose ) std::cout << "my: putcj(_task," << j << "," << this->getLinObjectives()[j] << ")" << std::endl;
            _r = MSK_putcj( _task, j, this->getLinObjectives()[j] );
        }
    }

    // set Quadratic Objectives
    if ( MSK_RES_OK == _r )
    {
        const int numNonZeros = this->getQuadraticObjectives().size();
        MSKint32t *qsubi = new MSKint32t[numNonZeros],
                  *qsubj = new MSKint32t[numNonZeros];
        double    *qval  = new double[numNonZeros];

        for ( size_t qi = 0; qi != this->getQuadraticObjectives().size(); ++qi )
        {
            qsubi[qi] = this->getQuadraticObjectives()[qi].row();
            qsubj[qi] = this->getQuadraticObjectives()[qi].col();
            qval [qi] = this->getQuadraticObjectives()[qi].value();
        }

        if ( verbose ) std::cout<<"my: putqobj( _task, " << numNonZeros << ",\n";
        for ( size_t vi = 0; vi != numNonZeros; ++vi )
        {
            if ( verbose ) std::cout << qsubi[vi] << "," << qsubj[vi] << ", " << qval[vi] << std::endl;
        }
        if ( verbose ) std::cout << ");" << std::endl;

        _r = MSK_putqobj( _task, numNonZeros, qsubi, qsubj, qval );

        if ( qsubi ) { delete[] qsubi; qsubi = NULL; }
        if ( qsubj ) { delete[] qsubj; qsubj = NULL; }
        if ( qval  ) { delete[] qval ; qval  = NULL; }

        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "Setting Quadratic Objectives caused error code " << (int)_r << std::endl;
    } // ...Quadratic objective

    // set Linear Constraints
    {
        typename ParentType::SparseMatrix A( this->getLinConstraintsMatrix() );
//        ( this->getConstraintCount(), this->getVarCount() );
//        A.setFromTriplets( this->getLinConstraints().begin(), this->getLinConstraints().end() );
        std::vector<double>         aval;                // Linear constraints coeff matrix (sparse)
        std::vector<int>            asub;                // Linear constraints coeff matrix indices
        std::vector<int>            aptrb, aptre;
        for ( int row = 0; (row < A.outerSize()) && (MSK_RES_OK == _r); ++row )
        {
            // set Constraint Bounds for row
            if ( MSK_RES_OK == _r )
            {
                if ( verbose ) std::cout << "my: MSK_putconbound( _task, " << row << ", "
                                         << MosekOpt<Scalar>::getBoundTypeCustom( this->getConstraintBoundType(row) ) << ", "
                                         << this->getConstraintLowerBound( row ) << ", "
                                         << this->getConstraintUpperBound( row ) << ")"
                                         << std::endl; fflush( stdout );

                _r = MSK_putconbound( _task,
                                      row,                                                          /* Index of constraint.*/
                                      MosekOpt<Scalar>::getBoundTypeCustom(this->getConstraintBoundType(row)), /* Bound key.*/
                                      this->getConstraintLowerBound(row),                           /* Numerical value of lower bound.*/
                                      this->getConstraintUpperBound(row) );                         /* Numerical value of upper bound.*/
            }

            // set Linear Constraint row
            if ( MSK_RES_OK == _r )
            {
                // new line starts at index == current size
                aptrb.push_back( aval.size() );
                // add coeffs from new line
                for ( typename ParentType::SparseMatrix::InnerIterator it(A,row); it; ++it )
                {
                    if ( row != it.row() ) std::cerr << "[" << __func__ << "]: " << "this shouldn't happen" << std::endl;
                    // coeff value
                    aval.push_back( it.value() );  // TODO: A should be a matrix, not a vector...
                    // coeff subscript
                    asub.push_back( it.col() );
                }
                // new line ends at index == new size
                aptre.push_back( aval.size() );

                if ( verbose ) {
                    std::cout << "my: MSK_putarow( _task, "
                              << row << ", "
                              << aptre[row] - aptrb[row] << ", "
                              << *(asub.data() + aptrb[row]) << ", "
                              << *(aval.data() + aptrb[row]) << ");"
                              << std::endl; fflush( stdout );
                }

                _r = MSK_putarow( _task,
                                  row,                 /* Row index.*/
                                  aptre[row] - aptrb[row], /* Number of non-zeros in row i.*/
                                  asub.data() + aptrb[row],     /* Pointer to column indexes of row i.*/
                                  aval.data() + aptrb[row]);    /* Pointer to values of row i.*/
            }
        } // ... for A.rows

        // report error
        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "Setting Lin constraints caused error code " << (int)_r << std::endl;
    } // ...set Linear Constraints

    // set Quadratic constraints
    if ( verbose ) std::cout << "[" << __func__ << "]: " << "adding q constraints" << std::endl;
    for ( size_t constr_id = 0; (constr_id != this->getQuadraticConstraints().size()) && (MSK_RES_OK == _r); ++constr_id )
    {
        const int numNonZeros = this->getQuadraticConstraints(constr_id).size();

        MSKint32t *qsubi = new MSKint32t[numNonZeros],
                  *qsubj = new MSKint32t[numNonZeros];
        double    *qval  = new double[numNonZeros];

        for ( size_t qi = 0; qi != this->getQuadraticConstraints(constr_id).size(); ++qi )
        {
            qsubi[qi] = this->getQuadraticConstraints(constr_id)[qi].row();
            qsubj[qi] = this->getQuadraticConstraints(constr_id)[qi].col();
            qval [qi] = this->getQuadraticConstraints(constr_id)[qi].value();
        }

        if ( verbose ) std::cout<<"my: MSK_putqonk( _task, " << constr_id << ", " << numNonZeros << ",\n";
        for(size_t vi=0;vi!=numNonZeros;++vi)
        {
            if ( verbose ) std::cout << qsubi[vi] << "," << qsubj[vi] << ", " << qval[vi] << std::endl;
        }
        if ( verbose ) std::cout << "); " << std::endl;

        _r = MSK_putqconk(_task,
                          constr_id,
                          numNonZeros,
                          qsubi,
                          qsubj,
                          qval);

        if ( qsubi ) { delete[] qsubi; qsubi = NULL; }
        if ( qsubj ) { delete[] qsubj; qsubj = NULL; }
        if ( qval  ) { delete[] qval ; qval  = NULL; }

        if ( MSK_RES_OK != _r )
            std::cerr << "[" << __func__ << "]: " << "Setting Quad constraints caused error code " << (int)_r << std::endl;
    } // ...set Quadratic Constraints

    // save to file
    {
        if ( _r == MSK_RES_OK )
        {
            _r = MSK_putintparam( _task, MSK_IPAR_WRITE_DATA_FORMAT, MSK_DATA_FORMAT_LP );
            if ( _r == MSK_RES_OK )
            {
                _r = MSK_writedata( _task, "mosek.lp" );
                if ( _r != MSK_RES_OK )
                {
                    std::cerr << "[" << __func__ << "]: " << "Writedata did not work" << (int)_r << std::endl;
                }
            }
        }
    }

    if ( _r == MSK_RES_OK )
    {
        this->_x.setZero();
        this->_updated = true;
    }

    // return error code
    return _r;
} // ...MosekOpt::update()
예제 #5
0
/**********************
lap: the upper RHS of the symmetric graph laplacian matrix which will be transformed
	to the hessian of the non-linear part of the optimisation function
	has dimensions num_variables, dummy vars do not have entries in lap
cs: array of pointers to separation constraints
***********************/
MosekEnv *mosek_init_sep(float *lap, int num_variables, int num_dummy_vars,
			 Constraint ** cs, int num_constraints)
{
    int i, j;
    MosekEnv *mskEnv = GNEW(MosekEnv);
    int count = 0;
    int nonzero_lapsize = num_variables * (num_variables - 1) / 2;
    /* fix var 0 */
    mskEnv->num_variables = num_variables + num_dummy_vars - 1;

    fprintf(stderr, "MOSEK!\n");
    logfile = fopen("quad_solve_log", "w");

    /* nonlinear coefficients matrix of objective function */
    mskEnv->qval = N_GNEW(nonzero_lapsize, double);
    mskEnv->qsubi = N_GNEW(nonzero_lapsize, int);
    mskEnv->qsubj = N_GNEW(nonzero_lapsize, int);

    /* solution vector */
    mskEnv->xx = N_GNEW(mskEnv->num_variables, double);

    /* pointer to beginning of nonzero sequence in a column */

    for (i = 0; i < num_variables - 1; i++) {
	for (j = i; j < num_variables - 1; j++) {
	    mskEnv->qval[count] = -2 * lap[count + num_variables];
	    /* assert(mskEnv->qval[count]!=0); */
	    mskEnv->qsubi[count] = j;
	    mskEnv->qsubj[count] = i;
	    count++;
	}
    }
#ifdef DUMP_CONSTRAINTS
    fprintf(logfile, "Q=[");
    count = 0;
    for (i = 0; i < num_variables - 1; i++) {
	if (i != 0)
	    fprintf(logfile, ";");
	for (j = 0; j < num_variables - 1; j++) {
	    if (j < i) {
		fprintf(logfile, "0 ");
	    } else {
		fprintf(logfile, "%f ", -2 * lap[num_variables + count++]);
	    }
	}
    }
    fprintf(logfile, "]\nQ=Q-diag(diag(Q))+Q'\n");
#endif
    /* Make the mosek environment. */
    mskEnv->r = MSK_makeenv(&mskEnv->env, NULL, NULL, NULL, NULL);

    /* Check whether the return code is ok. */
    if (mskEnv->r == MSK_RES_OK) {
	/* Directs the log stream to the user
	   specified procedure 'printstr'. */
	MSK_linkfunctoenvstream(mskEnv->env, MSK_STREAM_LOG, NULL,
				printstr);
    }

    /* Initialize the environment. */
    mskEnv->r = MSK_initenv(mskEnv->env);
    if (mskEnv->r == MSK_RES_OK) {
	/* Make the optimization task. */
	mskEnv->r =
	    MSK_maketask(mskEnv->env, num_constraints,
			 mskEnv->num_variables, &mskEnv->task);

	if (mskEnv->r == MSK_RES_OK) {
	    mskEnv->r =
		MSK_linkfunctotaskstream(mskEnv->task, MSK_STREAM_LOG,
					 NULL, printstr);
	    /* Resize the task. */
	    if (mskEnv->r == MSK_RES_OK)
		mskEnv->r = MSK_resizetask(mskEnv->task, num_constraints, mskEnv->num_variables, 0,	/* no cones!! */
					   /* number of non-zero constraint matrix entries:
					    *   each constraint applies to 2 vars
					    */
					   2 * num_constraints,
					   nonzero_lapsize);

	    /* Append the constraints. */
	    if (mskEnv->r == MSK_RES_OK)
		mskEnv->r = MSK_append(mskEnv->task, 1, num_constraints);

	    /* Append the variables. */
	    if (mskEnv->r == MSK_RES_OK)
		mskEnv->r =
		    MSK_append(mskEnv->task, 0, mskEnv->num_variables);
	    /* Put variable bounds. */
	    for (j = 0;
		 j < mskEnv->num_variables && mskEnv->r == MSK_RES_OK; j++)
		mskEnv->r =
		    MSK_putbound(mskEnv->task, 0, j, MSK_BK_RA,
				 -MSK_INFINITY, MSK_INFINITY);
	    for (i = 0; i < num_constraints; i++) {
		int u = getLeftVarID(cs[i]) - 1;
		int v = getRightVarID(cs[i]) - 1;
		double separation = getSeparation(cs[i]);
		if (u < 0) {
		    mskEnv->r =
			MSK_putbound(mskEnv->task, 0, v, MSK_BK_RA,
				     -MSK_INFINITY, -separation);
		    assert(mskEnv->r == MSK_RES_OK);
		} else if (v < 0) {
		    mskEnv->r =
			MSK_putbound(mskEnv->task, 0, u, MSK_BK_RA,
				     separation, MSK_INFINITY);
		    assert(mskEnv->r == MSK_RES_OK);
		} else {
		    /* fprintf(stderr,"u=%d,v=%d,sep=%f\n",u,v,separation); */
		    INIT_sub_val(u,v);
		    mskEnv->r =
			MSK_putavec(mskEnv->task, 1, i, 2, subi, vali);
		    assert(mskEnv->r == MSK_RES_OK);
		    mskEnv->r =
			MSK_putbound(mskEnv->task, 1, i, MSK_BK_LO,
				     separation, MSK_INFINITY);
		    assert(mskEnv->r == MSK_RES_OK);
		}
	    }
	    if (mskEnv->r == MSK_RES_OK) {
		/*
		 * The lower triangular part of the Q
		 * matrix in the objective is specified.
		 */
		mskEnv->r =
		    MSK_putqobj(mskEnv->task, nonzero_lapsize,
				mskEnv->qsubi, mskEnv->qsubj,
				mskEnv->qval);
		assert(mskEnv->r == MSK_RES_OK);
	    }
	}
    }
    return mskEnv;
}