The NAG Library for Java, Mark 30.3

Users' Note for Linux



Contents

1. Availability

The NAG Library for Java is a set of Java wrappers that enable users to easily call the NAG Library from Java. The NAG Library for Java Mark 30.3 is compatible with Java 7 and later.

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:

2. Installation and accessing the NAG Library for Java on Linux

Installation

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/intel64
and 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.

Compilation

The 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.java
where 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.java

Running 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 Driver

Accessibility 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

3. Documentation

There is no Java-specific documentation. You should use the NAG 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
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:

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

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 Library from Java 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 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: 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.

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 */

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
/* 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) */
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.
/* 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();
    }

}

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

There are several situations in which a NAG 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: It is required to first initialize a routine object or call Routine.init() before assigning a NAGPrintStream. You may use different print streams for error and advisory messages.

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.

6. Multi-threading

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

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.

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, Mark 30.3

  Java file version:   30.3.0.0
  Native file version: 30.3.0.0
  Integer size:        32-bit

8. Further examples

Please see the GitHub repository

https://github.com/numericalalgorithmsgroup/NAGJavaExamples

for in-depth examples of using the NAG Library for Java.

9. Support from NAG

Please see

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.

10. Contact Addresses

Please see

https://www.nag.com/content/worldwide-contact-information

for worldwide contact details for the Numerical Algorithms Group.