# Getting started with the object-oriented interface

The Knitro object-oriented interface provides an object-oriented wrapper around the Knitro callable library. The interface is available in C++, C#, and Java. This document focuses on the C++ version of the interface. The interfaces are the same in functionality, differing only in language syntax and data types used in functions (e.g., std::vector<> in C++, IList<> in C#, and List<> in Java). Examples for each of the languages are available in the Knitro examples folders.

Complete source code for the interface is included with Knitro for informational purposes.
Usage requires including the `knitro.h`

header within the `include`

directory
of Knitro and linking against the appropriate Knitro library file within the
`lib`

directory of Knitro.

The object-oriented API is used to solve an optimization problem through a sequence of function calls:

`KNProblem instance`

: create an instance of the problem to be solved by Knitro. The class is user-defined, inherits from the KNProblem class, and defines the problem characteristics.`KNSolver solver(instance)`

: load the problem definition into the Knitro solver and check out a Knitro license.`solver.solve()`

: solve the problem, with output stored in the`solver`

object.

The example below shows how to define a problem and class and use these function calls.

## First example

The follwing defines the same toy problem solved using AMPL, MATLAB, and the callable library.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | ```
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* This example demonstrates how to use Knitro to solve the following
* simple quadratically constrained quadratic programming problem (QCQP).
*
* min 1000 - x0^2 - 2 x1^2 - x2^2 - x0 x1 - x0 x2
* s.t. 8 x0 + 14 x1 + 7 x2 = 56
* x0^2 + x1^2 + x2^2 >= 25
* x0 >= 0, x1 >= 0, x2 >= 0
*
* The start point (2, 2, 2) converges to the minimum at (0, 0, 8),
* with final objective = 936.0. From a different start point,
* Knitro may converge to an alternate local solution at (7, 0, 0),
* with objective = 951.0.
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#include "KNSolver.h"
#include "KNProblem.h"
using namespace knitro;
class ProblemQCQP1 : public knitro::KNProblem {
public:
ProblemQCQP1() : KNProblem(3,2) {
// Variables
this->setVarLoBnds({{0, 0, 0}});
this->setXInitial({{2.0, 2.0, 2.0}});
// Constraints Strucutres
// -> Linear parts (in 1 constraint (0))
// 8 x0 + 14 x1 + 7 x2
this->getConstraintsLinearParts().add(0, {{ 0, 1, 2}, {8.0, 14.0, 7.0}});
// -> Quaddratic parts (in 1 constraint (1))
// x0^2 + x1^2 + x2^2
this->getConstraintsQuadraticParts().add(1, {{ 0, 1, 2}, {0, 1, 2}, {1.0, 1.0, 1.0}});
// Bounds
// c0 = 56
// c1 >= 25
this->getConEqBnds().set({0}, {56.0});
this->getConLoBnds().set({1}, {25.0});
// Objective structure
this->setObjConstPart(1000.0);
// -> Objective quadratic structure
// - x0^2 - 2 x1^2 - x2^2 - x0 x1 - x0 x2
this->setObjectiveQuadraticPart({ { 0, 1, 2, 0, 0}, { 0, 1, 2, 1, 2}, {-1.0, -2.0, -1.0, -1.0, -1.0} });
}
};
int main() {
// Create a problem instance.
ProblemQCQP1 instance = ProblemQCQP1();
// Create a solver
knitro::KNSolver solver(&instance);
solver.initProblem();
int solveStatus = solver.solve();
std::vector<double> x;
std::vector<double> lambda;
int nStatus = solver.getSolution(x, lambda);
printf ("Knitro converged with final status = %d\n", nStatus);
printf (" optimal objective value = %e\n", solver.getObjValue());
printf (" optimal primal values x = (%e, %e, %e)\n", x[0], x[1], x[2]);
printf (" feasibility violation = %e\n", solver.getAbsFeasError());
printf (" KKT optimality violation = %e\n", solver.getAbsOptError());
return 0;
}
``` |

This is similar to the callable library example. The problem definition is contained in a class definition and is simpler. Variable and constraint properties can be defined more compactly; memory for the problem characteristics does not need to be allocated by the user; and the Jacobian sparsity pattern is automatically defined internally by Knitro because no Jacobian non-zero size is need for linear and quadratic elements of a problem.

The Knitro solver functions are called from the `KNSolver`

class. Like the
callable library, the object-oriented interface does not provide automatic
derivatives. Derivatives can be computed manually and defined in the `KNProblem`

class. This is covered in the chapter on Derivatives.

The above example can be compiled and linked against Knitro, and produces the same output as the callable library output.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | ```
=======================================
Commercial License
Artelys Knitro 14.0.0
=======================================
Knitro presolve eliminated 0 variables and 0 constraints.
The problem is identified as a QCQP.
Problem Characteristics ( Presolved)
-----------------------
Objective goal: Minimize
Objective type: quadratic
Number of variables: 3 ( 3)
bounded below only: 3 ( 3)
bounded above only: 0 ( 0)
bounded below and above: 0 ( 0)
fixed: 0 ( 0)
free: 0 ( 0)
Number of constraints: 2 ( 2)
linear equalities: 1 ( 1)
quadratic equalities: 0 ( 0)
gen. nonlinear equalities: 0 ( 0)
linear one-sided inequalities: 0 ( 0)
quadratic one-sided inequalities: 1 ( 1)
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: 6 ( 6)
Number of nonzeros in Hessian: 5 ( 5)
Iter Objective FeasError OptError ||Step|| CGits
-------- -------------- ---------- ---------- ---------- -------
0 9.760000e+02 1.300e+01
9 9.360000e+02 0.000e+00 1.515e-09 5.910e-05 0
Knitro using the Interior-Point/Barrier Direct algorithm.
EXIT: Locally optimal solution found.
HINT: Knitro spent 8.5% of solution time (0.000707 secs) checking model
convexity. To skip the automatic convexity checker for QPs and QCQPs,
explicity set the user option convex=0 or convex=1.
Final Statistics
----------------
Final objective value = 9.36000000015579e+02
Final feasibility error (abs / rel) = 0.00e+00 / 0.00e+00
Final optimality error (abs / rel) = 1.51e-09 / 9.47e-11
# of iterations = 9
# of CG iterations = 2
# of function evaluations = 0
# of gradient evaluations = 0
# of Hessian evaluations = 0
Total program time (secs) = 0.00791 ( 0.004 CPU time)
Time spent in evaluations (secs) = 0.00000
===============================================================================
Knitro converged with final status = 0
optimal objective value = 9.360000e+02
optimal primal values x = (1.514577e-09, 1.484136e-14, 8.000000e+00)
feasibility violation = 0.000000e+00
KKT optimality violation = 1.514577e-09
``` |

The object-oriented interface provide ease-of-use over the callable library with similar functionality and performance.

## Further information

Another chapter of this documentation is dedicated to the object-oriented interface (Object-oriented interface reference). The reference manual chapter on the callable library (Callable library API reference) provides information on the callable library underlying the object-oriented interface. This section provides a comprehensive documentation of the Knitro callable library functions, which are accessible through methods of the KNSolver class.

Finally, the source code for the object-oriented interface is provided as a
reference. The `.hpp`

header files for the C++ interface document the interface
functionality.

## Additional examples

More examples using the object-oriented interface are provided in
the `examples/C++`

, `examples/CSharp`

and `examples/Java`

directories of the Knitro distribution.