Class SimpsonsRule<P>

java.lang.Object
org.bzdev.math.SimpsonsRule<P>

public abstract class SimpsonsRule<P> extends Object
Implementation of Simpson's rule. This class provides an implementation of Simpson's rule for numerical integration. For the simplest case, one will create an anonymous inner class implementing a method named function as follows:

      SimpsonsRule sr = new SimpsonsRule() {
        protected double function(double u) {
          return u*u + 3;
        }
      }
 
To integrate, one then calls sr.integrate(a, b, n) where a and b are the limits and n is the number of points. Alternatively, one may use a lambda expression to define the function:

      SimpsonsRule sr = SimpsonsRule.newInstance((u) -> u*u+3);
      double integral  = sr.integrate(a, b, n);
 

The type parameter P, if specified, can be used to provide a class that will store the values of parameters used in computing the function to be integrated. These values can be set by calling setParameters(P) and read by calling getParameters(). Parameters may also be provided explicitly when an "integrate" method is called. The two-argument "function" should be implemented in this case:


      GLQuadrature<Data> srp = new SimpsonsRule<Data>() {
        protected double function(double u, Data data) {
          return u*u + data.value;
        }
      }
 
When used, this allows one to define parameterized functions - the parameters act as additional arguments that are typically constant during the integration. A parameter is stored, not copied, so it should not be modified while an integral is being computed (not an issue for single-threaded programs). If a series of integrals are computed for different values of the parameters, this allows one instance of SimpsonsRule to be used, rather than a separate object for each value. An example of usage is:

     ...
     Data data;
     data.value = 3.0;
     srp.setParameter(data);
     System.out.println(srp.integrate(a, b, n));
 
or

     ...
     Data data;
     data.value = 3.0;
     System.out.println(srp.integrateWithP(a, b, n, data));
 

In addition, the methods getArguments(double,double,int) and integrate(double[]) can be used to precompute function arguments in cases where those will be used repetitively (e.g., for a series of integrals where the parameters change but not the range or the number of points). For example, consider the following code:


       SimpsonsRule<Data> sr = new SimpsonsRule<Data>() {
          double[] u5cache = null;
          public double[] getArguments(double a, double b, int n) {
             double[] results = super.getArguments(a, b, n);
             u5cache = new double[n+1];
             for (i = 0; i <= n; i++) {
                double u = results[i];
                double uu = u*u;
                u5cache[i] = uu*uu*u;
                result[i] = (double)i;
             }
          }
           protected double function(double u) {
                double u5 = u5cache[(int)(Math.round(u))];
                Data data = getParameters();
                return u5 * data.value;
           }
       };
       double[] args = sr.getArguments(a, b, 100);
       Data data = new Data();
       sr.setParameters(data);
       for (double value: list) {
              data.value = value;
              System.out.println(sr.integrate(args));
       }
 
As an optimization, the code caches the arguments raised to the fifth power to reduce the number of multiplications needed, assuming list contains multiple elements. This sort of optimization would typically be used only in special cases where sufficiently expensive terms in the function to be integrated can be precomputed.

Finally, the method newInstance(org.bzdev.math.RealValuedFunctOps) will construct an instance of SimpsonsRule where the function is represented as an instance of RealValuedFunction. While the implementation is trivial in Java, newInstance simplifies the use of this class from a scripting language. For example,


         fs = {valueAt: function(u) {return Math.sin(u);}}
         rvf = new RealValuedFunction(scripting, fs);
         glq = SimpsonsRule.newInstance(rvf);
         integral = rvf.integrate(0.0, Math.PI, 100);
 
shows how to use newInstance with ECMAScript.

