diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaFieldIntegrator.java index d174bb2e0..eab1bbff3 100644 --- a/src/main/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaFieldIntegrator.java +++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaFieldIntegrator.java @@ -19,6 +19,9 @@ package org.apache.commons.math3.ode.nonstiff; import org.apache.commons.math3.Field; import org.apache.commons.math3.RealFieldElement; +import org.apache.commons.math3.ode.AbstractFieldIntegrator; +import org.apache.commons.math3.ode.FieldEquationsMapper; +import org.apache.commons.math3.util.MathArrays; /** * This class implements the classical fourth order Runge-Kutta @@ -49,31 +52,59 @@ import org.apache.commons.math3.RealFieldElement; public class ClassicalRungeKuttaFieldIntegrator> extends RungeKuttaFieldIntegrator { - /** Time steps Butcher array. */ - private static final double[] STATIC_C = { - 1.0 / 2.0, 1.0 / 2.0, 1.0 - }; - - /** Internal weights Butcher array. */ - private static final double[][] STATIC_A = { - { 1.0 / 2.0 }, - { 0.0, 1.0 / 2.0 }, - { 0.0, 0.0, 1.0 } - }; - - /** Propagation weights Butcher array. */ - private static final double[] STATIC_B = { - 1.0 / 6.0, 1.0 / 3.0, 1.0 / 3.0, 1.0 / 6.0 - }; - /** Simple constructor. * Build a fourth-order Runge-Kutta integrator with the given step. * @param field field to which the time and state vector elements belong * @param step integration step */ public ClassicalRungeKuttaFieldIntegrator(final Field field, final T step) { - super(field, "classical Runge-Kutta", STATIC_C, STATIC_A, STATIC_B, - new ClassicalRungeKuttaFieldStepInterpolator(), step); + super(field, "classical Runge-Kutta", step); + } + + /** {@inheritDoc} */ + @Override + protected T[] getC() { + final T[] c = MathArrays.buildArray(getField(), 3); + c[0] = getField().getOne().multiply(0.5); + c[1] = c[0]; + c[2] = getField().getOne(); + return c; + } + + /** {@inheritDoc} */ + @Override + protected T[][] getA() { + final T[][] a = MathArrays.buildArray(getField(), 3, -1); + for (int i = 0; i < a.length; ++i) { + a[i] = MathArrays.buildArray(getField(), i + 1); + } + a[0][0] = fraction(1, 2); + a[1][0] = getField().getZero(); + a[1][1] = a[0][0]; + a[2][0] = getField().getZero(); + a[2][1] = getField().getZero(); + a[2][2] = getField().getOne(); + return a; + } + + /** {@inheritDoc} */ + @Override + protected T[] getB() { + final T[] b = MathArrays.buildArray(getField(), 4); + b[0] = fraction(1, 6); + b[1] = fraction(1, 3); + b[2] = b[1]; + b[3] = b[0]; + return b; + } + + /** {@inheritDoc} */ + @Override + protected ClassicalRungeKuttaFieldStepInterpolator + createInterpolator(final AbstractFieldIntegrator rkIntegrator, final T[] y, + final T[][] yDotArray, final boolean forward, + final FieldEquationsMapper mapper) { + return new ClassicalRungeKuttaFieldStepInterpolator(rkIntegrator, y, yDotArray, forward, mapper); } } diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/EulerFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/EulerFieldIntegrator.java index c591e3edd..7fb32a1d7 100644 --- a/src/main/java/org/apache/commons/math3/ode/nonstiff/EulerFieldIntegrator.java +++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/EulerFieldIntegrator.java @@ -19,6 +19,9 @@ package org.apache.commons.math3.ode.nonstiff; import org.apache.commons.math3.Field; import org.apache.commons.math3.RealFieldElement; +import org.apache.commons.math3.ode.AbstractFieldIntegrator; +import org.apache.commons.math3.ode.FieldEquationsMapper; +import org.apache.commons.math3.util.MathArrays; /** * This class implements a simple Euler integrator for Ordinary @@ -51,26 +54,42 @@ import org.apache.commons.math3.RealFieldElement; public class EulerFieldIntegrator> extends RungeKuttaFieldIntegrator { - /** Time steps Butcher array. */ - private static final double[] STATIC_C = { - }; - - /** Internal weights Butcher array. */ - private static final double[][] STATIC_A = { - }; - - /** Propagation weights Butcher array. */ - private static final double[] STATIC_B = { - 1.0 - }; - /** Simple constructor. * Build an Euler integrator with the given step. * @param field field to which the time and state vector elements belong * @param step integration step */ public EulerFieldIntegrator(final Field field, final T step) { - super(field, "Euler", STATIC_C, STATIC_A, STATIC_B, new EulerFieldStepInterpolator(), step); + super(field, "Euler", step); + } + + /** {@inheritDoc} */ + @Override + protected T[] getC() { + return MathArrays.buildArray(getField(), 0); + } + + /** {@inheritDoc} */ + @Override + protected T[][] getA() { + return MathArrays.buildArray(getField(), 0, 0); + } + + /** {@inheritDoc} */ + @Override + protected T[] getB() { + final T[] b = MathArrays.buildArray(getField(), 1); + b[0] = getField().getOne(); + return b; + } + + /** {@inheritDoc} */ + @Override + protected EulerFieldStepInterpolator + createInterpolator(final AbstractFieldIntegrator rkIntegrator, final T[] y, + final T[][] yDotArray, final boolean forward, + final FieldEquationsMapper mapper) { + return new EulerFieldStepInterpolator(rkIntegrator, y, yDotArray, forward, mapper); } } diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/GillFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/GillFieldIntegrator.java index 21cd5d67a..d8460c203 100644 --- a/src/main/java/org/apache/commons/math3/ode/nonstiff/GillFieldIntegrator.java +++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/GillFieldIntegrator.java @@ -19,7 +19,9 @@ package org.apache.commons.math3.ode.nonstiff; import org.apache.commons.math3.Field; import org.apache.commons.math3.RealFieldElement; -import org.apache.commons.math3.util.FastMath; +import org.apache.commons.math3.ode.AbstractFieldIntegrator; +import org.apache.commons.math3.ode.FieldEquationsMapper; +import org.apache.commons.math3.util.MathArrays; /** @@ -50,30 +52,69 @@ import org.apache.commons.math3.util.FastMath; public class GillFieldIntegrator> extends RungeKuttaFieldIntegrator { - /** Time steps Butcher array. */ - private static final double[] STATIC_C = { - 1.0 / 2.0, 1.0 / 2.0, 1.0 - }; - - /** Internal weights Butcher array. */ - private static final double[][] STATIC_A = { - { 1.0 / 2.0 }, - { (FastMath.sqrt(2.0) - 1.0) / 2.0, (2.0 - FastMath.sqrt(2.0)) / 2.0 }, - { 0.0, -FastMath.sqrt(2.0) / 2.0, (2.0 + FastMath.sqrt(2.0)) / 2.0 } - }; - - /** Propagation weights Butcher array. */ - private static final double[] STATIC_B = { - 1.0 / 6.0, (2.0 - FastMath.sqrt(2.0)) / 6.0, (2.0 + FastMath.sqrt(2.0)) / 6.0, 1.0 / 6.0 - }; - /** Simple constructor. * Build a fourth-order Gill integrator with the given step. * @param field field to which the time and state vector elements belong * @param step integration step */ public GillFieldIntegrator(final Field field, final T step) { - super(field, "Gill", STATIC_C, STATIC_A, STATIC_B, new GillFieldStepInterpolator(), step); + super(field, "Gill", step); + } + + /** {@inheritDoc} */ + @Override + protected T[] getC() { + final T[] c = MathArrays.buildArray(getField(), 3); + c[0] = fraction(1, 2); + c[1] = c[0]; + c[2] = getField().getOne(); + return c; + } + + /** {@inheritDoc} */ + @Override + protected T[][] getA() { + + final T two = getField().getOne().multiply(2); + final T sqrtTwo = two.sqrt(); + + final T[][] a = MathArrays.buildArray(getField(), 3, -1); + for (int i = 0; i < a.length; ++i) { + a[i] = MathArrays.buildArray(getField(), i + 1); + } + a[0][0] = fraction(1, 2); + a[1][0] = sqrtTwo.subtract(1).multiply(0.5); + a[1][1] = sqrtTwo.subtract(2).multiply(-0.5); + a[2][0] = getField().getZero(); + a[2][1] = sqrtTwo.multiply(-0.5); + a[2][2] = sqrtTwo.add(2).multiply(0.5); + return a; + } + + /** {@inheritDoc} */ + @Override + protected T[] getB() { + + final T two = getField().getOne().multiply(2); + final T sqrtTwo = two.sqrt(); + + final T[] b = MathArrays.buildArray(getField(), 4); + b[0] = fraction(1, 6); + b[1] = two.subtract(sqrtTwo).divide(6); + b[2] = two.add(sqrtTwo).divide(6); + b[3] = b[0]; + + return b; + + } + + /** {@inheritDoc} */ + @Override + protected GillFieldStepInterpolator + createInterpolator(final AbstractFieldIntegrator rkIntegrator, final T[] y, + final T[][] yDotArray, final boolean forward, + final FieldEquationsMapper mapper) { + return new GillFieldStepInterpolator(rkIntegrator, y, yDotArray, forward, mapper); } } diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/LutherFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/LutherFieldIntegrator.java index 26156d134..363e04272 100644 --- a/src/main/java/org/apache/commons/math3/ode/nonstiff/LutherFieldIntegrator.java +++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/LutherFieldIntegrator.java @@ -19,7 +19,9 @@ package org.apache.commons.math3.ode.nonstiff; import org.apache.commons.math3.Field; import org.apache.commons.math3.RealFieldElement; -import org.apache.commons.math3.util.FastMath; +import org.apache.commons.math3.ode.AbstractFieldIntegrator; +import org.apache.commons.math3.ode.FieldEquationsMapper; +import org.apache.commons.math3.util.MathArrays; /** @@ -60,27 +62,7 @@ public class LutherFieldIntegrator> extends RungeKuttaFieldIntegrator { /** Square root. */ - private static final double Q = FastMath.sqrt(21); - - /** Time steps Butcher array. */ - private static final double[] STATIC_C = { - 1.0, 1.0 / 2.0, 2.0 / 3.0, (7.0 - Q) / 14.0, (7.0 + Q) / 14.0, 1.0 - }; - - /** Internal weights Butcher array. */ - private static final double[][] STATIC_A = { - { 1.0 }, - { 3.0 / 8.0, 1.0 / 8.0 }, - { 8.0 / 27.0, 2.0 / 27.0, 8.0 / 27.0 }, - { ( -21.0 + 9.0 * Q) / 392.0, ( -56.0 + 8.0 * Q) / 392.0, ( 336.0 - 48.0 * Q) / 392.0, (-63.0 + 3.0 * Q) / 392.0 }, - { (-1155.0 - 255.0 * Q) / 1960.0, (-280.0 - 40.0 * Q) / 1960.0, ( 0.0 - 320.0 * Q) / 1960.0, ( 63.0 + 363.0 * Q) / 1960.0, (2352.0 + 392.0 * Q) / 1960.0 }, - { ( 330.0 + 105.0 * Q) / 180.0, ( 120.0 + 0.0 * Q) / 180.0, (-200.0 + 280.0 * Q) / 180.0, (126.0 - 189.0 * Q) / 180.0, (-686.0 - 126.0 * Q) / 180.0, (490.0 - 70.0 * Q) / 180.0 } - }; - - /** Propagation weights Butcher array. */ - private static final double[] STATIC_B = { - 1.0 / 20.0, 0, 16.0 / 45.0, 0, 49.0 / 180.0, 49.0 / 180.0, 1.0 / 20.0 - }; + private final T q; /** Simple constructor. * Build a fourth-order Luther integrator with the given step. @@ -88,7 +70,78 @@ public class LutherFieldIntegrator> * @param step integration step */ public LutherFieldIntegrator(final Field field, final T step) { - super(field, "Luther", STATIC_C, STATIC_A, STATIC_B, new LutherFieldStepInterpolator(), step); + super(field, "Luther", step); + q = getField().getOne().multiply(21).sqrt(); + } + + /** {@inheritDoc} */ + @Override + protected T[] getC() { + final T[] c = MathArrays.buildArray(getField(), 6); + c[0] = getField().getOne(); + c[1] = fraction(1, 2); + c[2] = fraction(2, 3); + c[3] = q.subtract(7).divide(-14); + c[4] = q.add(7).divide(14); + c[5] = getField().getOne(); + return c; + } + + /** {@inheritDoc} */ + @Override + protected T[][] getA() { + final T[][] a = MathArrays.buildArray(getField(), 6, -1); + for (int i = 0; i < a.length; ++i) { + a[i] = MathArrays.buildArray(getField(), i + 1); + } + a[0][0] = getField().getOne(); + a[1][0] = fraction(3, 8); + a[1][1] = fraction(1, 8); + a[2][0] = fraction(8, 27); + a[2][1] = fraction(2, 27); + a[2][2] = fraction(8, 27); + a[3][0] = q.multiply( 9).subtract( 21).divide( 392); + a[3][1] = q.multiply( 8).subtract( 56).divide( 392); + a[3][2] = q.multiply( 48).subtract(336).divide(-392); + a[3][3] = q.multiply( 3).subtract( 63).divide( 392); + a[4][0] = q.multiply(255).add(1155).divide(-1960); + a[4][1] = q.multiply( 40).add( 280).divide(-1960); + a[4][2] = q.multiply(20) .divide(-1960); + a[4][3] = q.multiply(363).add( 63).divide( 1960); + a[4][4] = q.multiply(392).add(2352).divide( 1960); + a[5][0] = q.multiply(105).add( 330).divide( 180); + a[5][1] = fraction(120, 180); + a[5][2] = q.multiply(280).add(-200).divide( 180); + a[5][3] = q.multiply(189).add(-126).divide(-180); + a[5][4] = q.multiply(126).add( 686).divide(-180); + a[5][5] = q.multiply( 70).add(-490).divide(-180); + return a; + } + + /** {@inheritDoc} */ + @Override + protected T[] getB() { + + final T[] b = MathArrays.buildArray(getField(), 7); + b[0] = fraction( 1, 20); + b[1] = getField().getZero(); + b[2] = fraction(16, 45); + b[3] = getField().getZero(); + b[4] = fraction(49, 180); + b[5] = b[4]; + b[6] = b[0]; + + return b; + + } + + /** {@inheritDoc} */ + @Override + protected LutherFieldStepInterpolator + createInterpolator(final AbstractFieldIntegrator rkIntegrator, final T[] y, + final T[][] yDotArray, final boolean forward, + final FieldEquationsMapper mapper) { + return new LutherFieldStepInterpolator(rkIntegrator, y, yDotArray, forward, mapper); } } diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/MidpointFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/MidpointFieldIntegrator.java index dd9f0bf57..f74fdbae3 100644 --- a/src/main/java/org/apache/commons/math3/ode/nonstiff/MidpointFieldIntegrator.java +++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/MidpointFieldIntegrator.java @@ -19,6 +19,9 @@ package org.apache.commons.math3.ode.nonstiff; import org.apache.commons.math3.Field; import org.apache.commons.math3.RealFieldElement; +import org.apache.commons.math3.ode.AbstractFieldIntegrator; +import org.apache.commons.math3.ode.FieldEquationsMapper; +import org.apache.commons.math3.util.MathArrays; /** * This class implements a second order Runge-Kutta integrator for @@ -46,28 +49,47 @@ import org.apache.commons.math3.RealFieldElement; public class MidpointFieldIntegrator> extends RungeKuttaFieldIntegrator { - /** Time steps Butcher array. */ - private static final double[] STATIC_C = { - 1.0 / 2.0 - }; - - /** Internal weights Butcher array. */ - private static final double[][] STATIC_A = { - { 1.0 / 2.0 } - }; - - /** Propagation weights Butcher array. */ - private static final double[] STATIC_B = { - 0.0, 1.0 - }; - /** Simple constructor. * Build a midpoint integrator with the given step. * @param field field to which the time and state vector elements belong * @param step integration step */ public MidpointFieldIntegrator(final Field field, final T step) { - super(field, "midpoint", STATIC_C, STATIC_A, STATIC_B, new MidpointFieldStepInterpolator(), step); + super(field, "midpoint", step); + } + + /** {@inheritDoc} */ + @Override + protected T[] getC() { + final T[] c = MathArrays.buildArray(getField(), 1); + c[0] = getField().getOne().multiply(0.5); + return c; + } + + /** {@inheritDoc} */ + @Override + protected T[][] getA() { + final T[][] a = MathArrays.buildArray(getField(), 1, 1); + a[0][0] = fraction(1, 2); + return a; + } + + /** {@inheritDoc} */ + @Override + protected T[] getB() { + final T[] b = MathArrays.buildArray(getField(), 2); + b[0] = getField().getZero(); + b[1] = getField().getOne(); + return b; + } + + /** {@inheritDoc} */ + @Override + protected MidpointFieldStepInterpolator + createInterpolator(final AbstractFieldIntegrator rkIntegrator, final T[] y, + final T[][] yDotArray, final boolean forward, + final FieldEquationsMapper mapper) { + return new MidpointFieldStepInterpolator(rkIntegrator, y, yDotArray, forward, mapper); } } diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesFieldIntegrator.java index 37f9f9532..6ba4b7257 100644 --- a/src/main/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesFieldIntegrator.java +++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesFieldIntegrator.java @@ -19,6 +19,9 @@ package org.apache.commons.math3.ode.nonstiff; import org.apache.commons.math3.Field; import org.apache.commons.math3.RealFieldElement; +import org.apache.commons.math3.ode.AbstractFieldIntegrator; +import org.apache.commons.math3.ode.FieldEquationsMapper; +import org.apache.commons.math3.util.MathArrays; /** * This class implements the 3/8 fourth order Runge-Kutta @@ -48,30 +51,59 @@ import org.apache.commons.math3.RealFieldElement; public class ThreeEighthesFieldIntegrator> extends RungeKuttaFieldIntegrator { - /** Time steps Butcher array. */ - private static final double[] STATIC_C = { - 1.0 / 3.0, 2.0 / 3.0, 1.0 - }; - - /** Internal weights Butcher array. */ - private static final double[][] STATIC_A = { - { 1.0 / 3.0 }, - { -1.0 / 3.0, 1.0 }, - { 1.0, -1.0, 1.0 } - }; - - /** Propagation weights Butcher array. */ - private static final double[] STATIC_B = { - 1.0 / 8.0, 3.0 / 8.0, 3.0 / 8.0, 1.0 / 8.0 - }; - /** Simple constructor. * Build a 3/8 integrator with the given step. * @param field field to which the time and state vector elements belong * @param step integration step */ public ThreeEighthesFieldIntegrator(final Field field, final T step) { - super(field, "3/8", STATIC_C, STATIC_A, STATIC_B, new ThreeEighthesFieldStepInterpolator(), step); + super(field, "3/8", step); + } + + /** {@inheritDoc} */ + @Override + protected T[] getC() { + final T[] c = MathArrays.buildArray(getField(), 3); + c[0] = fraction(1, 3); + c[1] = c[0].add(c[0]); + c[2] = getField().getOne(); + return c; + } + + /** {@inheritDoc} */ + @Override + protected T[][] getA() { + final T[][] a = MathArrays.buildArray(getField(), 3, -1); + for (int i = 0; i < a.length; ++i) { + a[i] = MathArrays.buildArray(getField(), i + 1); + } + a[0][0] = fraction(1, 3); + a[1][0] = a[0][0].negate(); + a[1][1] = getField().getOne(); + a[2][0] = getField().getOne(); + a[2][1] = getField().getOne().negate(); + a[2][2] = getField().getOne(); + return a; + } + + /** {@inheritDoc} */ + @Override + protected T[] getB() { + final T[] b = MathArrays.buildArray(getField(), 4); + b[0] = fraction(1, 8); + b[1] = fraction(3, 8); + b[2] = b[1]; + b[3] = b[0]; + return b; + } + + /** {@inheritDoc} */ + @Override + protected ThreeEighthesFieldStepInterpolator + createInterpolator(final AbstractFieldIntegrator rkIntegrator, final T[] y, + final T[][] yDotArray, final boolean forward, + final FieldEquationsMapper mapper) { + return new ThreeEighthesFieldStepInterpolator(rkIntegrator, y, yDotArray, forward, mapper); } }