Set up a shared interface for Butcher arrays used by integrators.
This commit is contained in:
parent
87edfd2751
commit
a2718fc3a9
|
@ -62,7 +62,7 @@ public class ClassicalRungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getC() {
|
||||
public T[] getC() {
|
||||
final T[] c = MathArrays.buildArray(getField(), 3);
|
||||
c[0] = getField().getOne().multiply(0.5);
|
||||
c[1] = c[0];
|
||||
|
@ -72,7 +72,7 @@ public class ClassicalRungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[][] getA() {
|
||||
public 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);
|
||||
|
@ -88,7 +88,7 @@ public class ClassicalRungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getB() {
|
||||
public T[] getB() {
|
||||
final T[] b = MathArrays.buildArray(getField(), 4);
|
||||
b[0] = fraction(1, 6);
|
||||
b[1] = fraction(1, 3);
|
||||
|
|
|
@ -130,7 +130,7 @@ public class DormandPrince54FieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getC() {
|
||||
public T[] getC() {
|
||||
final T[] c = MathArrays.buildArray(getField(), 6);
|
||||
c[0] = fraction(1, 5);
|
||||
c[1] = fraction(3, 10);
|
||||
|
@ -143,7 +143,7 @@ public class DormandPrince54FieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[][] getA() {
|
||||
public 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);
|
||||
|
@ -174,7 +174,7 @@ public class DormandPrince54FieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getB() {
|
||||
public T[] getB() {
|
||||
final T[] b = MathArrays.buildArray(getField(), 7);
|
||||
b[0] = fraction( 35, 384);
|
||||
b[1] = getField().getZero();
|
||||
|
|
|
@ -191,7 +191,7 @@ public class DormandPrince853FieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getC() {
|
||||
public T[] getC() {
|
||||
|
||||
final T sqrt6 = getField().getOne().multiply(6).sqrt();
|
||||
|
||||
|
@ -218,7 +218,7 @@ public class DormandPrince853FieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[][] getA() {
|
||||
public T[][] getA() {
|
||||
|
||||
final T sqrt6 = getField().getOne().multiply(6).sqrt();
|
||||
|
||||
|
@ -371,7 +371,7 @@ public class DormandPrince853FieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getB() {
|
||||
public T[] getB() {
|
||||
final T[] b = MathArrays.buildArray(getField(), 16);
|
||||
b[ 0] = fraction(104257, 1929240);
|
||||
b[ 1] = getField().getZero();
|
||||
|
|
|
@ -52,7 +52,7 @@ class DormandPrince853FieldStepInterpolator<T extends RealFieldElement<T>>
|
|||
super(field, forward, mapper);
|
||||
|
||||
// interpolation weights
|
||||
d = MathArrays.buildArray(getField(), 4, 16);
|
||||
d = MathArrays.buildArray(getField(), 7, 16);
|
||||
|
||||
// this row is the same as the b array
|
||||
d[0][ 0] = fraction(104257, 1929240);
|
||||
|
|
|
@ -68,7 +68,8 @@ import org.apache.commons.math4.util.MathUtils;
|
|||
*/
|
||||
|
||||
public abstract class EmbeddedRungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
|
||||
extends AdaptiveStepsizeFieldIntegrator<T> {
|
||||
extends AdaptiveStepsizeFieldIntegrator<T>
|
||||
implements FieldButcherArrayProvider<T> {
|
||||
|
||||
/** Index of the pre-computed derivative for <i>fsal</i> methods. */
|
||||
private final int fsal;
|
||||
|
@ -180,21 +181,6 @@ public abstract class EmbeddedRungeKuttaFieldIntegrator<T extends RealFieldEleme
|
|||
return getField().getOne().multiply(p).divide(q);
|
||||
}
|
||||
|
||||
/** Get the time steps from Butcher array (without the first zero).
|
||||
* @return time steps from Butcher array (without the first zero
|
||||
*/
|
||||
protected abstract T[] getC();
|
||||
|
||||
/** Get the internal weights from Butcher array (without the first empty row).
|
||||
* @return internal weights from Butcher array (without the first empty row)
|
||||
*/
|
||||
protected abstract T[][] getA();
|
||||
|
||||
/** Get the external weights for the high order method from Butcher array.
|
||||
* @return external weights for the high order method from Butcher array
|
||||
*/
|
||||
protected abstract T[] getB();
|
||||
|
||||
/** Create an interpolator.
|
||||
* @param forward integration direction indicator
|
||||
* @param mapper equations mapper for the all equations
|
||||
|
|
|
@ -64,19 +64,19 @@ public class EulerFieldIntegrator<T extends RealFieldElement<T>> extends RungeKu
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getC() {
|
||||
public T[] getC() {
|
||||
return MathArrays.buildArray(getField(), 0);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[][] getA() {
|
||||
public T[][] getA() {
|
||||
return MathArrays.buildArray(getField(), 0, 0);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getB() {
|
||||
public T[] getB() {
|
||||
final T[] b = MathArrays.buildArray(getField(), 1);
|
||||
b[0] = getField().getOne();
|
||||
return b;
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math4.ode.nonstiff;
|
||||
|
||||
import org.apache.commons.math4.RealFieldElement;
|
||||
|
||||
/** This interface represents an integrator based on Butcher arrays.
|
||||
* @see RungeKuttaFieldIntegrator
|
||||
* @see EmbeddedRungeKuttaFieldIntegrator
|
||||
* @param <T> the type of the field elements
|
||||
* @since 3.6
|
||||
*/
|
||||
|
||||
public interface FieldButcherArrayProvider<T extends RealFieldElement<T>> {
|
||||
|
||||
/** Get the time steps from Butcher array (without the first zero).
|
||||
* @return time steps from Butcher array (without the first zero
|
||||
*/
|
||||
T[] getC();
|
||||
|
||||
/** Get the internal weights from Butcher array (without the first empty row).
|
||||
* @return internal weights from Butcher array (without the first empty row)
|
||||
*/
|
||||
T[][] getA();
|
||||
|
||||
/** Get the external weights for the high order method from Butcher array.
|
||||
* @return external weights for the high order method from Butcher array
|
||||
*/
|
||||
T[] getB();
|
||||
|
||||
}
|
|
@ -62,7 +62,7 @@ public class GillFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getC() {
|
||||
public T[] getC() {
|
||||
final T[] c = MathArrays.buildArray(getField(), 3);
|
||||
c[0] = fraction(1, 2);
|
||||
c[1] = c[0];
|
||||
|
@ -72,7 +72,7 @@ public class GillFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[][] getA() {
|
||||
public T[][] getA() {
|
||||
|
||||
final T two = getField().getZero().add(2);
|
||||
final T sqrtTwo = two.sqrt();
|
||||
|
@ -92,7 +92,7 @@ public class GillFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getB() {
|
||||
public T[] getB() {
|
||||
|
||||
final T two = getField().getZero().add(2);
|
||||
final T sqrtTwo = two.sqrt();
|
||||
|
|
|
@ -105,7 +105,7 @@ public class HighamHall54FieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getC() {
|
||||
public T[] getC() {
|
||||
final T[] c = MathArrays.buildArray(getField(), 6);
|
||||
c[0] = fraction(2, 9);
|
||||
c[1] = fraction(1, 3);
|
||||
|
@ -118,7 +118,7 @@ public class HighamHall54FieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[][] getA() {
|
||||
public 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);
|
||||
|
@ -149,7 +149,7 @@ public class HighamHall54FieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getB() {
|
||||
public T[] getB() {
|
||||
final T[] b = MathArrays.buildArray(getField(), 7);
|
||||
b[0] = fraction( 1, 12);
|
||||
b[1] = getField().getZero();
|
||||
|
|
|
@ -71,7 +71,7 @@ public class LutherFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getC() {
|
||||
public T[] getC() {
|
||||
final T q = getField().getZero().add(21).sqrt();
|
||||
final T[] c = MathArrays.buildArray(getField(), 6);
|
||||
c[0] = getField().getOne();
|
||||
|
@ -85,7 +85,7 @@ public class LutherFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[][] getA() {
|
||||
public T[][] getA() {
|
||||
final T q = getField().getZero().add(21).sqrt();
|
||||
final T[][] a = MathArrays.buildArray(getField(), 6, -1);
|
||||
for (int i = 0; i < a.length; ++i) {
|
||||
|
@ -117,7 +117,7 @@ public class LutherFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getB() {
|
||||
public T[] getB() {
|
||||
|
||||
final T[] b = MathArrays.buildArray(getField(), 7);
|
||||
b[0] = fraction( 1, 20);
|
||||
|
|
|
@ -59,7 +59,7 @@ public class MidpointFieldIntegrator<T extends RealFieldElement<T>> extends Rung
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getC() {
|
||||
public T[] getC() {
|
||||
final T[] c = MathArrays.buildArray(getField(), 1);
|
||||
c[0] = getField().getOne().multiply(0.5);
|
||||
return c;
|
||||
|
@ -67,7 +67,7 @@ public class MidpointFieldIntegrator<T extends RealFieldElement<T>> extends Rung
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[][] getA() {
|
||||
public T[][] getA() {
|
||||
final T[][] a = MathArrays.buildArray(getField(), 1, 1);
|
||||
a[0][0] = fraction(1, 2);
|
||||
return a;
|
||||
|
@ -75,7 +75,7 @@ public class MidpointFieldIntegrator<T extends RealFieldElement<T>> extends Rung
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getB() {
|
||||
public T[] getB() {
|
||||
final T[] b = MathArrays.buildArray(getField(), 2);
|
||||
b[0] = getField().getZero();
|
||||
b[1] = getField().getOne();
|
||||
|
|
|
@ -58,7 +58,8 @@ import org.apache.commons.math4.util.MathArrays;
|
|||
*/
|
||||
|
||||
public abstract class RungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
|
||||
extends AbstractFieldIntegrator<T> {
|
||||
extends AbstractFieldIntegrator<T>
|
||||
implements FieldButcherArrayProvider<T> {
|
||||
|
||||
/** Time steps from Butcher array (without the first zero). */
|
||||
private final T[] c;
|
||||
|
@ -96,21 +97,6 @@ public abstract class RungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
|
|||
return getField().getZero().add(p).divide(q);
|
||||
}
|
||||
|
||||
/** Get the time steps from Butcher array (without the first zero).
|
||||
* @return time steps from Butcher array (without the first zero
|
||||
*/
|
||||
protected abstract T[] getC();
|
||||
|
||||
/** Get the internal weights from Butcher array (without the first empty row).
|
||||
* @return internal weights from Butcher array (without the first empty row)
|
||||
*/
|
||||
protected abstract T[][] getA();
|
||||
|
||||
/** Get the external weights for the high order method from Butcher array.
|
||||
* @return external weights for the high order method from Butcher array
|
||||
*/
|
||||
protected abstract T[] getB();
|
||||
|
||||
/** Create an interpolator.
|
||||
* @param forward integration direction indicator
|
||||
* @param mapper equations mapper for the all equations
|
||||
|
|
|
@ -61,7 +61,7 @@ public class ThreeEighthesFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getC() {
|
||||
public T[] getC() {
|
||||
final T[] c = MathArrays.buildArray(getField(), 3);
|
||||
c[0] = fraction(1, 3);
|
||||
c[1] = c[0].add(c[0]);
|
||||
|
@ -71,7 +71,7 @@ public class ThreeEighthesFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[][] getA() {
|
||||
public 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);
|
||||
|
@ -87,7 +87,7 @@ public class ThreeEighthesFieldIntegrator<T extends RealFieldElement<T>>
|
|||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected T[] getB() {
|
||||
public T[] getB() {
|
||||
final T[] b = MathArrays.buildArray(getField(), 4);
|
||||
b[0] = fraction(1, 8);
|
||||
b[1] = fraction(3, 8);
|
||||
|
|
|
@ -140,10 +140,10 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest {
|
|||
RungeKuttaFieldStepInterpolator<T> interpolator = createInterpolator(field, t1 > t0,
|
||||
new FieldExpandableODE<T>(eqn).getMapper());
|
||||
// get the Butcher arrays from the field integrator
|
||||
RungeKuttaFieldIntegrator<T> fieldIntegrator = createFieldIntegrator(field, interpolator);
|
||||
T[][] a = fieldIntegrator.getA();
|
||||
T[] b = fieldIntegrator.getB();
|
||||
T[] c = fieldIntegrator.getC();
|
||||
FieldButcherArrayProvider<T> provider = createButcherArrayProvider(field, interpolator);
|
||||
T[][] a = provider.getA();
|
||||
T[] b = provider.getB();
|
||||
T[] c = provider.getC();
|
||||
|
||||
// store initial state
|
||||
T t = field.getZero().add(t0);
|
||||
|
@ -259,25 +259,23 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest {
|
|||
|
||||
}
|
||||
|
||||
private <T extends RealFieldElement<T>> RungeKuttaFieldIntegrator<T>
|
||||
createFieldIntegrator(final Field<T> field, final RungeKuttaFieldStepInterpolator<T> interpolator) {
|
||||
RungeKuttaFieldIntegrator<T> integrator = null;
|
||||
private <T extends RealFieldElement<T>> FieldButcherArrayProvider<T>
|
||||
createButcherArrayProvider(final Field<T> field, final RungeKuttaFieldStepInterpolator<T> provider) {
|
||||
FieldButcherArrayProvider<T> integrator = null;
|
||||
try {
|
||||
String interpolatorName = interpolator.getClass().getName();
|
||||
String interpolatorName = provider.getClass().getName();
|
||||
String integratorName = interpolatorName.replaceAll("StepInterpolator", "Integrator");
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<RungeKuttaFieldIntegrator<T>> clz = (Class<RungeKuttaFieldIntegrator<T>>) Class.forName(integratorName);
|
||||
Class<FieldButcherArrayProvider<T>> clz = (Class<FieldButcherArrayProvider<T>>) Class.forName(integratorName);
|
||||
try {
|
||||
integrator = clz.getConstructor(Field.class, RealFieldElement.class).
|
||||
newInstance(field, field.getOne());
|
||||
newInstance(field, field.getOne());
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
try {
|
||||
integrator = clz.getConstructor(Field.class,
|
||||
RealFieldElement.class,
|
||||
RealFieldElement.class,
|
||||
RealFieldElement.class).
|
||||
newInstance(field, field.getZero().add(0.001),
|
||||
field.getOne(), field.getOne(), field.getOne());
|
||||
Double.TYPE, Double.TYPE,
|
||||
Double.TYPE, Double.TYPE).
|
||||
newInstance(field, 0.001, 1.0, 1.0, 1.0);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Assert.fail(e.getLocalizedMessage());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue