## Knitro on Quest

## Knitro Overview

Knitro is a software library used to find solutions of continuous and discrete optimization models. It is designed for general, nonlinear optimization problem and can be used for a wide range of cases such as systems of non-linear equations, least square problems, convex and non-convex quadratic problems etc. Please refer to the user manual for a complete set of instructions on how to use Knitro.

Knitro is not a standalone program. It provides a programmable API to be used within other software such MATLAB, Python, and R. Knitro is installed on Quest. There are multiple versions, with 10.3 being the latest. You can check by typing the following command on terminal:

% module avail knitro -------------------------------------------------- /software/Modules/3.2.9/modulefiles ----------------------------------------- knitro/10.0 knitro/10.3 knitro/8(default) knitro/9.1 knitro/9.1.orig

MATLAB and R users typically do not need to load the knitro modules directly; knitro is integrated within the application modules. Python users do need to load the knitro module *before* loading Python. We try to match the latest versions of Knitro to the latest versions of the applications. If users require updates to the versions they are using let us know by submitting a ticket to quest-help@northwestern.edu

## MATLAB

Knitro is loaded by each version of MATLAB. The path to the Knitro installation is added to the MATLAB path by root, and it is automatically loaded when the application starts. If users want to have a different version of knitro loaded they must modify the search path within their MATLAB code. Instructions on how to do this are included at the end of this section.

knitromatlab is the interface used to call Knitro from the MATLAB environment. To test that the installation exists, and to find out the version of knitro loaded, a user can run a test function on MATLAB's command line as shown (find the minimum value of cos(x)):

>> [x fval] = knitromatlab(@(x)cos(x),1) ======================================= Academic License (NOT FOR COMMERCIAL USE) Artelys Knitro 10.0.0 ======================================= Knitro presolve eliminated 0 variables and 0 constraints. algorithm: 1 gradopt: 4 hessopt: 2 honorbnds: 1 maxit: 10000 outlev: 1 par_concurrent_evals: 0 The problem is identified as unconstrained. 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 1. Knitro changing linsolver from AUTO to 2. Problem Characteristics ( Presolved) ----------------------- Objective goal: Minimize Number of variables: 1 ( 1) bounded below: 0 ( 0) bounded above: 0 ( 0) bounded below and above: 0 ( 0) fixed: 0 ( 0) free: 1 ( 1) Number of constraints: 0 ( 0) linear equalities: 0 ( 0) nonlinear equalities: 0 ( 0) linear inequalities: 0 ( 0) nonlinear inequalities: 0 ( 0) range: 0 ( 0) Number of nonzeros in Jacobian: 0 ( 0) Number of nonzeros in Hessian: 1 ( 1) EXIT: Locally optimal solution found. Final Statistics ---------------- Final objective value = -1.00000000000000e+00 Final feasibility error (abs / rel) = 0.00e+00 / 0.00e+00 Final optimality error (abs / rel) = 2.37e-09 / 2.37e-09 # of iterations = 7 # of CG iterations = 0 # of function evaluations = 22 # of gradient evaluations = 0 Total program time (secs) = 0.46135 ( 0.092 CPU time) Time spent in evaluations (secs) = 0.04807 =============================================================================== x = 3.1416 fval = -1.0000

Users can access different versions of kntiromatlab by pointing their path to the relevant location. Please consult the knitro module to find the installation directory. For example, MATLAB 2016a loads by default knitro/10.0. To use version 10.3 type in the command line:

module load matlab/r2016a module load knitro/10.3

Querying the 10.3 knitro module shows:

module avail knitro/10.3 /software/knitro/10.3/knitromatlab ------------------------------------------------------------------- /software/Modules/3.2.9/modulefiles/knitro/10.3: module-whatis This module sets up the environment for knitro/10.3 prepend-path KNITRODIR /software/knitro/10.3 prepend-path PATH /software/knitro/10.3/knitroampl:/software/knitro/10.3/knitromatlab prepend-path LD_LIBRARY_PATH /software/knitro/10.3/lib setenv ZIENA_LICENSE_NETWORK_ADDR 129.105.94.37:8349 -------------------------------------------------------------------

