Although the the matrix A is two dimensional, we choose
to store it in a one-dimensional Java array of type double[].
This makes the Java code slightly harder to read than it would be
otherwise, because we need to deal with array subscripting,
but it makes the C code that we need to write in the
interface library much simpler. On the Java side,
we write, for example,

a[2*n + 2] = -17.0;

instead of

a[2][2] = -17.0;

The NAG Library routine f04arc overwrites the array A
by its LU factors. We therefore make a copy of
A in array copyA, so that we can use it to compute
the residual vector r = A x – b
as a check of the returned solution.

As before, we must include the appropriate NAG C Library header files,
and also declare a variable fail of type NagError
to pass as the fail argument to f04arc.

We cannot access the elements of array arguments a,
b and x directly, because they are not C-style arrays
but rather Java-style arrays of type jdoubleArray. Trying
to access the array elements directly would lead to catastrophe.
Instead, we must convert them to C-style double arrays, using the JNI
function GetDoubleArrayElements. This function is
declared in the JNI header file jni.h like this:

GetDoubleArrayElements is accessed through
the JNIEnv pointer, *env. Given the array
of type jdoubleArray,
it returns a pointer to an array of elements of type jdouble
which can safely be manipulated by C. The output argument isCopy
tells us whether Java made a copy of the array, or just passed
us a pointer to the elements in situ. Here, we are not
interested which happened.

Our C program therefore makes three calls of
GetDoubleArrayElements, one for each array argument.
The returned pointers are passed directly to the NAG Library
function f04arc.

After return from the NAG Library, we need to tell Java that
we are finished with the array pointers that it gave us. We
therefore make three calls of function
ReleaseDoubleArrayElements, declared in jni.h as

We need to do this for two reasons:
to ensure that our results get copied back to the
appropriate Java arrays, and
so that Java garbage collection can work properly (if we did not
do it, Java might leak the memory that it allocated for us).