NAG recommends that you read How to Use the NAG Library and its Documentation 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 26.2 is available for the following platforms:
Platform NAG Library Linux 64-bit CLL6I262CL Windows 64-bit CLW6I262EL
Note that this document only provides information for Windows users. Linux users should consult the Linux version of this document.
All the routines from the NAG Library Mark 26.2 are available with the following exceptions:
Once a compatible version of the NAG Library is installed and operational on your system it is easy to make the NAG Library for Java available. 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:
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_jni262.so - (Interface shareable Library suitable for 64-bit Linux) | +-- win64 | \-- nag_jni262.dll - (Interface shareable Library suitable for 64-bit Windows) | |-- how_to_use_the_NAG_library_for_Java_Linux.html | \-- how_to_use_the_NAG_library_for_Java_Windows.html - (This note)
Compilation
To compile a Java source file that includes calls to the NAG Library for Java, issue one of the following commands:
If NAGJava.jar is not included in your system CLASSPATH:
javac -cp [path_to_NAGJava.jar]\NAGJava.jar Driver.javawhere Driver.java is your calling program.
If NAGJava.jar is included in your system CLASSPATH:
javac Driver.java
Note that to compile using javac, the Java Development Kit (JDK) must be installed and in the PATH.
Running a program
It is imperative that the NAG Library components are made available by setting PATH appropriately.
To use CLW6I262EL, you will need to add to your PATH:
[wrappers_shared_lib_folder];[clw6i262el_install_dir]\bin;[clw6i262el_install_dir]\rtl\bin
To run your program under Windows issue one of the following commands:
If NAGJava.jar is not included in your system CLASSPATH
java -cp [path_to_NAGJava.jar]\NAGJava.jar;. DriverIf NAGJava.jar is included in your system CLASSPATH
java Driver(Note that in this case, the current directory '.' must also be included in the CLASSPATH.)
Accessibility check
On all platforms, you may use NAGJavaDiagnostic provided in the folder diagnostic of the NAG Library for Java distribution to check that the NAG Java materials and the underlying NAG Library are accessible. To run it, go to this folder and run the commands:
javac -cp [path_to_NAGJava.jar]\NAGJava.jar NAGJavaDiagnostic.javajava -cp [path_to_NAGJava.jar]\NAGJava.jar;. NAGJavaDiagnostic
Or if CLASSPATH includes NAGJava.jar and the current directory:
javac NAGJavaDiagnostic.javajava NAGJavaDiagnostic
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.
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 |
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 4.3.1 of How to Use the NAG Library and its Documentation and the document for the specific NAG Library routine 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.
The second step is to create an object of the class of the wrapper you want to use. You may use a constructor with or without arguments. In the first case, you will then be able to call the function eval() from this object; in the second case, you will need to call the eval function taking the arguments.
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 initialize the wrappers library and then we will build a wrapper object for C05AZF and call the routine.
/* Beginning of the example program for a simple routine */ import com.nag.exceptions.NAGBadIntegerException; import com.nag.routines.C05.C05AZ; import com.nag.routines.Routine; import java.util.logging.Level; import java.util.logging.Logger; public class SimpleRoutineExample { public static void main (String[] args) throws NAGBadIntegerException { Routine.init(); 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.
You will notice that the main method throws the NAGBadIntegerException. This stems from a check made in Routine.init(), to ensure that the correct integer size (32- or 64-bit) is being used. If you wish, this exception can be caught with a try-catch block, using getMessage() on the exception to determine which integer size was expected.
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. The source code for the NAGComplex class is given below:
/* Beginning of NAGComplex class */ package com.nag.types; public class NAGComplex implements NAGComplexInterface { private double re=0, im=0; public double getRe() { return re; } public double getIm() { return im; } public void setRe(double re) { this.re = re; } public void setIm(double im) { this.im = im; } public NAGComplexInterface getInstance() { NAGComplex res = new NAGComplex(); return res; } public NAGComplexInterface[] getArrayOfInstances(int size) { NAGComplex[] res = new NAGComplex[size]; for (int i = 0; i < size; i++) { res[i] = new NAGComplex(); } return res; } } /* End of NAGComplex class */The user must provide an object of this class 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.exceptions.NAGBadIntegerException; import com.nag.routines.F06.F06CL; import com.nag.routines.Routine; import com.nag.types.NAGComplex; // Here we use the provided NAGComplex class, but you can use your own. public class ComplexArgumentExample { public static void main(String[] args) throws NAGBadIntegerException { Routine.init(); // INITIALIZING THE WRAPPERS LIBRARY boolean fail = false; // CREATING NAGComplex OBJECTS NAGComplex z1 = new NAGComplex(); NAGComplex z2 = new NAGComplex(); NAGComplex z3 = new NAGComplex(); Routine.setComplex(z1); // SETTING THE TYPE OF COMPLEX IN USE // (CAN USE ANY COMPLEX OBJECT AS THE ARGUMENT) // INITIALIZING COMPLEX VALUES z1.setRe(1.0); z1.setIm(1.0); z2.setRe(2.0); z2.setIm(2.0); F06CL f06cl = new F06CL(z1,z2,fail); z3 = (NAGComplex)f06cl.eval(); fail = f06cl.getFAIL(); if (fail) { System.err.println("Something went wrong..."); } else { System.out.println("("+z1.getRe()+", "+z1.getIm()+")/(" + z2.getRe()+", "+z2.getIm()+") = (" + z3.getRe()+", "+z3.getIm()+")"); } } } /* 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.exceptions.NAGBadIntegerException; import com.nag.routines.Routine; import com.nag.routines.D01.D01BD; import java.text.NumberFormat; public class UserDefinedFunctionExample1 { public static void main(String[] args) throws NAGBadIntegerException { Routine.init(); 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.exceptions.NAGBadIntegerException; import com.nag.routines.Routine; import com.nag.routines.D01.D01BD; import java.text.NumberFormat; public class UserDefinedFunctionExample2 { public static void main(String[] args) throws NAGBadIntegerException { Routine.init(); 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.exceptions.NAGBadIntegerException; 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) throws NAGBadIntegerException { PrintStream file = null; try { Routine.init(); // INITIALIZING THE WRAPPERS LIBRARY 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 section 3.12 of How to Use the NAG Library and its Documentation, along with a list of thread unsafe routines.
NAG Library for Java, Mark 26.2 Java file version: 26.2.0.0 Native file version: 26.2.0.0 Integer size: 32-bit
https://www.nag.co.uk/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.co.uk/content/worldwide-contact-information
for worldwide contact details for the Numerical Algorithms Group.