1.12.6 Using NAG Functions
To call any NAG function, you need to include the header file or files where the NAG function is declared.
A single header file, which includes all the commonly used NAG header files, is provided below. Usually, you can just include this header file in your code.
#include <OC_nag.h> // includes all common NAG header files
If only a single NAG function or just a few are used, you can also just include its (their) own individual NAG header file(s). For example, if the NAG function f02abc is called in the code, then two related NAG header files need to be included.
#include <NAG\nag.h> // NAG struct and type definitions
#include <NAG\nagf02.h> // contains the f02 function declarations
All NAG functions accept one argument, which is a pointer of NagError structure. This structure is used to test whether the NAG function is executing successfully or not.
The example below shows whether the NAG function f02abc works successfully.
NagError err; // Declare an error structure
f02abc(n, mx, n, r, v, n, &err); // Call NAG f02abc function
if( err.code != NE_NOERROR ) // If an error occurred
printf(err.message); // Output error message
If you don't need to know whether the call is successful or not, the error structure declaration is not needed. And the NAGERR_DEFAULT macro can be passed instead. This macro is a NULL pointer. To ensure compatibility with future versions of NAG functions, it will be better to use this macro if you can work without error structure.
f02abc(n, mx, n, r, v, n, NAGERR_DEFAULT);
In the NAG Library, most of the routines involve callback functions. Before defining a callback function, you need to know the return type and argument types of the callback function that NAG will expect when calling it.
Take the NAG function d01ajc for example. In the header file nagd01.h, we can see that the first argument is NAG_D01AJC_FUN f. This argument is a callback function. Then in nag_types.h, we find that NAG_D01AJC_FUN is a type of NAG_D01_FUN, which is defined as:
typedef double (NAG_CALL * NAG_D01_FUN)(double);
Then we can define the callback function as follows:
double NAG_CALL myFunc(double x)
// Do processing on 'x'
When calling the NAG function d01ajc, myFunc (defined above) can be passed as the first argument.
Calling c05adc Example
This example will show how to call the NAG function c05adc, the fourth argument of which is the callback function argument. This callback function of type NAG_C05ADC_FUN is defined in nag_types.h.
typedef double (NAG_CALL * NAG_C05ADC_FUN)(double);
From the definition, we know that both the return type and the only argument type are double. So we define the callback function as follows:
double NAG_CALL myC05ADCfunc(double x)
The following code shows how to call the c05adc function by passing the myC05ADCfunc callback function.
double a = 0.0, b = 1.0, x, ftol = 0.0, xtol = 1e-05;
c05adc(a, b, &x, myC05ADCfunc, xtol, ftol, &err);
NAG Get Data From Origin
Many NAG functions take a pointer to an array of numeric data. Both Origin worksheets and matrix sheets allow getting a pointer to their data. This pointer can be passed to NAG functions. In Origin C, data is commonly passed using Dataset or DataRange objects. The sections below will show how to pass data from a worksheet by using Dataset and DataRange. The DataRange way is recommended.
A Dataset object can be passed to a NAG function as long as the Dataset is of the data type expected by the NAG function. The data type of an Origin worksheet column is Text & Numeric by default. For most, but not all, NAG functions, this data type is not allowed to be passed, because NAG functions expect floating or integer pointers.
If you make sure that the Dataset is of the type expected by the NAG function, the following code can be used to pass a Dataset object to a NAG function.
// Get access to the active worksheet.
Worksheet wks = Project.ActiveLayer();
// Construct Datasets to get access to the wks data.
Dataset dsX, dsY;
// Call NAG's nag_1d_spline_interpolant(e01bac) function.
e01bac(m, dsX, dsY, &spline, &err);
The DataRange class provides the GetData method for getting data from a worksheet into a vector, even if the worksheet columns are of the Text & Numeric data type. The GetData method can also ignore the rows with missing values easily, which is very important when passing data to NAG functions.
Using DataRange to pass data from Origin to NAG functions is much safer, and is recommended. The following example demonstrates how to do that.
int i, numPoints = 5;
// Create a new worksheet page.
// Get access to the active worksheet and add two more columns.
Worksheet wks = Project.ActiveLayer();
// Add X2 column
i = wks.AddCol();
Column col(wks, i);
// Add Y2 column
// Create some starting XY values in first two columns
Dataset dsX, dsY;
for (i = 0; i < numPoints; i++)
int r = rnd(0) * 10;
if (r < 1)
r = 1;
if (i > 0)
r += dsX[i - 1];
// Create data range object.
dr.Add(wks, 0, "X");
dr.Add(wks, 1, "Y");
// Copy data from wks to vector using data range.
// This copy will ignore rows with missing values.
vector vX1, vY1;
dr.GetData(DRR_GET_DEPENDENT, 0, NULL, NULL, &vY1, &vX1);
// Call NAG to calculate coefficients.
e01bac(vX1.GetSize(), vX1, vY1, &spline, &err);
// Get the spline's XY values
vector vX2, vY2;
double fit, xarg;
for (i = 0; i < vX1.GetSize(); i++)
if (i < vX1.GetSize() - 1)
xarg = (vX1[i] + vX1[i + 1]) * 0.5;
e02bbc(xarg, &fit, &spline, &err);
// Free memory allocated by NAG
// Copy spline values to worksheet
dsX = vX2;
dsY = vY2;
How to Call NAG e04 Functions
The following example will show how to call the NAG function, nag_opt_simplex_easy, safely. And the results will output to a file.
#define NULLFN NULL
Integer maxcal, n;
printf("\ne04cbc example: \n");
maxcal = 100;
n = 2;
x = 0.4;
x = -0.8;
tolf = sqrt(nag_machine_precision);
tolx = sqrt(tolf);
// call the NAG function, e04cbc = nag_opt_simplex_easy
nag_opt_simplex_easy(n, x, &objf, tolf, tolx, funct, NULLFN, maxcal, NAGCOMM_NULL, &fail);
printf("\nerror = %d\n", err); // if there is an exception
printf("fail->code = %d\n", fail.code); // error code
printf("fail->message = %s\n", fail.message); // error message
printf("The final function value is %12.4f\n", objf);
printf("at the point");
for (int ii = 1; ii <= n; ++ii)
printf(" %12.4f", x[ii-1]);
// call back function for nag_opt_simplex_easy
void NAG_CALL funct(Integer n, double* xc, double* objf, Nag_Comm* comm)
*objf = exp(xc)*(xc*4.0*(xc+xc)+xc*2.0*(xc+1.0)+1.0);