NAG recommends that you read How to Use the NAG Library before trying to use these wrappers. This document gives information about the structure of, and conventions used in, the NAG Library that Java developers must be aware of in order to successfully use the NAG Library for Java.
The NAG Library for Java is NOT compatible with all implementations of the NAG Library. It is therefore important that you ensure that the correct implementation of the NAG Library is installed in order to use these wrappers.
The NAG Library for Java Mark 30.3 is available for the following platforms:
Platform NAG Library Linux 64-bit NLL6I303BL Windows 64-bit NLW6I303EL
Note that this document only provides information for Linux users. Windows users should consult the Windows version of this document.
All the routines from the NAG Library Mark 30.3 are available with the following exceptions:
The following shows the directory/file organization of the distribution material.
NAGJava +-- diagnostic | +-- NAGJavaDiagnostic.class - (Pre-compiled program) | \-- NAGJavaDiagnostic.java - (Java diagnostic program) | +-- examples | \-- source | \-- *.java - (Example Java source) | +-- jar | \-- NAGJava.jar - (Java suitable for all supported systems) | +-- linux_x64 | \-- libnag_jni303.so - (Interface shareable Library suitable for 64-bit Linux) | +-- win64 | \-- nag_jni303.dll - (Interface shareable Library suitable for 64-bit Windows) | |-- how_to_use_the_NAG_library_for_Java_Linux.html - (This note) | \-- how_to_use_the_NAG_library_for_Java_Windows.html
To install the NAG Library for Java, you simply have to unzip the distribution file and copy two files to convenient locations on your system:
The following must be in your LD_LIBRARY_PATH environment variable to use the NAG Library for Java:
It is also recommended that the path to NAGJava.jar is added to your CLASSPATH.
So your LD_LIBRARY_PATH should contain something like:
[nagjava_install_dir]/linux_x64:[nll6i303bl_install_dir]/lp64/lib:[nll6i303bl_install_dir]/rtl/lib/intel64and your CLASSPATH:
.:[nagjava_install_dir]/jar/NAGJava.jar(Note that the current directory '.' is also included in the CLASSPATH, so that Java can pick up classes defined in the user's driver code there.)
If you are using an IDE such as Eclipse, you may need to configure your project to enable the IDE to pick up any required dependency.
CompilationThe Java Development Kit (JDK) must be installed to use javac, with [jdk_install_dir]/bin in your PATH.
To compile a Java source file that includes calls to the NAG Library for Java, issue the following command:
javac Driver.javawhere Driver.java is your calling program.
If NAGJava.jar is not included in your system CLASSPATH, it must be supplied using the -cp flag:
javac -cp [nagjava_install_dir]/jar/NAGJava.jar Driver.javaRunning a program
To run your program on Linux issue the following command:
java Driver
If NAGJava.jar is not included in your system CLASSPATH, the -cp flag must be used again. Note that the current directory '.' is also included:
java -cp .:[nagjava_install_dir]/jar/NAGJava.jar DriverAccessibility check
On all platforms, you may use NAGJava/diagnostic/NAGJavaDiagnostic.java to check that the NAG Library for Java materials and the underlying NAG Library are accessible. To run it, go to NAGJava/diagnostic and run the commands:
javac NAGJavaDiagnostic.java java NAGJavaDiagnostic
If NAGJava.jar is not included in your system CLASSPATH:
javac -cp [nagjava_install_dir]/jar/NAGJava.jar NAGJavaDiagnostic.java java -cp .:[nagjava_install_dir]/jar/NAGJava.jar NAGJavaDiagnostic
Fortran type | Java type |
REAL(KIND=nag_wp) | double |
REAL(KIND=nag_rp) | float |
COMPLEX(KIND=nag_wp) | implementation of NAGComplexInterface |
COMPLEX(KIND=nag_rp) | implementation of NAGComplexFInterface |
INTEGER | int |
CHARACTER | String |
LOGICAL | boolean |
C_PTR | long |
USER-SUPPLIED FUNCTION | implementation of a routine-specific interface or routine-specific abstract class |
The following rules must be followed for the variables used as arguments:
the two-dimension Fortran array
|1 5 9| A = |2 6 10| |3 7 11| |4 8 12|is matched by the one-dimension Java array:
A = |1,2,3,4,5,6,7,8,9,10,11,12|When the documentation for the routine describes a parameter as being the first dimension of the array as declared in the calling (sub)program, from a Java calling program this should be interpreted as the number of rows in the two-dimensional structure. In the above example that would be 4.
Note that array indices start at 0 in Java, so care must be taken when using the Fortran documentation, in which array indices start at 1.
NAGComplex[] complexArray = new NAGComplex[10]; for (int i = 0; i < 10; ++i) complexArray[i] = new NAGComplex();
Make sure all other arguments and array elements, including those in user-supplied functions, are set when required. Refer to Section 2.2 of the Introduction to the NAG FL Interface and specific NAG Library routine documents for details.
The routines can be split into three main types:
The wrappers are organized in packages matching the structure of the NAG Library documentation. Under the package com.nag.routines, you will find one package per chapter, each of which contains one class per interfaced routine in this chapter.
The NAG Library's routines have two names:
Long names are not available.
For example, to call E04UCA, you will need to use com.nag.routines.E04.E04UC.
In the case of BLAS or LAPACK routines, you may use the NAG short name or the BLAS/LAPACK name of the routine, e.g. F07AAF/DGESV can be called with com.nag.routines.F07.F07AA or com.nag.routines.F07.DGESV. BLAS and LAPACK names are not modified.
Once the routine has returned control to the calling Java program, you can retrieve the values of the arguments using the
Here is an example calling the routine C05AZF. First, we will create a wrapper object for C05AZF, then call the routine.
/* Beginning of the example program for a simple routine */ import com.nag.routines.C05.C05AZ; import java.util.logging.Level; import java.util.logging.Logger; public class SimpleRoutineExample { public static void main (String[] args) { double tolx = 0.00001, x = 0.0, y = 1.0,fx; int ir = 0, ind = 1, ifail = -1; double[] c = new double[17]; boolean keepOn = true; C05AZ c05az = new C05AZ(); fx = fun(x); int ite = 0; System.out.println(" C05AZ Example Program results:\n"); System.out.println(" Iterations\n"); // Reverse communication loop while (keepOn) { ++ite; c05az.eval(x,y,fx,tolx,ir,c,ind,ifail); x = c05az.getX(); y = c05az.getY(); ind = c05az.getIND(); ifail = c05az.getIFAIL(); if (ind == 0) { keepOn = false; } else { fx = fun(x); System.out.printf(" X = %8.5f FX= %12.4e IND = %2d\n",x,fx,ind); } } switch (ifail) { case 0: System.out.println("\n Solution\n"); System.out.printf(" X = %8.5f Y = %8.5f\n",x,y); break; case 4: case 5: System.out.printf(" X = %8.5f Y = %8.5f\n",x,y); break; default: } } private static double fun(double x) { double res = (Math.expm1(-x) + 1) - x; return res; } } /* End of the example program for a simple routine */Note that for routines taking an IFAIL argument, the value of IFAIL on input is used to define the behaviour of the NAG Library should an error be encountered:
Please note that the BLAS and LAPACK routines do not follow this scheme. Some of them may simply terminate the execution of the application if an error occurred.
First, since there is no type for complex numbers in Java, a class must be created. In order to be compatible with the wrappers, it has to implement the interface com.nag.types.NAGComplexInterface or com.nag.types.NAGComplexFInterface for double- or single-precision respectively, as required by the NAG routine.
These interfaces simply require that an implementing class has the following methods:
Basic implementations are provided in com.nag.types.NAGComplex and com.nag.types.NAGComplexF.
An example program called NAGComplexExample.java is distributed which briefly demonstrates the functionality of the supplied NAGComplex type. It helps to follow the source code of this example along in order to see the different fields, constructors and methods used in the NAGComplex type. You can find the source code for this example in NAGJava/examples/source/.
Users can extend NAGComplex to add additional functionality, or implement NAGComplexInterface to build a complex type from scratch. An object of the class used must be provided to the method Routine.setComplex() to notify the wrappers library of the type of complex in use.
The following is an example Java code calling F06CLF which computes the quotient of two complex numbers and returns the result:
/* Beginning of the example program for a routine with complex arguments */ import com.nag.routines.F06.F06CL; import com.nag.routines.Routine; import com.nag.types.NAGComplex; /** * F06CL example program to demonstrate using complex arguments with the * NAG Library for Java. Here we use the provided NAGComplex class, but you can * use your own. * * @author The Numerical Algorithms Group Ltd. (Copyright 2019) */ public class ComplexArgumentExample { public static void main(String[] args) { boolean fail = false; F06CL f06cl = new F06CL(); NAGComplex z1, z2, z3; // Inform the Java wrappers what type is being used for complex numbers // This can be an object of any type that implements NAGComplexInterface Routine.setComplex(new NAGComplex()); // Set input arguments z1 = new NAGComplex(1.0, 1.0); z2 = new NAGComplex(2.0, 2.0); // Evaluate F06CL, store result, and get fail status z3 = (NAGComplex) f06cl.eval(z1, z2, fail); fail = f06cl.getFAIL(); if (fail) { System.err.println("F06CL reports that a/b would overflow"); } else { System.out.println(z1.toString() + " / " + z2.toString() + " = " + z3.toString()); } } } /* End of the example program for a routine with complex arguments */
/* Beginning of the example program for a routine with user-supplied functions as arguments (1) */ import com.nag.routines.D01.D01BD; import java.text.NumberFormat; public class UserDefinedFunctionExample1 { public static void main(String[] args) { double a = 0.0, b = 1.0; double epsabs = 0.0, epsrel = 0.0001; double result = Double.NaN; double abserr = Double.NaN; FUN fun = new FUN(); // INSTANTIATING THE USER-DEFINED FUNCTION D01BD d01bd = new D01BD(fun, a, b, epsabs, epsrel, result, abserr); d01bd.eval(); //GETTING THE RESULT FROM THE ROUTINE result = d01bd.getRESULT(); abserr = d01bd.getABSERR(); NumberFormat nform = NumberFormat.getInstance(); nform.setMinimumFractionDigits(4); nform.setMaximumFractionDigits(4); System.out.println("The result is "+result); } /* * The wrapper D01BD comes with an interface D01BD.D01BD_F to be implemented by the user. * The methods to implement are 1 pair of get/set per argument (here x), and 1 eval method. */ public static class FUN implements D01BD.D01BD_F { private double x; public double eval(double x) { return (x * x * Math.sin(10.0 * Math.PI * x)); } public double getX() { return x; } public void setX(double d) { x = d; } } } /* End of the example program for a routine with user-supplied functions as arguments (1) */
/* Beginning of the example program for a routine with user-supplied functions as arguments (2) */ import com.nag.routines.D01.D01BD; import java.text.NumberFormat; public class UserDefinedFunctionExample2 { public static void main(String[] args) { double a = 0.0, b = 1.0; double epsabs = 0.0, epsrel = 0.0001; double result = Double.NaN; double abserr = Double.NaN; FUN fun = new FUN(); // INSTANTIATING THE USER-DEFINED FUNCTION D01BD d01bd = new D01BD(fun, a, b, epsabs, epsrel, result, abserr); d01bd.eval(); //GETTING THE RESULT FROM THE ROUTINE result = d01bd.getRESULT(); abserr = d01bd.getABSERR(); NumberFormat nform = NumberFormat.getInstance(); nform.setMinimumFractionDigits(4); nform.setMaximumFractionDigits(4); System.out.println("The result is "+result); } /* * The wrapper D01BD comes with an abstract class D01BD.Abstract_D01BD_F to be extended by the user. * The method to override is an eval method, without argument. * X is a protected attribute of the abstract class. */ public static class FUN extends D01BD.Abstract_D01BD_F { public double eval() { return (X * X * Math.sin(10.0 * Math.PI * X)); } } } /* End of the example program for a routine with user-supplied functions as arguments (2) */
In some cases, a user-supplied function may be a routine provided by the NAG Library, e.g. LSQLIN for E04GB can be E04HEV or E04FCV.
The following shows how to use E04HEV as LSQLIN:
/** Using E04HEV as LSQLIN */ private static class LSQLIN extends E04HEV implements E04GB.E04GB_LSQLIN { public void eval() { super.eval(); } }
Below is an example showing how to redirect the output from a NAG Library routine to a file:
/* Beginning of the example program for a routine that redirects output to a file */ import com.nag.io.NAGPrintStream; import java.io.PrintStream; import java.io.File; import java.io.FileNotFoundException; import com.nag.routines.A00.A00AA; import com.nag.routines.Routine; public class OutputExample { public static void main(String[] args) { PrintStream file = null; try { A00AA a00aa = new A00AA(); // GETTING AN OBJECT FOR A00AA a00aa.eval(); // CALLS A00AA - IT PRINTS THROUGH System.out File outputFile = new File("out.txt"); file = new PrintStream(outputFile); NAGPrintStream nagFile = new NAGPrintStream(file); // CREATE A NAGPrintStream TO A FILE Routine.addNAGPrintStream(nagFile); // REGISTER IT WITH THE WRAPPERS Routine.setAdvisoryNAGPrintStream(nagFile); // SET IT AS THE ADVISORY PRINT STREAM a00aa.eval(); // CALL TO A00AA - IT PRINTS TO THE FILE out.txt } catch (FileNotFoundException ex) { System.out.println("Something went wrong: \n" + ex.getMessage()); } finally { if (file != null) file.close(); } } } /* End of the example program for a routine that redirects output to a file */When this example is run, you will get the result of A00AA printed to your screen and printed in the file.
Note that in the data files provided with the NAG Library's examples, the letter D is sometimes used to define the exponent of a double precision number. Java does not recognise this format when parsing a double from a String, so you must change them to E if you want to use them.
When calling a NAG routine from a multi-threaded environment, it is recommended that the soft failure mode (i.e. IFAIL = 1 or -1) is used when it is available. Extra care should be taken for those routines (e.g. BLAS and LAPACK routines) which do not have such a mode.
Further advice on multithreading is available in the FL Interface Multithreading document, along with a list of thread unsafe routines.
NAG Library for Java, Mark 30.3 Java file version: 30.3.0.0 Native file version: 30.3.0.0 Integer size: 32-bit
https://github.com/numericalalgorithmsgroup/NAGJavaExamples
for in-depth examples of using the NAG Library for Java.
https://www.nag.com/content/nag-technical-support-service
for information about the NAG Technical Support Service, including details of the NAG Technical Support Service contact points. We would also be delighted to receive your feedback on NAG's products and services.
https://www.nag.com/content/worldwide-contact-information
for worldwide contact details for the Numerical Algorithms Group.