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 {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = -7307007422156119622L;
|
||||
private static final long serialVersionUID = -7307007422156119622L;
|
||||
|
||||
/** Switching function. */
|
||||
private SwitchingFunction function;
|
||||
|
@ -50,10 +50,10 @@ class SwitchState implements Serializable {
|
|||
/** Maximal time interval between switching function checks. */
|
||||
private double maxCheckInterval;
|
||||
|
||||
/** Convergence threshold for event localisation. */
|
||||
/** Convergence threshold for event localization. */
|
||||
private double convergence;
|
||||
|
||||
/** Upper limit in the iteration count for event localisation. */
|
||||
/** Upper limit in the iteration count for event localization. */
|
||||
private int maxIterationCount;
|
||||
|
||||
/** Time at the beginning of the step. */
|
||||
|
@ -115,11 +115,11 @@ class SwitchState implements Serializable {
|
|||
* beginning of the step
|
||||
* @param y0 array containing the current value of the state vector
|
||||
* 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
|
||||
*/
|
||||
public void reinitializeBegin(double t0, double[] y0)
|
||||
throws FunctionEvaluationException {
|
||||
throws SwitchException {
|
||||
this.t0 = t0;
|
||||
g0 = function.g(t0, y0);
|
||||
g0Positive = (g0 >= 0);
|
||||
|
@ -132,12 +132,12 @@ class SwitchState implements Serializable {
|
|||
* rejected)
|
||||
* @exception DerivativeException if the interpolator fails to
|
||||
* compute the function somewhere within the step
|
||||
* @exception FunctionEvaluationException if the switching function
|
||||
* @exception SwitchException if the switching function
|
||||
* cannot be evaluated
|
||||
* @exception ConvergenceException if an event cannot be located
|
||||
*/
|
||||
public boolean evaluateStep(final StepInterpolator interpolator)
|
||||
throws DerivativeException, FunctionEvaluationException, ConvergenceException {
|
||||
throws DerivativeException, SwitchException, ConvergenceException {
|
||||
|
||||
try {
|
||||
|
||||
|
@ -169,6 +169,8 @@ class SwitchState implements Serializable {
|
|||
return function.g(t, interpolator.getInterpolatedState());
|
||||
} catch (DerivativeException 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) {
|
||||
Throwable cause = e.getCause();
|
||||
if ((cause != null) && (cause instanceof DerivativeException)) {
|
||||
throw (DerivativeException) cause;
|
||||
}
|
||||
throw e;
|
||||
if ((cause != null) && (cause instanceof DerivativeException)) {
|
||||
throw (DerivativeException) cause;
|
||||
} else if ((cause != null) && (cause instanceof SwitchException)) {
|
||||
throw (SwitchException) cause;
|
||||
}
|
||||
throw new SwitchException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -227,11 +231,10 @@ class SwitchState implements Serializable {
|
|||
* end of the step
|
||||
* @param y array containing the current value of the state vector
|
||||
* 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
|
||||
*/
|
||||
public void stepAccepted(double t, double[] y)
|
||||
throws FunctionEvaluationException {
|
||||
public void stepAccepted(double t, double[] y) throws SwitchException {
|
||||
|
||||
t0 = t;
|
||||
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
|
||||
* of the next step
|
||||
* @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) {
|
||||
return false;
|
||||
|
|
|
@ -19,8 +19,6 @@ package org.apache.commons.math.ode;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.FunctionEvaluationException;
|
||||
|
||||
/** This interface represents a switching function.
|
||||
*
|
||||
* <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 y array containing the current value of the state vector
|
||||
* @return value of the g function
|
||||
* @exception FunctionEvaluationException if the value of the function
|
||||
* cannot be evaluated
|
||||
* @exception SwitchException if the switching function 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.
|
||||
|
||||
|
@ -131,8 +128,9 @@ public interface SwitchingFunction extends Serializable {
|
|||
* @return indication of what the integrator should do next, this
|
||||
* value must be one of {@link #STOP}, {@link #RESET_STATE},
|
||||
* {@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.
|
||||
|
||||
|
@ -148,7 +146,8 @@ public interface SwitchingFunction extends Serializable {
|
|||
* @param t current value of the independent <i>time</i> variable
|
||||
* @param y array containing the current value of the state vector
|
||||
* 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;
|
||||
|
||||
import org.apache.commons.math.ConvergenceException;
|
||||
import org.apache.commons.math.FunctionEvaluationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.math.ConvergenceException;
|
||||
|
||||
/** This class handles several {@link SwitchingFunction switching
|
||||
* functions} during integration.
|
||||
*
|
||||
|
@ -147,8 +146,8 @@ public class SwitchingFunctionsHandler {
|
|||
|
||||
return first != null;
|
||||
|
||||
} catch (FunctionEvaluationException fee) {
|
||||
throw new IntegratorException(fee);
|
||||
} catch (SwitchException se) {
|
||||
throw new IntegratorException(se);
|
||||
} catch (ConvergenceException ce) {
|
||||
throw new IntegratorException(ce);
|
||||
}
|
||||
|
@ -180,8 +179,8 @@ public class SwitchingFunctionsHandler {
|
|||
for (Iterator iter = functions.iterator(); iter.hasNext();) {
|
||||
((SwitchState) iter.next()).stepAccepted(t, y);
|
||||
}
|
||||
} catch (FunctionEvaluationException fee) {
|
||||
throw new IntegratorException(fee);
|
||||
} catch (SwitchException se) {
|
||||
throw new IntegratorException(se);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,15 +203,21 @@ public class SwitchingFunctionsHandler {
|
|||
* @param y array were to put the desired state vector at the beginning
|
||||
* of the next step
|
||||
* @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) {
|
||||
boolean resetDerivatives = false;
|
||||
for (Iterator iter = functions.iterator(); iter.hasNext();) {
|
||||
if (((SwitchState) iter.next()).reset(t, y)) {
|
||||
resetDerivatives = true;
|
||||
public boolean reset(double t, double[] y) throws IntegratorException {
|
||||
try {
|
||||
boolean resetDerivatives = false;
|
||||
for (Iterator iter = functions.iterator(); iter.hasNext();) {
|
||||
if (((SwitchState) iter.next()).reset(t, y)) {
|
||||
resetDerivatives = true;
|
||||
}
|
||||
}
|
||||
return resetDerivatives;
|
||||
} catch (SwitchException se) {
|
||||
throw new IntegratorException(se);
|
||||
}
|
||||
}
|
||||
return resetDerivatives;
|
||||
}
|
||||
|
||||
/** Switching functions. */
|
||||
|
|
|
@ -35,11 +35,16 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
|
||||
<document>
|
||||
<properties>
|
||||
<title>
|
||||
Commons Math Release Notes</title>
|
||||
<title>Commons Math Release Notes</title>
|
||||
</properties>
|
||||
<body>
|
||||
<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">
|
||||
Added the getSwitchingFunctions and clearSwitchingFunctions to the
|
||||
FirstOrderIntegrator interface and all its implementations
|
||||
|
|
|
@ -17,17 +17,11 @@
|
|||
|
||||
package org.apache.commons.math.ode;
|
||||
|
||||
import org.apache.commons.math.ConvergenceException;
|
||||
import org.apache.commons.math.FunctionEvaluationException;
|
||||
import org.apache.commons.math.ode.DerivativeException;
|
||||
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.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import junit.framework.*;
|
||||
import org.apache.commons.math.ConvergenceException;
|
||||
|
||||
public class HighamHall54IntegratorTest
|
||||
extends TestCase {
|
||||
|
@ -185,11 +179,12 @@ public class HighamHall54IntegratorTest
|
|||
public int eventOccurred(double t, double[] y) {
|
||||
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 offset = t - middle;
|
||||
if (offset > 0) {
|
||||
throw new FunctionEvaluationException(t);
|
||||
throw new SwitchException("Evaluation failed for argument = {0}",
|
||||
new Object[] { new Double(t) });
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue