Fixed wrong array dimensions in secondary equations handling.
JIRA: MATH-961 git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1463684 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2e7d1278b1
commit
5b5f84db29
|
@ -78,6 +78,9 @@ Users are encouraged to upgrade to this version as this release not
|
||||||
2. A few methods in the FastMath class are in fact slower that their
|
2. A few methods in the FastMath class are in fact slower that their
|
||||||
counterpart in either Math or StrictMath (cf. MATH-740 and MATH-901).
|
counterpart in either Math or StrictMath (cf. MATH-740 and MATH-901).
|
||||||
">
|
">
|
||||||
|
<action dev="luc" type="fix" issue="MATH-961" >
|
||||||
|
Fixed wrong array dimensions in secondary equations handling in some cases.
|
||||||
|
</action>
|
||||||
<action dev="luc" type="fix" issue="MATH-960" >
|
<action dev="luc" type="fix" issue="MATH-960" >
|
||||||
Fixed missing side effects of secondary equations on main state in
|
Fixed missing side effects of secondary equations on main state in
|
||||||
Ordinary Differential Equations integration.
|
Ordinary Differential Equations integration.
|
||||||
|
|
|
@ -206,6 +206,22 @@ public abstract class AbstractIntegrator implements FirstOrderIntegrator {
|
||||||
this.expandable = equations;
|
this.expandable = equations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the differential equations to integrate.
|
||||||
|
* @return differential equations to integrate
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
protected ExpandableStatefulODE getExpandable() {
|
||||||
|
return expandable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the evaluations counter.
|
||||||
|
* @return evaluations counter
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
protected Incrementor getEvaluationsCounter() {
|
||||||
|
return evaluations;
|
||||||
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public double integrate(final FirstOrderDifferentialEquations equations,
|
public double integrate(final FirstOrderDifferentialEquations equations,
|
||||||
final double t0, final double[] y0, final double t, final double[] y)
|
final double t0, final double[] y0, final double t, final double[] y)
|
||||||
|
@ -340,11 +356,19 @@ public abstract class AbstractIntegrator implements FirstOrderIntegrator {
|
||||||
|
|
||||||
// get state at event time
|
// get state at event time
|
||||||
interpolator.setInterpolatedTime(eventT);
|
interpolator.setInterpolatedTime(eventT);
|
||||||
final double[] eventY = interpolator.getInterpolatedState().clone();
|
final double[] eventYPrimary = interpolator.getInterpolatedState().clone();
|
||||||
|
final double[] eventYComplete = new double[y.length];
|
||||||
|
expandable.getPrimaryMapper().insertEquationData(interpolator.getInterpolatedState(),
|
||||||
|
eventYComplete);
|
||||||
|
int index = 0;
|
||||||
|
for (EquationsMapper secondary : expandable.getSecondaryMappers()) {
|
||||||
|
secondary.insertEquationData(interpolator.getInterpolatedSecondaryState(index++),
|
||||||
|
eventYComplete);
|
||||||
|
}
|
||||||
|
|
||||||
// advance all event states to current time
|
// advance all event states to current time
|
||||||
for (final EventState state : eventsStates) {
|
for (final EventState state : eventsStates) {
|
||||||
state.stepAccepted(eventT, eventY);
|
state.stepAccepted(eventT, eventYPrimary);
|
||||||
isLastStep = isLastStep || state.stop();
|
isLastStep = isLastStep || state.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,18 +379,19 @@ public abstract class AbstractIntegrator implements FirstOrderIntegrator {
|
||||||
|
|
||||||
if (isLastStep) {
|
if (isLastStep) {
|
||||||
// the event asked to stop integration
|
// the event asked to stop integration
|
||||||
System.arraycopy(eventY, 0, y, 0, y.length);
|
System.arraycopy(eventYComplete, 0, y, 0, y.length);
|
||||||
return eventT;
|
return eventT;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean needReset = false;
|
boolean needReset = false;
|
||||||
for (final EventState state : eventsStates) {
|
for (final EventState state : eventsStates) {
|
||||||
needReset = needReset || state.reset(eventT, eventY);
|
needReset = needReset || state.reset(eventT, eventYComplete);
|
||||||
}
|
}
|
||||||
if (needReset) {
|
if (needReset) {
|
||||||
// some event handler has triggered changes that
|
// some event handler has triggered changes that
|
||||||
// invalidate the derivatives, we need to recompute them
|
// invalidate the derivatives, we need to recompute them
|
||||||
System.arraycopy(eventY, 0, y, 0, y.length);
|
interpolator.setInterpolatedTime(eventT);
|
||||||
|
System.arraycopy(eventYComplete, 0, y, 0, y.length);
|
||||||
computeDerivatives(eventT, y, yDot);
|
computeDerivatives(eventT, y, yDot);
|
||||||
resetOccurred = true;
|
resetOccurred = true;
|
||||||
return eventT;
|
return eventT;
|
||||||
|
|
|
@ -333,11 +333,27 @@ public class ContinuousOutputModel
|
||||||
* Get the state vector of the interpolated point.
|
* Get the state vector of the interpolated point.
|
||||||
* @return state vector at time {@link #getInterpolatedTime}
|
* @return state vector at time {@link #getInterpolatedTime}
|
||||||
* @exception MaxCountExceededException if the number of functions evaluations is exceeded
|
* @exception MaxCountExceededException if the number of functions evaluations is exceeded
|
||||||
|
* @see #getInterpolatedSecondaryState(int)
|
||||||
*/
|
*/
|
||||||
public double[] getInterpolatedState() throws MaxCountExceededException {
|
public double[] getInterpolatedState() throws MaxCountExceededException {
|
||||||
return steps.get(index).getInterpolatedState();
|
return steps.get(index).getInterpolatedState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the interpolated secondary state corresponding to the secondary equations.
|
||||||
|
* @param secondaryStateIndex index of the secondary set, as returned by {@link
|
||||||
|
* org.apache.commons.math3.ode.ExpandableStatefulODE#addSecondaryEquations(
|
||||||
|
* org.apache.commons.math3.ode.SecondaryEquations)
|
||||||
|
* ExpandableStatefulODE.addSecondaryEquations(SecondaryEquations)}
|
||||||
|
* @return interpolated secondary state at the current interpolation date
|
||||||
|
* @see #getInterpolatedState()
|
||||||
|
* @since 3.2
|
||||||
|
* @exception MaxCountExceededException if the number of functions evaluations is exceeded
|
||||||
|
*/
|
||||||
|
public double[] getInterpolatedSecondaryState(final int secondaryStateIndex)
|
||||||
|
throws MaxCountExceededException {
|
||||||
|
return steps.get(index).getInterpolatedSecondaryState(secondaryStateIndex);
|
||||||
|
}
|
||||||
|
|
||||||
/** Compare a step interval and a double.
|
/** Compare a step interval and a double.
|
||||||
* @param time point to locate
|
* @param time point to locate
|
||||||
* @param interval step interval
|
* @param interval step interval
|
||||||
|
|
|
@ -228,10 +228,31 @@ public abstract class MultistepIntegrator extends AdaptiveStepsizeIntegrator {
|
||||||
|
|
||||||
// start integration, expecting a InitializationCompletedMarkerException
|
// start integration, expecting a InitializationCompletedMarkerException
|
||||||
try {
|
try {
|
||||||
starter.integrate(new CountingDifferentialEquations(y0.length),
|
|
||||||
t0, y0, t, new double[y0.length]);
|
if (starter instanceof AbstractIntegrator) {
|
||||||
|
((AbstractIntegrator) starter).integrate(getExpandable(), t);
|
||||||
|
} else {
|
||||||
|
starter.integrate(new FirstOrderDifferentialEquations() {
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public int getDimension() {
|
||||||
|
return getExpandable().getTotalDimension();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public void computeDerivatives(double t, double[] y, double[] yDot) {
|
||||||
|
getExpandable().computeDerivatives(t, y, yDot);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, t0, y0, t, new double[y0.length]);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (InitializationCompletedMarkerException icme) { // NOPMD
|
} catch (InitializationCompletedMarkerException icme) { // NOPMD
|
||||||
// this is the expected nominal interruption of the start integrator
|
// this is the expected nominal interruption of the start integrator
|
||||||
|
|
||||||
|
// count the evaluations used by the starter
|
||||||
|
getEvaluationsCounter().incrementCount(starter.getEvaluations());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the specific step handler
|
// remove the specific step handler
|
||||||
|
@ -353,20 +374,33 @@ public abstract class MultistepIntegrator extends AdaptiveStepsizeIntegrator {
|
||||||
// first step, we need to store also the beginning of the step
|
// first step, we need to store also the beginning of the step
|
||||||
interpolator.setInterpolatedTime(prev);
|
interpolator.setInterpolatedTime(prev);
|
||||||
t[0] = prev;
|
t[0] = prev;
|
||||||
System.arraycopy(interpolator.getInterpolatedState(), 0,
|
final ExpandableStatefulODE expandable = getExpandable();
|
||||||
y[0], 0, y[0].length);
|
final EquationsMapper primary = expandable.getPrimaryMapper();
|
||||||
System.arraycopy(interpolator.getInterpolatedDerivatives(), 0,
|
primary.insertEquationData(interpolator.getInterpolatedState(), y[count]);
|
||||||
yDot[0], 0, yDot[0].length);
|
primary.insertEquationData(interpolator.getInterpolatedDerivatives(), yDot[count]);
|
||||||
|
int index = 0;
|
||||||
|
for (final EquationsMapper secondary : expandable.getSecondaryMappers()) {
|
||||||
|
secondary.insertEquationData(interpolator.getInterpolatedSecondaryState(index), y[count]);
|
||||||
|
secondary.insertEquationData(interpolator.getInterpolatedSecondaryDerivatives(index), yDot[count]);
|
||||||
|
++index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the end of the step
|
// store the end of the step
|
||||||
++count;
|
++count;
|
||||||
interpolator.setInterpolatedTime(curr);
|
interpolator.setInterpolatedTime(curr);
|
||||||
t[count] = curr;
|
t[count] = curr;
|
||||||
System.arraycopy(interpolator.getInterpolatedState(), 0,
|
|
||||||
y[count], 0, y[count].length);
|
final ExpandableStatefulODE expandable = getExpandable();
|
||||||
System.arraycopy(interpolator.getInterpolatedDerivatives(), 0,
|
final EquationsMapper primary = expandable.getPrimaryMapper();
|
||||||
yDot[count], 0, yDot[count].length);
|
primary.insertEquationData(interpolator.getInterpolatedState(), y[count]);
|
||||||
|
primary.insertEquationData(interpolator.getInterpolatedDerivatives(), yDot[count]);
|
||||||
|
int index = 0;
|
||||||
|
for (final EquationsMapper secondary : expandable.getSecondaryMappers()) {
|
||||||
|
secondary.insertEquationData(interpolator.getInterpolatedSecondaryState(index), y[count]);
|
||||||
|
secondary.insertEquationData(interpolator.getInterpolatedSecondaryDerivatives(index), yDot[count]);
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
|
||||||
if (count == t.length - 1) {
|
if (count == t.length - 1) {
|
||||||
|
|
||||||
|
@ -411,30 +445,4 @@ public abstract class MultistepIntegrator extends AdaptiveStepsizeIntegrator {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Wrapper for differential equations, ensuring start evaluations are counted. */
|
|
||||||
private class CountingDifferentialEquations implements FirstOrderDifferentialEquations {
|
|
||||||
|
|
||||||
/** Dimension of the problem. */
|
|
||||||
private final int dimension;
|
|
||||||
|
|
||||||
/** Simple constructor.
|
|
||||||
* @param dimension dimension of the problem
|
|
||||||
*/
|
|
||||||
public CountingDifferentialEquations(final int dimension) {
|
|
||||||
this.dimension = dimension;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
|
||||||
public void computeDerivatives(double t, double[] y, double[] dot)
|
|
||||||
throws MaxCountExceededException, DimensionMismatchException {
|
|
||||||
MultistepIntegrator.this.computeDerivatives(t, y, dot);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
|
||||||
public int getDimension() {
|
|
||||||
return dimension;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.apache.commons.math3.exception.MaxCountExceededException;
|
||||||
import org.apache.commons.math3.exception.NoBracketingException;
|
import org.apache.commons.math3.exception.NoBracketingException;
|
||||||
import org.apache.commons.math3.exception.NumberIsTooSmallException;
|
import org.apache.commons.math3.exception.NumberIsTooSmallException;
|
||||||
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
|
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
|
||||||
|
import org.apache.commons.math3.ode.EquationsMapper;
|
||||||
import org.apache.commons.math3.ode.ExpandableStatefulODE;
|
import org.apache.commons.math3.ode.ExpandableStatefulODE;
|
||||||
import org.apache.commons.math3.ode.sampling.NordsieckStepInterpolator;
|
import org.apache.commons.math3.ode.sampling.NordsieckStepInterpolator;
|
||||||
import org.apache.commons.math3.util.FastMath;
|
import org.apache.commons.math3.util.FastMath;
|
||||||
|
@ -255,7 +256,14 @@ public class AdamsBashforthIntegrator extends AdamsIntegrator {
|
||||||
final double stepEnd = stepStart + stepSize;
|
final double stepEnd = stepStart + stepSize;
|
||||||
interpolator.shift();
|
interpolator.shift();
|
||||||
interpolator.setInterpolatedTime(stepEnd);
|
interpolator.setInterpolatedTime(stepEnd);
|
||||||
System.arraycopy(interpolator.getInterpolatedState(), 0, y, 0, y0.length);
|
final ExpandableStatefulODE expandable = getExpandable();
|
||||||
|
final EquationsMapper primary = expandable.getPrimaryMapper();
|
||||||
|
primary.insertEquationData(interpolator.getInterpolatedState(), y);
|
||||||
|
int index = 0;
|
||||||
|
for (final EquationsMapper secondary : expandable.getSecondaryMappers()) {
|
||||||
|
secondary.insertEquationData(interpolator.getInterpolatedSecondaryState(index), y);
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
|
||||||
// evaluate the derivative
|
// evaluate the derivative
|
||||||
computeDerivatives(stepEnd, y, yDot);
|
computeDerivatives(stepEnd, y, yDot);
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.commons.math3.exception.NoBracketingException;
|
||||||
import org.apache.commons.math3.exception.NumberIsTooSmallException;
|
import org.apache.commons.math3.exception.NumberIsTooSmallException;
|
||||||
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
|
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
|
||||||
import org.apache.commons.math3.linear.RealMatrixPreservingVisitor;
|
import org.apache.commons.math3.linear.RealMatrixPreservingVisitor;
|
||||||
|
import org.apache.commons.math3.ode.EquationsMapper;
|
||||||
import org.apache.commons.math3.ode.ExpandableStatefulODE;
|
import org.apache.commons.math3.ode.ExpandableStatefulODE;
|
||||||
import org.apache.commons.math3.ode.sampling.NordsieckStepInterpolator;
|
import org.apache.commons.math3.ode.sampling.NordsieckStepInterpolator;
|
||||||
import org.apache.commons.math3.util.FastMath;
|
import org.apache.commons.math3.util.FastMath;
|
||||||
|
@ -250,7 +251,14 @@ public class AdamsMoultonIntegrator extends AdamsIntegrator {
|
||||||
// predict a first estimate of the state at step end (P in the PECE sequence)
|
// predict a first estimate of the state at step end (P in the PECE sequence)
|
||||||
final double stepEnd = stepStart + stepSize;
|
final double stepEnd = stepStart + stepSize;
|
||||||
interpolator.setInterpolatedTime(stepEnd);
|
interpolator.setInterpolatedTime(stepEnd);
|
||||||
System.arraycopy(interpolator.getInterpolatedState(), 0, yTmp, 0, y0.length);
|
final ExpandableStatefulODE expandable = getExpandable();
|
||||||
|
final EquationsMapper primary = expandable.getPrimaryMapper();
|
||||||
|
primary.insertEquationData(interpolator.getInterpolatedState(), yTmp);
|
||||||
|
int index = 0;
|
||||||
|
for (final EquationsMapper secondary : expandable.getSecondaryMappers()) {
|
||||||
|
secondary.insertEquationData(interpolator.getInterpolatedSecondaryState(index), yTmp);
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
|
||||||
// evaluate a first estimate of the derivative (first E in the PECE sequence)
|
// evaluate a first estimate of the derivative (first E in the PECE sequence)
|
||||||
computeDerivatives(stepEnd, yTmp, yDot);
|
computeDerivatives(stepEnd, yTmp, yDot);
|
||||||
|
|
Loading…
Reference in New Issue