Exemplo n.º 1
0
int main(int argc,char *argv[])
{
  MSKrescodee  r;
  
  const MSKint32t numvar = 6,
                  numcon = 1;
      
  MSKboundkeye bkc[] = { MSK_BK_FX };
  double       blc[] = { 1.0 };
  double       buc[] = { 1.0 };
  
  MSKboundkeye bkx[] = {MSK_BK_LO,
                        MSK_BK_LO,
                        MSK_BK_LO,
                        MSK_BK_FR,
                        MSK_BK_FR,
                        MSK_BK_FR};
  double       blx[] = {0.0,
                        0.0,
                        0.0,
                        -MSK_INFINITY,
                        -MSK_INFINITY,
                        -MSK_INFINITY};
  double       bux[] = {+MSK_INFINITY,
                        +MSK_INFINITY,
                        +MSK_INFINITY,
                        +MSK_INFINITY,
                        +MSK_INFINITY,
                        +MSK_INFINITY};
  
  double       c[]   = {0.0,
                        0.0,
                        0.0,
                        1.0,
                        1.0,
                        1.0};

  MSKint32t   aptrb[] = {0, 1, 2, 3, 3, 3},
              aptre[] = {1, 2, 3, 3, 3, 3},
              asub[]  = {0, 0, 0, 0};
  double      aval[]  = {1.0, 1.0, 2.0};
  
   
  MSKint32t   i,j,csub[3];

  MSKenv_t    env  = NULL;
  MSKtask_t   task = NULL;

  /* Create the mosek environment. */
  r = MSK_makeenv(&env,NULL);

  if ( r==MSK_RES_OK )
  {
    /* Create the optimization task. */
    r = MSK_maketask(env,numcon,numvar,&task);

    if ( r==MSK_RES_OK )
    {
      MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);

      /* Append 'numcon' empty constraints.
     The constraints will initially have no bounds. */
      if ( r == MSK_RES_OK )
        r = MSK_appendcons(task,numcon);

      /* Append 'numvar' variables.
     The variables will initially be fixed at zero (x=0). */
      if ( r == MSK_RES_OK )
        r = MSK_appendvars(task,numvar);

      for(j=0; j<numvar && r == MSK_RES_OK; ++j)
      {
        /* Set the linear term c_j in the objective.*/  
        if(r == MSK_RES_OK)
          r = MSK_putcj(task,j,c[j]);

        /* Set the bounds on variable j.
       blx[j] <= x_j <= bux[j] */
        if(r == MSK_RES_OK)
          r = MSK_putvarbound(task,
                              j,           /* Index of variable.*/
                              bkx[j],      /* Bound key.*/
                              blx[j],      /* Numerical value of lower bound.*/
                              bux[j]);     /* Numerical value of upper bound.*/

        /* Input column j of A */   
        if(r == MSK_RES_OK)
          r = MSK_putacol(task,
                          j,                 /* Variable (column) index.*/
                          aptre[j]-aptrb[j], /* Number of non-zeros in column j.*/
                          asub+aptrb[j],     /* Pointer to row indexes of column j.*/
                          aval+aptrb[j]);    /* Pointer to Values of column j.*/
      
      }

      /* Set the bounds on constraints.
       for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
      for(i=0; i<numcon && r==MSK_RES_OK; ++i)
        r = MSK_putconbound(task,
                            i,           /* Index of constraint.*/
                            bkc[i],      /* Bound key.*/
                            blc[i],      /* Numerical value of lower bound.*/
                            buc[i]);     /* Numerical value of upper bound.*/
                 
      if ( r==MSK_RES_OK )
      {
        /* Append the first cone. */
        csub[0] = 3;
        csub[1] = 0;
        csub[2] = 1;
        r = MSK_appendcone(task,
                           MSK_CT_QUAD,
                           0.0, /* For future use only, can be set to 0.0 */
                           3,
                           csub);
      }

      if ( r==MSK_RES_OK )
      {
        /* Append the second cone. */
        csub[0] = 4;
        csub[1] = 5;
        csub[2] = 2;

        r = MSK_appendcone(task,
                           MSK_CT_RQUAD,
                           0.0,
                           3,
                           csub);
      }

      if ( r==MSK_RES_OK )
      {
        MSKrescodee trmcode;
        
        /* Run optimizer */
        r = MSK_optimizetrm(task,&trmcode);


        /* Print a summary containing information
           about the solution for debugging purposes*/
        MSK_solutionsummary (task,MSK_STREAM_MSG);
        
        if ( r==MSK_RES_OK )
        {
          MSKsolstae solsta;
          
          MSK_getsolsta (task,MSK_SOL_ITR,&solsta);
          
          switch(solsta)
          {
             case MSK_SOL_STA_OPTIMAL:   
             case MSK_SOL_STA_NEAR_OPTIMAL:
               {
                 double *xx = NULL;
                 
                 xx = calloc(numvar,sizeof(double));
                 if ( xx )
                 {                 
                   MSK_getxx (task,
                              MSK_SOL_ITR,    /* Request the interior solution. */
                              xx);

                   printf("Optimal primal solution\n");
                   for(j=0; j<numvar; ++j)
                     printf("x[%d]: %e\n",j,xx[j]);
                 }
                 else
                 {
                   r = MSK_RES_ERR_SPACE;
                 }
                 free(xx);
               }
               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:  
               printf("Primal or dual infeasibility certificate found.\n");
               break;
             case MSK_SOL_STA_UNKNOWN:
               printf("The status of the solution could not be determined.\n");
               break;
             default:
               printf("Other solution status.");
               break;
          }
        }
        else
        {
          printf("Error while optimizing.\n");
        }
      }
    
      if (r != MSK_RES_OK)
      {
        /* In case of an error print error code and description. */      
        char symname[MSK_MAX_STR_LEN];
        char desc[MSK_MAX_STR_LEN];
        
        printf("An error occurred while optimizing.\n");     
        MSK_getcodedesc (r,
                         symname,
                         desc);
        printf("Error %s - '%s'\n",symname,desc);
      }
    }
    /* Delete the task and the associated data. */
    MSK_deletetask(&task);
  }
 
  /* Delete the environment and the associated data. */
  MSK_deleteenv(&env);

  return ( r );
} /* main */
Exemplo n.º 2
0
template <typename _Scalar> typename MosekOpt<_Scalar>::ReturnType
MosekOpt<_Scalar>::optimize( std::vector<_Scalar> *x_out, OBJ_SENSE objective_sense )
{
    if ( !this->_updated )
    {
        std::cerr << "[" << __func__ << "]: " << "Please call update() first!" << std::endl;
        return MSK_RES_ERR_UNKNOWN;
    }

    // cache problem size
    const int numvar = this->getVarCount();

    // determine problem type
    MSKobjsense_enum objsense = (objective_sense == OBJ_SENSE::MINIMIZE) ? MSK_OBJECTIVE_SENSE_MINIMIZE
                                                                         : MSK_OBJECTIVE_SENSE_MAXIMIZE;
    if ( MSK_RES_OK == _r )
        _r = MSK_putobjsense( _task, objsense );

    if ( MSK_RES_OK == _r  )
    {
        // set termination sensitivity
        MSKrescodee trmcode;
        if ( (_r == MSK_RES_OK) && (this->getTolRelGap() > Scalar(0)) )
        {
            _r = MSK_putdouparam( _task, MSK_DPAR_MIO_TOL_REL_GAP, this->getTolRelGap() /*1e-10f*/ );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_DPAR_MIO_DISABLE_TERM_TIME to " << this->getTimeLimit() << " did NOT work!" << std::endl;
            }
        }


        if ( (_r == MSK_RES_OK) && (this->getTimeLimit() > Scalar(0)) )
        {
            _r = MSK_putdouparam(_task, MSK_DPAR_MIO_DISABLE_TERM_TIME, this->getTimeLimit() );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_DPAR_MIO_DISABLE_TERM_TIME to " << this->getTimeLimit() << " did NOT work!" << std::endl;
            }
            _r = MSK_putdouparam(_task, MSK_DPAR_MIO_MAX_TIME, this->getTimeLimit()+Scalar(5) );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_DPAR_MIO_MAX_TIME to " << this->getTimeLimit()+Scalar(5) << " did NOT work!" << std::endl;
            }
        }

        if (_r == MSK_RES_OK)
        {
            //_r = MSK_putintparam(_task, MSK_IPAR_OPTIMIZER, MSK_OPTIMIZER_MIXED_INT_CONIC );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_OPTIMIZER_MIXED_INT_CONIC did not work!" << std::endl;
            }
        }

        if ( _r == MSK_RES_OK )
        {
            _r = MSK_putintparam( _task, MSK_IPAR_MIO_PRESOLVE_USE, MSK_ON );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_IPAR_MIO_PRESOLVE_USE did not work!" << std::endl;
            }
        }

        if ( _r == MSK_RES_OK )
        {
            _r = MSK_putintparam( _task, MSK_IPAR_MIO_HEURISTIC_LEVEL, 5 );
            if ( _r != MSK_RES_OK )
            {
                std::cerr << "[" << __func__ << "]: " << "setting MSK_IPAR_MIO_HEURISTIC_LEVEL did not work!" << std::endl;
            }
        }

        // Run optimizer
        _r = MSK_optimizetrm( _task, &trmcode );

        // Print a summary containing information about the solution for debugging purposes.
        MSK_solutionsummary( _task, MSK_STREAM_LOG );

        // save solution
        double *xx = (double*) calloc(numvar,sizeof(double));
        if ( _r == MSK_RES_OK )
        {
            MSKsolstae solsta;

            if ( _r == MSK_RES_OK )
            {
                _r = MSK_getsolsta( _task, MSK_SOL_ITR, &solsta );
                if ( _r != MSK_RES_OK )
                {
                    _r = MSK_getsolsta( _task, MSK_SOL_ITG, &solsta );
                }
                if ( _r != MSK_RES_OK )
                {
                    std::cerr << "[" << __func__ << "]: " << "neithter MSK_SOL_ITR, nor MSK_SOL_ITR worked" << std::endl;
                }
            }

            switch ( solsta )
            {
                case MSK_SOL_STA_OPTIMAL:
                case MSK_SOL_STA_NEAR_OPTIMAL:
                {
                    if ( xx )
                    {
                        MSK_getxx(_task,
                                  MSK_SOL_ITR,    /* Request the basic solution. */
                                  xx);

                        _storeSolution( xx, numvar );
                        printf("Optimal primal solution\n");
                    }
                    else
                    {
                        _r = MSK_RES_ERR_SPACE;
                    }
                    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:
                    printf("Primal or dual infeasibility certificate found.\n");
                    break;
                case MSK_SOL_STA_UNKNOWN:
                {
                    MSKprostae prosta;
                    MSK_getprosta(_task,MSK_SOL_ITG,&prosta);
                    switch (prosta)
                    {
                        case MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED:
                            printf("Problem status Infeasible or unbounded\n");
                            break;
                        case MSK_PRO_STA_PRIM_INFEAS:
                            printf("Problem status Infeasible.\n");
                            break;
                        case MSK_PRO_STA_UNKNOWN:
                            printf("Problem status unknown.\n");
                            break;
                        default:
                            printf("Other problem status.");
                            break;
                    }
                    char symname[MSK_MAX_STR_LEN];
                    char desc[MSK_MAX_STR_LEN];

                    /* If the solutions status is unknown, print the termination code
               indicating why the optimizer terminated prematurely. */

                    MSK_getcodedesc(trmcode,
                                    symname,
                                    desc);

                    printf("The solutuion status is unknown.\n");
                    printf("The optimizer terminitated with code: %s\n",symname);
                    break;
                }
                    // ITG
                    //asdf todo: consolidate this last part:
                case MSK_SOL_STA_INTEGER_OPTIMAL:
                case MSK_SOL_STA_NEAR_INTEGER_OPTIMAL :
                    MSK_getxx(_task,
                              MSK_SOL_ITG,    /* Request the integer solution. */
                              xx);
                    _storeSolution( xx, numvar );
                    printf("Optimal integer solution.\n");

                    break;

                case MSK_SOL_STA_PRIM_FEAS:
                    /* A feasible but not necessarily optimal solution was located. */
                    MSK_getxx(_task,MSK_SOL_ITG,xx);
                    _storeSolution( xx, numvar );
                    printf("Feasible solution.\n");
                    break;

                default:
                    std::cerr << "[" << __func__ << "]: " << "unknown code " << (int)solsta << std::endl;
                    break;
            }

            if ( xx ) { free(xx); xx = NULL; }
        }
    }

    if ( MSK_RES_OK != _r )
    {
        /* In case of an error print error code and description. */
        char symname[MSK_MAX_STR_LEN];
        char desc[MSK_MAX_STR_LEN];

        printf("An error occurred while optimizing.\n");
        MSK_getcodedesc( _r,
                         symname,
                         desc);
        printf("Error %s - '%s'\n",symname,desc);
    }
    else
    {
        // output
        if ( x_out )
        {
            x_out->clear();
            x_out->reserve( this->_x.size() );
            for ( int j=0; j < this->_x.size(); ++j )
            {
                x_out->push_back( this->_x[j] );
            }
        }
    }

    return _r;
} // ...MosekOpt::optimize()
Exemplo n.º 3
0
int main(int argc,char *argv[])
{
  const MSKint32t numvar = 2,
                  numcon = 2;

  double       c[]   = {  1.0, 0.64 };
  MSKboundkeye bkc[] = { MSK_BK_UP,    MSK_BK_LO };
  double       blc[] = { -MSK_INFINITY,-4.0 };
  double       buc[] = { 250.0,        MSK_INFINITY };

  MSKboundkeye bkx[] = { MSK_BK_LO,    MSK_BK_LO };
  double       blx[] = { 0.0,          0.0 };
  double       bux[] = { MSK_INFINITY, MSK_INFINITY };
  

  MSKint32t    aptrb[] = { 0, 2 },
               aptre[] = { 2, 4 },
               asub[] = { 0,    1,   0,    1 };
  double       aval[] = { 50.0, 3.0, 31.0, -2.0 };
  MSKint32t    i,j;

  MSKenv_t     env = NULL;
  MSKtask_t    task = NULL;
  MSKrescodee  r;

  /* Create the mosek environment. */
  r = MSK_makeenv(&env,NULL);

  /* Check if return code is ok. */
  if ( r==MSK_RES_OK )
  {
    /* Create the optimization task. */
    r = MSK_maketask(env,0,0,&task);

    if ( r==MSK_RES_OK )
      r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
    
    /* Append 'numcon' empty constraints.
     The constraints will initially have no bounds. */
    if ( r == MSK_RES_OK )
      r = MSK_appendcons(task,numcon);

    /* Append 'numvar' variables.
     The variables will initially be fixed at zero (x=0). */
    if ( r == MSK_RES_OK )
      r = MSK_appendvars(task,numvar);

    /* Optionally add a constant term to the objective. */
    if ( r ==MSK_RES_OK )
      r = MSK_putcfix(task,0.0);
    for(j=0; j<numvar && r == MSK_RES_OK; ++j)
    {
      /* Set the linear term c_j in the objective.*/  
      if(r == MSK_RES_OK)
        r = MSK_putcj(task,j,c[j]);

      /* Set the bounds on variable j.
       blx[j] <= x_j <= bux[j] */
      if(r == MSK_RES_OK)
        r = MSK_putvarbound(task,
                            j,           /* Index of variable.*/
                            bkx[j],      /* Bound key.*/
                            blx[j],      /* Numerical value of lower bound.*/
                            bux[j]);     /* Numerical value of upper bound.*/

      /* Input column j of A */   
      if(r == MSK_RES_OK)
        r = MSK_putacol(task,
                        j,                 /* Variable (column) index.*/
                        aptre[j]-aptrb[j], /* Number of non-zeros in column j.*/
                        asub+aptrb[j],     /* Pointer to row indexes of column j.*/
                        aval+aptrb[j]);    /* Pointer to Values of column j.*/
      
    }

    /* Set the bounds on constraints.
       for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
    for(i=0; i<numcon && r==MSK_RES_OK; ++i)
      r = MSK_putconbound(task,
                          i,           /* Index of constraint.*/
                          bkc[i],      /* Bound key.*/
                          blc[i],      /* Numerical value of lower bound.*/
                          buc[i]);     /* Numerical value of upper bound.*/
    
    /* Specify integer variables. */
    for(j=0; j<numvar && r == MSK_RES_OK; ++j)
      r = MSK_putvartype(task,j,MSK_VAR_TYPE_INT);
    
    if ( r==MSK_RES_OK )
      r =  MSK_putobjsense(task,
                           MSK_OBJECTIVE_SENSE_MAXIMIZE);
    
    if ( r==MSK_RES_OK )
    {
      MSKrescodee trmcode;

      /* Run optimizer */
      r = MSK_optimizetrm(task,&trmcode);

      /* Print a summary containing information
         about the solution for debugging purposes*/
      MSK_solutionsummary (task,MSK_STREAM_MSG);

      if ( r==MSK_RES_OK )
      {
        MSKint32t  j;
        MSKsolstae solsta;
        double     *xx = NULL; 

        MSK_getsolsta (task,MSK_SOL_ITG,&solsta);

        xx = calloc(numvar,sizeof(double));
        if ( xx ) 
        {        
          switch(solsta)
          {
             case MSK_SOL_STA_INTEGER_OPTIMAL:
             case MSK_SOL_STA_NEAR_INTEGER_OPTIMAL :             
               MSK_getxx(task,
                         MSK_SOL_ITG,    /* Request the integer solution. */
                         xx);
               
               printf("Optimal solution.\n");
               for(j=0; j<numvar; ++j)
                 printf("x[%d]: %e\n",j,xx[j]);                              
               break;
             case MSK_SOL_STA_PRIM_FEAS:
               /* A feasible but not necessarily optimal solution was located. */
               MSK_getxx(task,MSK_SOL_ITG,xx);
               
               printf("Feasible solution.\n");
               for(j=0; j<numvar; ++j)
                 printf("x[%d]: %e\n",j,xx[j]);               
               break;
             case MSK_SOL_STA_UNKNOWN:
               {
                 MSKprostae prosta; 
                 MSK_getprosta(task,MSK_SOL_ITG,&prosta); 
                 switch (prosta) 
                 {
                    case MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED:
                      printf("Problem status Infeasible or unbounded\n"); 
                      break; 
                    case MSK_PRO_STA_PRIM_INFEAS:
                      printf("Problem status Infeasible.\n"); 
                      break; 
                    case MSK_PRO_STA_UNKNOWN:
                      printf("Problem status unknown.\n"); 
                      break; 
                    default:
                      printf("Other problem status."); 
                      break;
                 }
               }
               break; 
             default:
               printf("Other solution status."); 
               break;               
          }
        }
        else
        {
          r = MSK_RES_ERR_SPACE;
        }
        free(xx);
      }
    }

    if (r != MSK_RES_OK)
    {
      /* In case of an error print error code and description. */
      char symname[MSK_MAX_STR_LEN];
      char desc[MSK_MAX_STR_LEN];

      printf("An error occurred while optimizing.\n");
      MSK_getcodedesc (r,
                       symname,
                       desc);
      printf("Error %s - '%s'\n",symname,desc);
    }

    MSK_deletetask(&task);
  }
  MSK_deleteenv(&env);

  printf("Return code: %d.\n",r);
  return ( r );
} /* main */
Exemplo n.º 4
0
int do_thing()
{
   const MSKint32t numvar = 4,
   numcon = 3;
   
   double       c[]     = {3.0, 1.0, 5.0, 1.0};
   /* Below is the sparse representation of the A
    matrix stored by column. */
   MSKint32t    aptrb[] = {0, 2, 5, 7},
   aptre[] = {2, 5, 7, 9},
   asub[]  = { 0, 1,
      0, 1, 2,
      0, 1,
      1, 2};
   double       aval[]  = { 3.0, 2.0,
      1.0, 1.0, 2.0,
      2.0, 3.0,
      1.0, 3.0};
   
   /* Bounds on constraints. */
   MSKboundkeye bkc[]  = {MSK_BK_FX, MSK_BK_LO,     MSK_BK_UP    };
   double       blc[]  = {30.0,      15.0,          -MSK_INFINITY};
   double       buc[]  = {30.0,      +MSK_INFINITY, 25.0         };
   /* Bounds on variables. */
   MSKboundkeye bkx[]  = {MSK_BK_LO,     MSK_BK_RA, MSK_BK_LO,     MSK_BK_LO     };
   double       blx[]  = {0.0,           0.0,       0.0,           0.0           };
   double       bux[]  = {+MSK_INFINITY, 10.0,      +MSK_INFINITY, +MSK_INFINITY };
   MSKenv_t     env  = NULL;
   MSKtask_t    task = NULL;
   MSKrescodee  r;
   MSKint32t    i,j;
   
   /* Create the mosek environment. */
   r = MSK_makeenv(&env,NULL);
   
   if ( r==MSK_RES_OK )
   {
      /* Create the optimization task. */
      r = MSK_maketask(env,numcon,numvar,&task);
      
      /* Directs the log task stream to the 'printstr' function. */
      if ( r==MSK_RES_OK )
         r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);
      
      /* Append 'numcon' empty constraints.
       The constraints will initially have no bounds. */
      if ( r == MSK_RES_OK )
         r = MSK_appendcons(task,numcon);
      
      /* Append 'numvar' variables.
       The variables will initially be fixed at zero (x=0). */
      if ( r == MSK_RES_OK )
         r = MSK_appendvars(task,numvar);
      
      for(j=0; j<numvar && r == MSK_RES_OK; ++j)
      {
         /* Set the linear term c_j in the objective.*/
         if(r == MSK_RES_OK)
            r = MSK_putcj(task,j,c[j]);
         
         /* Set the bounds on variable j.
          blx[j] <= x_j <= bux[j] */
         if(r == MSK_RES_OK)
            r = MSK_putvarbound(task,
                                j,           /* Index of variable.*/
                                bkx[j],      /* Bound key.*/
                                blx[j],      /* Numerical value of lower bound.*/
                                bux[j]);     /* Numerical value of upper bound.*/
         
         /* Input column j of A */
         if(r == MSK_RES_OK)
            r = MSK_putacol(task,
                            j,                 /* Variable (column) index.*/
                            aptre[j]-aptrb[j], /* Number of non-zeros in column j.*/
                            asub+aptrb[j],     /* Pointer to row indexes of column j.*/
                            aval+aptrb[j]);    /* Pointer to Values of column j.*/
      }
      
      /* Set the bounds on constraints.
       for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
      for(i=0; i<numcon && r==MSK_RES_OK; ++i)
         r = MSK_putconbound(task,
                             i,           /* Index of constraint.*/
                             bkc[i],      /* Bound key.*/
                             blc[i],      /* Numerical value of lower bound.*/
                             buc[i]);     /* Numerical value of upper bound.*/
      
      /* Maximize objective function. */
      if (r == MSK_RES_OK)
         r = MSK_putobjsense(task, MSK_OBJECTIVE_SENSE_MAXIMIZE);
      
      if ( r==MSK_RES_OK )
      {
         MSKrescodee trmcode;
         
         /* Run optimizer */
         r = MSK_optimizetrm(task,&trmcode);
         
         /* Print a summary containing information
          about the solution for debugging purposes. */
         MSK_solutionsummary (task,MSK_STREAM_LOG);
         
         if ( r==MSK_RES_OK )
         {
            MSKsolstae solsta;
            
            if ( r==MSK_RES_OK )
               r = MSK_getsolsta (task,
                                  MSK_SOL_BAS,
                                  &solsta);
            switch(solsta)
            {
               case MSK_SOL_STA_OPTIMAL:
               case MSK_SOL_STA_NEAR_OPTIMAL:
               {
                  double *xx = (double*) calloc(numvar,sizeof(double));
                  if ( xx )
                  {
                     MSK_getxx(task,
                               MSK_SOL_BAS,    /* Request the basic solution. */
                               xx);
                     
                     printf("Optimal primal solution\n");
                     for(j=0; j<numvar; ++j)
                        printf("x[%d]: %e\n",j,xx[j]);
                     
                     free(xx);
                  }
                  else
                     r = MSK_RES_ERR_SPACE;
                  
                  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:
                  printf("Primal or dual infeasibility certificate found.\n");
                  break;
               case MSK_SOL_STA_UNKNOWN:
               {
                  char symname[MSK_MAX_STR_LEN];
                  char desc[MSK_MAX_STR_LEN];
                  
                  /* If the solutions status is unknown, print the termination code
                   indicating why the optimizer terminated prematurely. */
                  
                  MSK_getcodedesc(trmcode,
                                  symname,
                                  desc);
                  
                  printf("The solution status is unknown.\n");
                  printf("The optimizer terminitated with code: %s\n",symname);
                  break;
               }
               default:
                  printf("Other solution status.\n");
                  break;
            }
         }
      }
      
      if (r != MSK_RES_OK)
      {
         /* In case of an error print error code and description. */
         char symname[MSK_MAX_STR_LEN];
         char desc[MSK_MAX_STR_LEN];
         
         printf("An error occurred while optimizing.\n");     
         MSK_getcodedesc (r,
                          symname,
                          desc);
         printf("Error %s - '%s'\n",symname,desc);
      }
      
      /* Delete the task and the associated data. */
      MSK_deletetask(&task);
   }
   
   /* Delete the environment and the associated data. */
   MSK_deleteenv(&env);
   
   return r;
}