improved array structure in Romberg integrator

since the integrator uses only two rows at a time, we allocate only two arrays and reuse them

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@824822 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2009-10-13 15:56:51 +00:00
parent e975825996
commit dd9b7b477a
1 changed files with 20 additions and 16 deletions

View File

@ -67,37 +67,41 @@ public class RombergIntegrator extends UnivariateRealIntegratorImpl {
final double min, final double max) final double min, final double max)
throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException { throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
int i = 1, j, m = maximalIterationCount + 1; final int m = maximalIterationCount + 1;
// Array structure here can be improved for better space double previousRow[] = new double[m];
// efficiency because only the lower triangle is used. double currentRow[] = new double[m];
double r, t[][] = new double[m][m], s, olds;
clearResult(); clearResult();
verifyInterval(min, max); verifyInterval(min, max);
verifyIterationCount(); verifyIterationCount();
TrapezoidIntegrator qtrap = new TrapezoidIntegrator(); TrapezoidIntegrator qtrap = new TrapezoidIntegrator();
t[0][0] = qtrap.stage(f, min, max, 0); currentRow[0] = qtrap.stage(f, min, max, 0);
olds = t[0][0]; double olds = currentRow[0];
while (i <= maximalIterationCount) { for (int i = 1; i <= maximalIterationCount; ++i) {
t[i][0] = qtrap.stage(f, min, max, i);
for (j = 1; j <= i; j++) { // switch rows
final double[] tmpRow = previousRow;
previousRow = currentRow;
currentRow = tmpRow;
currentRow[0] = qtrap.stage(f, min, max, i);
for (int j = 1; j <= i; j++) {
// Richardson extrapolation coefficient // Richardson extrapolation coefficient
r = (1L << (2 * j)) -1; final double r = (1L << (2 * j)) - 1;
t[i][j] = t[i][j-1] + (t[i][j-1] - t[i-1][j-1]) / r; final double tIJm1 = currentRow[j - 1];
currentRow[j] = tIJm1 + (tIJm1 - previousRow[j - 1]) / r;
} }
s = t[i][i]; final double s = currentRow[i];
if (i >= minimalIterationCount) { if (i >= minimalIterationCount) {
final double delta = Math.abs(s - olds); final double delta = Math.abs(s - olds);
final double rLimit = final double rLimit = relativeAccuracy * (Math.abs(olds) + Math.abs(s)) * 0.5;
relativeAccuracy * (Math.abs(olds) + Math.abs(s)) * 0.5;
if ((delta <= rLimit) || (delta <= absoluteAccuracy)) { if ((delta <= rLimit) || (delta <= absoluteAccuracy)) {
setResult(s, i); setResult(s, i);
return result; return result;
} }
} }
olds = s; olds = s;
i++;
} }
throw new MaxIterationsExceededException(maximalIterationCount); throw new MaxIterationsExceededException(maximalIterationCount);
} }