# Obtaining information

In addition to the Knitro log that is printed on screen, information about the computation performed by Knitro is available in the form of various function calls. This section explains how this information can be retrieved and interpreted.

## Knitro output for continuous problems

This section describes Knitro outputs at various levels
for continuous problems. We examine the output that results from running
`examples/C/exampleNLP1.c`

with full output.

Note

If `outlev=0`

then all printing of output is suppressed.
If `outlev`

is positive, then Knitro prints
information about the solution of your optimization problem either to
standard output (`outmode`

= *screen*), to a file named
`knitro.log`

(`outmode`

= *file*), or to
both (`outmode`

= *both*).
The option `outdir`

controls the directory where output files are
created (if any are) and the option `outappend`

controls whether
output is appended to existing files.

Display of Nondefault Options

Knitro first prints the banner displaying the Artelys license type
and version of Knitro that is installed.
It then lists all user options which are different from their default values
If nothing is listed in this section then it must be that all user options
are set to their default values.
Lastly, Knitro prints messages that describe how it resolved user
options that were set to automatic values.
For example, if option `algorithm`

= *auto*, then Knitro
prints the algorithm that it chooses.

```
=======================================
Commercial License
Artelys Knitro 12.0.0
=======================================
Knitro presolve eliminated 0 variables and 0 constraints.
outlev: 6
Knitro changing algorithm from AUTO to 1.
Knitro changing bar_initpt from AUTO to 3.
Knitro changing bar_murule from AUTO to 4.
Knitro changing bar_penaltycons from AUTO to 1.
Knitro changing bar_penaltyrule from AUTO to 2.
Knitro changing bar_switchrule from AUTO to 2.
Knitro changing linesearch from AUTO to 1.
Knitro changing linsolver from AUTO to 2.
```

In the example above, it is indicated that we are using a more verbose
output level (`outlev`

= 6) instead of the default value
(`outlev`

= 2).
Knitro chose algorithm 1 (Interior/Direct), and then automatically
determined some other options related to the algorithm.

Display of problem characteristics

Knitro next prints a summary description of the problem characteristics including the number and type of variables and constraints and the number of nonzero elements in the Jacobian matrix and Hessian matrix. If the Knitro presolver is enabled, then information about the presolved form of the problem is printed as well.

```
Problem Characteristics ( Presolved)
-----------------------
Objective goal: Minimize
Objective type: general
Number of variables: 2 ( 2)
bounded below only: 0 ( 0)
bounded above only: 1 ( 1)
bounded below and above: 0 ( 0)
fixed: 0 ( 0)
free: 1 ( 1)
Number of constraints: 2 ( 2)
linear equalities: 0 ( 0)
quadratic equalities: 0 ( 0)
gen. nonlinear equalities: 0 ( 0)
linear one-sided inequalities: 0 ( 0)
quadratic one-sided inequalities: 2 ( 2)
gen. nonlinear one-sided inequalities: 0 ( 0)
linear two-sided inequalities: 0 ( 0)
quadratic two-sided inequalities: 0 ( 0)
gen. nonlinear two-sided inequalities: 0 ( 0)
Number of nonzeros in Jacobian: 4 ( 4)
Number of nonzeros in Hessian: 3 ( 3)
```

Display of Iteration Information

Next, if `outlev`

is greater than 2, Knitro prints
columns of data reflecting detailed information about individual
iterations during the solution process.
An iteration is defined as a step
which generates a new solution estimate (i.e., a successful step).

If `outlev`

= 2, summary data is printed every 10
iterations, and on the final iteration. If
`outlev`

= 3, summary data is printed every
iteration. If `outlev`

= 4, the most verbose
iteration information is printed every iteration.

