Creating C++ Interfaces for the NAG Library: A Work in Progress

Posted on
2 Apr 2019

Following the success of the new suite of Python interfaces for the NAG Library, and motivated by some recent client discussions, we decided to look into trying something similar for C++. This article is, assuming all goes to plan, the first in a series whose aim is to give a flavour of what undertaking a project of this type at NAG involves and to explain some of the thinking behind the various decisions made.

Requirements

When planning a new set of interfaces we need to identify a minimal set of requirements. For this project these are currently:
  • The interfaces should not impose a rigid data structure
    • ideally they should work with any widely used data structure.
  • The interfaces should be as simplified as possible
    • without losing any useful functionality.
  • The interfaces will use exception type error handling
    • with the caveat that they can be turned off, if required.
  • The interfaces will work with any standard NAG Library
    • and hence portable across OS and compiler (for any combinations we implement the Library on).

Restrictions

Because of the nature of the NAG Library we are also working under a number of known restrictions:
  • The majority of any code produced must be automatically generated.
  • The interfaces must be inferable from existing information.
    • With over 1900+ routines in the NAG Library it is not practical to hand write each wrapper or hand tune each interface.
  • The interfaces will consist of thin wrappers, with all algorithmic work being done by the NAG Library Engine.
    • The upshot of this is that any input types must (eventually) be ANSI C compatible when being passed to the Engine.

Due to its size, the task of producing a new set of interfaces for the whole Library can be a bit daunting, so rather than tackle everything at once we are going to start with a small subset of routines. This allows us to play around with some ideas and garner feedback before rolling out the process across the full library. With this in mind we will initially be looking at the following routines:
  • g01gb: Computes probabilities for the non-central Student's t-distribution.
  • c05ay: Zero of continuous function in a given interval, Brent algorithm.
  • d01fb: Multidimensional Gaussian quadrature over hyper-rectangle.
  • e01ba: Interpolating functions, cubic spline interpolant, one variable.
  • e04mt: Linear programming (LP), sparse, interior point method (IPM).
    • e04ra: Initialization of a handle for the NAG optimization modelling suite for problems, such as, linear programming (LP), quadratic programming (QP), nonlinear programming (NLP), least squares (LSQ) problems, linear semidefinite programming (SDP) or SDP with bilinear matrix inequalities (BMI-SDP).
    • e04rf: Define a linear or a quadratic objective function to a problem initialized by e04ra.
    • e04rj: Define a block of linear constraints to a problem initialized by e04ra.
    • e04rz: Destroy the problem handle initialized by e04ra and deallocate all the memory used.
    • e04zm: Option setting routine for the solvers from the NAG optimization modelling suite.
  • e04uc: Nonlinear programming (NLP), dense, active-set SQP method, using function values and optionally first derivatives, recommended.
    • e04wb: Initialization routine for e04dg, e04mf, e04nc, e04nf, e04nk, e04uc, e04uf, e04ug and e04us.
    • e04ue: Supply optional parameter values to e04uc or e04uf from a character string.

which is small enough to be manageable, but large enough to cover a number of different interface features: scalars, arrays, callbacks, optional arguments etc. The functionality covered by these routines should also be sufficient to allow some non-trivial problems to be solved.

Even though we are initially restricting ourselves to a small subset of routines, we need to keep in mind how any decisions made will effect routines not in the subset. There is nothing more annoying than designing a nice interface for a few routines to find out that the decisions made cannot be applied more widely, resulting either in wasted effort or an inconsistent set of interfaces across the Library as a whole.
In the next article we aim to flesh out the basic requirements outlined here and come up with a specification that we can use as a template for writing the first version of a wrapper generator.