function
as follows:
To integrate, one then callsSimpsonsRule sr = new SimpsonsRule() { protected double function(double u) { return u*u + 3; } }
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:
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:GLQuadrature<Data> srp = new SimpsonsRule<Data>() { protected double function(double u, Data data) { return u*u + data.value; } }
or... Data data; data.value = 3.0; srp.setParameter(data); System.out.println(srp.integrate(a, b, n));
... 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:
As an optimization, the code caches the arguments raised to the fifth power to reduce the number of multiplications needed, assumingSimpsonsRule<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)); }
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,
shows how to usefs = {valueAt: function(u) {return Math.sin(u);}} rvf = new RealValuedFunction(scripting, fs); glq = SimpsonsRule.newInstance(rvf); integral = rvf.integrate(0.0, Math.PI, 100);
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 -
Method Summary
Modifier and TypeMethodDescriptionprotected double
function
(double t) The function to integrate.protected double
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.static SimpsonsRule
Create a new instance of SimpsonsRule that uses an instance of RealValuedFunction or RealValuedFunctOps as its function.void
setParameters
(P parameters) Set parameters.
-
Constructor Details
-
SimpsonsRule
public SimpsonsRule()
-
-
Method Details
-
setParameters
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
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 offunction(double,Object)
using the parameters supplied by a previous call tosetParameters(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
The function (with parameters) to integrate. Typically, this function will be defined via an anonymous subclass.- Parameters:
t
- the function's argumentp
- 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 integralb
- the upper limit of the integral- Returns:
- the definite integral from a to b
-
integrateWithP
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 integralb
- the upper limit of the integralp
- 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 rulea
- the lower limit of the integralb
- the upper limit of the integral- Returns:
- the definite integral from a to b
-
integrateWithP
Integrate from a to b in multiple steps and with explicit parameters.- Parameters:
n
- the number of subintervals over which to apply Simpson's rulea
- the lower limit of the integralb
- the upper limit of the integralp
- 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 withintegrate(double[])
for cases where a function may be integrated repeatedly over the same range, but with varying parameters.- Parameters:
a
- the lower limit of integrationb
- the upper limit of integrationn
- 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 withgetArguments(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 bygetArguments(a,b,n)
- Returns:
- the definite integral from a to b
- See Also:
-
integrateWithP
Integrate a function using precomputed arguments and with parameters. This method is used in conjunction withgetArguments(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 bygetArguments(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 integrationb
- the upper limit of integrationvalues
- the values to integraten
- the number of values- Returns:
- the definite integral from a to b
- Throws:
IllegalArgumentException
- n is less than 2
-
newInstance
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
-