```
Iter fCount Objective FeasError OptError ||Step|| CGits
-------- -------- -------------- ---------- ---------- ---------- -------
0 7 9.090000e+02 3.000e+00
1 8 7.996681e+02 2.859e+00 2.186e+01 7.226e-02 0
2 9 1.859212e+01 9.066e-01 3.943e+01 2.199e+00 0
3 17 3.280079e+02 8.816e-01 6.903e+00 1.356e+00 8
4 18 1.445972e+01 4.912e-01 6.736e-01 1.173e+00 2
5 19 3.562070e+01 3.874e-01 3.874e-01 1.929e-01 0
6 20 1.153310e+02 2.196e-01 5.652e-01 4.098e-01 0
7 21 2.363651e+02 7.226e-02 7.226e-02 4.156e-01 0
8 22 3.018949e+02 5.268e-03 1.827e-02 1.861e-01 0
9 23 3.064952e+02 6.791e-06 1.513e-04 1.267e-02 0
10 24 3.065000e+02 9.480e-11 9.480e-11 1.358e-05 0
```

The meaning of each column is described below.

**Iter**: iteration number.**fCount**: the cumulative number of (nonlinear) function evalutions. (This information is only printed if`outlev`

is greater than 3).**Objective**: the value of the objective function at the current iterate.**FeasError**: a measure of the feasibility violation at the current iterate**OptError**: a measure of the violation of the Karush-Kuhn-Tucker (KKT) (first-order) optimality conditions (not including feasibility) at the current iterate.**Step**: the 2-norm length of the step (i.e., the distance between the new iterate and the previous iterate).**CGits**: the number of Projected Conjugate Gradient (CG) iterations required to compute the step.

Display of termination status

At the end of the run a termination message is printed indicating whether or not the optimal solution was found and if not, why Knitro stopped. The termination message typically starts with the word “EXIT”. If Knitro was successful in satisfying the termination test, the message will look as follows:

```
EXIT: Locally optimal solution found.
```

Display of Final Statistics

Following the termination message, a summary of some final statistics on the run are printed. Both relative and absolute error values are printed.

```
Final Statistics
----------------
Final objective value = 3.06499999937285e+02
Final feasibility error (abs / rel) = 9.48e-11 / 3.16e-11
Final optimality error (abs / rel) = 9.48e-11 / 6.50e-12
# of iterations = 10
# of CG iterations = 10
# of function evaluations = 24
# of gradient evaluations = 15
# of Hessian evaluations = 10
Total program time (secs) = 0.00258 ( 0.002 CPU time)
Time spent in evaluations (secs) = 0.00002
```

Display of solution vector and constraints

If `outlev`

equals 5 or 6, the values of the solution vector are printed
after the final statistics. If `outlev`

equals 6, the final constraint
values are also printed, and the values of the
Lagrange multipliers (or dual variables) are printed next to their corresponding
constraint or bound.

```
Constraint Vector Lagrange Multipliers
----------------- ---------------------
c[ 0] = 9.99999999905e-01, lambda[ 0] = -6.99999999925e+02
c[ 1] = 4.49999999927e+00, lambda[ 1] = -8.09211653221e-10
Solution Vector
---------------
x[ 0] = 4.99999999998e-01, lambda[ 2] = 1.75099999969e+03
x[ 1] = 1.99999999982e+00, lambda[ 3] = 0.00000000000e+00
```

Debugging / profiling information

Knitro can produce
additional information which may be useful in debugging or analyzing
performance. If `outlev`

is positive and
`debug`

= 1, then multiple files named `kdbg_*.log`

are
created which contain detailed information on performance.
If `outlev`

is positive and `debug`

= 2,
then Knitro prints information useful for debugging program execution.
The information produced by `debug`

is primarily intended for developers, and should not be
used in a production setting.

Intermediate iterates

Users can generate a file containing iterates and/or solution points
with option `newpoint`

. The output file is called
`knitro_newpoint.log`

.

## Knitro output for discrete problems

This section describes Knitro outputs at various levels
for discrete or mixed integer problems. We examine the output
that results from running `examples/C/callbackMINLP1.c`

.

Note

When `outlev`

is positive, the options `mip_outlevel`