Therefore the path to the knitromatlab API is available on Quest in: /software/knitro/10.3/knitromatlab. You can now start MATLAB. At the MATLAB command prompt you can type:

>> addpath('/hpc/software/knitro/10.3/knitromatlab') >> savepath

The knitro interface for the user is now updated to version 10.3.

More information on using the MATLAB/Knitro interface can be found in the Knitro Documentation.

## R

The knitro API for R is only available for version 10.3. Tt is loaded as part of R module 3.3.3. You can submit a ticket to quest-help@northwestern.edu and request adding the KnitroR library to other versions of R if needed. From the command line you can access the knitro R interface as:

% module load R/3.3.3 % R R version 3.3.3 (2017-03-06) -- "Another Canoe" Copyright (C) 2017 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. Natural language support but running in an English locale R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(KnitroR)

You can access the manual page from within R by typing:

> library(help = KnitroR)

One can list the routines included within knitroR as:

> lsf.str("package:KnitroR") knitro : function (nvar = numeric(0), ncon = numeric(0), nnzJ = numeric(0), nnzH = numeric(0), x0 = numeric(0), objective, gradient = NULL, constraints = NULL, jacobian = NULL, jacIndexCons = numeric(0), jacIndexVars = numeric(0), jacBitMap = numeric(0), hessianLag = NULL, hessIndexRows = numeric(0), hessIndexCols = numeric(0), hessBitMap = numeric(0), xL = numeric(0), xU = numeric(0), cL = numeric(0), cU = numeric(0), numCompConstraints = numeric(0), ccIdxList1 = NULL, ccIdxList2 = NULL, xScaleFactors = numeric(0), xScaleCenters = numeric(0), cScaleFactors = numeric(0), ccScaleFactors = numeric(0), objScaleFactor = numeric(0), honorBnds = numeric(0), constraintsTypes = numeric(0), constraintTypes = numeric(0), options = list(), optionsFile = NULL) knitrolsq : function (dimp = numeric(0), par0 = numeric(0), dataFrameX, dataFrameY, residual, jacobian = NULL, parL = numeric(0), parU = numeric(0), xScaleFactors = numeric(0), xScaleCenters = numeric(0), objScaleFactor = numeric(0), jacIndexRows = numeric(0), jacIndexCols = numeric(0), options = list(), optionsFile = NULL) knitromip : function (nvar = numeric(0), ncon = numeric(0), nnzJ = numeric(0), nnzH = numeric(0), x0 = numeric(0), objective, gradient = NULL, constraints = NULL, jacobian = NULL, jacIndexCons = numeric(0), jacIndexVars = numeric(0), jacBitMap = numeric(0), hessianLag = NULL, hessIndexRows = numeric(0), hessIndexCols = numeric(0), hessBitMap = numeric(0), xL = numeric(0), xU = numeric(0), cL = numeric(0), cU = numeric(0), xType = numeric(0), cFnType = numeric(0), objfntype = numeric(0), xScaleFactors = numeric(0), xScaleCenters = numeric(0), cScaleFactors = numeric(0), ccScaleFactors = numeric(0), objScaleFactor = numeric(0), xIndex = numeric(0), xStrategy = numeric(0), constraintsTypes = numeric(0), constraintTypes = numeric(0), options = list(), optionsFile = NULL)

To verify access to the knitroR interface a user can run a simple example of the minimization of the Rosenbrock function: f(x,y) = (1-x^2)+100*(y-x^2)^2.

At the R prompt, cut and paste the following commands that evaluate the function and its derivatives and then call the KnitroR interface calculate the location and value of the global minimum based on an initial estimate.

