Getting started with R
The Knitro interface for R, called KnitroR
, is provided with your Knitro distribution.
In order to install it, you need R 3.0 or later.
For Mac with Apple silicon processors
Starting with certain models introduced in late 2020, Apple began the transition from Intel processors to Apple silicon in Mac computers.
Even though it is recommended to use apps built for Apple silicon processors when available, apps built for a Mac with an Intel processor can still be used.
Artelys provides both versions for Artelys Knitro.
R also provides both versions.
To use KnitroR
, it is necessary to have the same version (Intel or Silicon/Arm) for both R and Artelys Knitro.
The version of R is displayed at the beginning of the R prompt after the Platform
keyword.
For Apple silicon:
R version 4.1.1 (2021-08-10) -- "Kick Things"
Copyright (C) 2021 The R Foundation for Statistical Computing
Platform: aarch64-apple-darwin20 (64-bit)
For Intel:
R version 4.3.1 (2023-06-16) -- "Beagle Scouts"
Copyright (C) 2023 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin20.6.0 (64-bit)
Installation
The installation steps are as follows:
Set a
KNITRODIR
environment variable pointing to the absolute path of the installation folder of Knitro.Set the
ARTELYS_LICENSE
environment variable to point to the absolute path of the license file of Knitro.Open a terminal in the directory containing the KnitroR folder (this folder is generally
$KNITRODIR/examples/R
) and type the following command:R CMD INSTALL KnitroR
The pdf documentation of KnitroR can be built using:
R CMD Rd2pdf KnitroR
To test whether your installation is correct, type in the expression:
library('KnitroR')
knitro(objective = function(x) x[1] * x[2], x0 = c(1, 1))
at the R command prompt. If your installation was successful, KnitroR
returns the following message:
=======================================
Commercial License
Artelys Knitro 14.1.0
=======================================
Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables and 0 constraints.
concurrent_evals: 0
The problem is identified as unconstrained.
Problem Characteristics ( Presolved)
-----------------------
Objective goal: Minimize
Objective type: general
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)
quadratic equalities: 0 ( 0)
gen. nonlinear equalities: 0 ( 0)
linear one-sided inequalities: 0 ( 0)
quadratic one-sided inequalities: 0 ( 0)
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: 0 ( 0)
Number of nonzeros in Hessian: 0 ( 3)
Knitro using the Interior-Point/Barrier Direct algorithm.
Iter Objective FeasError OptError ||Step|| CGits
-------- -------------- ---------- ---------- ---------- -------
0 1.000000e+00 0.000e+00
1 0.000000e+00 0.000e+00 0.000e+00 1.414e+00 0
EXIT: Locally optimal solution found.
Final Statistics
----------------
Final objective value = 0.00000000000000e+00
Final feasibility error (abs / rel) = 0.00e+00 / 0.00e+00
Final optimality error (abs / rel) = 0.00e+00 / 0.00e+00
# of iterations = 1
# of CG iterations = 0
# of function evaluations = 8
# of gradient evaluations = 0
Total program time (secs) = 0.04607 ( 0.047 CPU time)
Time spent in evaluations (secs) = 0.00001
===============================================================================
$status
[1] 0
$obj
[1] 0
$x
[1] 0 0
$lambda
[1] 0 0
$objGrad
[1] 0 0
$objGradIndexVars
[1] 0 1
$c
NULL
$r
NULL
$jac
NULL
$jacIndexCons
NULL
$jacIndexVars
NULL
$rsdJac
NULL
$rsdJacIndexRsds
NULL
$rsdJacIndexVars
NULL
$numFCevals
[1] 8
$numGAevals
[1] 0
$numHevals
[1] 0
$numHVevals
[1] 0
$numIters
[1] 1
$numCGiters
[1] 8
Troubleshooting KnitroR
If running the above example does not work, it may be the case that either the
KNITRODIR
or ARTELYS_LICENSE
environment variable was not set correctly, or was not
recognized from within your R session. In particular IDEs used with R,
especially, RStudio, do not inherit environment variable settings from your terminal
(e.g. variables set in .bashrc
on Linux-based systems) but instead, inherit system wide environment variables.
This could cause issues such as “license not found” or “KNITRODIR undefined” messages.
In order to prevent these issues, you should define KNITRODIR
and ARTELYS_LICENSE
system wide. How to do this depends on your operating system.
Another way to circumvent this issue is to directly set these environment variables at the R command prompt (or in your R script) from the IDE before calling KnitroR. For instance, in order to set these variables and then run the example above, you would issue the following sequence of commands in an R session:
> Sys.setenv(ARTELYS_LICENSE = 'my/absolute/path/to/license')
> Sys.setenv(KNITRODIR = 'my/absolute/path/to/knitro')
> library('KnitroR')
> knitro(objective = function(x) x[1] * x[2], x0 = c(1,1))
Setting environment variables directly in R such as in the example above, will work on all platforms. For more general Knitro installation troubleshooting help, please see Troubleshooting.
The KnitroR
interface
The Knitro solver can be called via the following optimization function:
res <- knitro(nvar=..., ncon=..., x0=...,
objective=..., objGoal=..., gradient=..., gradientIndexVars=...,
constraints=..., constraintsIndexCons,
jacobian=..., jacIndexCons=..., jacIndexVars=...,
hessianLag=..., hessIndexVars1=..., hessIndexVars2=...,
callbackEvalFCGA=...,
objLinearStruct=..., objLinearStructIndexVars=...,
conLinearStruct=..., conLinearStructIndexCons=..., conLinearStructIndexVars=...,
objQuadraticStruct=..., objQuadraticStructIndexVars1=..., objQuadraticStructIndexVars2=...,
conQuadraticStruct=..., conQuadraticStructIndexCons=...,
conQuadraticStructIndexVars1=..., conQuadraticStructIndexVars2=...,
xL=..., xU=..., cL=..., cU=...,
xTypes=..., xTypesIndexVars=...,
xStrategies=..., xStrategiesIndexVars=...,
xPriorities=..., xPrioritiesIndexVars=...,
xHonorBnds=..., xHonorBndsIndexVars=...,
ccTypes=..., ccIdxList1=..., ccIdxList2=...,
objScaleFactor=..., xScaleFactors=..., xScaleCenters=...,
cScaleFactors=..., ccScaleFactors=...,
newptCallback=...,
options=..., optionsFile=...,)
but the simplest function call reduces to:
res <- knitro(objective=..., x0=...)
res <- knitro(objective=..., xL=...)
res <- knitro(objective=..., xU=...)
res <- knitro(nvar=..., objective=...)
First R example
The following introductory examples shows how to solve the Rosenbrock banana function.
library('KnitroR')
# Rosenbrock Banana function
eval_f <- function(x)
{
return( 100 * (x[2] - x[1] * x[1])^2 + (1 - x[1])^2 )
}
# initial values
x0 <- c(-1.2, 1)
res <- knitro(x0 = x0, objective = eval_f)
We can save this code in a file ‘example.R’ and run it from the R command prompt via the following command:
source('example.R')
KnitroR
returns the following output:
=======================================
Commercial License
Artelys Knitro 14.1.0
=======================================
Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables and 0 constraints.
concurrent_evals: 0
The problem is identified as unconstrained.
Problem Characteristics ( Presolved)
-----------------------
Objective goal: Minimize
Objective type: general
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)
quadratic equalities: 0 ( 0)
gen. nonlinear equalities: 0 ( 0)
linear one-sided inequalities: 0 ( 0)
quadratic one-sided inequalities: 0 ( 0)
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: 0 ( 0)
Number of nonzeros in Hessian: 0 ( 3)
Knitro using the Interior-Point/Barrier Direct algorithm.
Iter Objective FeasError OptError ||Step|| CGits
-------- -------------- ---------- ---------- ---------- -------
0 2.420000e+01 0.000e+00
10 1.041827e+00 0.000e+00 3.760e+00 1.537e-01 0
20 6.142193e-02 0.000e+00 9.571e-01 4.461e-02 0
30 5.418836e-08 0.000e+00 3.747e-03 2.290e-03 0
37 1.866328e-11 0.000e+00 1.666e-06 5.990e-11 0
EXIT: Primal feasible solution; terminate because the relative change in
the objective function < 1.000000e-15 for 5 consecutive feasible iterations.
Decrease ftol or increase ftol_iters to try for more accuracy.
Final Statistics
----------------
Final objective value = 1.86632757150284e-11
Final feasibility error (abs / rel) = 0.00e+00 / 0.00e+00
Final optimality error (abs / rel) = 1.67e-06 / 1.67e-06
# of iterations = 37
# of CG iterations = 4
# of function evaluations = 191
# of gradient evaluations = 0
Total program time (secs) = 0.01465 ( 0.031 CPU time)
Time spent in evaluations (secs) = 0.00018
===============================================================================
Note in the example above that Knitro approximated the gradient of the objective function using finite-differences. However, Knitro will typically converge much faster if the first derivatives can be provided. This can be done by defining a function to evaluate the gradient of the objective:
eval_grad_f <- function(x)
{
return (c(2 * x[1] - 2 + 400 * x[1]^3 - 400 * x[1] * x[2],
200 * (x[2] - x[1]^2)))
}
and then passing this in the call to knitro:
res <- knitro(x0 = x0, objective = eval_f, gradient = eval_grad_f)
In this case, KnitroR
returns the following output:
=======================================
Commercial License
Artelys Knitro 14.1.0
=======================================
Knitro presolve eliminated 0 variables and 0 constraints.
concurrent_evals: 0
The problem is identified as unconstrained.
Problem Characteristics ( Presolved)
-----------------------
Objective goal: Minimize
Objective type: general
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)
quadratic equalities: 0 ( 0)
gen. nonlinear equalities: 0 ( 0)
linear one-sided inequalities: 0 ( 0)
quadratic one-sided inequalities: 0 ( 0)
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: 0 ( 0)
Number of nonzeros in Hessian: 0 ( 3)
Knitro using the Interior-Point/Barrier Direct algorithm.
Iter Objective FeasError OptError ||Step|| CGits
-------- -------------- ---------- ---------- ---------- -------
0 2.420000e+01 0.000e+00
10 1.041833e+00 0.000e+00 3.760e+00 1.537e-01 0
20 6.136281e-02 0.000e+00 9.652e-01 4.395e-02 0
30 5.772274e-08 0.000e+00 3.907e-03 2.378e-03 0
33 2.708220e-22 0.000e+00 2.992e-10 2.089e-07 0
EXIT: Locally optimal solution found.
Final Statistics
----------------
Final objective value = 2.70821957121458e-22
Final feasibility error (abs / rel) = 0.00e+00 / 0.00e+00
Final optimality error (abs / rel) = 2.99e-10 / 2.99e-10
# of iterations = 33
# of CG iterations = 4
# of function evaluations = 58
# of gradient evaluations = 34
Total program time (secs) = 0.01170 ( 0.016 CPU time)
Time spent in evaluations (secs) = 0.00448
===============================================================================
Further information
The knitro
function can be used to solve mixed-integer models by defining integer variables using the parameter xTypes
.
KnitroR
also includes a function knitrolsq
dedicated to solving least
square problems.
Another chapter of this documentation is dedicated to the R interface (Knitro / R reference)
and provides exhaustive references.
Any Knitro option can also be provided to the R interface. A comprehensive documentation of Knitro options is available in the section Knitro user options.
Additional examples
More examples using the R interface are provided in
the examples/R
directory of the Knitro distribution.