NAG CL Interface
Introduction
1
Introduction
The NAG CL Interface is NAG's traditional set of C Library interfaces.
The
NAG Library Manual is the principal documentation for the
NAG Library. The Library Manual provides you with information to support this interface. Full details of how to use the
NAG Library are provided in
How to Use the NAG Library and if you are a new user you are strongly advised to read this document.
The following information is specific to the NAG CL Interface.
2
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 CL Interface.
2.1
Classification of Arguments
Arguments are classified as follows.
Input: you must assign values to these arguments on or before entry to the function, and these values are unchanged on exit from the function.
Output: you need not assign values to these arguments before entry to the function; the function may assign values to them.
Input/Output: you must assign values to these arguments before entry to the function, and the function may then change these values.
Communication Structure and Arrays:
arguments which are used to communicate data from one function call to another.
External Function: a function which must be supplied (e.g., to evaluate an integrand or to print intermediate output). Usually it must be supplied as part of your calling program, in which case its specification includes full details of its argument list and specifications of its arguments (all enclosed in a box). Its arguments are classified in the same way as those of the Library function, but because you must write the procedure rather than call it, the significance of the classification is different.
- Input: values may be supplied on entry.
- Output: you may or must assign values to these arguments before exit from your procedure.
- Input/Output: values may be supplied on entry, and you may or must assign values to them before exit from your procedure.
2.2
Constraints and suggested values
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 usually take an error exit.
Occasionally, an enhancement of an existing function at a given Mark may weaken some constraints on some arguments, this will not change the behaviour of existing code that calls the function, but will allow new code to take advantage of enhanced functionality.
The phrase ‘Suggested value:’ introduces a suggestion for a reasonable initial setting for an Input argument (e.g., accuracy or maximum number of iterations) in case you are unsure what value to use; you should be prepared to use a different setting if the suggested value turns out to be unsuitable for your problem.
2.3
Example Programs and Results
The example program in Section 10 of most function documents illustrates a simple call of the function. The programs are designed so that they can be fairly easily modified, and so serve as the basis for a simple program to solve your problem.
For each implementation of the Library,
NAG distributes the example programs in machine-readable form, with all necessary modifications already applied. Many sites make the programs accessible to you in this form.
These programs can also be obtained by using the nag_example scripts, provided with the product. The
Users' Note for your implementation will mention any special changes which need to be made to the example programs from the generic form.
These example programs may contain preprocessor identifiers such as NAG_CALL to enable cross platform portability. Such identifiers are subsequently replaced by appropriate implementation-specific tokens via the header files nag.h or nag_basic_types.h (included by nag.h), using the C preprocessor #defines.
Note that the results obtained from running the example programs may not be identical in all implementations and may not agree exactly with the results in the Manual.
For many function documents, a plot of the example program results is also provided. In some cases the example program has been modified slightly to produce larger sets of results to give a more representative plot of the solution profile produced.
3
Programming Advice
When writing a calling program, a number of environmental features common to all such NAG programs must be observed in addition to specific features which are relevant to the particular NAG function being called. These features are discussed below; you should also refer to the example program.
3.1
The NAG C environment
The environment for the
NAG Library is defined in a number of include files; a list is given in
Section 3.1.6. The most important of the header files is
nag.h, which must be included in any program that calls a
NAG Library function and must precede any other
NAG header file.
These include files are placed in <product_folder>/include folder by the installer. For its exact location please see the
Users' Note or other local documentation.
The file nag.h defines data types and error codes used in the NAG Library together with a number of macros used in example programs.
3.1.1
NAG data types
- Integer
- This data type is used for integer arguments to NAG Library functions. It is normally defined to be long. Please refer to the Users' Note for its exact type.
- Nag_Boolean
- This is an enumeration type defined as
typedef enum{Nag_FALSE=0; Nag_TRUE=1} Nag_Boolean;
- Complex
- This data type is a structure defined for use with complex numbers:
typedef struct {double re, im;} Complex;
- Pointer
- This data type represents the generic pointer void *.
- Nag_Comm
- This data type is a structure with a number of fields among which are a generic pointer, an Integer pointer and a double pointer which may be used for communicating information between a user-defined function and your calling program, where the user-defined function is supplied as an argument to the NAG function. This avoids the necessity of using global variables for such communication. The use of Integer and double pointers allows double and Integer arrays to be communicated with no casting. For an example of use, please see Section 10 in e04cbc.
- Nag_User
- This is also a communication structure with a generic pointer with usage similar to Nag_Comm.
- Nag_FileID
- This data type is an integer type used by certain NAG Library functions which deal with input or output files. Functions in Chapter X04 must be used to associate a file name with the file ID.
- Enumeration Types
- A number of other enumeration types are defined in nag_types.h (included by nag.h) for use in calls to various NAG Library functions. You should use these enumeration types in your C/C++ calling programs. If the NAG Library is being called from languages other than C/C++ we have provided a function to map the enumeration members to integer values (see x04nac).
- Other structure types
- A number of structures have been defined to facilitate calls to NAG functions. Please note that only those components of a structure that are relevant to a call to a specific NAG function are described in the corresponding function document. A complete specification of a NAG defined structure can be found in the NAG Library header file nag_types.h included in the distribution materials.
3.1.2
Memory management in the Library
Memory is frequently dynamically allocated within
NAG Library functions. All requests for memory are checked for success or failure. In the unlikely event of failure occurring the Library function returns or terminates with the error state
NE_ALLOC_FAIL (details of error handling in the Library are given in
Section 7).
The macros
NAG_ALLOC,
NAG_REALLOC and
NAG_FREE are defined to select suitable memory management functions for the
NAG Library.
NAG_ALLOC has two arguments; the first specifies the number of elements to be allocated while the second specifies the type of element. The statement
p = NAG_ALLOC(n, double);
allocates
n elements of memory of type
double to
p, a pointer to
double.
NAG_REALLOC has three arguments; the first specifies the name of the pointer whose memory is to be extended, the second specifies the number of elements and the third specifies the type of element.
The statement
p = NAG_REALLOC(p, n, double);
allocates
n elements of memory of type
double to
p, a pointer to
double.
NAG_FREE frees memory allocated by
NAG_ALLOC or
NAG_REALLOC; its single argument is the pointer which specifies the memory to be deallocated. The statement
NAG_FREE(p);
deallocates memory pointed to by
p and sets its value to
NULL.
These macros are defined in the header file
nag.h.
NAG_FREE must be used to free memory allocated and returned from a
NAG function. If memory is allocated using
NAG_ALLOC for whatever reason, it must be freed using
NAG_FREE. For an illustration of their use, see
Section 10.1 in
e02agc. The use of
NAG_ALLOC,
NAG_REALLOC and
NAG_FREE is strongly recommended.
3.1.3
The Nag_Order Argument
Different programming languages lay out two-dimensional data in memory in different ways. The C language treats a two-dimensional array as a single block of memory arranged in rows, the so called ‘row-major’ ordering. Some other languages, notably Fortran, arrange two-dimensional arrays by column (‘column-major’ ordering). Those functions in the NAG CL Interface that deal with two-dimensional arrays and where deemed appropriate have an extra argument, called order, which allows you to specify that your data is arranged in rows (by setting order to Nag_RowMajor) or in columns (by setting order to Nag_ColMajor). This is particularly useful if the NAG CL Interface is being called from a language which uses the column-major ordering or if you wish to call a function from a language, such as Visual Basic 7 onwards, which supports column-major ordering.
3.1.4
Array references
In C it is possible to declare a two-dimensional variable using notation of the form:
double a[dim1][dim2];
When this variable is an argument to a function, it is effectively treated by the compiler as a pointer, *a, of type double with an allocated memory of dim1*dim2 on the stack. The address of an element of this array, say a[3][5] is then an explicit address computed to be *(a+3*dim2+5), since C stores data in row-major order.
Alternatively it is possible for you to allocate memory explicitly (on the heap) to a pointer of type
double *, using the form:
a=(double *)malloc((size_t)(dim1*dim2*sizeof(double)); | [1] |
In this case the C preprocessor allows a succinct notation for computing this explicit address by using a macro definition:
#define A(I,J) a[I*dim2+J] | [2] |
The element of this array if indexed
is then indexed using the pointer notation
*(a+i*dim2+j) or by using the array notation
a[i*dim2+j]; or by using
A(I,J) assuming the macro
[2] is already defined.
We often wish to refer to the storage of elements representing a submatrix of the matrix
, for example, the submatrix comprising rows
to
and columns
to
. For convenience we use the notation
A(k:l,m:n) to refer to those elements of
a storing the given submatrix with elements
(see
[2] and
[4]), for
and
. That is,
A(k:l,m:n) = {a[p], p = (i-1)*pda+j-1, i=k,...,l and j=m,...,n}, | [3] |
for row major ordering.
If the data is to be stored using column-major ordering and we have declared an array variable as
double a[dim1][dim2];
then the element indexed
is effectively transposed. That is, the element
a[i][j] under row-major ordering is the element
a[j][i] under column-major ordering.
As another alternative you may choose to malloc the required memory as in
[1] above. In this case, the element indexed
is using the pointer notation
*(a+j*dim1+i); or by using the array notation
a[j*dim1+i]; or by using
A(I,J) if the macro is defined as
#define A(I,J) A[J*dim1+I] | [4] |
Note the difference in definition between
[2] and
[4] above.
In order to simplify the documentation, we refer to array elements using the macro definitions above. Further, we note that in the preprocessor directive
[2] and
[4], the critical dimension is either
dim2 if the row-major ordering is used or
dim1 if column-major ordering is used. We designate either
dim2 or
dim1 as the principal dimension depending on the storage ordering scheme. The principal dimension can be thought of as a stride which must be taken to traverse either a row or a column depending on the
order argument.
Typically in the NAG Library we use the convention 'pda' if the function has the order argument and pda can have different values depending on whether the array is stored in row major or in column major order. If the specification of an array is such that its elements must be stored in row major order we use the term 'tda' (meaning trailing dimension). For arrays whose elements must be stored in column major order we use the term 'lda' (meaning leading dimension). As of Mark 24, new functions in the library generally store two-dimensional data in the column major order. We are standardizing on the phrase ‘stride separating row elements’ to mean column-major order storage and the phrase ‘stride separating column elements’ to mean row-major order storage.
Functions such as
f16qfc are provided in
Chapter F16 to facilitate calling functions in which data has to be stored in a mutually exclusive manner, performing a variety of copying tasks such as triangular copy, etc.. For example, function A requires data to be in row-major order while function B requires data to be stored in column-major order and the
order argument has not been provided.
We illustrate these concepts using two examples. In the first example, memory is allocated while in the second example memory is declared. In both examples, row or column modes are demarcated using the preprocessor macro NAG_ROW_MAJOR. Memory is allocated using NAG_ALLOC, which is a macro defined in nag.h, in preference to explicit malloc calls. This macro maps to calls to internal Library functions to allocate memory. Also note the use of NAG_FREE to free the memory.
Example 1
/* Example Program, with memory allocated, based on:
*
* f08afc Example Program.
*
* Copyright Numerical Algorithms Group.
*
*/
#include <stdio.h>
#include <string.h>
#include <nag.h>
int main(void)
{
/* Scalars */
Integer i, j, m, n, pda_row, pda_column, tau_len;
Integer exit_status=0;
NagError fail;
/* Arrays */
char *title=0;
double *a_row=0, *a_column=0, *tau=0;
char matrx_data [] = {
" -0.57 -1.28 -0.39 0.25 "
" -1.93 1.08 -0.31 -2.14 "
" 2.30 0.24 0.40 -0.35 "
" -1.93 0.64 -0.66 0.08 "
" 0.15 0.30 0.15 -2.13 "
" -0.02 1.03 -1.43 0.50 "
}, *matrix_data_ptr = matrx_data;
/* Initialize strtok */
matrix_data_ptr = strtok(matrix_data_ptr, " \t\n");
#define A_COLUMN(I,J) a_column[(J-1)*pda_column + I - 1]
#define A_ROW(I,J) a_row[(I-1)*pda_row + J - 1]
INIT_FAIL(fail);
m = 6;
n = 4;;
pda_column = m;
pda_row = n;
tau_len = MIN(m, n);
/* Allocate memory */
if ( !(title = NAG_ALLOC(31, char)) ||
!(a_row = NAG_ALLOC(m * n, double)) ||
!(a_column = NAG_ALLOC(m * n, double)) ||
!(tau = NAG_ALLOC(tau_len, double)) )
{
printf("Allocation failure\n");
exit_status = -1;
goto End;
}
#ifdef NAG_ROW_MAJOR
printf("Using row major storage, allocated memory\n");
/* Read A from data above */
for (i = 1; i <= m; ++i)
{
for (j = 1; j<= n; j++)
{
sscanf(matrix_data_ptr, "%lf", &A_ROW(i,j));
matrix_data_ptr = strtok(0, " \t\n");
}
}
/* Compute the QR factorization of A */
f08aec(Nag_RowMajor, m, n, a_row, pda_row, tau, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from f08aec.\n%s\n", fail.message);
exit_status = 1;
goto End;
}
/* Form the leading N columns of Q explicitly */
f08afc(Nag_RowMajor, m, n, n, a_row, pda_row, tau, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from f08afc.\n%s\n", fail.message);
exit_status = 2;
goto End;
}
/* Print the leading N columns of Q only */
sprintf(title, "The leading %2ld columns of Q\n", n);
x04cac(Nag_RowMajor, Nag_GeneralMatrix, Nag_NonUnitDiag, m, n,
a_row, pda_row, title, 0, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from x04cac.\n%s\n", fail.message);
exit_status = 3;
goto End;
}
#else
printf("Using column major storage, allocated memory\n");
/* Read A from data above */
for (i = 1; i <= m; ++i)
{
for (j = 1; j<= n; j++)
{
sscanf(matrix_data_ptr, "%lf", &A_COLUMN(i,j));
matrix_data_ptr = strtok(0, " \t\n");
}
}
f08aec(Nag_ColMajor, m, n, a_column, pda_column, tau, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from f08aec.\n%s\n", fail.message);
exit_status = 1;
goto End;
}
/* Form the leading N columns of Q explicitly */
f08afc(Nag_ColMajor, m, n, n, a_column, pda_column, tau, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from f08afc.\n%s\n", fail.message);
exit_status = 2;
goto End;
}
/* Print the leading N columns of Q only */
sprintf(title, "The leading %2ld columns of Q\n", n);
x04cac(Nag_ColMajor, Nag_GeneralMatrix, Nag_NonUnitDiag, m, n,
a_column, pda_column, title, 0, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from x04cac.\n%s\n", fail.message);
exit_status = 3;
goto End;
}
#endif
End:
if (title) NAG_FREE(title);
if (a_row) NAG_FREE(a_row);
if (a_column) NAG_FREE(a_column);
if (tau) NAG_FREE(tau);
return exit_status;
}
Example 2
/* Example Program, with memory declared, based on:
*
* f08afc Example Program.
*
* Copyright Numerical Algorithms Group.
*
*/
#include <stdio.h>
#include <string.h>
#include <nag.h>
#define MMAX 10
#define NMAX 8
int main(void)
{
/* Scalars */
Integer i, j, m, n, pda, tau_len;
Integer exit_status=0;
NagError fail;
/* Arrays */
char title[30];
double a_row[MMAX][NMAX], a_column[NMAX][MMAX], tau[NMAX];
char matrx_data [] = {
" -0.57 -1.28 -0.39 0.25 "
" -1.93 1.08 -0.31 -2.14 "
" 2.30 0.24 0.40 -0.35 "
" -1.93 0.64 -0.66 0.08 "
" 0.15 0.30 0.15 -2.13 "
" -0.02 1.03 -1.43 0.50 "
}, *matrix_data_ptr = matrx_data;
/* Initialize strtok */
matrix_data_ptr = strtok(matrix_data_ptr, " \t\n");
INIT_FAIL(fail);
m = 6;
n = 4;;
pda = NMAX;
tau_len = MIN(m, n);
/* Read A from data above */
#ifdef NAG_ROW_MAJOR
for (i = 0; i < m; ++i)
{
for (j = 0; j< n; j++)
{
sscanf(matrix_data_ptr, "%lf", &a_row[i][j]);
matrix_data_ptr = strtok(0, " \t\n");
}
}
/* Compute the QR factorization of A */
printf("Using row major storage, declared memory\n");
f08aec(Nag_RowMajor, m, n, &a_row[0][0], pda, tau, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from f08aec.\n%s\n", fail.message);
exit_status = 1;
goto End;
}
/* Form the leading N columns of Q explicitly */
f08afc(Nag_RowMajor, m, n, n, &a_row[0][0], pda, tau, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from f08afc.\n%s\n", fail.message);
exit_status = 2;
goto End;
}
/* Print the leading N columns of Q only */
sprintf(title, "The leading %2ld columns of Q\n", n);
x04cac(Nag_RowMajor, Nag_GeneralMatrix, Nag_NonUnitDiag, m, n,
&a_row[0][0], pda, title, 0, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from x04cac.\n%s\n", fail.message);
exit_status = 3;
goto End;
}
#else
printf("Using column major storage, declared memory\n");
for (i = 0; i < m; ++i)
for (j = 0; j< n; j++)
{
/* Note column data is transposed */
sscanf(matrix_data_ptr, "%lf", &a_column[j][i]);
matrix_data_ptr = strtok(0, " \t\n");
}
f08aec(Nag_ColMajor, m, n, &a_column[0][0], pda, tau, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from f08aec.\n%s\n", fail.message);
exit_status = 1;
goto End;
}
/* Form the leading N columns of Q explicitly */
f08afc(Nag_ColMajor, m, n, n, &a_column[0][0], pda, tau, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from f08afc.\n%s\n", fail.message);
exit_status = 2;
goto End;
}
/* Print the leading N columns of Q only */
sprintf(title, "The leading %2ld columns of Q\n", n);
x04cac(Nag_ColMajor, Nag_GeneralMatrix, Nag_NonUnitDiag, m, n,
&a_column[0][0], pda, title, 0, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from x04cac.\n%s\n", fail.message);
exit_status = 3;
goto End;
}
#endif
End:
return exit_status;
}
3.1.5
Internal data structures
For efficiency, and wherever possible, the NAG CL Interface is designed to make use of the Basic Linear Algebra Subprograms (BLAS), a suite of low-level functions tuned by many computer manufacturers for their particular hardware. Since the BLAS are specified in Fortran, and therefore use the column-major storage order, the NAG CL Interface also uses this scheme, internally, for new functions wherever it is practical. Thus any two-dimensional arrays you have provided may be re-ordered on entry and/or on exit from the NAG functions, as appropriate. It is therefore slightly more efficient to use the column-major ordering; however, except for very large data sets, the effect is negligible in practice.
3.1.6
Chapter header files
It is no longer necessary to include anything other than the header file nag.h to call any NAG CL Interface function.
Prior to Mark 27 of the NAG Library, Chapter header files, containing the function declarations for each function in a Chapter of the Library, had to be included in order to call the function. These Chapter header files are now included by nag.h, so need not be included separately. Existing programs that do include Chapter header files will continue to work as normal.
4
Use of NAG Long Names
The long names defined in the header file nag_names.h are #defines. As the header file nag_names.h is already included via nag.h, you need not include nag_names.h in their calling programs.
NAG Library functions output all error and warning messages to the C standard error stream
stderr.
Chapters E04,
E05,
G02 and
G13 will optionally output results to the C standard output stream
stdout or to an alternative user-specified file. A number of functions in
Chapters E04 and
H read input from external files.
6
Auxiliary Functions
In addition to the documented functions, the NAG Library contains a much larger number of auxiliary functions. You do not normally need to concern yourself with these functions, as they will automatically be called as required by the user-callable function you have selected.
7
Error Handling and the fail Argument
All functions that have error exits have an argument that allows you control over the printing of error messages when an error is detected. There is a further option which allows you to either continue running your program, having returned from the NAG function, or to stop with either an exit statement or an abort within the NAG function. The different ways of using these error handling facilities are described below.
Note that in some implementations, the Library is linked with the vendor library containing LAPACK functions and the
Chapters F07 and
F08 function interfaces, where appropriate, act as wrappers to the corresponding vendor LAPACK functions. In this case, the
fail argument passed through the
Chapters F07 and
F08 interfaces does not have full control over the printing of error messages; nor does it determine whether or not control is returned to the calling program when an error is detected.
7.1
Use of NAGERR_DEFAULT
The simplest method of using the error handling facility is to put NAGERR_DEFAULT in place of the fail argument in calls to the NAG C functions. If an error is detected the appropriate NAG error message is output on stderr and the program is stopped by the use of exit.
7.2
Use of the fail Argument
The two remaining ways of using the
NAG error handling facility both involve defining the
fail argument in the calling program. The
fail argument is of type
NagError which is a structure fully defined in
nag_types.h. The fields of this structure of relevance to you as a user of the
NAG CL Interface are:
int code;
Nag_Boolean print;
char message[NAG_ERROR_BUF_LEN];
Integer errnum;
void (*handler)(char*,int,char*);
where the symbol
NAG_ERROR_BUF_LEN is normally defined to be 512.
This structure will contain the
NAG error code and message on return from a call to a
NAG Library function. The
NAG error codes and some associated
NAG error messages are defined in
nag_errlist.h. A detailed description of the individual members of this structure is given below (see
Section 7.3).
The
NAG error argument
fail is declared in the calling program as:
NagError fail;
The address of the argument is then passed to the NAG C function being called. Relevant members of the structure must be initialized before passing the argument to the called function, even though you may not actually require all members. It is recommended that the NAG defined macro INIT_FAIL be used for this purpose.
The
INIT_FAIL macro sets:
The SET_FAIL macro is also available. It sets the contents of fail in the same way as INIT_FAIL except that is set to Nag_TRUE.
(a) Use of the fail argument with the print member set to Nag_TRUE
If you require that the NAG error message be printed when an error is found, but that the called function should return control to the calling program, then the fail argument must be declared with all members initialized and the print member set to Nag_TRUE. Use of the NAG-defined macro SET_FAIL with the statement SET_FAIL(fail); performs the appropriate assignments. Alternatively the initialization could be done by declaring the fail argument with static and then setting fail.print to Nag_TRUE.
If no error occurs,
fail.code will contain the error code NE_NOERROR on return from the called function. However, if an error is found, the appropriate
NAG error message will be output on
stderr before returning control to the calling program;
fail.code will contain the relevant
NAG error code. You must ensure that the calling program tests the
code member of the
fail argument on return from the
NAG C function; you may then choose whether to exit the calling program or continue. See the example program for
c05qbc for such a case. The option of continuing may be advantageous if the results being returned are of some value even when an error has been detected. In the case of
c05qbc the code could be altered to allow the program to continue if the specific error codes
NE_TOO_MANY_FEVALS,
NE_TOO_SMALL and
NE_NO_IMPROVEMENT occur, as in such a case useful partial results are returned (see the function document for
c05qbc).
(b) Use of the fail argument with the print member set to Nag_FALSE
If you do not wish the NAG error messages to be printed automatically when an error is found then the fail argument must be declared with all members initialized and the print member set to Nag_FALSE. Use of static in the declaration of fail will automatically leave the print member as Nag_FALSE as will the use of INIT_FAIL(fail).
This method is suitable for those of you who wish to produce your own error messages rather than use the NAG Library versions. Alternative error messages may be coded directly into the calling program or be produced via a user-written error-handling function which is assigned to the handler member of the fail argument (see the description of the handler member below).
7.3
The NagError structure
The members of the NagError structure, of relevance to you as the user of the NAG CL Interface, are described in full below.
- code
-
On successful exit, code contains the NAG error code NE_NOERROR; if an error or warning has been detected, then code contains the specific error or warning code. Error codes are prefixed with NE_ whereas warning codes have the prefix NW_.
- print
-
print must be set before calling any NAG Library function with a fail argument. It should be set to Nag_TRUE if the NAG error message is to be printed, otherwise Nag_FALSE. It is not changed by the NAG Library function.
- message
-
On successful exit the array message contains the character string "NE_NOERROR:\n No error". If an error has been detected, then message contains the error message text, whether or not this is printed.
- errnum
-
On successful exit, errnum is unchanged. For certain error or warning exits errnum will contain a value specifying additional information concerning the error. For example if a vector is supplied incorrectly, then errnum may specify which component of the vector is wrong. Cases where errnum returns information are described in the relevant function documents.
- handler
-
handler must be set to 0 if control is to be returned to the calling function after an error has been detected. Otherwise it must point to a user-supplied error-handling function. An example of the ANSI C declaration of a user-supplied error function (here called errhan) is:
void errhan(const char *string, int code, const char *name)
where string contains the NAG error message on input, code is the NAG error code and name is the short name of the NAG Library function which detected the error. If print (see above) is Nag_TRUE, then the NAG error message is printed before the user-supplied error handler is called. If the user-supplied error handler returns control, then the NAG error handler will return control to the calling program; otherwise the user-supplied error handler may exit.
An elementary example of where this feature might be used is if it is preferred to print error messages on
stdout rather than the default
stderr. In this case
errhan could be defined as:
void errhan(const char *string, int code, const char *name)
{
if (code != NE_NOERROR)
{
printf("\nError or warning from %s.\n", name);
printf("%s\n", string);
}
}
7.4
Structure of the NAG Error Messages
For illustrative purposes, let us consider two examples of the format of the NAG Library error messages in the NAG Library documentation:
NE_INT
- On entry, .
Constraint: .
NE_BAD_PARAM
- On entry, argument had an illegal value.
If the
NAG function in question detects an error and error messages are being displayed, either by using the default error handler
NAGERR_DEFAULT or by setting
, then text of the following form would be displayed:
NE_INT:
On entry, n = 1
Constraint: n > 1.
or
NE_BAD_PARAM:
On entry, argument order had an illegal value.
i.e., 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.
7.5
Unexpected Errors
Internal calls to Library functions are checked for error exits even when these exits are not to be expected. Should an unexpected error exit occur the function returns or terminates with the error state NE_INTERNAL_ERROR.
8
Licence Management
If your implementation is licence managed then your local site will have details on how the licence management is implemented; please contact your site installer. To determine whether a valid licence is available on your machine run the example program for
a00acc.
Should a valid licence not be found when calling licence-managed functions from the Library then the function returns or terminates with the error state NE_NO_LICENCE. On Unix-based systems, the appropriate environment variables should then be checked (e.g., NAG_KUSARI_FILE) to make sure this points to the licence file containing a valid licence and the licence file should be checked for any obvious errors (e.g., the licence refers to a different implementation). If everything appears to be correct then please contact
NAG (see
NAG Technical Support Service for details).
9
References
ACM (1960–1976) Collected algorithms from ACM index by subject to algorithms
Anderson E, Bai Z, Bischof C, Blackford S, Demmel J, Dongarra J J, Du Croz J J, Greenbaum A, Hammarling S, McKenney A and Sorensen D (1999)
LAPACK Users' Guide (3rd Edition) SIAM, Philadelphia
https://www.netlib.org/lapack/lug
ANSI/IEEE (1985) IEEE standard for binary floating-point arithmetic Std 754-1985 IEEE, New York
Dongarra J J, Du Croz J J, Hammarling S and Hanson R J (1988) An extended set of FORTRAN basic linear algebra subprograms ACM Trans. Math. Software 14 1–32