You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2009/07/05 16:06:00 UTC
svn commit: r791248 -
/commons/proper/math/trunk/src/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.java
Author: luc
Date: Sun Jul 5 14:06:00 2009
New Revision: 791248
URL: http://svn.apache.org/viewvc?rev=791248&view=rev
Log:
compute state variation avoiding cancellation in a critical subtraction to preserve accuracy
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.java
Modified: commons/proper/math/trunk/src/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.java?rev=791248&r1=791247&r2=791248&view=diff
==============================================================================
--- commons/proper/math/trunk/src/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.java (original)
+++ commons/proper/math/trunk/src/java/org/apache/commons/math/ode/sampling/NordsieckStepInterpolator.java Sun Jul 5 14:06:00 2009
@@ -23,6 +23,7 @@
import java.util.Arrays;
import org.apache.commons.math.linear.Array2DRowRealMatrix;
+import org.apache.commons.math.ode.DerivativeException;
/**
* This class implements an interpolator for integrators using Nordsieck representation.
@@ -58,6 +59,9 @@
/** Nordsieck vector. */
private Array2DRowRealMatrix nordsieck;
+ /** State variation. */
+ protected double[] stateVariation;
+
/** Simple constructor.
* This constructor builds an instance that is not usable yet, the
* {@link AbstractStepInterpolator#reinitialize} method should be called
@@ -83,6 +87,9 @@
if (interpolator.nordsieck != null) {
nordsieck = new Array2DRowRealMatrix(interpolator.nordsieck.getDataRef(), true);
}
+ if (interpolator.stateVariation != null) {
+ stateVariation = interpolator.stateVariation.clone();
+ }
}
/** {@inheritDoc} */
@@ -101,6 +108,7 @@
@Override
public void reinitialize(final double[] y, final boolean forward) {
super.reinitialize(y, forward);
+ stateVariation = new double[y.length];
}
/** Reinitialize the instance.
@@ -151,6 +159,27 @@
}
+ /**
+ * Get the state vector variation from current to interpolated state.
+ * <p>This method is aimed at computing y(t<sub>interpolation</sub>)
+ * -y(t<sub>current</sub>) accurately by avoiding the cancellation errors
+ * that would occur if the subtraction were performed explicitly.</p>
+ * <p>The returned vector is a reference to a reused array, so
+ * it should not be modified and it should be copied if it needs
+ * to be preserved across several calls.</p>
+ * @return state vector at time {@link #getInterpolatedTime}
+ * @see #getInterpolatedDerivatives()
+ * @throws DerivativeException if this call induces an automatic
+ * step finalization that throws one
+ */
+ public double[] getInterpolatedStateVariation()
+ throws DerivativeException {
+ // compute and ignore interpolated state
+ // to make sure state variation is computed as a side effect
+ getInterpolatedState();
+ return stateVariation;
+ }
+
/** {@inheritDoc} */
@Override
protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) {
@@ -158,7 +187,7 @@
final double x = interpolatedTime - referenceTime;
final double normalizedAbscissa = x / scalingH;
- Arrays.fill(interpolatedState, 0.0);
+ Arrays.fill(stateVariation, 0.0);
Arrays.fill(interpolatedDerivatives, 0.0);
// apply Taylor formula from high order to low order,
@@ -170,13 +199,14 @@
final double power = Math.pow(normalizedAbscissa, order);
for (int j = 0; j < nDataI.length; ++j) {
final double d = nDataI[j] * power;
- interpolatedState[j] += d;
+ stateVariation[j] += d;
interpolatedDerivatives[j] += order * d;
}
}
for (int j = 0; j < currentState.length; ++j) {
- interpolatedState[j] += currentState[j] + scaled[j] * normalizedAbscissa;
+ stateVariation[j] += scaled[j] * normalizedAbscissa;
+ interpolatedState[j] = currentState[j] + stateVariation[j];
interpolatedDerivatives[j] =
(interpolatedDerivatives[j] + scaled[j] * normalizedAbscissa) / x;
}
@@ -212,6 +242,8 @@
out.writeObject(nordsieck);
}
+ // we don't save state variation, it will be recomputed
+
}
/** {@inheritDoc} */
@@ -246,7 +278,10 @@
if (hasScaled && hasNordsieck) {
// we can now set the interpolated time and state
+ stateVariation = new double[n];
setInterpolatedTime(t);
+ } else {
+ stateVariation = null;
}
}