,
`mip_debug`

, `mip_outinterval`

and
`mip_outsub`

control the
amount and type of MIP output generated as described below.

Knitro first prints the banner displaying the license type
and version of Knitro that is installed.
It then lists all user options which are different from their default values.
If nothing is listed in this section then it must be that all user options
are set to their default values.
Lastly, Knitro prints messages that describe how it resolved user
options that were set to automatic values. For example, if
option `mip_branchrule`

= *auto*,
then Knitro prints the branching rule that it chooses.

```
=======================================
Commercial License
Artelys Knitro 12.0.0
=======================================
mip_method: 1
mip_outinterval: 1
Knitro changing mip_rootalg from AUTO to 1.
Knitro changing mip_lpalg from AUTO to 3.
Knitro changing mip_branchrule from AUTO to 2.
Knitro changing mip_selectrule from AUTO to 2.
Knitro changing mip_rounding from AUTO to 3.
Knitro changing mip_heuristic from AUTO to 2.
Knitro changing mip_pseudoinit from AUTO to 1.
```

In the example above, it is indicated that we are using
`mip_method`

= 1 which is the standard branch and bound method,
and that we are printing output
information at every node since `mip_outinterval`

= 1.
It then determined seven other options related to the MIP method.

Display of Problem Characteristics

Knitro next prints a summary description of the problem characteristics including the number and type of variables and constraints and the number of nonzero elements in the Jacobian matrix and Hessian matrix (if providing the exact Hessian).

If no initial point is provided by the user, Knitro indicates that it is computing one. Knitro also prints the results of any MIP preprocessing to detect special structure and indicates which MIP method it is using.

```
Problem Characteristics
-----------------------
Objective goal: Minimize
Objective type: general
Number of variables: 6
bounded below only: 0
bounded above only: 0
bounded below and above: 6
fixed: 0
free: 0
Number of binary variables: 3
Number of integer variables: 0
Number of constraints: 6
linear equalities: 0
quadratic equalities: 0
gen. nonlinear equalities: 0
linear one-sided inequalities: 4
quadratic one-sided inequalities: 0
gen. nonlinear one-sided inequalities: 2
linear two-sided inequalities: 0
quadratic two-sided inequalities: 0
gen. nonlinear two-sided inequalities: 0
Number of nonzeros in Jacobian: 16
Number of nonzeros in Hessian: 3
No start point provided -- Knitro computing one.
Knitro detected 1 GUB constraints
Knitro derived 0 knapsack covers after examining 3 constraints
Knitro solving root node relaxation
Knitro searching for integer feasible point using heuristic
* iter = 1: Iinf = 0, FeasError = 2.068e-26, Obj = 1.000e+01
Knitro found integer feasible point in 1 heuristic iteration
Knitro MIP using Branch and Bound method
```

Display of Node Information

Next, if `mip_outlevel`

= 1, Knitro prints
columns of data reflecting detailed information about individual
nodes during the solution process.
If `mip_outlevel`

= 2, the accumulated time is printed at
each node also.
The frequency of this node
information is controlled by the `mip_outinterval`

parameter.
For example, if `mip_outinterval`

= 100, this node information
is printed only for every 100th node (printing output less
frequently may save significant CPU time in some cases). In the example
below, `mip_outinterval`

= 1, so information about every node is
printed (without the accumulated time).

```
Node Left Iinf Objective Best Relaxatn Best Incumbent
------ ------ ------ -------------- -------------- --------------
1 0 2 7.592844e-01 7.592844e-01 1.000000e+01
2 1 1 5.171320e+00 7.592844e-01 1.000000e+01
* 2 1 r 7.671320e+00
* 3 2 0 6.009759e+00 f 5.171320e+00 6.009759e+00
4 1 1.000000e+01 pr 5.171320e+00 6.009759e+00
5 0 7.092732e+00 pr 6.009759e+00 6.009759e+00
```

The meaning of each column is described below.