Note: some of the methods are named integrate while those that use parameters explicitly are named integrateWithP. While Java's type system treats primitive types and class types differently, a scripting language may not.

  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    protected double
    function(double t)
    The function to integrate.
    protected double
    function(double t, P p)
    The function (with parameters) to integrate.
    double[]
    getArguments(double a, double b, int n)
    Set up data for an integration.
    Get parameters.
    double
    integrate(double[] args)
    Integrate a function using precomputed arguments.
    double
    integrate(double a, double b)
    Integrate from a to b in one step.
    static final double
    integrate(double a, double b, double[] values, int n)
    Simpson's rule integration given an array of equally spaced values for the range [a, b]: values[0] is the value for a and values[n-1] is the value for b.
    double
    integrate(double a, double b, int n)
    Integrate from a to b in multiple steps.
    double
    integrateWithP(double[] args, P p)
    Integrate a function using precomputed arguments and with parameters.
    double
    integrateWithP(double a, double b, int n, P p)
    Integrate from a to b in multiple steps and with explicit parameters.
    double
    integrateWithP(double a, double b, P p)
    Integrate from a to b in one step with explicit parameters.
    Create a new instance of SimpsonsRule that uses an instance of RealValuedFunction or RealValuedFunctOps as its function.
    void
    setParameters(P parameters)
    Set parameters.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • SimpsonsRule

      public SimpsonsRule()
  • Method Details

    • setParameters

      public void setParameters(P parameters)
      Set parameters. Parameters are used to provide additional values for computing the function being integrated. The argument is stored, not copied, and will typically not be changed while an integration is in progress.
      Parameters:
      parameters - the parameters
    • getParameters

      public P getParameters()
      Get parameters. Parameters are used to provide additional values for computing the function being integrated.
      Returns:
      an instance of the class representing a root finder's parameters (this will be the same instance passed to setParameters)
    • function

      protected double function(double t)
      The function to integrate. The default implementation calls the two-argument implementation of function(double,Object) using the parameters supplied by a previous call to setParameters(P). If parameters are not used, this method may be overridden.
      Parameters:
      t - the value of the parameter with respect to which one integrates
      Returns:
      the value of the function when its argument is t
    • function

      protected double function(double t, P p)
      The function (with parameters) to integrate. Typically, this function will be defined via an anonymous subclass.
      Parameters:
      t - the function's argument
      p - the parameters
      Returns:
      the value of the function given its arguments
      Throws:
      UnsupportedOperationException - the method was needed but not implemented.
    • integrate

      public double integrate(double a, double b)
      Integrate from a to b in one step. This is suitable for very short intervals.
      Parameters:
      a - the lower limit of the integral
      b - the upper limit of the integral
      Returns:
      the definite integral from a to b
    • integrateWithP

      public double integrateWithP(double a, double b, P p)
      Integrate from a to b in one step with explicit parameters. This is suitable for very short intervals.
      Parameters:
      a - the lower limit of the integral
      b - the upper limit of the integral
      p - the parameters
      Returns:
      the definite integral from a to b
    • integrate

      public double integrate(double a, double b, int n)
      Integrate from a to b in multiple steps.
      Parameters:
      n - the number of subintervals over which to apply Simpson's rule
      a - the lower limit of the integral
      b - the upper limit of the integral
      Returns:
      the definite integral from a to b
    • integrateWithP

      public double integrateWithP(double a, double b, int n, P p)
      Integrate from a to b in multiple steps and with explicit parameters.
      Parameters:
      n - the number of subintervals over which to apply Simpson's rule
      a - the lower limit of the integral
      b - the upper limit of the integral
      p - the parameters
      Returns:
      the definite integral from a to b
    • getArguments

      public double[] getArguments(double a, double b, int n)
      Set up data for an integration. This method is used in conjunction with integrate(double[]) for cases where a function may be integrated repeatedly over the same range, but with varying parameters.
      Parameters:
      a - the lower limit of integration
      b - the upper limit of integration
      n - an estimate of the number of points to use
      Returns:
      an array of values at which the function should be evaluated, with the last argument containing the scaling factor (b-a)/(3n)
      See Also:
    • integrate

      public double integrate(double[] args)
      Integrate a function using precomputed arguments. This method is used in conjunction with getArguments(double,double,int) for cases where a function may be integrated repeatedly over the same range, but with varying parameters. It is provided as an optimization for a special case.
      Parameters:
      args - the array returned by getArguments(a,b,n)
      Returns:
      the definite integral from a to b
      See Also:
    • integrateWithP

      public double integrateWithP(double[] args, P p)
      Integrate a function using precomputed arguments and with parameters. This method is used in conjunction with getArguments(double,double,int) for cases where a function may be integrated repeatedly over the same range, but with varying parameters. It is provided as an optimization for a special case.
      Parameters:
      args - the array returned by getArguments(a,b,n)
      p - the parameters
      Returns:
      the definite integral from a to b
      See Also:
    • integrate

      public static final double integrate(double a, double b, double[] values, int n)
      Simpson's rule integration given an array of equally spaced values for the range [a, b]: values[0] is the value for a and values[n-1] is the value for b.
      Parameters:
      a - the lower limit of integration
      b - the upper limit of integration
      values - the values to integrate
      n - the number of values
      Returns:
      the definite integral from a to b
      Throws:
      IllegalArgumentException - n is less than 2
    • newInstance

      public static SimpsonsRule newInstance(RealValuedFunctOps f)
      Create a new instance of SimpsonsRule that uses an instance of RealValuedFunction or RealValuedFunctOps as its function.
      Parameters:
      f - the function
      Returns:
      the new instance of SimpsonsRule
      Throws:
      IllegalArgumentException - n is less than 1