Set up a shared interface for Butcher arrays used by integrators.

This commit is contained in:
Luc Maisonobe 2016-01-06 12:41:27 +01:00
parent 87edfd2751
commit a2718fc3a9
14 changed files with 91 additions and 75 deletions

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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();
}

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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());
}