**Node:**the node number. If an integer feasible point was found at a given node, then it is marked with a star (*).**Left:**the current number of active nodes left in the branch and bound tree.**Iinf:**the number of integer infeasible variables at the current node solution.**Objective:**the value of the objective function at the solution of the relaxed subproblem solved at the current node. If the subproblem was infeasible or failed, this is indicated. Additional symbols may be printed at some nodes if the node was pruned (*pr*), integer feasible (*f*), or an integer feasible point was found through rounding (*r*).**Best relaxatn:**the value of the current best relaxation (lower bound on the solution if minimizing).**Best incumbent:**the value of the current best integer feasible point (upper bound on the solution if minimizing).

Display of Termination Status

At the end of the run a termination message is printed indicating whether or not the optimal solution was found and if not, why Knitro stopped. The termination message typically starts with the word “EXIT”. If Knitro was successful in satisfying the termination test, the message will look as follows:

```
EXIT: Optimal solution found.
```

See the reference manual (Return codes) for a list of possible termination
messages and a description of their meaning and the corresponding
value returned by `KN_solve()`

.

Display of Final Statistics

Following the termination message, a summary of some final statistics on the run are printed.

```
Final Statistics for MIP
------------------------
Final objective value = 6.00975890892825e+00
Final integrality gap (abs / rel) = 0.00e+00 / 0.00e+00 (0.00%)
# of nodes processed = 5
# of subproblems solved = 8
Total program time (secs) = 0.09930 (0.099 CPU time)
Time spent in evaluations (secs) = 0.00117
```

Display of Solution Vector and Constraints

If `outlev`

equals 5 or 6, the values of the solution vector are printed
after the final statistics. If `outlev`

equals 6, the constraint values
at the solution are also printed.

```
Solution Vector
---------------
x[0] = 1.30097589089e+00
x[1] = 0.00000000000e+00
x[2] = 1.00000000000e+00
x[3] = 0.00000000000e+00 (binary variable)
x[4] = 1.00000000000e+00 (binary variable)
x[5] = 0.00000000000e+00 (binary variable)
```

Knitro can produce
additional information which may be useful in debugging or analyzing
MIP performance. If `outlev`

is positive and
`mip_debug`

= 1, then the file named `kdbg_mip.log`

is
created which contains detailed information on the MIP performance.
In addition, if `mip_outsub`

= 1, this file will contain
extensive output for each subproblem solve in the MIP solution process.
The information produced by `mip_debug`

is primarily intended for developers, and should not be
used in a production setting.

## Getting information programmatically in callable library

Important solution information from Knitro can be retrieved through special API function calls.

Information related to the final statistics can be retrieved through the following function calls. The precise meaning of each function is described in the reference manual (Callable library API reference).

```
int KNITRO_API KN_get_number_FC_evals (const KN_context_ptr kc,
int * const numFCevals);
int KNITRO_API KN_get_number_GA_evals (const KN_context_ptr kc,
int * const numGAevals);
int KNITRO_API KN_get_number_H_evals (const KN_context_ptr kc,
int * const numHevals);
int KNITRO_API KN_get_number_HV_evals (const KN_context_ptr kc,
int * const numHVevals);
int KNITRO_API KN_get_solution (const KN_context_ptr kc,
int * const status,
double * const obj,
double * const x,
double * const lambda);
int KNITRO_API KN_get_obj_value (const KN_context_ptr kc,
double * const obj);
int KNITRO_API KN_get_con_values (const KN_context_ptr kc,
const KNINT nC,
const KNINT * const indexCons,
double * const c);
int KNITRO_API KN_get_rsd_values (const KN_context_ptr kc,
const KNINT nR,
const KNINT * const indexRsds,
double * const r);
```

Continuous problems

