7.1 Accessing the solution

This section contains important information about the status of the solver and the status of the solution, which must be checked in order to properly interpret the results of the optimization.

7.1.1 Solver termination

The optimizer provides a response code of type rescode, relevant for error handling. It indicates if any errors occurred in any phase of optimization (including processing input data). It will also indicate system-related errors (such as an out of memory error, licensing error etc.). Finally, it will also indicate if the optimizer terminated correctly, but for a non-standard reason, for example because it reached a time limit or met another criterion set by the user. Such termination codes are not errors. The expected value for a typical successful optimization without any special settings is "MSK_RES_OK".

If a runtime error causes the program to crash during optimization, the first debugging step is to enable logging and check the log output. See Sec. 7.3 (Input/Output).

If the optimization completes successfully, the next step is to check the solution status, as explained below.

7.1.2 Available solutions

MOSEK uses three kinds of optimizers and provides three types of solutions:

  • basic solution from the simplex optimizer,

  • interior-point solution from the interior-point optimizer,

  • integer solution from the mixed-integer optimizer.

Under standard parameters settings the following solutions will be available for various problem types:

Table 7.1 Types of solutions available from MOSEK

Simplex optimizer

Interior-point optimizer

Mixed-integer optimizer

Linear problem

res.sol.bas

res.sol.itr

Nonlinear continuous problem

res.sol.itr

Problem with integer variables

res.sol.int

For linear problems the user can force a specific optimizer choice making only one of the two solutions available. For example, if the user disables basis identification, then only the interior point solution will be available for a linear problem. Numerical issues may cause one of the solutions to be unknown even if another one is feasible.

Not all components of a solution are always available. For example, there is no dual solution for integer problems and no dual conic variables from the simplex optimizer.

The user will always need to specify which solution should be accessed.

7.1.3 Problem and solution status

Assuming that the optimization terminated without errors, the next important step is to check the problem and solution status. There is one for every type of solution, as explained above.

Problem status

Problem status (prosta) determines whether the problem is certified as feasible. Its values can roughly be divided into the following broad categories:

  • feasible — the problem is feasible. For continuous problems and when the solver is run with default parameters, the feasibility status should ideally be "MSK_PRO_STA_PRIM_AND_DUAL_FEAS".

  • primal/dual infeasible — the problem is infeasible or unbounded or a combination of those. The exact problem status will indicate the type of infeasibility.

  • unknown — the solver was unable to reach a conclusion, most likely due to numerical issues.

Solution status

Solution status (solsta) provides the information about what the solution values actually contain. The most important broad categories of values are:

  • optimal ("MSK_SOL_STA_OPTIMAL") — the solution values are feasible and optimal.

  • certificate — the solution is in fact a certificate of infeasibility (primal or dual, depending on the solution).

  • unknown/undefined — the solver could not solve the problem or this type of solution is not available for a given problem.

Problem and solution status can be found in the fields prosta and solsta of a solution structure solution, for instance res.sol.itr.prosta, res.sol.itr.solsta for the interior-point solution.

The solution status determines the action to be taken. For example, in some cases a suboptimal solution may still be valuable and deserve attention. It is the user’s responsibility to check the status and quality of the solution.

Typical status reports

Here are the most typical optimization outcomes described in terms of the problem and solution statuses. Note that these do not cover all possible situations that can occur.

Table 7.2 Continuous problems (solution status for interior-point and basic solution)

Outcome

Problem status

Solution status

Optimal

"MSK_PRO_STA_PRIM_AND_DUAL_FEAS"

"MSK_SOL_STA_OPTIMAL"

Primal infeasible

"MSK_PRO_STA_PRIM_INFEAS"

"MSK_SOL_STA_PRIM_INFEAS_CER"

Dual infeasible (unbounded)

"MSK_PRO_STA_DUAL_INFEAS"

"MSK_SOL_STA_DUAL_INFEAS_CER"

Uncertain (stall, numerical issues, etc.)

"MSK_PRO_STA_UNKNOWN"

"MSK_SOL_STA_UNKNOWN"

Table 7.3 Integer problems (solution status for integer solution, others undefined)

Outcome

Problem status

Solution status

Integer optimal

"MSK_PRO_STA_PRIM_FEAS"

"MSK_SOL_STA_INTEGER_OPTIMAL"

Infeasible

"MSK_PRO_STA_PRIM_INFEAS"

"MSK_SOL_STA_UNKNOWN"

Integer feasible point

"MSK_PRO_STA_PRIM_FEAS"

"MSK_SOL_STA_PRIM_FEAS"

No conclusion

"MSK_PRO_STA_UNKNOWN"

"MSK_SOL_STA_UNKNOWN"

7.1.4 Retrieving solution values

After the meaning and quality of the solution (or certificate) have been established, we can query for the actual numerical values. They can be accessed using:

  • res.sol.itr.pobjval, res.sol.itr.dobjval — the primal and dual objective value.

  • res.sol.itr.xx — solution values for the variables.

  • res.sol.itr.y, res.sol.itr.slx and so on — dual values for the linear constraints

and many other fields of the solution structure (replace itr with bas or int for other solution types). Note that if the optimization failed then the res.sol field may not exist and attempting to access it will cause an error.

7.1.5 Source code example

Below is a source code example with a simple framework for assessing and retrieving the solution to a conic optimization problem.

Listing 7.1 Sample framework for checking optimization result. Click here to download.
function response(inputfile)

  cmd = sprintf('read(%s)', inputfile)
  % In this example we read the problem from file
  [r, res] = mosekopt(cmd)

  % Read was successful
  if strcmp(res.rcodestr, 'MSK_RES_OK')

      prob = res.prob;
      param = []

      % (Optionally) Uncomment the next line to get solution status Unknown
      % param.MSK_IPAR_INTPNT_MAX_ITERATIONS = 1

      % Perform the optimization.
      [r, res] = mosekopt('minimize', prob, param); 

      % Expected result: The solution status of the interior-point solution is optimal.

      % Check if we have non-error termination code or OK
      if isempty(strfind(res.rcodestr, 'MSK_RES_ERR'))
      
          solsta = strcat('MSK_SOL_STA_', res.sol.itr.solsta)

          if strcmp(solsta, 'MSK_SOL_STA_OPTIMAL')
              fprintf('An optimal interior-point solution is located:\n');
              res.sol.itr.xx;
              
          elseif strcmp(solsta, 'MSK_SOL_STA_DUAL_INFEASIBLE_CER')
              fprintf('Dual infeasibility certificate found.');

          elseif strcmp(solsta, 'MSK_SOL_STA_PRIMAL_INFEASIBLE_CER')
              fprintf('Primal infeasibility certificate found.');

          elseif strcmp(solsta, 'MSK_SOL_STA_UNKNOWN') 
              % The solutions status is unknown. The termination code 
              % indicates why the optimizer terminated prematurely. 
              fprintf('The solution status is unknown.\n');
              fprintf('Termination code: %s (%d) %s.\n', res.rcodestr, res.rcode, res.rmsg);  
          else
            fprintf('An unexpected solution status is obtained.');
          end
      
      else
          fprintf('Error during optimization: %s (%d) %s.\n', res.rcodestr, res.rcode, res.rmsg);  
      end

  else
      fprintf('Could not read input file, error: %s (%d) %s.\n', res.rcodestr, res.rcode, res.rmsg)
  end

end