
public class Quadrature
{

  // Declaration of the Native (C) function
  private native int d01ajc(String funName,
                            double a, double b,
                            double epsabs, double epsrel,
                            int max_num_subint);

  // Member variables to hold results returned by d01ajc
  double result, abserr;
  int nFun, nSubInt;

  static
    {
      // The runtime system executes a class's static
      // initializer when it loads the class.
      System.loadLibrary("nagCJavaInterface");
    }

  // An example function to be integrated.
  private double myFunction(double x)
    {
      double ret;
      ret = x * x * x;
      return ret;
    }

  // Another example function to be integrated (this one is from
  // the example program for d01ajc in the NAG C Library manual).
  private double myFunction2(double x)
    {
      double ret;
      ret = x * Math.sin(x * 30.0) /
               Math.sqrt(1.0 - x * x / (Math.PI * Math.PI * 4.0));
      return ret;
    }

  // The main program
  public static void main(String[] args)
    {
      double a, b;

      // Create an object of class Quadrature
      Quadrature quad = new Quadrature();

      System.out.println();
      System.out.println("Calls of NAG quadrature routine d01ajc");
      System.out.println();

      // Integrate the first example function
      a = 0.0;
      b = 1.0;
      System.out.println("Integral of x*x*x");
      quad.Integrate("myFunction", a, b);

      // Integrate the second example function
      a = 0.0;
      b = Math.PI * 2.0;
      System.out.println("Integral of x*sin(30*x) / sqrt(1-x*x/(4*PI*PI))");
      quad.Integrate("myFunction2", a, b);

    }

  // A routine to integrate by calling the native (C) function
  private void Integrate(String functionName, double a, double b)
    {
      double epsabs, epsrel;
      int max_num_subint, resCode;

      epsabs = 0.0;
      epsrel = 0.0001;
      max_num_subint = 200;

      resCode = d01ajc(functionName, a, b, epsabs, epsrel, max_num_subint);

      // Check the result code returned by the C function.
      if (resCode == -1)
        System.out.println("Cannot load library nagc.dll / libnagc.so");
      else if (resCode == -2)
        System.out.println("Cannot find function d01ajc in nagc.dll / libnagc.so");
      else if (resCode == -3)
        System.out.println("Cannot find method " + functionName +
                           " with signature (D)D");
      else if (resCode > 0)
        {
          System.out.print("NAG function d01ajc returned non-zero exit code: ");
          System.out.println(resCode);
        }
      else
        {
          // resCode = 0 - we got some results.
          System.out.print("Lower limit of integration = ");
          System.out.println(a);
          System.out.print("Upper limit of integration = ");
          System.out.println(b);
          System.out.print("Requested relative error = ");
          System.out.println(epsrel);
          System.out.print("Integral value = ");
          System.out.println(result);
          System.out.print("Estimate of absolute error = ");
          System.out.println(abserr);
          System.out.print("Number of function evaluations = ");
          System.out.println(nFun);
          System.out.print("Number of subintervals used = ");
          System.out.println(nSubInt);
        }
      System.out.println();
    }
}