```
int KNITRO_API KN_get_number_iters (const KN_context_ptr kc,
int * const numIters);
int KNITRO_API KN_get_number_cg_iters (const KN_context_ptr kc,
int * const numCGiters);
int KNITRO_API KN_get_abs_feas_error (const KN_context_ptr kc,
double * const absFeasError);
int KNITRO_API KN_get_rel_feas_error (const KN_context_ptr kc,
double * const relFeasError);
int KNITRO_API KN_get_abs_opt_error (const KN_context_ptr kc,
double * const absOptError);
int KNITRO_API KN_get_rel_opt_error (const KN_context_ptr kc,
double * const relOptError);
int KNITRO_API KN_get_objgrad_nnz (const KN_context_ptr kc,
KNINT * const nnz);
int KNITRO_API KN_get_objgrad_values (const KN_context_ptr kc,
KNINT * const indexVars,
double * const objGrad);
int KNITRO_API KN_get_objgrad_values_all (const KN_context_ptr kc,
double * const objGrad);
int KNITRO_API KN_get_jacobian_nnz (const KN_context_ptr kc,
KNLONG * const nnz);
int KNITRO_API KN_get_jacobian_values (const KN_context_ptr kc,
KNINT * const indexCons,
KNINT * const indexVars,
double * const jac);
int KNITRO_API KN_get_rsd_jacobian_nnz (const KN_context_ptr kc,
KNLONG * const nnz);
int KNITRO_API KN_get_rsd_jacobian_values (const KN_context_ptr kc,
KNINT * const indexRsds,
KNINT * const indexVars,
double * const rsdJac);
int KNITRO_API KN_get_hessian_nnz (const KN_context_ptr kc,
KNLONG * const nnz);
int KNITRO_API KN_get_hessian_values (const KN_context_ptr kc,
KNINT * const indexVars1,
KNINT * const indexVars2,
double * const hess);
```

Discrete or mixed integer problems

```
int KNITRO_API KN_get_mip_number_nodes (const KN_context_ptr kc,
int * const numNodes);
int KNITRO_API KN_get_mip_number_solves (const KN_context_ptr kc,
int * const numSolves);
int KNITRO_API KN_get_mip_abs_gap (const KN_context_ptr kc,
double * const absGap);
int KNITRO_API KN_get_mip_rel_gap (const KN_context_ptr kc,
double * const relGap);
int KNITRO_API KN_get_mip_incumbent_obj (const KN_context_ptr kc,
double * const incumbentObj);
int KNITRO_API KN_get_mip_relaxation_bnd (const KN_context_ptr kc,
double * const relaxBound);
int KNITRO_API KN_get_mip_lastnode_obj (const KN_context_ptr kc,
double * const lastNodeObj);
int KNITRO_API KN_get_mip_incumbent_x (const KN_context_ptr kc,
double * const x);
```

## Getting information programmatically in the object-oriented interface

Solution information can be retrieved after a call to
`KTRSolver::solve()`

. After `solve()`

is called, `KTRSolver::getObj()`

returns the objective function value, and `KTRSolver::getXValues()`

and `KTRSolver::getLambdaValues()`

return the final primal and
and dual variable values, respectively. The solution status code
is returned by `KTRSolver::solve()`

method.

In addition, information related to the final statistics can be
retrieved through the following `KTRSolver`

methods.
The precise meaning of each function is described in the reference manual
(Callable library API reference).

```
int KTRSolver::getNumberFCEvals();
int KTRSolver::getNumberGAEvals();
int KTRSolver::getNumberHEvals();
int KTRSolver::getNumberHVEvals();
std::vector<double> KTRSolver::getConstraintValues();
```

Continuous problems

```
int KTRSolver::getNumberIters();
int KTRSolver::getNumberCGIters();
double KTRSolver::getAbsFeasError();
double KTRSolver::getRelFeasError();
double KTRSolver::getAbsOptError();
double KTRSolver::getRelOptError();
std::vector<double> KTRSolver::getObjgradValues();
std::vector<double> KTRSolver::getJacobianValues();
std::vector<double> KTRSolver::getHessianValues();
```

Discrete or mixed integer problems

