Author: luc
Date: Sun Jan 18 12:45:16 2009
New Revision: 735536
URL: http://svn.apache.org/viewvc?rev=735536&view=rev
Log:
added absolute accuracy handling for integrators
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/RombergIntegrator.java
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/SimpsonIntegrator.java
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.java
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java
commons/proper/math/trunk/src/site/xdoc/changes.xml
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java?rev=735536&r1=735535&r2=735536&view=diff
==============================================================================
---
commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java
(original)
+++
commons/proper/math/trunk/src/java/org/apache/commons/math/MessagesResources_fr.java
Sun Jan 18 12:45:16 2009
@@ -283,6 +283,7 @@
"les valeurs de la fonction aux bornes n''ont pas des signes
diff\u00e9rents. Bornes : [{0}, {1}], valeurs : [{2}, {3}]" },
// org.apache.commons.math.analysis.solvers.UnivariateRealSolverImpl
+ // org.apache.commons.math.analysis.integration.UnivariateRealIntegratorImpl
// org.apache.commons.math.transform.FastFourierTransformer
{ "endpoints do not specify an interval: [{0}, {1}]",
"les extr\u00e9mit\u00e9s ne constituent pas un intervalle : [{0}, {1}]"
},
@@ -295,6 +296,10 @@
{ "function is not differentiable",
"la fonction n''est pas diff\u00e9rentiable" },
+ // org.apache.commons.math.analysis.integration.UnivariateRealIntegratorImpl
+ { "invalid iteration limits: min={0}, max={1}",
+ "limites d''it\u00e9rations invalides : min = {0}, max = {1}" },
+
// org.apache.commons.math.fraction.Fraction
{ "zero denominator in fraction {0}/{1}",
"d\u00e9nominateur null dans le nombre rationnel {0}/{1}" },
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/RombergIntegrator.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/RombergIntegrator.java?rev=735536&r1=735535&r2=735536&view=diff
==============================================================================
---
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/RombergIntegrator.java
(original)
+++
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/RombergIntegrator.java
Sun Jan 18 12:45:16 2009
@@ -17,6 +17,7 @@
package org.apache.commons.math.analysis.integration;
import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
@@ -26,7 +27,7 @@
* reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X,
* chapter 3.
* <p>
- * Romberg integration employs k successvie refinements of the trapezoid
+ * Romberg integration employs k successive refinements of the trapezoid
* rule to remove error terms less than order O(N^(-2k)). Simpson's rule
* is a special case of k = 2.</p>
*
@@ -47,23 +48,12 @@
super(f, 32);
}
- /**
- * Integrate the function in the given interval.
- *
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @return the value of integral
- * @throws MaxIterationsExceededException if the maximum iteration count
is exceeded
- * or the integrator detects convergence problems otherwise
- * @throws FunctionEvaluationException if an error occurs evaluating the
- * function
- * @throws IllegalArgumentException if any parameters are invalid
- */
- public double integrate(double min, double max) throws
MaxIterationsExceededException,
+ /** {...@inheritdoc} */
+ public double integrate(double min, double max) throws
MaxIterationsExceededException,
FunctionEvaluationException, IllegalArgumentException {
int i = 1, j, m = maximalIterationCount + 1;
- // Array strcture here can be improved for better space
+ // Array structure here can be improved for better space
// efficiency because only the lower triangle is used.
double r, t[][] = new double[m][m], s, olds;
@@ -83,7 +73,10 @@
}
s = t[i][i];
if (i >= minimalIterationCount) {
- if (Math.abs(s - olds) <= Math.abs(relativeAccuracy * olds)) {
+ final double delta = Math.abs(s - olds);
+ final double rLimit =
+ relativeAccuracy * (Math.abs(olds) + Math.abs(s)) * 0.5;
+ if ((delta <= rLimit) || (delta <= absoluteAccuracy)) {
setResult(s, i);
return result;
}
@@ -94,18 +87,14 @@
throw new MaxIterationsExceededException(maximalIterationCount);
}
- /**
- * Verifies that the iteration limits are valid and within the range.
- *
- * @throws IllegalArgumentException if not
- */
+ /** {...@inheritdoc} */
protected void verifyIterationCount() throws IllegalArgumentException {
super.verifyIterationCount();
// at most 32 bisection refinements due to higher order divider
if (maximalIterationCount > 32) {
- throw new IllegalArgumentException
- ("Iteration upper limit out of [0, 32] range: " +
- maximalIterationCount);
+ throw MathRuntimeException.createIllegalArgumentException(
+ "invalid iteration limits: min={0}, max={1}",
+ new Object[] { 0, 32 });
}
}
}
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/SimpsonIntegrator.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/SimpsonIntegrator.java?rev=735536&r1=735535&r2=735536&view=diff
==============================================================================
---
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/SimpsonIntegrator.java
(original)
+++
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/SimpsonIntegrator.java
Sun Jan 18 12:45:16 2009
@@ -17,6 +17,7 @@
package org.apache.commons.math.analysis.integration;
import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
@@ -46,18 +47,7 @@
super(f, 64);
}
- /**
- * Integrate the function in the given interval.
- *
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @return the value of integral
- * @throws MaxIterationsExceededException if the maximum iteration count
is exceeded
- * or the integrator detects convergence problems otherwise
- * @throws FunctionEvaluationException if an error occurs evaluating the
- * function
- * @throws IllegalArgumentException if any parameters are invalid
- */
+ /** {...@inheritdoc} */
public double integrate(double min, double max) throws
MaxIterationsExceededException,
FunctionEvaluationException, IllegalArgumentException {
@@ -81,7 +71,10 @@
t = qtrap.stage(min, max, i);
s = (4 * t - oldt) / 3.0;
if (i >= minimalIterationCount) {
- if (Math.abs(s - olds) <= Math.abs(relativeAccuracy * olds)) {
+ final double delta = Math.abs(s - olds);
+ final double rLimit =
+ relativeAccuracy * (Math.abs(olds) + Math.abs(s)) * 0.5;
+ if ((delta <= rLimit) || (delta <= absoluteAccuracy)) {
setResult(s, i);
return result;
}
@@ -93,18 +86,14 @@
throw new MaxIterationsExceededException(maximalIterationCount);
}
- /**
- * Verifies that the iteration limits are valid and within the range.
- *
- * @throws IllegalArgumentException if not
- */
+ /** {...@inheritdoc} */
protected void verifyIterationCount() throws IllegalArgumentException {
super.verifyIterationCount();
// at most 64 bisection refinements
if (maximalIterationCount > 64) {
- throw new IllegalArgumentException
- ("Iteration upper limit out of [0, 64] range: " +
- maximalIterationCount);
+ throw MathRuntimeException.createIllegalArgumentException(
+ "invalid iteration limits: min={0}, max={1}",
+ new Object[] { 0, 64 });
}
}
}
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java?rev=735536&r1=735535&r2=735536&view=diff
==============================================================================
---
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java
(original)
+++
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java
Sun Jan 18 12:45:16 2009
@@ -17,6 +17,7 @@
package org.apache.commons.math.analysis.integration;
import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
@@ -87,18 +88,7 @@
}
}
- /**
- * Integrate the function in the given interval.
- *
- * @param min the lower bound for the interval
- * @param max the upper bound for the interval
- * @return the value of integral
- * @throws MaxIterationsExceededException if the maximum iteration count
is exceeded
- * or the integrator detects convergence problems otherwise
- * @throws FunctionEvaluationException if an error occurs evaluating the
- * function
- * @throws IllegalArgumentException if any parameters are invalid
- */
+ /** {...@inheritdoc} */
public double integrate(double min, double max) throws
MaxIterationsExceededException,
FunctionEvaluationException, IllegalArgumentException {
@@ -113,7 +103,10 @@
while (i <= maximalIterationCount) {
t = stage(min, max, i);
if (i >= minimalIterationCount) {
- if (Math.abs(t - oldt) <= Math.abs(relativeAccuracy * oldt)) {
+ final double delta = Math.abs(t - oldt);
+ final double rLimit =
+ relativeAccuracy * (Math.abs(oldt) + Math.abs(t)) * 0.5;
+ if ((delta <= rLimit) || (delta <= absoluteAccuracy)) {
setResult(t, i);
return result;
}
@@ -124,18 +117,14 @@
throw new MaxIterationsExceededException(maximalIterationCount);
}
- /**
- * Verifies that the iteration limits are valid and within the range.
- *
- * @throws IllegalArgumentException if not
- */
+ /** {...@inheritdoc} */
protected void verifyIterationCount() throws IllegalArgumentException {
super.verifyIterationCount();
// at most 64 bisection refinements
if (maximalIterationCount > 64) {
- throw new IllegalArgumentException
- ("Iteration upper limit out of [0, 64] range: " +
- maximalIterationCount);
+ throw MathRuntimeException.createIllegalArgumentException(
+ "invalid iteration limits: min={0}, max={1}",
+ new Object[] { 0, 64 });
}
}
}
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.java?rev=735536&r1=735535&r2=735536&view=diff
==============================================================================
---
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.java
(original)
+++
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegrator.java
Sun Jan 18 12:45:16 2009
@@ -17,6 +17,7 @@
package org.apache.commons.math.analysis.integration;
import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.ConvergingAlgorithm;
import org.apache.commons.math.FunctionEvaluationException;
/**
@@ -25,39 +26,9 @@
* @version $Revision$ $Date$
* @since 1.2
*/
-public interface UnivariateRealIntegrator {
+public interface UnivariateRealIntegrator extends ConvergingAlgorithm {
- /**
- * Set the upper limit for the number of iterations.
- * <p>
- * Usually a high iteration count indicates convergence problem. However,
- * the "reasonable value" varies widely for different cases. Users are
- * advised to use the default value.</p>
- * <p>
- * A <code>ConvergenceException</code> will be thrown if this number
- * is exceeded.</p>
- *
- * @param count maximum number of iterations
- */
- void setMaximalIterationCount(int count);
-
- /**
- * Get the upper limit for the number of iterations.
- *
- * @return the actual upper limit
- */
- int getMaximalIterationCount();
-
- /**
- * Reset the upper limit for the number of iterations to the default.
- * <p>
- * The default value is supplied by the implementation.</p>
- *
- * @see #setMaximalIterationCount(int)
- */
- void resetMaximalIterationCount();
-
- /**
+ /**
* Set the lower limit for the number of iterations.
* <p>
* Minimal iteration is needed to avoid false early convergence, e.g.
@@ -88,33 +59,6 @@
void resetMinimalIterationCount();
/**
- * Set the relative accuracy.
- * <p>
- * This is used to stop iterations.</p>
- *
- * @param accuracy the relative accuracy
- * @throws IllegalArgumentException if the accuracy can't be achieved
- * or is otherwise deemed unreasonable
- */
- void setRelativeAccuracy(double accuracy);
-
- /**
- * Get the actual relative accuracy.
- *
- * @return the accuracy
- */
- double getRelativeAccuracy();
-
- /**
- * Reset the relative accuracy to the default.
- * <p>
- * The default value is provided by the implementation.</p>
- *
- * @see #setRelativeAccuracy(double)
- */
- void resetRelativeAccuracy();
-
- /**
* Integrate the function in the given interval.
*
* @param min the lower bound for the interval
@@ -139,18 +83,4 @@
*/
double getResult() throws IllegalStateException;
- /**
- * Get the number of iterations in the last run of the integrator.
- * <p>
- * This is mainly meant for testing purposes. It may occasionally
- * help track down performance problems: if the iteration count
- * is notoriously high, check whether the function is evaluated
- * properly, and whether another integrator is more amenable to the
- * problem.</p>
- *
- * @return the last iteration count
- * @throws IllegalStateException if there is no result available, either
- * because no result was yet computed or the last attempt failed
- */
- int getIterationCount() throws IllegalStateException;
}
Modified:
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java?rev=735536&r1=735535&r2=735536&view=diff
==============================================================================
---
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java
(original)
+++
commons/proper/math/trunk/src/java/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java
Sun Jan 18 12:45:16 2009
@@ -16,8 +16,7 @@
*/
package org.apache.commons.math.analysis.integration;
-import java.io.Serializable;
-
+import org.apache.commons.math.ConvergingAlgorithmImpl;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
@@ -27,27 +26,15 @@
* @version $Revision$ $Date$
* @since 1.2
*/
-public abstract class UnivariateRealIntegratorImpl implements
- UnivariateRealIntegrator, Serializable {
-
- /** serializable version identifier */
- static final long serialVersionUID = -3365294665201465048L;
+public abstract class UnivariateRealIntegratorImpl
+ extends ConvergingAlgorithmImpl implements UnivariateRealIntegrator {
- /** maximum relative error */
- protected double relativeAccuracy;
-
- /** maximum number of iterations */
- protected int maximalIterationCount;
+ /** Serializable version identifier. */
+ private static final long serialVersionUID = 6248808456637441533L;
/** minimum number of iterations */
protected int minimalIterationCount;
- /** default maximum relative error */
- protected double defaultRelativeAccuracy;
-
- /** default maximum number of iterations */
- protected int defaultMaximalIterationCount;
-
/** default minimum number of iterations */
protected int defaultMinimalIterationCount;
@@ -57,9 +44,6 @@
/** the last computed integral */
protected double result;
- /** the last iteration count */
- protected int iterationCount;
-
/** the integrand function */
protected UnivariateRealFunction f;
@@ -71,21 +55,18 @@
* @throws IllegalArgumentException if f is null or the iteration
* limits are not valid
*/
- protected UnivariateRealIntegratorImpl(
- UnivariateRealFunction f,
- int defaultMaximalIterationCount) throws IllegalArgumentException {
-
+ protected UnivariateRealIntegratorImpl(final UnivariateRealFunction f,
+ final int
defaultMaximalIterationCount)
+ throws IllegalArgumentException {
+ super(defaultMaximalIterationCount, 1.0e-15);
if (f == null) {
throw new IllegalArgumentException("Function can not be null.");
}
this.f = f;
- // parameters that may depend on algorithm
- this.defaultMaximalIterationCount = defaultMaximalIterationCount;
- this.maximalIterationCount = defaultMaximalIterationCount;
+
// parameters that are problem specific
- this.defaultRelativeAccuracy = 1E-6;
- this.relativeAccuracy = defaultRelativeAccuracy;
+ setRelativeAccuracy(1.0e-6);
this.defaultMinimalIterationCount = 3;
this.minimalIterationCount = defaultMinimalIterationCount;
@@ -107,20 +88,6 @@
}
/**
- * Access the last iteration count.
- *
- * @return the last iteration count
- * @throws IllegalStateException if no integral has been computed
- */
- public int getIterationCount() throws IllegalStateException {
- if (resultComputed) {
- return iterationCount;
- } else {
- throw MathRuntimeException.createIllegalStateException("no result
available", null);
- }
- }
-
- /**
* Convenience function for implementations.
*
* @param result the result to set
@@ -136,99 +103,26 @@
* Convenience function for implementations.
*/
protected final void clearResult() {
+ this.iterationCount = 0;
this.resultComputed = false;
}
- /**
- * Set the upper limit for the number of iterations.
- *
- * @param count maximum number of iterations
- */
- public void setMaximalIterationCount(int count) {
- maximalIterationCount = count;
- }
-
- /**
- * Get the upper limit for the number of iterations.
- *
- * @return the actual upper limit
- */
- public int getMaximalIterationCount() {
- return maximalIterationCount;
- }
-
- /**
- * Reset the upper limit for the number of iterations to the default.
- */
- public void resetMaximalIterationCount() {
- maximalIterationCount = defaultMaximalIterationCount;
- }
-
- /**
- * Set the lower limit for the number of iterations.
- *
- * @param count minimum number of iterations
- */
+ /** {...@inheritdoc} */
public void setMinimalIterationCount(int count) {
minimalIterationCount = count;
}
- /**
- * Get the lower limit for the number of iterations.
- *
- * @return the actual lower limit
- */
+ /** {...@inheritdoc} */
public int getMinimalIterationCount() {
return minimalIterationCount;
}
- /**
- * Reset the lower limit for the number of iterations to the default.
- */
+ /** {...@inheritdoc} */
public void resetMinimalIterationCount() {
minimalIterationCount = defaultMinimalIterationCount;
}
/**
- * Set the relative accuracy.
- *
- * @param accuracy the relative accuracy
- * @throws IllegalArgumentException if the accuracy can't be achieved by
- * the integrator or is otherwise deemed unreasonable
- */
- public void setRelativeAccuracy(double accuracy) {
- relativeAccuracy = accuracy;
- }
-
- /**
- * Get the actual relative accuracy.
- *
- * @return the accuracy
- */
- public double getRelativeAccuracy() {
- return relativeAccuracy;
- }
-
- /**
- * Reset the relative accuracy to the default.
- */
- public void resetRelativeAccuracy() {
- relativeAccuracy = defaultRelativeAccuracy;
- }
-
- /**
- * Returns true if the arguments form a (strictly) increasing sequence
- *
- * @param start first number
- * @param mid second number
- * @param end third number
- * @return true if the arguments form an increasing sequence
- */
- protected boolean isSequence(double start, double mid, double end) {
- return (start < mid) && (mid < end);
- }
-
- /**
* Verifies that the endpoints specify an interval.
*
* @param lower lower endpoint
@@ -238,9 +132,9 @@
protected void verifyInterval(double lower, double upper) throws
IllegalArgumentException {
if (lower >= upper) {
- throw new IllegalArgumentException
- ("Endpoints do not specify an interval: [" + lower +
- ", " + upper + "]");
+ throw MathRuntimeException.createIllegalArgumentException(
+ "endpoints do not specify an interval: [{0}, {1}]",
+ new Object[] { lower, upper });
}
}
@@ -250,10 +144,10 @@
* @throws IllegalArgumentException if not valid
*/
protected void verifyIterationCount() throws IllegalArgumentException {
- if (!isSequence(0, minimalIterationCount, maximalIterationCount+1)) {
- throw new IllegalArgumentException
- ("Invalid iteration limits: min=" + minimalIterationCount +
- " max=" + maximalIterationCount);
+ if ((minimalIterationCount <= 0) || (maximalIterationCount <=
minimalIterationCount)) {
+ throw MathRuntimeException.createIllegalArgumentException(
+ "invalid iteration limits: min={0}, max={1}",
+ new Object[] { minimalIterationCount,
maximalIterationCount });
}
}
}
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=735536&r1=735535&r2=735536&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Sun Jan 18 12:45:16 2009
@@ -39,6 +39,10 @@
</properties>
<body>
<release version="2.0" date="TBD" description="TBD">
+ <action dev="luc" type="update" >
+ Integration algorithms now can have both relative and absolute
+ accuracy settings.
+ </action>
<action dev="luc" type="add" issue="MATH-177" due-to="Gilles Sadowski">
Added a new minimization sub-package below the analysis package.
</action>