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:

  1. Set a KNITRODIR environment variable pointing to the absolute path of the installation folder of Knitro.

  2. Set the ARTELYS_LICENSE environment variable to point to the absolute path of the license file of Knitro.

  3. 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.