> eval_f <- function(x) { return( 100 * (x[2] - x[1] * x[1])^2 + (1 - x[1])^2 )} > eval_grad_f <- function(x) { grad_f <-rep(0, length(x)) grad_f[1] <- 2*x[1]-2+400*x[1]^3-400*x[1]*x[2] grad_f[2] <- 200*(x[2]-x[1]^2) return( grad_f )} > x0 <- c( -1.2, 1 ) > sol <- knitro(x0 = x0, objective = eval_f)

Knitro then returns:

======================================= Academic License (NOT FOR COMMERCIAL USE) Artelys Knitro 10.3.0 ======================================= Knitro performing finite-difference gradient computation with 1 thread. Knitro presolve eliminated 0 variables and 0 constraints. gradopt: 2 hessopt: 2 outlev: 1 par_concurrent_evals: 0 The problem is identified as unconstrained. 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 1. Knitro changing linesearch from AUTO to 1. Knitro changing linsolver from AUTO to 2. Problem Characteristics ( Presolved) ----------------------- Objective goal: Minimize Number of variables: 2 ( 2) bounded below only: 0 ( 0) bounded above only: 0 ( 0) bounded below and above: 0 ( 0) fixed: 0 ( 0) free: 2 ( 2) Number of constraints: 0 ( 0) linear equalities: 0 ( 0) nonlinear equalities: 0 ( 0) linear one-sided inequalities: 0 ( 0) nonlinear one-sided inequalities: 0 ( 0) linear two-sided inequalities: 0 ( 0) nonlinear two-sided inequalities: 0 ( 0) Number of nonzeros in Jacobian: 0 ( 0) Number of nonzeros in Hessian: 3 ( 3) EXIT: Locally optimal solution found. Final Statistics ---------------- Final objective value = 2.00694602943133e-11 Final feasibility error (abs / rel) = 0.00e+00 / 0.00e+00 Final optimality error (abs / rel) = 1.54e-08 / 1.54e-08 # of iterations = 18 # of CG iterations = 2 # of function evaluations = 71 # of gradient evaluations = 0 Total program time (secs) = 0.00355 ( 0.004 CPU time) Time spent in evaluations (secs) = 0.00062 =============================================================================== > sol$x [1] 0.9999955 0.9999910

The theoretical location of the minimum is at (1,1) and the global minimum value of 0. Knitro returns:

Final objective value = 2.00694602943133e-11

Further examples are provided on Quest in /software/knitro/10.3/examples/R/examples. Further information is available in the Knitro documentation.

## Python

Knitro provides a Python interface for the Knitro callable library functions and supports Python versions 2.7 and 3.6. Knitro's Python API is thread-safe where a Python code can launch multiple instances of the knitro solver in different threads, each solving a different problems. Examples are provided on Quest in /software/knitro/10.3/examples/Python for users to gauge the structure of a knitro enabled python code. To use knitro/Python on Quest it is important that you load the knitro module first and the python module second:

% module load knitro/10.3 % module load python/anaconda3.6

Copy the knitro.py module from /software/knitro/10.3/examples/Python/knitro.py to the directory with your code or where you're working, or add that location to the path that Python searches for modules.

Then from within Python, import the knitro module:

$ python Python 3.6.0 |Anaconda 4.3.0 (64-bit)| (default, Dec 23 2016, 12:22:00) [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux Type " help",="" "copyright",="" "credits"="" or="" "license"="" for="" more="" information.=""> >> import knitro

For more information please refer to the Knitro documentation.

## AMPL

AMPL is a modeling language to solve optimization problems. AMPL is installed on Quest and can be loaded as:

% module load ampl

There are only 2 licenses available on Quest at present. Users can check if any there are any licenses available by running the following command:

% ampl_lic status

Loading the AMPL module also loads knitro/10.3 which sets the path to the knitroampl executable found on Quest in /software/knitro/10.3/knitroampl.

To invoke knitro within AMPL one must either run or include in their script the following line:

For more information and examples please see the Knitro documentation.