added a way to handle errors in user-defined switching functions
previously, only the function evaluation could trigger errors, not the other functions of the interface git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/branches/MATH_2_0@651514 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
de621a4151
commit
03b9e6771e
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import org.apache.commons.math.MathException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exception is made available to users to report
|
||||||
|
* the error conditions that are triggered by {@link SwitchingFunction}
|
||||||
|
* @version $Revision: 620312 $ $Date: 2008-02-10 20:28:59 +0100 (dim., 10 févr. 2008) $
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public class SwitchException extends MathException {
|
||||||
|
|
||||||
|
/** Serialization UID. */
|
||||||
|
private static final long serialVersionUID = -3662133702316614545L;
|
||||||
|
|
||||||
|
/** Simple constructor.
|
||||||
|
* Build an exception by translating and formating a message
|
||||||
|
* @param specifier format specifier (to be translated)
|
||||||
|
* @param parts to insert in the format (no translation)
|
||||||
|
*/
|
||||||
|
public SwitchException(String specifier, Object[] parts) {
|
||||||
|
super(specifier, parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an exception with a given root cause.
|
||||||
|
* @param cause the exception or error that caused this exception to be thrown
|
||||||
|
*/
|
||||||
|
public SwitchException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -42,7 +42,7 @@ import org.apache.commons.math.analysis.UnivariateRealSolver;
|
||||||
class SwitchState implements Serializable {
|
class SwitchState implements Serializable {
|
||||||
|
|
||||||
/** Serializable version identifier. */
|
/** Serializable version identifier. */
|
||||||
private static final long serialVersionUID = -7307007422156119622L;
|
private static final long serialVersionUID = -7307007422156119622L;
|
||||||
|
|
||||||
/** Switching function. */
|
/** Switching function. */
|
||||||
private SwitchingFunction function;
|
private SwitchingFunction function;
|
||||||
|
@ -50,10 +50,10 @@ class SwitchState implements Serializable {
|
||||||
/** Maximal time interval between switching function checks. */
|
/** Maximal time interval between switching function checks. */
|
||||||
private double maxCheckInterval;
|
private double maxCheckInterval;
|
||||||
|
|
||||||
/** Convergence threshold for event localisation. */
|
/** Convergence threshold for event localization. */
|
||||||
private double convergence;
|
private double convergence;
|
||||||
|
|
||||||
/** Upper limit in the iteration count for event localisation. */
|
/** Upper limit in the iteration count for event localization. */
|
||||||
private int maxIterationCount;
|
private int maxIterationCount;
|
||||||
|
|
||||||
/** Time at the beginning of the step. */
|
/** Time at the beginning of the step. */
|
||||||
|
@ -115,11 +115,11 @@ class SwitchState implements Serializable {
|
||||||
* beginning of the step
|
* beginning of the step
|
||||||
* @param y0 array containing the current value of the state vector
|
* @param y0 array containing the current value of the state vector
|
||||||
* at the beginning of the step
|
* at the beginning of the step
|
||||||
* @exception FunctionEvaluationException if the switching function
|
* @exception SwitchException if the switching function
|
||||||
* value cannot be evaluated at the beginning of the step
|
* value cannot be evaluated at the beginning of the step
|
||||||
*/
|
*/
|
||||||
public void reinitializeBegin(double t0, double[] y0)
|
public void reinitializeBegin(double t0, double[] y0)
|
||||||
throws FunctionEvaluationException {
|
throws SwitchException {
|
||||||
this.t0 = t0;
|
this.t0 = t0;
|
||||||
g0 = function.g(t0, y0);
|
g0 = function.g(t0, y0);
|
||||||
g0Positive = (g0 >= 0);
|
g0Positive = (g0 >= 0);
|
||||||
|
@ -132,12 +132,12 @@ class SwitchState implements Serializable {
|
||||||
* rejected)
|
* rejected)
|
||||||
* @exception DerivativeException if the interpolator fails to
|
* @exception DerivativeException if the interpolator fails to
|
||||||
* compute the function somewhere within the step
|
* compute the function somewhere within the step
|
||||||
* @exception FunctionEvaluationException if the switching function
|
* @exception SwitchException if the switching function
|
||||||
* cannot be evaluated
|
* cannot be evaluated
|
||||||
* @exception ConvergenceException if an event cannot be located
|
* @exception ConvergenceException if an event cannot be located
|
||||||
*/
|
*/
|
||||||
public boolean evaluateStep(final StepInterpolator interpolator)
|
public boolean evaluateStep(final StepInterpolator interpolator)
|
||||||
throws DerivativeException, FunctionEvaluationException, ConvergenceException {
|
throws DerivativeException, SwitchException, ConvergenceException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -169,6 +169,8 @@ class SwitchState implements Serializable {
|
||||||
return function.g(t, interpolator.getInterpolatedState());
|
return function.g(t, interpolator.getInterpolatedState());
|
||||||
} catch (DerivativeException e) {
|
} catch (DerivativeException e) {
|
||||||
throw new FunctionEvaluationException(t, e);
|
throw new FunctionEvaluationException(t, e);
|
||||||
|
} catch (SwitchException e) {
|
||||||
|
throw new FunctionEvaluationException(t, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -205,10 +207,12 @@ class SwitchState implements Serializable {
|
||||||
|
|
||||||
} catch (FunctionEvaluationException e) {
|
} catch (FunctionEvaluationException e) {
|
||||||
Throwable cause = e.getCause();
|
Throwable cause = e.getCause();
|
||||||
if ((cause != null) && (cause instanceof DerivativeException)) {
|
if ((cause != null) && (cause instanceof DerivativeException)) {
|
||||||
throw (DerivativeException) cause;
|
throw (DerivativeException) cause;
|
||||||
}
|
} else if ((cause != null) && (cause instanceof SwitchException)) {
|
||||||
throw e;
|
throw (SwitchException) cause;
|
||||||
|
}
|
||||||
|
throw new SwitchException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -227,11 +231,10 @@ class SwitchState implements Serializable {
|
||||||
* end of the step
|
* end of the step
|
||||||
* @param y array containing the current value of the state vector
|
* @param y array containing the current value of the state vector
|
||||||
* at the end of the step
|
* at the end of the step
|
||||||
* @exception FunctionEvaluationException if the value of the switching
|
* @exception SwitchException if the value of the switching
|
||||||
* function cannot be evaluated
|
* function cannot be evaluated
|
||||||
*/
|
*/
|
||||||
public void stepAccepted(double t, double[] y)
|
public void stepAccepted(double t, double[] y) throws SwitchException {
|
||||||
throws FunctionEvaluationException {
|
|
||||||
|
|
||||||
t0 = t;
|
t0 = t;
|
||||||
g0 = function.g(t, y);
|
g0 = function.g(t, y);
|
||||||
|
@ -261,8 +264,10 @@ class SwitchState implements Serializable {
|
||||||
* @param y array were to put the desired state vector at the beginning
|
* @param y array were to put the desired state vector at the beginning
|
||||||
* of the next step
|
* of the next step
|
||||||
* @return true if the integrator should reset the derivatives too
|
* @return true if the integrator should reset the derivatives too
|
||||||
|
* @exception SwitchException if the state cannot be reseted by the switching
|
||||||
|
* function
|
||||||
*/
|
*/
|
||||||
public boolean reset(double t, double[] y) {
|
public boolean reset(double t, double[] y) throws SwitchException {
|
||||||
|
|
||||||
if (! pendingEvent) {
|
if (! pendingEvent) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -19,8 +19,6 @@ package org.apache.commons.math.ode;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import org.apache.commons.math.FunctionEvaluationException;
|
|
||||||
|
|
||||||
/** This interface represents a switching function.
|
/** This interface represents a switching function.
|
||||||
*
|
*
|
||||||
* <p>A switching function allows to handle discrete events in
|
* <p>A switching function allows to handle discrete events in
|
||||||
|
@ -93,10 +91,9 @@ public interface SwitchingFunction extends Serializable {
|
||||||
* @param t current value of the independent <i>time</i> variable
|
* @param t current value of the independent <i>time</i> variable
|
||||||
* @param y array containing the current value of the state vector
|
* @param y array containing the current value of the state vector
|
||||||
* @return value of the g function
|
* @return value of the g function
|
||||||
* @exception FunctionEvaluationException if the value of the function
|
* @exception SwitchException if the switching function cannot be evaluated
|
||||||
* cannot be evaluated
|
|
||||||
*/
|
*/
|
||||||
public double g(double t, double[] y) throws FunctionEvaluationException;
|
public double g(double t, double[] y) throws SwitchException;
|
||||||
|
|
||||||
/** Handle an event and choose what to do next.
|
/** Handle an event and choose what to do next.
|
||||||
|
|
||||||
|
@ -131,8 +128,9 @@ public interface SwitchingFunction extends Serializable {
|
||||||
* @return indication of what the integrator should do next, this
|
* @return indication of what the integrator should do next, this
|
||||||
* value must be one of {@link #STOP}, {@link #RESET_STATE},
|
* value must be one of {@link #STOP}, {@link #RESET_STATE},
|
||||||
* {@link #RESET_DERIVATIVES} or {@link #CONTINUE}
|
* {@link #RESET_DERIVATIVES} or {@link #CONTINUE}
|
||||||
|
* @exception SwitchException if the event occurrence triggers an error
|
||||||
*/
|
*/
|
||||||
public int eventOccurred(double t, double[] y);
|
public int eventOccurred(double t, double[] y) throws SwitchException;
|
||||||
|
|
||||||
/** Reset the state prior to continue the integration.
|
/** Reset the state prior to continue the integration.
|
||||||
|
|
||||||
|
@ -148,7 +146,8 @@ public interface SwitchingFunction extends Serializable {
|
||||||
* @param t current value of the independent <i>time</i> variable
|
* @param t current value of the independent <i>time</i> variable
|
||||||
* @param y array containing the current value of the state vector
|
* @param y array containing the current value of the state vector
|
||||||
* the new state should be put in the same array
|
* the new state should be put in the same array
|
||||||
|
* @exception SwitchException if the state cannot be reseted
|
||||||
*/
|
*/
|
||||||
public void resetState(double t, double[] y);
|
public void resetState(double t, double[] y) throws SwitchException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,14 @@
|
||||||
|
|
||||||
package org.apache.commons.math.ode;
|
package org.apache.commons.math.ode;
|
||||||
|
|
||||||
import org.apache.commons.math.ConvergenceException;
|
|
||||||
import org.apache.commons.math.FunctionEvaluationException;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.math.ConvergenceException;
|
||||||
|
|
||||||
/** This class handles several {@link SwitchingFunction switching
|
/** This class handles several {@link SwitchingFunction switching
|
||||||
* functions} during integration.
|
* functions} during integration.
|
||||||
*
|
*
|
||||||
|
@ -147,8 +146,8 @@ public class SwitchingFunctionsHandler {
|
||||||
|
|
||||||
return first != null;
|
return first != null;
|
||||||
|
|
||||||
} catch (FunctionEvaluationException fee) {
|
} catch (SwitchException se) {
|
||||||
throw new IntegratorException(fee);
|
throw new IntegratorException(se);
|
||||||
} catch (ConvergenceException ce) {
|
} catch (ConvergenceException ce) {
|
||||||
throw new IntegratorException(ce);
|
throw new IntegratorException(ce);
|
||||||
}
|
}
|
||||||
|
@ -180,8 +179,8 @@ public class SwitchingFunctionsHandler {
|
||||||
for (Iterator iter = functions.iterator(); iter.hasNext();) {
|
for (Iterator iter = functions.iterator(); iter.hasNext();) {
|
||||||
((SwitchState) iter.next()).stepAccepted(t, y);
|
((SwitchState) iter.next()).stepAccepted(t, y);
|
||||||
}
|
}
|
||||||
} catch (FunctionEvaluationException fee) {
|
} catch (SwitchException se) {
|
||||||
throw new IntegratorException(fee);
|
throw new IntegratorException(se);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,15 +203,21 @@ public class SwitchingFunctionsHandler {
|
||||||
* @param y array were to put the desired state vector at the beginning
|
* @param y array were to put the desired state vector at the beginning
|
||||||
* of the next step
|
* of the next step
|
||||||
* @return true if the integrator should reset the derivatives too
|
* @return true if the integrator should reset the derivatives too
|
||||||
|
* @exception IntegratorException if one of the switching functions
|
||||||
|
* that should reset the state fails to do it
|
||||||
*/
|
*/
|
||||||
public boolean reset(double t, double[] y) {
|
public boolean reset(double t, double[] y) throws IntegratorException {
|
||||||
boolean resetDerivatives = false;
|
try {
|
||||||
for (Iterator iter = functions.iterator(); iter.hasNext();) {
|
boolean resetDerivatives = false;
|
||||||
if (((SwitchState) iter.next()).reset(t, y)) {
|
for (Iterator iter = functions.iterator(); iter.hasNext();) {
|
||||||
resetDerivatives = true;
|
if (((SwitchState) iter.next()).reset(t, y)) {
|
||||||
|
resetDerivatives = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resetDerivatives;
|
||||||
|
} catch (SwitchException se) {
|
||||||
|
throw new IntegratorException(se);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return resetDerivatives;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Switching functions. */
|
/** Switching functions. */
|
||||||
|
|
|
@ -35,11 +35,16 @@ The <action> type attribute can be add,update,fix,remove.
|
||||||
|
|
||||||
<document>
|
<document>
|
||||||
<properties>
|
<properties>
|
||||||
<title>
|
<title>Commons Math Release Notes</title>
|
||||||
Commons Math Release Notes</title>
|
|
||||||
</properties>
|
</properties>
|
||||||
<body>
|
<body>
|
||||||
<release version="2.0" date="TBD" description="TBD">
|
<release version="2.0" date="TBD" description="TBD">
|
||||||
|
<action dev="luc" type="add" >
|
||||||
|
Switching functions can now throw dedicated SwitchException from all their
|
||||||
|
method. At upper call level, the various ODE integrators handle these new
|
||||||
|
exceptions and wrap them into IntegratorException instances, hence the
|
||||||
|
integrators methods signature did not change.
|
||||||
|
</action>
|
||||||
<action dev="luc" type="add" issue="MATH-202">
|
<action dev="luc" type="add" issue="MATH-202">
|
||||||
Added the getSwitchingFunctions and clearSwitchingFunctions to the
|
Added the getSwitchingFunctions and clearSwitchingFunctions to the
|
||||||
FirstOrderIntegrator interface and all its implementations
|
FirstOrderIntegrator interface and all its implementations
|
||||||
|
|
|
@ -17,17 +17,11 @@
|
||||||
|
|
||||||
package org.apache.commons.math.ode;
|
package org.apache.commons.math.ode;
|
||||||
|
|
||||||
import org.apache.commons.math.ConvergenceException;
|
import junit.framework.Test;
|
||||||
import org.apache.commons.math.FunctionEvaluationException;
|
import junit.framework.TestCase;
|
||||||
import org.apache.commons.math.ode.DerivativeException;
|
import junit.framework.TestSuite;
|
||||||
import org.apache.commons.math.ode.FirstOrderIntegrator;
|
|
||||||
import org.apache.commons.math.ode.HighamHall54Integrator;
|
|
||||||
import org.apache.commons.math.ode.IntegratorException;
|
|
||||||
import org.apache.commons.math.ode.StepHandler;
|
|
||||||
import org.apache.commons.math.ode.StepInterpolator;
|
|
||||||
import org.apache.commons.math.ode.SwitchingFunction;
|
|
||||||
|
|
||||||
import junit.framework.*;
|
import org.apache.commons.math.ConvergenceException;
|
||||||
|
|
||||||
public class HighamHall54IntegratorTest
|
public class HighamHall54IntegratorTest
|
||||||
extends TestCase {
|
extends TestCase {
|
||||||
|
@ -185,11 +179,12 @@ public class HighamHall54IntegratorTest
|
||||||
public int eventOccurred(double t, double[] y) {
|
public int eventOccurred(double t, double[] y) {
|
||||||
return SwitchingFunction.CONTINUE;
|
return SwitchingFunction.CONTINUE;
|
||||||
}
|
}
|
||||||
public double g(double t, double[] y) throws FunctionEvaluationException {
|
public double g(double t, double[] y) throws SwitchException {
|
||||||
double middle = (pb.getInitialTime() + pb.getFinalTime()) / 2;
|
double middle = (pb.getInitialTime() + pb.getFinalTime()) / 2;
|
||||||
double offset = t - middle;
|
double offset = t - middle;
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
throw new FunctionEvaluationException(t);
|
throw new SwitchException("Evaluation failed for argument = {0}",
|
||||||
|
new Object[] { new Double(t) });
|
||||||
}
|
}
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue