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 2011/06/21 17:47:24 UTC
svn commit: r1138061 - in /commons/proper/math/trunk/src:
main/java/org/apache/commons/math/ode/sampling/ site/xdoc/
test/java/org/apache/commons/math/ode/sampling/
Author: luc
Date: Tue Jun 21 15:47:23 2011
New Revision: 1138061
URL: http://svn.apache.org/viewvc?rev=1138061&view=rev
Log:
Extended StepNormalizer with normalization mode and bounds settings.
JIRA: MATH-595
Added:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerBounds.java (with props)
commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerMode.java (with props)
commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputOverlapTest.java (with props)
commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTest.java (with props)
commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTestBase.java (with props)
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizer.java
commons/proper/math/trunk/src/site/xdoc/changes.xml
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizer.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizer.java?rev=1138061&r1=1138060&r2=1138061&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizer.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizer.java Tue Jun 21 15:47:23 2011
@@ -18,6 +18,9 @@
package org.apache.commons.math.ode.sampling;
import org.apache.commons.math.exception.MathUserException;
+import org.apache.commons.math.ode.sampling.FixedStepHandler;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
import org.apache.commons.math.util.FastMath;
/**
@@ -31,50 +34,140 @@ import org.apache.commons.math.util.Fast
*
* <p>The stepsize used is selected at construction time. The {@link
* FixedStepHandler#handleStep handleStep} method of the underlying
- * {@link FixedStepHandler} object is called at the beginning time of
- * the integration t0 and also at times t0+h, t0+2h, ... If the
- * integration range is an integer multiple of the stepsize, then the
- * last point handled will be the endpoint of the integration tend, if
- * not, the last point will belong to the interval [tend - h ;
- * tend].</p>
+ * {@link FixedStepHandler} object is called at normalized times. The
+ * normalized times can be influenced by the {@link StepNormalizerMode} and
+ * {@link StepNormalizerBounds}.</p>
*
- * <p>There is no constraint on the integrator, it can use any
- * timestep it needs (time steps longer or shorter than the fixed time
- * step and non-integer ratios are all allowed).</p>
+ * <p>There is no constraint on the integrator, it can use any time step
+ * it needs (time steps longer or shorter than the fixed time step and
+ * non-integer ratios are all allowed).</p>
+ *
+ * <p>
+ * <table border="1" align="center">
+ * <tr BGCOLOR="#CCCCFF"><td colspan=6><font size="+2">Examples (step size = 0.5)</font></td></tr>
+ * <tr BGCOLOR="#EEEEFF"><font size="+1"><td>Start time</td><td>End time</td>
+ * <td>Direction</td><td>{@link StepNormalizerMode Mode}</td>
+ * <td>{@link StepNormalizerBounds Bounds}</td><td>Output</td></font></tr>
+ * <tr><td>0.3</td><td>3.1</td><td>forward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#NEITHER NEITHER}</td><td>0.8, 1.3, 1.8, 2.3, 2.8</td></tr>
+ * <tr><td>0.3</td><td>3.1</td><td>forward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#FIRST FIRST}</td><td>0.3, 0.8, 1.3, 1.8, 2.3, 2.8</td></tr>
+ * <tr><td>0.3</td><td>3.1</td><td>forward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#LAST LAST}</td><td>0.8, 1.3, 1.8, 2.3, 2.8, 3.1</td></tr>
+ * <tr><td>0.3</td><td>3.1</td><td>forward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#BOTH BOTH}</td><td>0.3, 0.8, 1.3, 1.8, 2.3, 2.8, 3.1</td></tr>
+ * <tr><td>0.3</td><td>3.1</td><td>forward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#NEITHER NEITHER}</td><td>0.5, 1.0, 1.5, 2.0, 2.5, 3.0</td></tr>
+ * <tr><td>0.3</td><td>3.1</td><td>forward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#FIRST FIRST}</td><td>0.3, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0</td></tr>
+ * <tr><td>0.3</td><td>3.1</td><td>forward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#LAST LAST}</td><td>0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.1</td></tr>
+ * <tr><td>0.3</td><td>3.1</td><td>forward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#BOTH BOTH}</td><td>0.3, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.1</td></tr>
+ * <tr><td>0.0</td><td>3.0</td><td>forward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#NEITHER NEITHER}</td><td>0.5, 1.0, 1.5, 2.0, 2.5, 3.0</td></tr>
+ * <tr><td>0.0</td><td>3.0</td><td>forward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#FIRST FIRST}</td><td>0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0</td></tr>
+ * <tr><td>0.0</td><td>3.0</td><td>forward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#LAST LAST}</td><td>0.5, 1.0, 1.5, 2.0, 2.5, 3.0</td></tr>
+ * <tr><td>0.0</td><td>3.0</td><td>forward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#BOTH BOTH}</td><td>0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0</td></tr>
+ * <tr><td>0.0</td><td>3.0</td><td>forward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#NEITHER NEITHER}</td><td>0.5, 1.0, 1.5, 2.0, 2.5, 3.0</td></tr>
+ * <tr><td>0.0</td><td>3.0</td><td>forward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#FIRST FIRST}</td><td>0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0</td></tr>
+ * <tr><td>0.0</td><td>3.0</td><td>forward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#LAST LAST}</td><td>0.5, 1.0, 1.5, 2.0, 2.5, 3.0</td></tr>
+ * <tr><td>0.0</td><td>3.0</td><td>forward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#BOTH BOTH}</td><td>0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0</td></tr>
+ * <tr><td>3.1</td><td>0.3</td><td>backward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#NEITHER NEITHER}</td><td>2.6, 2.1, 1.6, 1.1, 0.6</td></tr>
+ * <tr><td>3.1</td><td>0.3</td><td>backward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#FIRST FIRST}</td><td>3.1, 2.6, 2.1, 1.6, 1.1, 0.6</td></tr>
+ * <tr><td>3.1</td><td>0.3</td><td>backward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#LAST LAST}</td><td>2.6, 2.1, 1.6, 1.1, 0.6, 0.3</td></tr>
+ * <tr><td>3.1</td><td>0.3</td><td>backward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#BOTH BOTH}</td><td>3.1, 2.6, 2.1, 1.6, 1.1, 0.6, 0.3</td></tr>
+ * <tr><td>3.1</td><td>0.3</td><td>backward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#NEITHER NEITHER}</td><td>3.0, 2.5, 2.0, 1.5, 1.0, 0.5</td></tr>
+ * <tr><td>3.1</td><td>0.3</td><td>backward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#FIRST FIRST}</td><td>3.1, 3.0, 2.5, 2.0, 1.5, 1.0, 0.5</td></tr>
+ * <tr><td>3.1</td><td>0.3</td><td>backward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#LAST LAST}</td><td>3.0, 2.5, 2.0, 1.5, 1.0, 0.5, 0.3</td></tr>
+ * <tr><td>3.1</td><td>0.3</td><td>backward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#BOTH BOTH}</td><td>3.1, 3.0, 2.5, 2.0, 1.5, 1.0, 0.5, 0.3</td></tr>
+ * <tr><td>3.0</td><td>0.0</td><td>backward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#NEITHER NEITHER}</td><td>2.5, 2.0, 1.5, 1.0, 0.5, 0.0</td></tr>
+ * <tr><td>3.0</td><td>0.0</td><td>backward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#FIRST FIRST}</td><td>3.0, 2.5, 2.0, 1.5, 1.0, 0.5, 0.0</td></tr>
+ * <tr><td>3.0</td><td>0.0</td><td>backward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#LAST LAST}</td><td>2.5, 2.0, 1.5, 1.0, 0.5, 0.0</td></tr>
+ * <tr><td>3.0</td><td>0.0</td><td>backward</td><td>{@link StepNormalizerMode#INCREMENT INCREMENT}</td><td>{@link StepNormalizerBounds#BOTH BOTH}</td><td>3.0, 2.5, 2.0, 1.5, 1.0, 0.5, 0.0</td></tr>
+ * <tr><td>3.0</td><td>0.0</td><td>backward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#NEITHER NEITHER}</td><td>2.5, 2.0, 1.5, 1.0, 0.5, 0.0</td></tr>
+ * <tr><td>3.0</td><td>0.0</td><td>backward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#FIRST FIRST}</td><td>3.0, 2.5, 2.0, 1.5, 1.0, 0.5, 0.0</td></tr>
+ * <tr><td>3.0</td><td>0.0</td><td>backward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#LAST LAST}</td><td>2.5, 2.0, 1.5, 1.0, 0.5, 0.0</td></tr>
+ * <tr><td>3.0</td><td>0.0</td><td>backward</td><td>{@link StepNormalizerMode#MULTIPLES MULTIPLES}</td><td>{@link StepNormalizerBounds#BOTH BOTH}</td><td>3.0, 2.5, 2.0, 1.5, 1.0, 0.5, 0.0</td></tr>
+ * </table>
+ * </p>
*
* @see StepHandler
* @see FixedStepHandler
+ * @see StepNormalizerMode
+ * @see StepNormalizerBounds
* @version $Id$
* @since 1.2
*/
public class StepNormalizer implements StepHandler {
-
/** Fixed time step. */
private double h;
/** Underlying step handler. */
private final FixedStepHandler handler;
+ /** First step time. */
+ private double firstTime;
+
/** Last step time. */
private double lastTime;
- /** Last State vector. */
+ /** Last state vector. */
private double[] lastState;
- /** Last Derivatives vector. */
+ /** Last derivatives vector. */
private double[] lastDerivatives;
/** Integration direction indicator. */
private boolean forward;
- /** Simple constructor.
+ /** The step normalizer bounds settings to use. */
+ private final StepNormalizerBounds bounds;
+
+ /** The step normalizer mode to use. */
+ private final StepNormalizerMode mode;
+
+ /** Simple constructor. Uses {@link StepNormalizerMode#INCREMENT INCREMENT}
+ * mode, and {@link StepNormalizerBounds#FIRST FIRST} bounds setting, for
+ * backwards compatibility.
* @param h fixed time step (sign is not used)
* @param handler fixed time step handler to wrap
*/
public StepNormalizer(final double h, final FixedStepHandler handler) {
+ this(h, handler, StepNormalizerMode.INCREMENT,
+ StepNormalizerBounds.FIRST);
+ }
+
+ /** Simple constructor. Uses {@link StepNormalizerBounds#FIRST FIRST}
+ * bounds setting.
+ * @param h fixed time step (sign is not used)
+ * @param handler fixed time step handler to wrap
+ * @param mode step normalizer mode to use
+ * @since 3.0
+ */
+ public StepNormalizer(final double h, final FixedStepHandler handler,
+ final StepNormalizerMode mode) {
+ this(h, handler, mode, StepNormalizerBounds.FIRST);
+ }
+
+ /** Simple constructor. Uses {@link StepNormalizerMode#INCREMENT INCREMENT}
+ * mode.
+ * @param h fixed time step (sign is not used)
+ * @param handler fixed time step handler to wrap
+ * @param bounds step normalizer bounds setting to use
+ * @since 3.0
+ */
+ public StepNormalizer(final double h, final FixedStepHandler handler,
+ final StepNormalizerBounds bounds) {
+ this(h, handler, StepNormalizerMode.INCREMENT, bounds);
+ }
+
+ /** Simple constructor.
+ * @param h fixed time step (sign is not used)
+ * @param handler fixed time step handler to wrap
+ * @param mode step normalizer mode to use
+ * @param bounds step normalizer bounds setting to use
+ * @since 3.0
+ */
+ public StepNormalizer(final double h, final FixedStepHandler handler,
+ final StepNormalizerMode mode,
+ final StepNormalizerBounds bounds) {
this.h = FastMath.abs(h);
this.handler = handler;
+ this.mode = mode;
+ this.bounds = bounds;
reset();
}
@@ -93,6 +186,7 @@ public class StepNormalizer implements S
* handled.
*/
public void reset() {
+ firstTime = Double.NaN;
lastTime = Double.NaN;
lastState = null;
lastDerivatives = null;
@@ -112,50 +206,89 @@ public class StepNormalizer implements S
* @throws MathUserException this exception is propagated to the
* caller if the underlying user function triggers one
*/
- public void handleStep(final StepInterpolator interpolator, final boolean isLast)
- throws MathUserException {
-
+ public void handleStep(final StepInterpolator interpolator,
+ final boolean isLast) throws MathUserException {
+ // The first time, update the last state with the start information.
if (lastState == null) {
-
+ firstTime = interpolator.getPreviousTime();
lastTime = interpolator.getPreviousTime();
interpolator.setInterpolatedTime(lastTime);
lastState = interpolator.getInterpolatedState().clone();
lastDerivatives = interpolator.getInterpolatedDerivatives().clone();
- // take the integration direction into account
+ // Take the integration direction into account.
forward = interpolator.getCurrentTime() >= lastTime;
- if (! forward) {
- h = -h;
- }
-
+ if (!forward) h = -h;
}
- double nextTime = lastTime + h;
- boolean nextInStep = forward ^ (nextTime > interpolator.getCurrentTime());
+ double nextTime = (mode == StepNormalizerMode.INCREMENT) ?
+ lastTime + h :
+ (FastMath.floor(lastTime / h) + 1) * h;
+ boolean nextInStep = isNextInStep(nextTime, interpolator);
while (nextInStep) {
+ // Output the stored previous step.
+ doNormalizedStep(false);
- // output the stored previous step
- handler.handleStep(lastTime, lastState, lastDerivatives, false);
-
- // store the next step
- lastTime = nextTime;
- interpolator.setInterpolatedTime(lastTime);
- System.arraycopy(interpolator.getInterpolatedState(), 0,
- lastState, 0, lastState.length);
- System.arraycopy(interpolator.getInterpolatedDerivatives(), 0,
- lastDerivatives, 0, lastDerivatives.length);
-
- nextTime += h;
- nextInStep = forward ^ (nextTime > interpolator.getCurrentTime());
+ // Store the next step as last step.
+ storeStep(interpolator, nextTime);
+ // Move on to the next step.
+ nextTime += h;
+ nextInStep = isNextInStep(nextTime, interpolator);
}
if (isLast) {
- // there will be no more steps,
- // the stored one should be flagged as being the last
- handler.handleStep(lastTime, lastState, lastDerivatives, true);
+ // There will be no more steps. The stored one should be given to
+ // the handler. We may have to output one more step. Only the last
+ // one of those should be flagged as being the last.
+ boolean addLast = bounds.lastIncluded() &&
+ lastTime != interpolator.getCurrentTime();
+ doNormalizedStep(!addLast);
+ if (addLast) {
+ storeStep(interpolator, interpolator.getCurrentTime());
+ doNormalizedStep(true);
+ }
}
+ }
+ /**
+ * Returns a value indicating whether the next normalized time is in the
+ * current step.
+ * @param nextTime the next normalized time
+ * @param interpolator interpolator for the last accepted step, to use to
+ * get the end time of the current step
+ * @return value indicating whether the next normalized time is in the
+ * current step
+ */
+ private boolean isNextInStep(double nextTime,
+ StepInterpolator interpolator) {
+ return forward ? nextTime <= interpolator.getCurrentTime()
+ : nextTime >= interpolator.getCurrentTime();
+ }
+
+ /**
+ * Invokes the underlying step handler for the current normalized step.
+ * @param isLast true if the step is the last one
+ * @throws MathUserException this exception is propagated to the
+ * caller if the underlying user function triggers one
+ */
+ private void doNormalizedStep(boolean isLast) throws MathUserException {
+ if (!bounds.firstIncluded() && firstTime == lastTime) return;
+ handler.handleStep(lastTime, lastState, lastDerivatives, isLast);
}
+ /** Stores the interpolated information for the given time in the current
+ * state.
+ * @param interpolator interpolator for the last accepted step, to use to
+ * get the interpolated information
+ * @param t the time for which to store the interpolated information
+ */
+ private void storeStep(StepInterpolator interpolator, double t) {
+ lastTime = t;
+ interpolator.setInterpolatedTime(lastTime);
+ System.arraycopy(interpolator.getInterpolatedState(), 0,
+ lastState, 0, lastState.length);
+ System.arraycopy(interpolator.getInterpolatedDerivatives(), 0,
+ lastDerivatives, 0, lastDerivatives.length);
+ }
}
Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerBounds.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerBounds.java?rev=1138061&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerBounds.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerBounds.java Tue Jun 21 15:47:23 2011
@@ -0,0 +1,84 @@
+/*
+ * 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.math.ode.sampling;
+
+/** {@link StepNormalizer Step normalizer} bounds settings. They influence
+ * whether the underlying fixed step size step handler is called for the first
+ * and last points. Note that if the last point coincides with a normalized
+ * point, then the underlying fixed step size step handler is always called,
+ * regardless of these settings.
+ * @see StepNormalizer
+ * @see StepNormalizerMode
+ * @version $Id$
+ * @since 3.0
+ */
+public enum StepNormalizerBounds {
+ /** Do not include the first and last points. */
+ NEITHER(false, false),
+
+ /** Include the first point, but not the last point. */
+ FIRST(true, false),
+
+ /** Include the last point, but not the first point. */
+ LAST(false, true),
+
+ /** Include both the first and last points. */
+ BOTH(true, true);
+
+ /** Whether the first point should be passed to the underlying fixed
+ * step size step handler.
+ */
+ private final boolean first;
+
+ /** Whether the last point should be passed to the underlying fixed
+ * step size step handler.
+ */
+ private final boolean last;
+
+ /**
+ * Simple constructor.
+ * @param first Whether the first point should be passed to the
+ * underlying fixed step size step handler.
+ * @param last Whether the last point should be passed to the
+ * underlying fixed step size step handler.
+ */
+ private StepNormalizerBounds(final boolean first, final boolean last) {
+ this.first = first;
+ this.last = last;
+ }
+
+ /**
+ * Returns a value indicating whether the first point should be passed
+ * to the underlying fixed step size step handler.
+ * @return value indicating whether the first point should be passed
+ * to the underlying fixed step size step handler.
+ */
+ public boolean firstIncluded() {
+ return first;
+ }
+
+ /**
+ * Returns a value indicating whether the last point should be passed
+ * to the underlying fixed step size step handler.
+ * @return value indicating whether the last point should be passed
+ * to the underlying fixed step size step handler.
+ */
+ public boolean lastIncluded() {
+ return last;
+ }
+}
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerBounds.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerBounds.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerMode.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerMode.java?rev=1138061&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerMode.java (added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerMode.java Tue Jun 21 15:47:23 2011
@@ -0,0 +1,70 @@
+/*
+ * 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.math.ode.sampling;
+
+
+/** {@link StepNormalizer Step normalizer} modes. Determines how the step size
+ * is interpreted.
+ * @see StepNormalizer
+ * @see StepNormalizerBounds
+ * @version $Id$
+ * @since 3.0
+ */
+public enum StepNormalizerMode {
+ /**
+ * Steps are fixed increments of the start value. In other words, they
+ * are relative to the start value.
+ *
+ * <p>If the integration start time is t0, then the points handled by
+ * the underlying fixed step size step handler are t0 (depending on
+ * the {@link StepNormalizerBounds bounds settings}), t0+h, t0+2h, ...</p>
+ *
+ * <p>If the integration range is an integer multiple of the step size
+ * (h), then the last point handled will be the end point of the
+ * integration (tend). If not, the last point may be the end point
+ * tend, or it may be a point belonging to the interval [tend - h ;
+ * tend], depending on the {@link StepNormalizerBounds bounds settings}.
+ * </p>
+ *
+ * @see StepNormalizer
+ * @see StepNormalizerBounds
+ */
+ INCREMENT,
+
+ /** Steps are multiples of a fixed value. In other words, they are
+ * relative to the first multiple of the step size that is encountered
+ * after the start value.
+ *
+ * <p>If the integration start time is t0, and the first multiple of
+ * the fixed step size that is encountered is t1, then the points
+ * handled by the underlying fixed step size step handler are t0
+ * (depending on the {@link StepNormalizerBounds bounds settings}), t1,
+ * t1+h, t1+2h, ...</p>
+ *
+ * <p>If the end point of the integration range (tend) is an integer
+ * multiple of the step size (h) added to t1, then the last point
+ * handled will be the end point of the integration (tend). If not,
+ * the last point may be the end point tend, or it may be a point
+ * belonging to the interval [tend - h ; tend], depending on the
+ * {@link StepNormalizerBounds bounds settings}.</p>
+ *
+ * @see StepNormalizer
+ * @see StepNormalizerBounds
+ */
+ MULTIPLES;
+}
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerMode.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/main/java/org/apache/commons/math/ode/sampling/StepNormalizerMode.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=1138061&r1=1138060&r2=1138061&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Tue Jun 21 15:47:23 2011
@@ -52,6 +52,9 @@ The <action> type attribute can be add,u
If the output is not quite correct, check for invisible trailing spaces!
-->
<release version="3.0" date="TBD" description="TBD">
+ <action dev="luc" type="fix" issue="MATH-595" due-to="Dennis Hendriks" >
+ Extended StepNormalizer with normalization mode and bounds settings.
+ </action>
<action dev="mikl" type="fix" issue="MATH-597">
Implemented faster generation of random exponential distributed values with
algorithm from Ahrens and Dieter (1972): Computer methods for sampling
Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputOverlapTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputOverlapTest.java?rev=1138061&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputOverlapTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputOverlapTest.java Tue Jun 21 15:47:23 2011
@@ -0,0 +1,52 @@
+package org.apache.commons.math.ode.sampling;
+
+/** Step normalizer output tests, for problems where the first and last points
+ * are overlap fixed points.
+ */
+public class StepNormalizerOutputOverlapTest extends StepNormalizerOutputTestBase {
+ @Override
+ protected double getStart() {
+ return 0.0;
+ }
+
+ @Override
+ protected double getEnd() {
+ return 10.0;
+ }
+
+ @Override
+ protected double[] getExpInc() {
+ return new double[] { 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0,
+ 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5,
+ 9.0, 9.5, 10.0 };
+ }
+
+ @Override
+ protected double[] getExpIncRev() {
+ return new double[] { 10.0, 9.5, 9.0, 8.5, 8.0, 7.5, 7.0, 6.5,
+ 6.0, 5.5, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5,
+ 2.0, 1.5, 1.0, 0.5, 0.0 };
+ }
+
+ @Override
+ protected double[] getExpMul() {
+ return new double[] { 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0,
+ 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5,
+ 9.0, 9.5, 10.0 };
+ }
+
+ @Override
+ protected double[] getExpMulRev() {
+ return new double[] { 10.0, 9.5, 9.0, 8.5, 8.0, 7.5, 7.0, 6.5,
+ 6.0, 5.5, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5,
+ 2.0, 1.5, 1.0, 0.5, 0.0 };
+ }
+
+ @Override
+ protected int[][] getO() {
+ return new int[][] {{1, 0}, {1, 0}, {0, 0}, {0, 0},
+ {1, 0}, {1, 0}, {0, 0}, {0, 0},
+ {1, 0}, {1, 0}, {0, 0}, {0, 0},
+ {1, 0}, {1, 0}, {0, 0}, {0, 0}};
+ }
+}
Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputOverlapTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputOverlapTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTest.java?rev=1138061&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTest.java Tue Jun 21 15:47:23 2011
@@ -0,0 +1,52 @@
+package org.apache.commons.math.ode.sampling;
+
+/** Step normalizer output tests, for problems where the first and last points
+ * are not fixed points.
+ */
+public class StepNormalizerOutputTest extends StepNormalizerOutputTestBase {
+ @Override
+ protected double getStart() {
+ return 0.3;
+ }
+
+ @Override
+ protected double getEnd() {
+ return 10.1;
+ }
+
+ @Override
+ protected double[] getExpInc() {
+ return new double[] { 0.3, 0.8, 1.3, 1.8, 2.3, 2.8, 3.3, 3.8, 4.3,
+ 4.8, 5.3, 5.8, 6.3, 6.8, 7.3, 7.8, 8.3, 8.8,
+ 9.3, 9.8, 10.1 };
+ }
+
+ @Override
+ protected double[] getExpIncRev() {
+ return new double[] { 10.1, 9.6, 9.1, 8.6, 8.1, 7.6, 7.1, 6.6,
+ 6.1, 5.6, 5.1, 4.6, 4.1, 3.6, 3.1, 2.6,
+ 2.1, 1.6, 1.1, 0.6, 0.3 };
+ }
+
+ @Override
+ protected double[] getExpMul() {
+ return new double[] { 0.3, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0,
+ 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5,
+ 9.0, 9.5, 10.0, 10.1 };
+ }
+
+ @Override
+ protected double[] getExpMulRev() {
+ return new double[] { 10.1, 10.0, 9.5, 9.0, 8.5, 8.0, 7.5, 7.0,
+ 6.5, 6.0, 5.5, 5.0, 4.5, 4.0, 3.5, 3.0, 2.5,
+ 2.0, 1.5, 1.0, 0.5, 0.3 };
+ }
+
+ @Override
+ protected int[][] getO() {
+ return new int[][] {{1, 1}, {1, 1}, {0, 1}, {0, 1},
+ {1, 0}, {1, 0}, {0, 0}, {0, 0},
+ {1, 1}, {1, 1}, {0, 1}, {0, 1},
+ {1, 0}, {1, 0}, {0, 0}, {0, 0}};
+ }
+}
Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTestBase.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTestBase.java?rev=1138061&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTestBase.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTestBase.java Tue Jun 21 15:47:23 2011
@@ -0,0 +1,224 @@
+package org.apache.commons.math.ode.sampling;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.math.exception.MathUserException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
+import org.apache.commons.math.ode.FirstOrderIntegrator;
+import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.ode.nonstiff.GraggBulirschStoerIntegrator;
+import org.junit.Test;
+
+/** Base class for step normalizer output tests. */
+public abstract class StepNormalizerOutputTestBase
+ implements FirstOrderDifferentialEquations, FixedStepHandler
+{
+ /** The normalized output time values. */
+ private List<Double> output;
+
+ /**
+ * Returns the start time.
+ * @return the start time
+ */
+ protected abstract double getStart();
+
+ /**
+ * Returns the end time.
+ * @return the end time
+ */
+ protected abstract double getEnd();
+
+ /**
+ * Returns the expected normalized output time values for increment mode.
+ * @return the expected normalized output time values for increment mode
+ */
+ protected abstract double[] getExpInc();
+
+ /**
+ * Returns the expected reversed normalized output time values for
+ * increment mode.
+ * @return the expected reversed normalized output time values for
+ * increment mode
+ */
+ protected abstract double[] getExpIncRev();
+
+ /**
+ * Returns the expected normalized output time values for multiples mode.
+ * @return the expected normalized output time values for multiples mode
+ */
+ protected abstract double[] getExpMul();
+
+ /**
+ * Returns the expected reversed normalized output time values for
+ * multiples mode.
+ * @return the expected reversed normalized output time values for
+ * multiples mode
+ */
+ protected abstract double[] getExpMulRev();
+
+ /**
+ * Returns the offsets for the unit tests below, in the order they are
+ * given below. For each test, the left and right offsets are returned.
+ * @return the offsets for the unit tests below, in the order they are
+ * given below
+ */
+ protected abstract int[][] getO();
+
+ /**
+ * Get the array, given left and right offsets.
+ * @param a the input array
+ * @param offsetL the left side offset
+ * @param offsetR the right side offset
+ * @return the modified array
+ */
+ private double[] getArray(double[] a, int offsetL, int offsetR) {
+ double[] copy = new double[a.length - offsetR - offsetL];
+ System.arraycopy(a, offsetL, copy, 0, copy.length);
+ return copy;
+ }
+
+ @Test
+ public void testIncNeither() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpInc(), getO()[0][0], getO()[0][1]);
+ doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.NEITHER, exp, false);
+ }
+
+ @Test
+ public void testIncNeitherRev() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpIncRev(), getO()[1][0], getO()[1][1]);
+ doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.NEITHER, exp, true);
+ }
+
+ @Test
+ public void testIncFirst() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpInc(), getO()[2][0], getO()[2][1]);
+ doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.FIRST, exp, false);
+ }
+
+ @Test
+ public void testIncFirstRev() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpIncRev(), getO()[3][0], getO()[3][1]);
+ doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.FIRST, exp, true);
+ }
+
+ @Test
+ public void testIncLast() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpInc(), getO()[4][0], getO()[4][1]);
+ doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.LAST, exp, false);
+ }
+
+ @Test
+ public void testIncLastRev() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpIncRev(), getO()[5][0], getO()[5][1]);
+ doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.LAST, exp, true);
+ }
+
+ @Test
+ public void testIncBoth() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpInc(), getO()[6][0], getO()[6][1]);
+ doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.BOTH, exp, false);
+ }
+
+ @Test
+ public void testIncBothRev() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpIncRev(), getO()[7][0], getO()[7][1]);
+ doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.BOTH, exp, true);
+ }
+
+ @Test
+ public void testMulNeither() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpMul(), getO()[8][0], getO()[8][1]);
+ doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.NEITHER, exp, false);
+ }
+
+ @Test
+ public void testMulNeitherRev() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpMulRev(), getO()[9][0], getO()[9][1]);
+ doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.NEITHER, exp, true);
+ }
+
+ @Test
+ public void testMulFirst() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpMul(), getO()[10][0], getO()[10][1]);
+ doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.FIRST, exp, false);
+ }
+
+ @Test
+ public void testMulFirstRev() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpMulRev(), getO()[11][0], getO()[11][1]);
+ doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.FIRST, exp, true);
+ }
+
+ @Test
+ public void testMulLast() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpMul(), getO()[12][0], getO()[12][1]);
+ doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.LAST, exp, false);
+ }
+
+ @Test
+ public void testMulLastRev() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpMulRev(), getO()[13][0], getO()[13][1]);
+ doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.LAST, exp, true);
+ }
+
+ @Test
+ public void testMulBoth() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpMul(), getO()[14][0], getO()[14][1]);
+ doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.BOTH, exp, false);
+ }
+
+ @Test
+ public void testMulBothRev() throws MathUserException, IntegratorException {
+ double[] exp = getArray(getExpMulRev(), getO()[15][0], getO()[15][1]);
+ doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.BOTH, exp, true);
+ }
+
+ /**
+ * The actual step normalizer output test code, shared by all the unit
+ * tests.
+ *
+ * @param mode the step normalizer mode to use
+ * @param bounds the step normalizer bounds setting to use
+ * @param expected the expected output (normalized time points)
+ * @param reverse whether to reverse the integration direction
+ */
+ private void doTest(StepNormalizerMode mode, StepNormalizerBounds bounds,
+ double[] expected, boolean reverse)
+ throws MathUserException, IntegratorException
+ {
+ // Forward test.
+ FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(
+ 1e-8, 1.0, 1e-5, 1e-5);
+ integ.addStepHandler(new StepNormalizer(0.5, this, mode, bounds));
+ double[] y = {0.0};
+ double start = reverse ? getEnd() : getStart();
+ double end = reverse ? getStart() : getEnd();
+ output = new ArrayList<Double>();
+ integ.integrate(this, start, y, end, y);
+ double[] actual = new double[output.size()];
+ for(int i = 0; i < actual.length; i++) {
+ actual[i] = output.get(i);
+ }
+ assertArrayEquals(expected, actual, 1e-5);
+ }
+
+ /** {@inheritDoc} */
+ public int getDimension() {
+ return 1;
+ }
+
+ /** {@inheritDoc} */
+ public void computeDerivatives(double t, double[] y, double[] yDot)
+ throws MathUserException {
+ yDot[0] = y[0];
+ }
+
+ /** {@inheritDoc} */
+ public void handleStep(double t, double[] y, double[] yDot, boolean isLast)
+ throws MathUserException {
+ output.add(t);
+ }
+}
Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTestBase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math/ode/sampling/StepNormalizerOutputTestBase.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision