The NAG Library for Java

Users' Note



Contents

1. Availability

The NAG Library for Java is a set of Java wrappers that enable users to easily call the NAG Fortran Library from Java. The NAG Library for Java requires the use of Java 1.5 or higher.

NAG recommends that you read the NAG Fortran Library Essential Introduction before trying to use these wrappers. This document gives information about the structure of, and conventions used in, the NAG Fortran 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 Fortran Library. It is therefore important that you ensure that the correct implementation of the NAG Fortran Library is installed in order to use these wrappers.

The NAG Library for Java is available for the following platforms:

Platform       Fortran Library
Windows 32-bit   FLW3224DCL
Windows 64-bit   FLW6I24DCL
Linux 32-bit     FLLUX24DCL
Linux 64-bit     FLL6I24DCL

All the routines from the NAG Fortran Library, Mark 24 are available with the following exceptions:

2. Installation and accessing the NAG Library for Java

Once a compatible version of the NAG Fortran 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: The following shows the directory/file organization of the distribution material.
          |-diagnostic|-NAGJavaDiagnostic.java  - (Java diagnostic program)
          |           |-NAGJavaDiagnostic.class - (Pre-compiled program)
          |
          |-examples/source/*.java  - (Example Java source)
          |
          |-how_to_use_the_NAG_Library_for_Java.html - (This note)
          |
          |-jar/NAGJava.jar - (Java suitable for use on all supported systems)
NAGJava - |
          |-linux_x64/libnag_jni24.so - (Interface shareable Library suitable for 64-bit Linux)
          |
          |-linux_x86/libnag_jni24.so - (Interface shareable Library suitable for 32-bit Linux)
          |
          |-win32/nag_jni24.dll - (Interface shareable Library suitable for 32-bit Windows)
          |
          |-win64/nag_jni24.dll - (Interface shareable Library suitable for 64-bit Windows)

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.java
on Linux systems or
javac -cp [path_to_NAGJava.jar]\NAGJava.jar Driver.java
on Windows systems.

If NAGJava.jar is included in your system CLASSPATH:

javac Driver.java

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;. Driver
If NAGJava.jar is included in your system CLASSPATH
java Driver
Note that in this case the application CLASSPATH must also contain the current folder.

To run your program under Linux issue one of the following commands. If NAGJava.jar is not included in your system CLASSPATH

 java -cp [path_to_NAGJava.jar]/NAGJava.jar:. Driver
If NAGJava.jar is included in your system CLASSPATH
 java Driver
Note that in this case the application CLASSPATH must also contain the current folder.

It is imperative that the NAG Fortran Library components are made available by setting either PATH or LD_LIBRARY_PATH appropriately.

For example, if you use FLL6I24DCL, you will need to add to your LD_LIBRARY_PATH:

[wrappers_shared_lib_folder]:[fll6i24dcl_install_dir]/lib/:[fll6i24dcl_install_dir]/rtl/
For FLLUX24DCL, you will need to add to your LD_LIBRARY_PATH:
[wrappers_shared_lib_folder]:[fllux24dcl_install_dir]/lib/:[fllux24dcl_install_dir]/rtl/
For FLW3224DCL, you will need to add to your PATH:
[wrappers_shared_lib_folder];[flw3224dcl_install_dir]\bin
For FLW6I24DCL, you will need to add to your PATH:
[wrappers_shared_lib_folder];[flw6i24dcl_install_dir]\bin

To check the availability of the NAG Fortran Library components on Windows, you can use the diagnostic program provided with the library. See section 4.2.3 "Accessibility Check" of the Installer's Note specific to your NAG Fortran Library.

On all platforms, you may use NAGJavaDiagnostic provided in the folder diagnostic of the NAG Library for Java distribution. To run it, go to this folder and run the command:

Under Linux

java -cp [path_to_NAGJava.jar]/NAGJava.jar:. NAGJavaDiagnostic
Under Windows
java -cp [path_to_NAGJava.jar]\NAGJava.jar;. 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.

3. Documentation

There is no Java-specific documentation. You should use the NAG Fortran Library documentation for information relating to a specific routine and its arguments. The following table can be used to match Java types to Fortran types:

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:

4. Using the NAG Library for Java

The following subsections demonstrate how to use the NAG Library for Java. Section 4.1 describes a call to a routine whose interface comprises only simple types. Subsequent sections introduce more complicated scenarios where the interface includes complex arguments or user-supplied functions. Examples are given to help understand the textual description. The source files of these examples can be found in the folder examples/source of the distribution.

The routines can be split into three main types:

The wrappers are organized in packages matching the structure of the NAG Fortran 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 Fortran Library's routines have two names:

From Java, only the short names are available, with the last letter removed if it is an A or an F.
If the last letter is not an A or an F, then the short name is 6 characters long, e.g. E04HEV.

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.

4.1. Calling a simple routine

The first step towards calling the NAG Fortran Library from Java is to initialize the wrappers library. To do so you have to call the static function init() from the class com.nag.routines.Routine. This will load all the required native libraries and retrieve the required information on the platform.

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 get[ARG_NAME] methods provided. Note that arrays will have been automatically updated.

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");
        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 Fortran Library should an error be encountered: If you decide to use -1 or 1 for IFAIL, it is essential to test the value of IFAIL returned by the routine using the getIFAIL() method of the wrapper object. If the value of IFAIL returned by the routine indicates an error, then you can access the corresponding error message by calling the getErrorMessage() method of the wrapper object. Note that this method call will clear the error message buffer. Any call to one of the eval methods also clears this buffer, which guarantees that an error message is related to the current state of the wrapper object.

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.

4.2. Calling a routine with complex arguments

There are two things that need to be done in order to utilize the NAG Library for Java routines that have arguments of type complex.

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];
        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:


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) {
        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()+")");
        }
    }
}

4.3. Calling a routine with user-supplied functions as arguments

When a routine has one or more user-supplied functions as arguments, the user will have a choice of implementing specific interfaces or extending abstract classes to represent those user-supplied functions and then pass objects of these classes as arguments to the routine. The following is an example Java code which calls D01BDF which computes a 1D quadrature of a user-supplied function. The first case implements the interface D01BD.D01BD_F. The second one extends the abstract class D01BD.Abstract_D01BD_F.
Implementing the interface
import com.nag.routines.Routine;
import com.nag.routines.D01.D01BD;
import java.text.NumberFormat;

public class UserDefinedFunctionExample {

    public static void main(String[] args) {
	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;
        }


    }
}
Extending the abstract class
In this case you only need to override the method eval(). The arguments for the user-defined function can be accessed via protected attributes, using Java basic types and their names being the names of the Fortran arguments upper-cased.
import com.nag.routines.Routine;
import com.nag.routines.D01.D01BD;
import java.text.NumberFormat;

public class UserDefinedFunctionExample {

    public static void main(String[] args) {
        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));
        }
   }
}

In some cases, a user-supplied function may be a routine provided by the NAG Fortran Library, e.g. LSQLIN for E04GB can be E04HEV or E04FCV.

The following shows how to extend E04GB.Abstract_E04GB_LSQLIN to call E04HEV:

  public static class LSQLIN extends E04GB.Abstract_E04GB_LSQLIN {

    public void eval() {
	try {
                E04HEV e04hev = new E04HEV(SELCT);
                e04hev.eval();
                SELCT = e04hev.getLSQLIN_SELECT();
        } catch (NAGBadIntegerException ex) {
		System.err.println("Something went wrong when calling E04HEV");
        }
    }

  }

5. The NAG Fortran Library and the Java I/O system

There are several situations in which a NAG Fortran Library routine will try to print information e.g. in the case of an error, an error message may be printed. The default output stream used by the NAG Library for Java is System.out. You can change this behaviour and set it to any stream by following these guidelines: You may use different print streams for error and advisory messages.

Below is an example showing how to redirect the output from a NAG Fortran Library routine 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 OutputShow {

    public static void main(String[] args) {
        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 {
            file.close();
        }
        
        
    }
}
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 Fortran Library's examples, the letter D is sometimes used to define the exponent of a double 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.

6. Multi-threading

Unless specifically stated in the NAG Fortran Library documentation, it is safe to call NAG Fortran Library routines from multiple Java threads.

Thread unsafe routines are listed under section 3 of the Thread Safety document contained in the NAG Fortran Library Manual introductory description.

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.

7. NAG Library for Java version

The static method Routine.getVersionString() will give information on the version of the NAG Library for Java you are using. You need to call Routine.init() first. Typically, it will return the following String:
NAG Library for Java:
	Java file version: 2.0
	Native file version: 2.0
	for use with NAG Fortran Library: Mark 24

8. Support from NAG

(a) Contact with NAG

Queries concerning this document or the implementation generally should be directed to NAG at one of the addresses given in the Appendix. Users subscribing to the support service are encouraged to contact our support team (see below).

(b) NAG Technical Support Service

The NAG Technical Support Service is available for general enquiries from all users and also for technical queries from sites with an annually licensed product or support service.

The technical support desks are open during office hours, but contact is possible by email and phone (answering machine) at all times.

When contacting us, it helps us deal with your enquiry quickly if you can quote your NAG customer reference number. You should also specify that you're using the NAG Library for Java as well as the NAG product code of the underlying NAG Fortran Library.

(c) NAG Websites

The NAG websites provide information about implementation availability, descriptions of products, downloadable software, product documentation and technical reports. The NAG websites can be accessed at the following URLs:

http://www.nag.co.uk/, http://www.nag.com/, http://www.nag-j.co.jp/ or http://www.nag-gc.com/

(d) NAG Electronic Newsletter

If you would like to be kept up to date with news from NAG then please register to receive our free electronic newsletter, which will alert you to announcements about new products or product/service enhancements, technical tips, customer stories and NAG's event diary. You can register via one of our websites, or by contacting us at nagnews@nag.co.uk.

9. User Feedback

Many factors influence the way that NAG's products and services evolve, and your ideas are invaluable in helping us to ensure that we meet your needs. If you would like to contribute to this process, we would be delighted to receive your comments. Please contact any of the NAG offices (shown below).

Appendix - Contact Addresses

NAG Ltd
Wilkinson House
Jordan Hill Road
OXFORD  OX2 8DR                         Technical Support (Europe & ROW)
United Kingdom                          email: support@nag.co.uk

Tel: +44 (0)1865 511245                 Tel: +44 (0)1865 311744

NAG Inc
801 Warrenville Road
Suite 185
Lisle, IL  60532-4332                   Technical Support (North America)
USA                                     email: support@nag.com

Tel: +1 630 971 2337                    Tel: +1 630 971 2337

Nihon NAG KK
Hatchobori Frontier Building 2F
4-9-9
Hatchobori
Chuo-ku
Tokyo 104-0032                          Technical Support (Japan)
Japan                                   email: naghelp@nag-j.co.jp

Tel: +81 3 5542 6311                    Tel: +81 3 5542 6311

NAG Taiwan Branch Office
5F.-5, No.36, Sec.3
Minsheng E. Rd.
Taipei City 10480                       Technical Support (Greater China)
Taiwan                                  email: support@nag-gc.com

Tel: +886 2 25093288                    Tel: +886 2 25093288