NAG CPP Interface
The NAG CPP Interface is a set of C++ interfaces for the NAG Library, supplied as a series of header files. The supplied material is laid out as follows:
||This directory, and its subdirectories, contain the header files that make up the bulk of the NAG CPP Interface.
||There are a number of directories named after the chapters of the NAG Library, for example e04, g01 etc.. The header files for the available functions are split by chapter, with each function in its own file. These header files contain wrappers which directly call the algorithmic engine and as such do minimal computation themselves.
||The header files use a naming convention based on the short NAG name of the NAG Library function, for example handle_solve_lp_ipm is in Chapter E04 and has a short NAG name of e04mt and so the associated header file is ‘nagcpp_e04mt.hpp’ and sits in the e04 subdirectory.
||In addition to the individual function header files these directories may also include a number of files defining communication classes. The naming convention adopted here is based on the short NAG name of the NAG Library function that initializes the communication information. For example, handle_init initializes the communication information required by a number of functions in Chapter E04, including handle_solve_dfls_rcomm, handle_solve_lp_ipm and handle_solve_ipopt. The associated communication class, CommE04RA, is defined in ‘nagcpp_class_CommE04RA.hpp’ in the e04 subdirectory.
||A series of header files containing various utility classes and functions.
||In addition to the subdirectories described above, this directory contains a header file per chapter, which brings together all the functions from that chapter, and a master header file which includes all functions from all chapters.
||This directory contains example files showing how to call a number of the available functions. Each example file can be individually compiled and run (see Section 2.1.5 for more details).
||This directory contains the expected results from each of the examples. In cases where a different implementation of the NAG Library may cause an example to give slightly different output, multiple results files are present.
||This directory contains some example data container classes. These files demonstrate one way to pass a custom class as an argument to the NAG Library (see Section 3.2 for more details) and are used by some of the examples.
||This directory contains a number of unit tests for various aspects of the NAG CPP Interface . It should be noted that these tests are only for the wrappers and so do not test the underlying algorithmics. Each unit test can be individually compiled and run.
||This directory contains a number of utilities used by the unit tests.
Prior to using the NAG CPP Interface you will need to have a version of Mark 28.6 of the NAG Library installed.
When using the interfaces supplied via the NAG CPP Interface you will need to add the include
subdirectory to the list of directories your compiler searches for header files, in addition to using any compiler flags usually required by the NAG Library.
The NAG Library Documentation
The Guide to the NAG Library Documentation
provides general information on how to use the NAG Library documentation; the following sections are specific to the NAG CPP Interface.
Classification of Arguments (Intents)
Arguments are classified as follows.
- input: unless stated otherwise in the individual function documentation, you must assign values to these arguments on or before calling the function, and these values are unchanged on exit from the function.
- output: you need not assign values to these arguments before calling the function; unless stated otherwise in the individual function documentation the function will assign values to them on exit. If possible the function will allocate array arguments to the correct size (see Section 2.1.3).
- input/output: unless stated otherwise in the individual function documentation, you must assign values to these arguments before calling the function, and the function may then change these values. For array arguments where the individual function documentation indicates that no values must be supplied on entry but that values are returned on exit, the function will attempt to allocate the argument to the correct size (see Section 2.1.3).
- Function: unless stated otherwise in the individual function documentation you must supply a callback function (e.g., to evaluate an integrand or to print intermediate output). The prototype for the callback function is given in the individual function documentation and includes full details of its argument list and specifications of its arguments (all enclosed in a box). The arguments of a callback function are classified in a similar manner to above but, because you must write the function rather than call it, the significance of the classification is different.
- input: unless stated otherwise in the individual function documentation, values will be supplied on entry, which your function must not change.
- output: unless stated otherwise in the individual function documentation, you must assign values to these arguments before returning from your function.
- input/output: unless stated otherwise in the individual function documentation, values will be supplied on entry, and you must assign values to them before returning from your function.
In cases where an argument is not referenced or, in the case of callback functions, where a default function has been supplied by NAG
you should pass nullptr
as the corresponding argument. See Section 10
for an example where a callback function is not referenced, Section 10
for an example where a default callback function is used and Section 10
for an example where an input
argument is set to nullptr
The word ‘Constraint
:’ or ‘Constraints
:’ in the specification of an input
argument introduces a statement of the range of valid values for that argument, e.g.,
If the function is called with an invalid value for the argument (e.g.,
), the function will raise an error (see Section 5
Constraints on string arguments only list upper case characters, e.g.,
In practice, all functions with string arguments are case insensitive.
The actual variable passed as an array argument to the function is referred to as a data container in this documentation.
The interfaces supplied with the NAG CPP Interface support a number of data containers (see Section 3
for details), as such all array arguments are templated and this is shown within the documented function prototype. However, such arguments are described later in the documentation in terms of a non-templated type. The non-templated type is the data type that the underlying function from the algorithmic engine is expecting and hence the type of data that the supplied data container must supply. For example, in quantiles
, argument rv
is described as having type RV
in Section 2
and being a double
array in Section 5
. A data container supplied as rv
must hold the required data as a double
, for example a std::vector<double>
could be supplied.
The dimensions of array arguments are given in their description, for example a vector (a one-dimensional
array) argument may be described as:
indicating that the vector should be of length
, or a matrix (a two-dimensional
array) may be described as:
indicating that a
matrix should be supplied (i.e., a matrix with
A number of functions in the NAG Library take a table as an argument. Here we define a table as containing
matrices (i.e., a three-dimensional
array), which may be described in the documentation as:
When declaring array arguments, you must ensure that all dimensions are of the documented size, i.e., you may not supply oversized array arguments.
array arguments, if a resize
method, or equivalent, has been supplied then the argument does not need to be pre-allocated to the correct size. If such a method is not supplied then you must pre-allocate the argument prior to calling the function (see Section 3.2
for more details on the resize
When describing individual elements of arrays, the notation , and is used for vectors, matrices and tables respectively, i.e., round brackets, . The indices used with this notation are zero based unless explicitly stated otherwise.
Callback Array Arguments
As with array arguments in the main wrapper, the interfaces supplied with the NAG CPP Interface support a number of data containers as arguments to callback functions. Unlike the array arguments in the main wrapper, when documenting callback functions, any arrays are described in terms of a particular array1D
(see for example objfun
). However, you can write your callback function using any of the supported data containers as described in Section 3
If implementing your own custom data container for use with the callback function (see Section 3.3.2
), the specialization of array1D
documented is the class types your specialization of nagcpp::data_handling::convert_nag_array_to_user_t
Structure of the Error Messages
Any error or warning messages that a function may return are categorised by exception type (see for example Section 6
). By default errors raised by a function will be thrown as exceptions, warnings will not. Details of any warnings raised can be obtained via fail
. See Section 5
for details on how to change this behaviour.
The notation appearing in the documented error message is a place holder that will be populated by the value of a variable, argument name or some other piece of information when that error message is displayed.
Example Programs and Results
Where available, the example program
in the Example Section of the function document illustrates a simple call of the function. These example programs are distributed with the NAG CPP Interface in the example
subdirectory and the expected results in the baseresults
For some example programs a number of alternative results files have been supplied, for example, ‘ex_e04mt.r’, ‘ex_e04mt.r_v1’, ‘ex_e04mt.r_v2’ are all results files obtained from running ‘ex_e04mt.cpp’ on different platforms. Only one of these results files (‘ex_e04mt.r’) will appear in the function documentation.
Note that even where variant results files have been supplied, the results you obtain may not agree exactly with any of the results files supplied, however any differences should be of a similar magnitude to that displayed between the variants.
Some examples use data container types that are only supported if that support is switched on (for example ‘ex_e04fg_boost.cpp’). See Section 3.1
for information on how to do this.
Documentation for several classes is provided. In many cases these classes contain members that are designed for use by the wrappers supplied by the NAG CPP Interface rather than directly. In such cases full documentation is only supplied for those members intended for direct use. Documentation for any other members will only be in the form of code comments.
Arguments to methods use the same classification of intent as described in Section 2.1.1
and may containt constraint information as described in Section 2.1.2
Communication Class Documentation
Many functions in the NAG CPP Interface need to communicate with each other, for example, in order to solve an optimization problem using handle_solve_ipopt
you first need to set up the type of problem you wish to solve using one or more functions from Chapter E04
. The mechanism used to communicate between functions is via a series of communication classes, for example, CommE04RA
is used by handle_solve_ipopt
, amongst others. Each class follows a similar format.
Each communication class has its own documentation. These documents can be found by following the links in the documentation for the function you are interested in.
A number of example programs change optional parameters through the communication class, see for example Section 10
and Section 10
In order to support all implementations of the NAG Library, the Manual has adopted a convention of using bold italics to distinguish terms which have different interpretations in different implementations.
One bold italicised term is machine precision, which denotes the relative precision to which real floating-point numbers are stored in the computer, e.g., in an implementation with approximately 16 decimal digits of precision, machine precision has a value of approximately .
The precise value of machine precision
is given by the function precision
As noted above, the actual variable passed as an array argument to the function is referred to as a data container in this documentation. The wrappers supplied by the NAG CPP Interface support a number of data containers. The type of data containers supported are divided into two groups, those supported as arguments to the main function interface and those supported as arguments to callback functions.
A list of supported data containers is given in Section 3.1
The wrappers supplied by the NAG CPP Interface can, in fact, support any arbitrary data container as long as that data container implements a number of standard methods (see Section 3.2
The following types are supported as arguments to both the main function interface and to callback functions:
- boost::numeric::ublas::vector<T>, support for this type must be switched on by defining #HAVE_BOOST_VECTOR.
- boost::numeric::ublas::matrix<T>, support for this type must be switched on by defining #HAVE_BOOST_MATRIX.
is either double
In a callback function it will usually be more efficient to use either array1D
. These classes work directly with the arrays used by the algorithmic engine, whereas std::vector<T>
all require data to be copied in and out. Similarly, when used as an argument to the main function the following data containers require a full copy of the data to be made: boost::numeric::ublas::vector<T>
The pre-processor variables like #HAVE_BOOST_VECTOR
can either be defined via compiler flags when compiling, or by uncommenting the corresponding entry in ‘nagcpp_available_data_containers.hpp’ in the utility
Using Arbitrary Data Containers
The NAG CPP Interface support the use of any arbitrary data container as an argument to the main function interface, as long as that data container implements a number of standard methods. The methods required for a data container to be used as a vector (1D array) are described in DummyVectorDataContainer
, the methods required for it to be used as a matrix (2D array) are described in DummyMatrixDataContainer
and the methods required for it to be used as a table (3D array) are described in DummyTableDataContainer
When using an arbitrary data container, if data of the wrong type is supplied, i.e., the function documentation states that the array argument in question should supply data of type double, but the supplied data container is of type float, then the data is converted, using std::static_cast, and copied both into and out of the calls to the algorithmic engine.
Examples of data containers of each type are included in the include
subdirectory, along with a generic data container that can be used as any of the three types (as a 1D, 2D or 3D array).
Arbitrary data containers can not
be used as arguments to callback functions, only those data containers listed in Section 3
can be used.
See Section 3.3
for information on using data containers which do not implement the required standard methods and for information on using a custom data container as an argument in a callback function.
When designing a multi-dimensional data container for use with the NAG CPP Interface (i.e., anything other than a vector), the underlying storage used for the data must be considered. Ultimately the data container must deliver the data in a contiguous block of memory (for example, through the data
method). The algorithmic engine supports data stored in one of two ways, column-major order or row-major order.
matrix, the value in the
th row and
th column must be stored in the
th element of the contiguous memory, with:
For a table containing
matrices (i.e., a
three-dimensional array), the value in the
th row and
th column of the matrix in the
th table must be stored in the
th element of the contiguous memory, with:
For performance reasons, it is usually preferable if the data is stored in column-major order.
If a function has multiple multi-dimensional array arguments then they must all use the same internal storage order, i.e., they must all be in column-major order or all in row-major order. Any multi-dimensional array in a callback function will have the storage order used when calling the main function. If the main function does not have any multi-dimensional array arguments then the default storage order is used as defined by default_to_col_major
Non-standard Data Containers
As Arguments to the Main Function
If you are unable or unwilling to implement the required standard methods in your data container then it can still be used as an argument to a function, however it will take a bit more work. In such a case a specialization of the nagcpp::data_handling::RawData
class must be supplied. What this entails is not documented here, however examples can be found in the utility
subdirectory in, for example, ‘nagcpp_data_handling_boost_matrix.hpp’ or ‘nagcpp_data_handling_boost_vector.hpp’.
Once you have implemented the specialization you can test that it performs as expected using one of the unit tests in the tests
subdirectory, specifically ‘ut_data_handling_1D.cpp’,
‘ut_data_handling_2D.cpp’ or ‘ut_data_handling_3D.cpp’. Code comments in the relevant file gives details on how to incorporate your own data container into the unit test. An example of the additional utility functions that you must supply can be found in the include
subdirectory in, for example ‘nagcpp_ut_boost_vector_setup.hpp’ and ‘nagcpp_ut_boost_vector_setup.hpp’.
As Arguments to a Callback Function
In order to use a non-supported data container as an argument in a callback function a specialization of the nagcpp::data_handling::convert_nag_array_to_user_t
must be supplied. What this entails is not documented here, however examples can be found in the utility
subdirectory in, for example, ‘nagcpp_data_handling_std_vector.hpp’, ‘nagcpp_data_handling_boost_matrix.hpp’ or ‘nagcpp_data_handling_boost_vector.hpp’.
Once the specialization has been implemented the same unit tests as described in Section 3.3.1
can be used to test its functionality, and the same examples apply.
There are two types of optional arguments to functions in the NAG CPP Interface, those that are supplied through the communication class (Section 2.3
) and those that are no different to standard interface arguments, other than the fact that a sensible default value can be chosen. For example in the function prob_students_t_noncentral
, sensible default values can be chosen for both tol
. Rather than being supplied directly in the function interface, such arguments are supplied via an optional argument class, which is unique to each function. Each optional argument is described in the individual function documentation.
Each optional argument class is a child of Optional
and as such can also be used for error handling and controlling file input/output
Each optional argument has two methods associated with it, a getter and a setter. The name of the setter method is based on the documented name of the optional argument, takes a single argument (the value to set the optional argument to) and returns a reference to the optional argument class (hence allowing the calls to be chained). For example, lars
has an optional argument pred
which indicates the type of data pre-processing to perform. The name of the setter method for pred
and it takes a single int
argument. The name of the getter method associated with an optional argument is similar to the setter method, just prepended by ‘get_’, so the getter for pred
. The getter methods take no arguments and return the value of the optional argument.
In some cases the default value for a particular argument is independent of the value of any other function argument, for example, tol
has a default values of
. In these instances the default value can be queried as soon as the optional argument class is instantiated. In other cases the default value depends on one more input arguments, see for example maxit
whose default value depends on mtype
. In these instances the default can only be queried after the associated function has been run.
Error handling is done through the ErrorHandler
class. The behaviour of ErrorHandler
can be controlled at a global level through GLOBAL_ERROR_HANDLER_CONTROL
or on a function by function basis through the instance of ErrorHandler
stored in the optional argument class (see Section 4
See Section 10
for an example of using the optional argument class to check for warnings issued by a function.
Irrespective of whether the issuing of a warning causes an exception to be thrown or not, when a warning is issued all output (and input/output) arguments will be populated as documented. In the case of a non-void function, if the issuing of a warning causes an exception to be thrown, then the return value can be obtained via return_value
Irrespective of whether the issuing of an error causes an exception to be thrown or not, when an error is issued the state of any output (and input/output) arguments are undefined, unless stated otherwise in the individual function documentation.
Within the NAG CPP Interface file input/output
is done through the IOManager
class which is used to translate between std::istream
and the input/output
unit numbers used in the algorithmic engine.