```
int KTRSolver::getMipNumNodes();
int KTRSolver::getMipNumSolves();
double KTRSolver::getMipAbsGap();
double KTRSolver::getMipRelGap();
double KTRSolver::getMipIncumbentObj();
std::vector<double> KTRSolver::getMipIncumbentX );
double KTRSolver::getMipRelaxationBnd();
double KTRSolver::getMipLastnodeObj();
```

## User-defined names in Knitro output

By default Knitro uses *x* for variable names and *c* for constraint names
in the output. However, the user can define more meaningful and customized names
for the objective function, the variables and the constraint functions through the
the API functions `KN_set_obj_name()`

, `KN_set_var_names()`

,
`KN_set_con_names()`

, and `KN_set_compcon_names()`

when using the callable library API.

When using the AMPL modeling language, you can have Knitro output objective function, variable and constraint names specified in the AMPL model by issuing the following command in the AMPL session:

```
option knitroampl_auxfiles rc;
```

## Suppressing all output in AMPL

Even when setting the options:

```
ampl: option solver_msg 0;
ampl: option knitro_options "outlev=0";
```

in an AMPL session, AMPL will still print some basic information like the solver name and non-default user option settings to the screen. In order to suppress all AMPL and Knitro output you must change your AMPL solve commands to something like:

```
ampl: solve >scratch-file;
```

where scratch-file is the name of some temporary file where the unwanted output can be sent. Under Unix, “solve >/dev/null” automatically throws away the unwanted output and under Windows, “solve > NUL” does the same.

## AMPL solution information through suffixes

Some Knitro solution information can be retrieved and displayed through AMPL
using AMPL suffixes defined for Knitro (see AMPL suffixes defined for Knitro). In particular, when solving a MIP
using Knitro/AMPL, the best relaxation bound and the incumbent solution
can be displayed using the *relaxbnd* and *incumbent* suffixes. For example,
if the objective function is named *obj*, then:

```
ampl: display obj.relaxbnd;
```

give the current relaxation bound and:

```
ampl: display obj.incumbent;
```

will give the current incumbent solution (if one exists).

## AMPL presolve

AMPL will often perform a reordering of the variables and constraints defined in the AMPL model. The AMPL presolver may also simplify the form of the problem by eliminating certain variables or constraints. The output printed by Knitro corresponds to the reordered, reformulated problem. To view final variable and constraint values in the original AMPL model, use the AMPL display command after Knitro has completed solving the problem.

It is possible to correlate Knitro variables and constraints with the original AMPL model. You must type an extra command in the AMPL session:

```
option knitroampl_auxfiles rc;
```

and set Knitro option `presolve_dbg`

= 2. Then the solver will
print the variables and constraints that Knitro receives, with their
upper and lower bounds, and their AMPL model names. The extra AMPL command
causes the model names to be passed to the Knitro/AMPL solver.

The output below is obtained with the
example file `testproblem.mod`

supplied with the distribution.
The center column of variable and constraint names are those used by
Knitro, while the names in the right-hand column are from the AMPL model:

```
ampl: model testproblem.mod;
ampl: option solver knitroampl;
ampl: option knitroampl_auxfiles rc;
ampl: option knitro_options "presolve_dbg=2 outlev=0";
Knitro 12.0.0: presolve_dbg=2
outlev=0
----- AMPL problem for Knitro -----
Objective name: obj
0.000000e+00 <= x[ 0] <= 1.000000e+20 x[1]
0.000000e+00 <= x[ 1] <= 1.000000e+20 x[2]
0.000000e+00 <= x[ 2] <= 1.000000e+20 x[3]
2.500000e+01 <= c[ 0] <= 1.000000e+20 c2 (general)
5.600000e+01 <= c[ 1] <= 5.600000e+01 c1 (linear)
-----------------------------------
Knitro 12.0.0: Locally optimal or satisfactory solution.
objective 935.9999978; feasibility error 6.74e-08
5 iterations; 7 function evaluations
```