commons-math3-3.2-src/checkstyle.xml 100644 1750 1750 17437 12126627721 16303 0 ustar luc luc 0 0
Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files.
* The redistribution policy for MINPACK is available here, for
* convenience, it is reproduced below. Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files.
* The redistribution policy for MINPACK is available here, for
* convenience, it is reproduced below. Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files.
* The redistribution policy for MINPACK is available here, for
* convenience, it is reproduced below. Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files.
* The redistribution policy for MINPACK is available here, for
* convenience, it is reproduced below. Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files.
* The redistribution policy for MINPACK is available here, for
* convenience, it is reproduced below.
* Parses the specified text lines, and extracts the indices of the first
* and last lines of the data defined by the specified {@code key}. This key
* must be one of
*
* In the NIST data files, the line indices are separated by the keywords
* {@code "lines"} and {@code "to"}.
* Some of the unit tests are re-implementations of the MINPACK file17 and file22 test files.
* The redistribution policy for MINPACK is available here, for
* convenience, it is reproduced below. This specific problem is the following differential equation :
* GaussianFitter
* instance.
*
* @param points data points where first dimension is a point index and
* second dimension is an array of length two representing the point
* with the first value corresponding to X and the second value
* corresponding to Y
* @param fitter fitter to which the points in points
should be
* added as observed points
*/
protected static void addDatasetToGaussianFitter(double[][] points,
GaussianFitter fitter) {
for (int i = 0; i < points.length; i++) {
fitter.addObservedPoint(points[i][0], points[i][1]);
}
}
}
././@LongLink 100644 0 0 152 12126630646 10257 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/fitting/HarmonicFitterTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/fitting/HarmonicFitterTest100644 1750 1750 16515 12126627670 32503 0 ustar luc luc 0 0 // 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.math3.optimization.fitting;
import java.util.Random;
import org.apache.commons.math3.analysis.function.HarmonicOscillator;
import org.apache.commons.math3.optimization.general.LevenbergMarquardtOptimizer;
import org.apache.commons.math3.exception.NumberIsTooSmallException;
import org.apache.commons.math3.exception.MathIllegalStateException;
import org.apache.commons.math3.util.FastMath;
import org.apache.commons.math3.util.MathUtils;
import org.junit.Test;
import org.junit.Assert;
public class HarmonicFitterTest {
@Test(expected=NumberIsTooSmallException.class)
public void testPreconditions1() {
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
fitter.fit();
}
// This test fails (throwing "ConvergenceException" instead).
// @Test(expected=ZeroException.class)
// public void testPreconditions2() {
// HarmonicFitter fitter =
// new HarmonicFitter(new LevenbergMarquardtOptimizer());
// final double x = 1.2;
// fitter.addObservedPoint(1, x, 1);
// fitter.addObservedPoint(1, x, -1);
// fitter.addObservedPoint(1, x, 0.5);
// fitter.addObservedPoint(1, x, 0);
// final double[] fitted = fitter.fit();
// }
@Test
public void testNoError() {
final double a = 0.2;
final double w = 3.4;
final double p = 4.1;
HarmonicOscillator f = new HarmonicOscillator(a, w, p);
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
for (double x = 0.0; x < 1.3; x += 0.01) {
fitter.addObservedPoint(1, x, f.value(x));
}
final double[] fitted = fitter.fit();
Assert.assertEquals(a, fitted[0], 1.0e-13);
Assert.assertEquals(w, fitted[1], 1.0e-13);
Assert.assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1e-13);
HarmonicOscillator ff = new HarmonicOscillator(fitted[0], fitted[1], fitted[2]);
for (double x = -1.0; x < 1.0; x += 0.01) {
Assert.assertTrue(FastMath.abs(f.value(x) - ff.value(x)) < 1e-13);
}
}
@Test
public void test1PercentError() {
Random randomizer = new Random(64925784252l);
final double a = 0.2;
final double w = 3.4;
final double p = 4.1;
HarmonicOscillator f = new HarmonicOscillator(a, w, p);
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
for (double x = 0.0; x < 10.0; x += 0.1) {
fitter.addObservedPoint(1, x,
f.value(x) + 0.01 * randomizer.nextGaussian());
}
final double[] fitted = fitter.fit();
Assert.assertEquals(a, fitted[0], 7.6e-4);
Assert.assertEquals(w, fitted[1], 2.7e-3);
Assert.assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1.3e-2);
}
@Test
public void testTinyVariationsData() {
Random randomizer = new Random(64925784252l);
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
for (double x = 0.0; x < 10.0; x += 0.1) {
fitter.addObservedPoint(1, x, 1e-7 * randomizer.nextGaussian());
}
fitter.fit();
// This test serves to cover the part of the code of "guessAOmega"
// when the algorithm using integrals fails.
}
@Test
public void testInitialGuess() {
Random randomizer = new Random(45314242l);
final double a = 0.2;
final double w = 3.4;
final double p = 4.1;
HarmonicOscillator f = new HarmonicOscillator(a, w, p);
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
for (double x = 0.0; x < 10.0; x += 0.1) {
fitter.addObservedPoint(1, x,
f.value(x) + 0.01 * randomizer.nextGaussian());
}
final double[] fitted = fitter.fit(new double[] { 0.15, 3.6, 4.5 });
Assert.assertEquals(a, fitted[0], 1.2e-3);
Assert.assertEquals(w, fitted[1], 3.3e-3);
Assert.assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1.7e-2);
}
@Test
public void testUnsorted() {
Random randomizer = new Random(64925784252l);
final double a = 0.2;
final double w = 3.4;
final double p = 4.1;
HarmonicOscillator f = new HarmonicOscillator(a, w, p);
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
// build a regularly spaced array of measurements
int size = 100;
double[] xTab = new double[size];
double[] yTab = new double[size];
for (int i = 0; i < size; ++i) {
xTab[i] = 0.1 * i;
yTab[i] = f.value(xTab[i]) + 0.01 * randomizer.nextGaussian();
}
// shake it
for (int i = 0; i < size; ++i) {
int i1 = randomizer.nextInt(size);
int i2 = randomizer.nextInt(size);
double xTmp = xTab[i1];
double yTmp = yTab[i1];
xTab[i1] = xTab[i2];
yTab[i1] = yTab[i2];
xTab[i2] = xTmp;
yTab[i2] = yTmp;
}
// pass it to the fitter
for (int i = 0; i < size; ++i) {
fitter.addObservedPoint(1, xTab[i], yTab[i]);
}
final double[] fitted = fitter.fit();
Assert.assertEquals(a, fitted[0], 7.6e-4);
Assert.assertEquals(w, fitted[1], 3.5e-3);
Assert.assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1.5e-2);
}
@Test(expected=MathIllegalStateException.class)
public void testMath844() {
final double[] y = { 0, 1, 2, 3, 2, 1,
0, -1, -2, -3, -2, -1,
0, 1, 2, 3, 2, 1,
0, -1, -2, -3, -2, -1,
0, 1, 2, 3, 2, 1, 0 };
final int len = y.length;
final WeightedObservedPoint[] points = new WeightedObservedPoint[len];
for (int i = 0; i < len; i++) {
points[i] = new WeightedObservedPoint(1, i, y[i]);
}
// The guesser fails because the function is far from an harmonic
// function: It is a triangular periodic function with amplitude 3
// and period 12, and all sample points are taken at integer abscissae
// so function values all belong to the integer subset {-3, -2, -1, 0,
// 1, 2, 3}.
final HarmonicFitter.ParameterGuesser guesser
= new HarmonicFitter.ParameterGuesser(points);
}
}
././@LongLink 100644 0 0 154 12126630646 10261 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/fitting/PolynomialFitterTe100644 1750 1750 27744 12126627670 32525 0 ustar luc luc 0 0 // 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.math3.optimization.fitting;
import java.util.Random;
import org.apache.commons.math3.analysis.polynomials.PolynomialFunction;
import org.apache.commons.math3.analysis.polynomials.PolynomialFunction.Parametric;
import org.apache.commons.math3.exception.ConvergenceException;
import org.apache.commons.math3.exception.TooManyEvaluationsException;
import org.apache.commons.math3.optimization.DifferentiableMultivariateVectorOptimizer;
import org.apache.commons.math3.optimization.general.GaussNewtonOptimizer;
import org.apache.commons.math3.optimization.general.LevenbergMarquardtOptimizer;
import org.apache.commons.math3.optimization.SimpleVectorValueChecker;
import org.apache.commons.math3.util.FastMath;
import org.apache.commons.math3.distribution.RealDistribution;
import org.apache.commons.math3.distribution.UniformRealDistribution;
import org.apache.commons.math3.TestUtils;
import org.junit.Test;
import org.junit.Assert;
/**
* Test for class {@link CurveFitter} where the function to fit is a
* polynomial.
*/
public class PolynomialFitterTest {
@Test
public void testFit() {
final RealDistribution rng = new UniformRealDistribution(-100, 100);
rng.reseedRandomGenerator(64925784252L);
final LevenbergMarquardtOptimizer optim = new LevenbergMarquardtOptimizer();
final PolynomialFitter fitter = new PolynomialFitter(optim);
final double[] coeff = { 12.9, -3.4, 2.1 }; // 12.9 - 3.4 x + 2.1 x^2
final PolynomialFunction f = new PolynomialFunction(coeff);
// Collect data from a known polynomial.
for (int i = 0; i < 100; i++) {
final double x = rng.sample();
fitter.addObservedPoint(x, f.value(x));
}
// Start fit from initial guesses that are far from the optimal values.
final double[] best = fitter.fit(new double[] { -1e-20, 3e15, -5e25 });
TestUtils.assertEquals("best != coeff", coeff, best, 1e-12);
}
@Test
public void testNoError() {
Random randomizer = new Random(64925784252l);
for (int degree = 1; degree < 10; ++degree) {
PolynomialFunction p = buildRandomPolynomial(degree, randomizer);
PolynomialFitter fitter = new PolynomialFitter(new LevenbergMarquardtOptimizer());
for (int i = 0; i <= degree; ++i) {
fitter.addObservedPoint(1.0, i, p.value(i));
}
final double[] init = new double[degree + 1];
PolynomialFunction fitted = new PolynomialFunction(fitter.fit(init));
for (double x = -1.0; x < 1.0; x += 0.01) {
double error = FastMath.abs(p.value(x) - fitted.value(x)) /
(1.0 + FastMath.abs(p.value(x)));
Assert.assertEquals(0.0, error, 1.0e-6);
}
}
}
@Test
public void testSmallError() {
Random randomizer = new Random(53882150042l);
double maxError = 0;
for (int degree = 0; degree < 10; ++degree) {
PolynomialFunction p = buildRandomPolynomial(degree, randomizer);
PolynomialFitter fitter = new PolynomialFitter(new LevenbergMarquardtOptimizer());
for (double x = -1.0; x < 1.0; x += 0.01) {
fitter.addObservedPoint(1.0, x,
p.value(x) + 0.1 * randomizer.nextGaussian());
}
final double[] init = new double[degree + 1];
PolynomialFunction fitted = new PolynomialFunction(fitter.fit(init));
for (double x = -1.0; x < 1.0; x += 0.01) {
double error = FastMath.abs(p.value(x) - fitted.value(x)) /
(1.0 + FastMath.abs(p.value(x)));
maxError = FastMath.max(maxError, error);
Assert.assertTrue(FastMath.abs(error) < 0.1);
}
}
Assert.assertTrue(maxError > 0.01);
}
@Test
public void testMath798() {
final double tol = 1e-14;
final SimpleVectorValueChecker checker = new SimpleVectorValueChecker(tol, tol);
final double[] init = new double[] { 0, 0 };
final int maxEval = 3;
final double[] lm = doMath798(new LevenbergMarquardtOptimizer(checker), maxEval, init);
final double[] gn = doMath798(new GaussNewtonOptimizer(checker), maxEval, init);
for (int i = 0; i <= 1; i++) {
Assert.assertEquals(lm[i], gn[i], tol);
}
}
/**
* This test shows that the user can set the maximum number of iterations
* to avoid running for too long.
* But in the test case, the real problem is that the tolerance is way too
* stringent.
*/
@Test(expected=TooManyEvaluationsException.class)
public void testMath798WithToleranceTooLow() {
final double tol = 1e-100;
final SimpleVectorValueChecker checker = new SimpleVectorValueChecker(tol, tol);
final double[] init = new double[] { 0, 0 };
final int maxEval = 10000; // Trying hard to fit.
final double[] gn = doMath798(new GaussNewtonOptimizer(checker), maxEval, init);
}
/**
* This test shows that the user can set the maximum number of iterations
* to avoid running for too long.
* Even if the real problem is that the tolerance is way too stringent, it
* is possible to get the best solution so far, i.e. a checker will return
* the point when the maximum iteration count has been reached.
*/
@Test
public void testMath798WithToleranceTooLowButNoException() {
final double tol = 1e-100;
final double[] init = new double[] { 0, 0 };
final int maxEval = 10000; // Trying hard to fit.
final SimpleVectorValueChecker checker = new SimpleVectorValueChecker(tol, tol, maxEval);
final double[] lm = doMath798(new LevenbergMarquardtOptimizer(checker), maxEval, init);
final double[] gn = doMath798(new GaussNewtonOptimizer(checker), maxEval, init);
for (int i = 0; i <= 1; i++) {
Assert.assertEquals(lm[i], gn[i], 1e-15);
}
}
/**
* @param optimizer Optimizer.
* @param maxEval Maximum number of function evaluations.
* @param init First guess.
* @return the solution found by the given optimizer.
*/
private double[] doMath798(DifferentiableMultivariateVectorOptimizer optimizer,
int maxEval,
double[] init) {
final CurveFitter
*
* @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests)
* @author Burton S. Garbow (original fortran minpack tests)
* @author Kenneth E. Hillstrom (original fortran minpack tests)
* @author Jorge J. More (original fortran minpack tests)
* @author Luc Maisonobe (non-minpack tests and minpack tests Java translation)
*/
public class MultivariateDifferentiableVectorMultiStartOptimizerTest {
@Test
public void testTrivial() {
LinearProblem problem =
new LinearProblem(new double[][] { { 2 } }, new double[] { 3 });
// TODO: the wrapper around GaussNewtonOptimizer is a temporary hack for
// version 3.1 of the library. It should be removed when GaussNewtonOptimizer
// will officialy be declared as implementing MultivariateDifferentiableVectorOptimizer
MultivariateDifferentiableVectorOptimizer underlyingOptimizer =
new MultivariateDifferentiableVectorOptimizer() {
private GaussNewtonOptimizer gn =
new GaussNewtonOptimizer(true,
new SimpleVectorValueChecker(1.0e-6, 1.0e-6));
public PointVectorValuePair optimize(int maxEval,
MultivariateDifferentiableVectorFunction f,
double[] target,
double[] weight,
double[] startPoint) {
return gn.optimize(maxEval, f, target, weight, startPoint);
}
public int getMaxEvaluations() {
return gn.getMaxEvaluations();
}
public int getEvaluations() {
return gn.getEvaluations();
}
public ConvergenceChecker
*
* Minpack Copyright Notice (1999) University of Chicago.
* All rights reserved
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
This product includes software developed by the University of
* Chicago, as Operator of Argonne National Laboratory.
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
* where {@code N(mean, sigma)} is a Gaussian distribution with the
* given mean and standard deviation.
*
* @param a Slope.
* @param b Intercept.
* @param sigma Standard deviation on the y-coordinate of the point.
* @param lo Lowest value of the x-coordinate.
* @param hi Highest value of the x-coordinate.
* @param seed RNG seed.
*/
public RandomStraightLinePointGenerator(double a,
double b,
double sigma,
double lo,
double hi,
long seed) {
final RandomGenerator rng = new Well44497b(seed);
slope = a;
intercept = b;
error = new NormalDistribution(rng, 0, sigma,
NormalDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
x = new UniformRealDistribution(rng, lo, hi,
UniformRealDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
}
/**
* Point generator.
*
* @param n Number of points to create.
* @return the cloud of {@code n} points.
*/
public Point2D.Double[] generate(int n) {
final Point2D.Double[] cloud = new Point2D.Double[n];
for (int i = 0; i < n; i++) {
cloud[i] = create();
}
return cloud;
}
/**
* Create one point.
*
* @return a point.
*/
private Point2D.Double create() {
final double abscissa = x.sample();
final double yModel = slope * abscissa + intercept;
final double ordinate = yModel + error.sample();
return new Point2D.Double(abscissa, ordinate);
}
}
././@LongLink 100644 0 0 171 12126630646 10260 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/general/AbstractLeastSquaresOptimizerTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/general/AbstractLeastSquar100644 1750 1750 10302 12126627671 32433 0 ustar luc luc 0 0 /*
* 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.math3.optimization.general;
import java.io.IOException;
import java.util.Arrays;
import org.junit.Assert;
import org.apache.commons.math3.optimization.PointVectorValuePair;
import org.apache.commons.math3.util.FastMath;
import org.junit.Test;
public class AbstractLeastSquaresOptimizerTest {
public static AbstractLeastSquaresOptimizer createOptimizer() {
return new AbstractLeastSquaresOptimizer(null) {
@Override
protected PointVectorValuePair doOptimize() {
final double[] params = getStartPoint();
final double[] res = computeResiduals(computeObjectiveValue(params));
setCost(computeCost(res));
return new PointVectorValuePair(params, null);
}
};
}
@Test
public void testGetChiSquare() throws IOException {
final StatisticalReferenceDataset dataset;
dataset = StatisticalReferenceDatasetFactory.createKirby2();
final AbstractLeastSquaresOptimizer optimizer;
optimizer = createOptimizer();
final double[] a = dataset.getParameters();
final double[] y = dataset.getData()[1];
final double[] w = new double[y.length];
Arrays.fill(w, 1.0);
optimizer.optimize(1, dataset.getLeastSquaresProblem(), y, w, a);
final double expected = dataset.getResidualSumOfSquares();
final double actual = optimizer.getChiSquare();
Assert.assertEquals(dataset.getName(), expected, actual,
1E-11 * expected);
}
@Test
public void testGetRMS() throws IOException {
final StatisticalReferenceDataset dataset;
dataset = StatisticalReferenceDatasetFactory.createKirby2();
final AbstractLeastSquaresOptimizer optimizer;
optimizer = createOptimizer();
final double[] a = dataset.getParameters();
final double[] y = dataset.getData()[1];
final double[] w = new double[y.length];
Arrays.fill(w, 1.0);
optimizer.optimize(1, dataset.getLeastSquaresProblem(), y, w, a);
final double expected = FastMath
.sqrt(dataset.getResidualSumOfSquares() /
dataset.getNumObservations());
final double actual = optimizer.getRMS();
Assert.assertEquals(dataset.getName(), expected, actual,
1E-11 * expected);
}
@Test
public void testComputeSigma() throws IOException {
final StatisticalReferenceDataset dataset;
dataset = StatisticalReferenceDatasetFactory.createKirby2();
final AbstractLeastSquaresOptimizer optimizer;
optimizer = createOptimizer();
final double[] a = dataset.getParameters();
final double[] y = dataset.getData()[1];
final double[] w = new double[y.length];
Arrays.fill(w, 1.0);
final int dof = y.length - a.length;
final PointVectorValuePair optimum = optimizer.optimize(1, dataset.getLeastSquaresProblem(), y, w, a);
final double[] sig = optimizer.computeSigma(optimum.getPoint(), 1e-14);
final double[] expected = dataset.getParametersStandardDeviations();
for (int i = 0; i < sig.length; i++) {
final double actual = FastMath.sqrt(optimizer.getChiSquare() / dof) * sig[i];
Assert.assertEquals(dataset.getName() + ", parameter #" + i,
expected[i], actual, 1e-7 * expected[i]);
}
}
}
commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/general/CircleScalar.java 100644 1750 1750 6001 12126627671 32113 0 ustar luc luc 0 0 /*
* 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.math3.optimization.general;
import java.util.ArrayList;
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableFunction;
import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
/**
* Class used in the tests.
*/
public class CircleScalar implements MultivariateDifferentiableFunction {
private ArrayList
* y = a x + b + N(0, error)
*
* Not enabled by default, as the class name does not end with "Test".
*
* Invoke by running
*
* or by running
*
* mvn test -Dtest=AbstractLeastSquaresOptimizerTestValidation
*
*/
public class AbstractLeastSquaresOptimizerTestValidation {
private static final int MONTE_CARLO_RUNS = Integer.parseInt(System.getProperty("mcRuns",
"100"));
/**
* Using a Monte-Carlo procedure, this test checks the error estimations
* as provided by the square-root of the diagonal elements of the
* covariance matrix.
*
* mvn test -Dtest=AbstractLeastSquaresOptimizerTestValidation -DargLine="-DmcRuns=1234 -server"
*
* The test generates sets of observations, each sampled from
* a Gaussian distribution.
*
* The optimization problem solved is defined in class
* {@link StraightLineProblem}.
*
* The output (on stdout) will be a table summarizing the distribution
* of parameters generated by the Monte-Carlo process and by the direct
* estimation provided by the diagonal elements of the covariance matrix.
*/
@Test
public void testParametersErrorMonteCarloObservations() {
// Error on the observations.
final double yError = 15;
// True values of the parameters.
final double slope = 123.456;
final double offset = -98.765;
// Samples generator.
final RandomStraightLinePointGenerator lineGenerator
= new RandomStraightLinePointGenerator(slope, offset,
yError,
-1e3, 1e4,
138577L);
// Number of observations.
final int numObs = 100; // XXX Should be a command-line option.
// number of parameters.
final int numParams = 2;
// Parameters found for each of Monte-Carlo run.
final SummaryStatistics[] paramsFoundByDirectSolution = new SummaryStatistics[numParams];
// Sigma estimations (square-root of the diagonal elements of the
// covariance matrix), for each Monte-Carlo run.
final SummaryStatistics[] sigmaEstimate = new SummaryStatistics[numParams];
// Initialize statistics accumulators.
for (int i = 0; i < numParams; i++) {
paramsFoundByDirectSolution[i] = new SummaryStatistics();
sigmaEstimate[i] = new SummaryStatistics();
}
// Dummy optimizer (to compute the covariance matrix).
final AbstractLeastSquaresOptimizer optim = new DummyOptimizer();
final double[] init = { slope, offset };
// Monte-Carlo (generates many sets of observations).
final int mcRepeat = MONTE_CARLO_RUNS;
int mcCount = 0;
while (mcCount < mcRepeat) {
// Observations.
final Point2D.Double[] obs = lineGenerator.generate(numObs);
final StraightLineProblem problem = new StraightLineProblem(yError);
for (int i = 0; i < numObs; i++) {
final Point2D.Double p = obs[i];
problem.addPoint(p.x, p.y);
}
// Direct solution (using simple regression).
final double[] regress = problem.solve();
// Estimation of the standard deviation (diagonal elements of the
// covariance matrix).
final PointVectorValuePair optimum = optim.optimize(Integer.MAX_VALUE,
problem, problem.target(), problem.weight(), init);
final double[] sigma = optim.computeSigma(optimum.getPoint(), 1e-14);
// Accumulate statistics.
for (int i = 0; i < numParams; i++) {
paramsFoundByDirectSolution[i].addValue(regress[i]);
sigmaEstimate[i].addValue(sigma[i]);
}
// Next Monte-Carlo.
++mcCount;
}
// Print statistics.
final String line = "--------------------------------------------------------------";
System.out.println(" True value Mean Std deviation");
for (int i = 0; i < numParams; i++) {
System.out.println(line);
System.out.println("Parameter #" + i);
StatisticalSummary s = paramsFoundByDirectSolution[i].getSummary();
System.out.printf(" %+.6e %+.6e %+.6e\n",
init[i],
s.getMean(),
s.getStandardDeviation());
s = sigmaEstimate[i].getSummary();
System.out.printf("sigma: %+.6e (%+.6e)\n",
s.getMean(),
s.getStandardDeviation());
}
System.out.println(line);
// Check the error estimation.
for (int i = 0; i < numParams; i++) {
Assert.assertEquals(paramsFoundByDirectSolution[i].getSummary().getStandardDeviation(),
sigmaEstimate[i].getSummary().getMean(),
8e-2);
}
}
/**
* In this test, the set of observations is fixed.
* Using a Monte-Carlo procedure, it generates sets of parameters,
* and determine the parameter change that will result in the
* normalized chi-square becoming larger by one than the value from
* the best fit solution.
*
* The optimization problem solved is defined in class
* {@link StraightLineProblem}.
*
* The output (on stdout) will be a list of lines containing:
*
*
* The output is separated into two blocks (with a blank line between
* them); the first block will contain all parameter sets for which
* {@code chi2 < chi2_b + 1}
* and the second block, all sets for which
* {@code chi2 >= chi2_b + 1}
* where {@code chi2_b} is the lowest chi-square (corresponding to the
* best solution).
*/
@Test
public void testParametersErrorMonteCarloParameters() {
// Error on the observations.
final double yError = 15;
// True values of the parameters.
final double slope = 123.456;
final double offset = -98.765;
// Samples generator.
final RandomStraightLinePointGenerator lineGenerator
= new RandomStraightLinePointGenerator(slope, offset,
yError,
-1e3, 1e4,
13839013L);
// Number of observations.
final int numObs = 10;
// number of parameters.
final int numParams = 2;
// Create a single set of observations.
final Point2D.Double[] obs = lineGenerator.generate(numObs);
final StraightLineProblem problem = new StraightLineProblem(yError);
for (int i = 0; i < numObs; i++) {
final Point2D.Double p = obs[i];
problem.addPoint(p.x, p.y);
}
// Direct solution (using simple regression).
final double[] regress = problem.solve();
// Dummy optimizer (to compute the chi-square).
final AbstractLeastSquaresOptimizer optim = new DummyOptimizer();
final double[] init = { slope, offset };
// Get chi-square of the best parameters set for the given set of
// observations.
final double bestChi2N = getChi2N(optim, problem, regress);
final double[] sigma = optim.computeSigma(regress, 1e-14);
// Monte-Carlo (generates a grid of parameters).
final int mcRepeat = MONTE_CARLO_RUNS;
final int gridSize = (int) FastMath.sqrt(mcRepeat);
// Parameters found for each of Monte-Carlo run.
// Index 0 = slope
// Index 1 = offset
// Index 2 = normalized chi2
final List
*
* @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests)
* @author Burton S. Garbow (original fortran minpack tests)
* @author Kenneth E. Hillstrom (original fortran minpack tests)
* @author Jorge J. More (original fortran minpack tests)
* @author Luc Maisonobe (non-minpack tests and minpack tests Java translation)
*/
public class NonLinearConjugateGradientOptimizerTest {
@Test
public void testTrivial() {
LinearProblem problem =
new LinearProblem(new double[][] { { 2 } }, new double[] { 3 });
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6));
PointValuePair optimum =
optimizer.optimize(100, problem, GoalType.MINIMIZE, new double[] { 0 });
Assert.assertEquals(1.5, optimum.getPoint()[0], 1.0e-10);
Assert.assertEquals(0.0, optimum.getValue(), 1.0e-10);
}
@Test
public void testColumnsPermutation() {
LinearProblem problem =
new LinearProblem(new double[][] { { 1.0, -1.0 }, { 0.0, 2.0 }, { 1.0, -2.0 } },
new double[] { 4.0, 6.0, 1.0 });
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6));
PointValuePair optimum =
optimizer.optimize(100, problem, GoalType.MINIMIZE, new double[] { 0, 0 });
Assert.assertEquals(7.0, optimum.getPoint()[0], 1.0e-10);
Assert.assertEquals(3.0, optimum.getPoint()[1], 1.0e-10);
Assert.assertEquals(0.0, optimum.getValue(), 1.0e-10);
}
@Test
public void testNoDependency() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 2, 0, 0, 0, 0, 0 },
{ 0, 2, 0, 0, 0, 0 },
{ 0, 0, 2, 0, 0, 0 },
{ 0, 0, 0, 2, 0, 0 },
{ 0, 0, 0, 0, 2, 0 },
{ 0, 0, 0, 0, 0, 2 }
}, new double[] { 0.0, 1.1, 2.2, 3.3, 4.4, 5.5 });
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6));
PointValuePair optimum =
optimizer.optimize(100, problem, GoalType.MINIMIZE, new double[] { 0, 0, 0, 0, 0, 0 });
for (int i = 0; i < problem.target.length; ++i) {
Assert.assertEquals(0.55 * i, optimum.getPoint()[i], 1.0e-10);
}
}
@Test
public void testOneSet() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 1, 0, 0 },
{ -1, 1, 0 },
{ 0, -1, 1 }
}, new double[] { 1, 1, 1});
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6));
PointValuePair optimum =
optimizer.optimize(100, problem, GoalType.MINIMIZE, new double[] { 0, 0, 0 });
Assert.assertEquals(1.0, optimum.getPoint()[0], 1.0e-10);
Assert.assertEquals(2.0, optimum.getPoint()[1], 1.0e-10);
Assert.assertEquals(3.0, optimum.getPoint()[2], 1.0e-10);
}
@Test
public void testTwoSets() {
final double epsilon = 1.0e-7;
LinearProblem problem = new LinearProblem(new double[][] {
{ 2, 1, 0, 4, 0, 0 },
{ -4, -2, 3, -7, 0, 0 },
{ 4, 1, -2, 8, 0, 0 },
{ 0, -3, -12, -1, 0, 0 },
{ 0, 0, 0, 0, epsilon, 1 },
{ 0, 0, 0, 0, 1, 1 }
}, new double[] { 2, -9, 2, 2, 1 + epsilon * epsilon, 2});
final Preconditioner preconditioner
= new Preconditioner() {
public double[] precondition(double[] point, double[] r) {
double[] d = r.clone();
d[0] /= 72.0;
d[1] /= 30.0;
d[2] /= 314.0;
d[3] /= 260.0;
d[4] /= 2 * (1 + epsilon * epsilon);
d[5] /= 4.0;
return d;
}
};
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-13, 1e-13),
new BrentSolver(),
preconditioner);
PointValuePair optimum =
optimizer.optimize(100, problem, GoalType.MINIMIZE, new double[] { 0, 0, 0, 0, 0, 0 });
Assert.assertEquals( 3.0, optimum.getPoint()[0], 1.0e-10);
Assert.assertEquals( 4.0, optimum.getPoint()[1], 1.0e-10);
Assert.assertEquals(-1.0, optimum.getPoint()[2], 1.0e-10);
Assert.assertEquals(-2.0, optimum.getPoint()[3], 1.0e-10);
Assert.assertEquals( 1.0 + epsilon, optimum.getPoint()[4], 1.0e-10);
Assert.assertEquals( 1.0 - epsilon, optimum.getPoint()[5], 1.0e-10);
}
@Test
public void testNonInversible() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 1, 2, -3 },
{ 2, 1, 3 },
{ -3, 0, -9 }
}, new double[] { 1, 1, 1 });
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6));
PointValuePair optimum =
optimizer.optimize(100, problem, GoalType.MINIMIZE, new double[] { 0, 0, 0 });
Assert.assertTrue(optimum.getValue() > 0.5);
}
@Test
public void testIllConditioned() {
LinearProblem problem1 = new LinearProblem(new double[][] {
{ 10.0, 7.0, 8.0, 7.0 },
{ 7.0, 5.0, 6.0, 5.0 },
{ 8.0, 6.0, 10.0, 9.0 },
{ 7.0, 5.0, 9.0, 10.0 }
}, new double[] { 32, 23, 33, 31 });
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-13, 1e-13),
new BrentSolver(1e-15, 1e-15));
PointValuePair optimum1 =
optimizer.optimize(200, problem1, GoalType.MINIMIZE, new double[] { 0, 1, 2, 3 });
Assert.assertEquals(1.0, optimum1.getPoint()[0], 1.0e-4);
Assert.assertEquals(1.0, optimum1.getPoint()[1], 1.0e-4);
Assert.assertEquals(1.0, optimum1.getPoint()[2], 1.0e-4);
Assert.assertEquals(1.0, optimum1.getPoint()[3], 1.0e-4);
LinearProblem problem2 = new LinearProblem(new double[][] {
{ 10.00, 7.00, 8.10, 7.20 },
{ 7.08, 5.04, 6.00, 5.00 },
{ 8.00, 5.98, 9.89, 9.00 },
{ 6.99, 4.99, 9.00, 9.98 }
}, new double[] { 32, 23, 33, 31 });
PointValuePair optimum2 =
optimizer.optimize(200, problem2, GoalType.MINIMIZE, new double[] { 0, 1, 2, 3 });
Assert.assertEquals(-81.0, optimum2.getPoint()[0], 1.0e-1);
Assert.assertEquals(137.0, optimum2.getPoint()[1], 1.0e-1);
Assert.assertEquals(-34.0, optimum2.getPoint()[2], 1.0e-1);
Assert.assertEquals( 22.0, optimum2.getPoint()[3], 1.0e-1);
}
@Test
public void testMoreEstimatedParametersSimple() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 3.0, 2.0, 0.0, 0.0 },
{ 0.0, 1.0, -1.0, 1.0 },
{ 2.0, 0.0, 1.0, 0.0 }
}, new double[] { 7.0, 3.0, 5.0 });
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6));
PointValuePair optimum =
optimizer.optimize(100, problem, GoalType.MINIMIZE, new double[] { 7, 6, 5, 4 });
Assert.assertEquals(0, optimum.getValue(), 1.0e-10);
}
@Test
public void testMoreEstimatedParametersUnsorted() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 },
{ 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 },
{ 0.0, 0.0, 0.0, 0.0, 1.0, -1.0 },
{ 0.0, 0.0, -1.0, 1.0, 0.0, 1.0 },
{ 0.0, 0.0, 0.0, -1.0, 1.0, 0.0 }
}, new double[] { 3.0, 12.0, -1.0, 7.0, 1.0 });
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6));
PointValuePair optimum =
optimizer.optimize(100, problem, GoalType.MINIMIZE, new double[] { 2, 2, 2, 2, 2, 2 });
Assert.assertEquals(0, optimum.getValue(), 1.0e-10);
}
@Test
public void testRedundantEquations() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 1.0, 1.0 },
{ 1.0, -1.0 },
{ 1.0, 3.0 }
}, new double[] { 3.0, 1.0, 5.0 });
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6));
PointValuePair optimum =
optimizer.optimize(100, problem, GoalType.MINIMIZE, new double[] { 1, 1 });
Assert.assertEquals(2.0, optimum.getPoint()[0], 1.0e-8);
Assert.assertEquals(1.0, optimum.getPoint()[1], 1.0e-8);
}
@Test
public void testInconsistentEquations() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 1.0, 1.0 },
{ 1.0, -1.0 },
{ 1.0, 3.0 }
}, new double[] { 3.0, 1.0, 4.0 });
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-6, 1e-6));
PointValuePair optimum =
optimizer.optimize(100, problem, GoalType.MINIMIZE, new double[] { 1, 1 });
Assert.assertTrue(optimum.getValue() > 0.1);
}
@Test
public void testCircleFitting() {
CircleScalar circle = new CircleScalar();
circle.addPoint( 30.0, 68.0);
circle.addPoint( 50.0, -6.0);
circle.addPoint(110.0, -20.0);
circle.addPoint( 35.0, 15.0);
circle.addPoint( 45.0, 97.0);
NonLinearConjugateGradientOptimizer optimizer =
new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE,
new SimpleValueChecker(1e-30, 1e-30),
new BrentSolver(1e-15, 1e-13));
PointValuePair optimum =
optimizer.optimize(100, circle, GoalType.MINIMIZE, new double[] { 98.680, 47.345 });
Vector2D center = new Vector2D(optimum.getPointRef()[0], optimum.getPointRef()[1]);
Assert.assertEquals(69.960161753, circle.getRadius(center), 1.0e-8);
Assert.assertEquals(96.075902096, center.getX(), 1.0e-8);
Assert.assertEquals(48.135167894, center.getY(), 1.0e-8);
}
private static class LinearProblem implements MultivariateDifferentiableFunction, Serializable {
private static final long serialVersionUID = 703247177355019415L;
final RealMatrix factors;
final double[] target;
public LinearProblem(double[][] factors, double[] target) {
this.factors = new BlockRealMatrix(factors);
this.target = target;
}
public double value(double[] variables) {
double[] y = factors.operate(variables);
double sum = 0;
for (int i = 0; i < y.length; ++i) {
double ri = y[i] - target[i];
sum += ri * ri;
}
return sum;
}
public DerivativeStructure value(DerivativeStructure[] variables) {
DerivativeStructure[] y = new DerivativeStructure[factors.getRowDimension()];
for (int i = 0; i < y.length; ++i) {
y[i] = variables[0].getField().getZero();
for (int j = 0; j < factors.getColumnDimension(); ++j) {
y[i] = y[i].add(variables[j].multiply(factors.getEntry(i, j)));
}
}
DerivativeStructure sum = variables[0].getField().getZero();
for (int i = 0; i < y.length; ++i) {
DerivativeStructure ri = y[i].subtract(target[i]);
sum = sum.add(ri.multiply(ri));
}
return sum;
}
}
}
././@LongLink 100644 0 0 167 12126630646 10265 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/general/LevenbergMarquardtOptimizerTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/general/LevenbergMarquardt100644 1750 1750 41603 12126627671 32465 0 ustar luc luc 0 0 /*
* 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.math3.optimization.general;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction;
import org.apache.commons.math3.exception.ConvergenceException;
import org.apache.commons.math3.exception.DimensionMismatchException;
import org.apache.commons.math3.exception.TooManyEvaluationsException;
import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
import org.apache.commons.math3.linear.SingularMatrixException;
import org.apache.commons.math3.optimization.PointVectorValuePair;
import org.apache.commons.math3.util.FastMath;
import org.apache.commons.math3.util.Precision;
import org.junit.Assert;
import org.junit.Test;
import org.junit.Ignore;
/**
*
*
* Minpack Copyright Notice (1999) University of Chicago.
* All rights reserved
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
This product includes software developed by the University of
* Chicago, as Operator of Argonne National Laboratory.
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests)
* @author Burton S. Garbow (original fortran minpack tests)
* @author Kenneth E. Hillstrom (original fortran minpack tests)
* @author Jorge J. More (original fortran minpack tests)
* @author Luc Maisonobe (non-minpack tests and minpack tests Java translation)
*/
public class LevenbergMarquardtOptimizerTest extends AbstractLeastSquaresOptimizerAbstractTest {
@Override
public AbstractLeastSquaresOptimizer createOptimizer() {
return new LevenbergMarquardtOptimizer();
}
@Override
@Test(expected=SingularMatrixException.class)
public void testNonInvertible() {
/*
* Overrides the method from parent class, since the default singularity
* threshold (1e-14) does not trigger the expected exception.
*/
LinearProblem problem = new LinearProblem(new double[][] {
{ 1, 2, -3 },
{ 2, 1, 3 },
{ -3, 0, -9 }
}, new double[] { 1, 1, 1 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum = optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0, 0 });
Assert.assertTrue(FastMath.sqrt(problem.target.length) * optimizer.getRMS() > 0.6);
optimizer.computeCovariances(optimum.getPoint(), 1.5e-14);
}
@Test
public void testControlParameters() {
CircleVectorial circle = new CircleVectorial();
circle.addPoint( 30.0, 68.0);
circle.addPoint( 50.0, -6.0);
circle.addPoint(110.0, -20.0);
circle.addPoint( 35.0, 15.0);
circle.addPoint( 45.0, 97.0);
checkEstimate(circle, 0.1, 10, 1.0e-14, 1.0e-16, 1.0e-10, false);
checkEstimate(circle, 0.1, 10, 1.0e-15, 1.0e-17, 1.0e-10, true);
checkEstimate(circle, 0.1, 5, 1.0e-15, 1.0e-16, 1.0e-10, true);
circle.addPoint(300, -300);
checkEstimate(circle, 0.1, 20, 1.0e-18, 1.0e-16, 1.0e-10, true);
}
private void checkEstimate(MultivariateDifferentiableVectorFunction problem,
double initialStepBoundFactor, int maxCostEval,
double costRelativeTolerance, double parRelativeTolerance,
double orthoTolerance, boolean shouldFail) {
try {
LevenbergMarquardtOptimizer optimizer
= new LevenbergMarquardtOptimizer(initialStepBoundFactor,
costRelativeTolerance,
parRelativeTolerance,
orthoTolerance,
Precision.SAFE_MIN);
optimizer.optimize(maxCostEval, problem, new double[] { 0, 0, 0, 0, 0 },
new double[] { 1, 1, 1, 1, 1 },
new double[] { 98.680, 47.345 });
Assert.assertTrue(!shouldFail);
} catch (DimensionMismatchException ee) {
Assert.assertTrue(shouldFail);
} catch (TooManyEvaluationsException ee) {
Assert.assertTrue(shouldFail);
}
}
// Test is skipped because it fails with the latest code update.
@Ignore@Test
public void testMath199() {
try {
QuadraticProblem problem = new QuadraticProblem();
problem.addPoint (0, -3.182591015485607);
problem.addPoint (1, -2.5581184967730577);
problem.addPoint (2, -2.1488478161387325);
problem.addPoint (3, -1.9122489313410047);
problem.addPoint (4, 1.7785661310051026);
LevenbergMarquardtOptimizer optimizer
= new LevenbergMarquardtOptimizer(100, 1e-10, 1e-10, 1e-10, 0);
optimizer.optimize(100, problem,
new double[] { 0, 0, 0, 0, 0 },
new double[] { 0.0, 4.4e-323, 1.0, 4.4e-323, 0.0 },
new double[] { 0, 0, 0 });
Assert.fail("an exception should have been thrown");
} catch (ConvergenceException ee) {
// expected behavior
}
}
/**
* Non-linear test case: fitting of decay curve (from Chapter 8 of
* Bevington's textbook, "Data reduction and analysis for the physical sciences").
* XXX The expected ("reference") values may not be accurate and the tolerance too
* relaxed for this test to be currently really useful (the issue is under
* investigation).
*/
@Test
public void testBevington() {
final double[][] dataPoints = {
// column 1 = times
{ 15, 30, 45, 60, 75, 90, 105, 120, 135, 150,
165, 180, 195, 210, 225, 240, 255, 270, 285, 300,
315, 330, 345, 360, 375, 390, 405, 420, 435, 450,
465, 480, 495, 510, 525, 540, 555, 570, 585, 600,
615, 630, 645, 660, 675, 690, 705, 720, 735, 750,
765, 780, 795, 810, 825, 840, 855, 870, 885, },
// column 2 = measured counts
{ 775, 479, 380, 302, 185, 157, 137, 119, 110, 89,
74, 61, 66, 68, 48, 54, 51, 46, 55, 29,
28, 37, 49, 26, 35, 29, 31, 24, 25, 35,
24, 30, 26, 28, 21, 18, 20, 27, 17, 17,
14, 17, 24, 11, 22, 17, 12, 10, 13, 16,
9, 9, 14, 21, 17, 13, 12, 18, 10, },
};
final BevingtonProblem problem = new BevingtonProblem();
final int len = dataPoints[0].length;
final double[] weights = new double[len];
for (int i = 0; i < len; i++) {
problem.addPoint(dataPoints[0][i],
dataPoints[1][i]);
weights[i] = 1 / dataPoints[1][i];
}
final LevenbergMarquardtOptimizer optimizer
= new LevenbergMarquardtOptimizer();
final PointVectorValuePair optimum
= optimizer.optimize(100, problem, dataPoints[1], weights,
new double[] { 10, 900, 80, 27, 225 });
final double[] solution = optimum.getPoint();
final double[] expectedSolution = { 10.4, 958.3, 131.4, 33.9, 205.0 };
final double[][] covarMatrix = optimizer.computeCovariances(solution, 1e-14);
final double[][] expectedCovarMatrix = {
{ 3.38, -3.69, 27.98, -2.34, -49.24 },
{ -3.69, 2492.26, 81.89, -69.21, -8.9 },
{ 27.98, 81.89, 468.99, -44.22, -615.44 },
{ -2.34, -69.21, -44.22, 6.39, 53.80 },
{ -49.24, -8.9, -615.44, 53.8, 929.45 }
};
final int numParams = expectedSolution.length;
// Check that the computed solution is within the reference error range.
for (int i = 0; i < numParams; i++) {
final double error = FastMath.sqrt(expectedCovarMatrix[i][i]);
Assert.assertEquals("Parameter " + i, expectedSolution[i], solution[i], error);
}
// Check that each entry of the computed covariance matrix is within 10%
// of the reference matrix entry.
for (int i = 0; i < numParams; i++) {
for (int j = 0; j < numParams; j++) {
Assert.assertEquals("Covariance matrix [" + i + "][" + j + "]",
expectedCovarMatrix[i][j],
covarMatrix[i][j],
FastMath.abs(0.1 * expectedCovarMatrix[i][j]));
}
}
}
@Test
public void testCircleFitting2() {
final double xCenter = 123.456;
final double yCenter = 654.321;
final double xSigma = 10;
final double ySigma = 15;
final double radius = 111.111;
// The test is extremely sensitive to the seed.
final long seed = 59421061L;
final RandomCirclePointGenerator factory
= new RandomCirclePointGenerator(xCenter, yCenter, radius,
xSigma, ySigma,
seed);
final CircleProblem circle = new CircleProblem(xSigma, ySigma);
final int numPoints = 10;
for (Vector2D p : factory.generate(numPoints)) {
circle.addPoint(p);
// System.out.println(p.x + " " + p.y);
}
// First guess for the center's coordinates and radius.
final double[] init = { 90, 659, 115 };
final LevenbergMarquardtOptimizer optimizer
= new LevenbergMarquardtOptimizer();
final PointVectorValuePair optimum = optimizer.optimize(100, circle,
circle.target(), circle.weight(),
init);
final double[] paramFound = optimum.getPoint();
// Retrieve errors estimation.
final double[][] covMatrix = optimizer.computeCovariances(paramFound, 1e-14);
final double[] asymptoticStandardErrorFound = optimizer.guessParametersErrors();
final double[] sigmaFound = new double[covMatrix.length];
for (int i = 0; i < covMatrix.length; i++) {
sigmaFound[i] = FastMath.sqrt(covMatrix[i][i]);
// System.out.println("i=" + i + " value=" + paramFound[i]
// + " sigma=" + sigmaFound[i]
// + " ase=" + asymptoticStandardErrorFound[i]);
}
// System.out.println("chi2=" + optimizer.getChiSquare());
// Check that the parameters are found within the assumed error bars.
Assert.assertEquals(xCenter, paramFound[0], asymptoticStandardErrorFound[0]);
Assert.assertEquals(yCenter, paramFound[1], asymptoticStandardErrorFound[1]);
Assert.assertEquals(radius, paramFound[2], asymptoticStandardErrorFound[2]);
}
private static class QuadraticProblem implements MultivariateDifferentiableVectorFunction, Serializable {
private static final long serialVersionUID = 7072187082052755854L;
private List
*
* Minpack Copyright Notice (1999) University of Chicago.
* All rights reserved
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
This product includes software developed by the University of
* Chicago, as Operator of Argonne National Laboratory.
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* The model functions are:
*
*
*/
class CircleProblem implements MultivariateDifferentiableVectorFunction {
/** Cloud of points assumed to be fitted by a circle. */
private final ArrayList
*
* @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests)
* @author Burton S. Garbow (original fortran minpack tests)
* @author Kenneth E. Hillstrom (original fortran minpack tests)
* @author Jorge J. More (original fortran minpack tests)
* @author Luc Maisonobe (non-minpack tests and minpack tests Java translation)
*/
public class GaussNewtonOptimizerTest
extends AbstractLeastSquaresOptimizerAbstractTest {
@Override
public AbstractLeastSquaresOptimizer createOptimizer() {
return new GaussNewtonOptimizer(new SimpleVectorValueChecker(1.0e-6, 1.0e-6));
}
@Override
@Test(expected = ConvergenceException.class)
public void testMoreEstimatedParametersSimple() {
/*
* Exception is expected with this optimizer
*/
super.testMoreEstimatedParametersSimple();
}
@Override
@Test(expected=ConvergenceException.class)
public void testMoreEstimatedParametersUnsorted() {
/*
* Exception is expected with this optimizer
*/
super.testMoreEstimatedParametersUnsorted();
}
@Test(expected=TooManyEvaluationsException.class)
public void testMaxEvaluations() throws Exception {
CircleVectorial circle = new CircleVectorial();
circle.addPoint( 30.0, 68.0);
circle.addPoint( 50.0, -6.0);
circle.addPoint(110.0, -20.0);
circle.addPoint( 35.0, 15.0);
circle.addPoint( 45.0, 97.0);
GaussNewtonOptimizer optimizer
= new GaussNewtonOptimizer(new SimpleVectorValueChecker(1.0e-30, 1.0e-30));
optimizer.optimize(100, circle, new double[] { 0, 0, 0, 0, 0 },
new double[] { 1, 1, 1, 1, 1 },
new double[] { 98.680, 47.345 });
}
@Override
@Test(expected=ConvergenceException.class)
public void testCircleFittingBadInit() {
/*
* This test does not converge with this optimizer.
*/
super.testCircleFittingBadInit();
}
@Override
@Test(expected = ConvergenceException.class)
public void testHahn1()
throws IOException {
/*
* TODO This test leads to a singular problem with the Gauss-Newton
* optimizer. This should be inquired.
*/
super.testHahn1();
}
}
././@LongLink 100644 0 0 201 12126630646 10252 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/general/AbstractLeastSquaresOptimizerAbstractTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/general/AbstractLeastSquar100644 1750 1750 62112 12126627671 32441 0 ustar luc luc 0 0 /*
* 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.math3.optimization.general;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction;
import org.apache.commons.math3.exception.ConvergenceException;
import org.apache.commons.math3.exception.DimensionMismatchException;
import org.apache.commons.math3.exception.NumberIsTooSmallException;
import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
import org.apache.commons.math3.linear.BlockRealMatrix;
import org.apache.commons.math3.linear.RealMatrix;
import org.apache.commons.math3.optimization.PointVectorValuePair;
import org.apache.commons.math3.util.FastMath;
import org.junit.Assert;
import org.junit.Test;
/**
*
*
* Minpack Copyright Notice (1999) University of Chicago.
* All rights reserved
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
This product includes software developed by the University of
* Chicago, as Operator of Argonne National Laboratory.
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests)
* @author Burton S. Garbow (original fortran minpack tests)
* @author Kenneth E. Hillstrom (original fortran minpack tests)
* @author Jorge J. More (original fortran minpack tests)
* @author Luc Maisonobe (non-minpack tests and minpack tests Java translation)
* @version $Id: AbstractLeastSquaresOptimizerAbstractTest.java 1407467 2012-11-09 14:30:49Z erans $
*/
public abstract class AbstractLeastSquaresOptimizerAbstractTest {
public abstract AbstractLeastSquaresOptimizer createOptimizer();
@Test
public void testTrivial() {
LinearProblem problem =
new LinearProblem(new double[][] { { 2 } }, new double[] { 3 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum =
optimizer.optimize(100, problem, problem.target, new double[] { 1 }, new double[] { 0 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
Assert.assertEquals(1.5, optimum.getPoint()[0], 1.0e-10);
Assert.assertEquals(3.0, optimum.getValue()[0], 1.0e-10);
try {
optimizer.guessParametersErrors();
Assert.fail("an exception should have been thrown");
} catch (NumberIsTooSmallException ee) {
// expected behavior
}
}
@Test
public void testQRColumnsPermutation() {
LinearProblem problem =
new LinearProblem(new double[][] { { 1.0, -1.0 }, { 0.0, 2.0 }, { 1.0, -2.0 } },
new double[] { 4.0, 6.0, 1.0 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum =
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
Assert.assertEquals(7.0, optimum.getPoint()[0], 1.0e-10);
Assert.assertEquals(3.0, optimum.getPoint()[1], 1.0e-10);
Assert.assertEquals(4.0, optimum.getValue()[0], 1.0e-10);
Assert.assertEquals(6.0, optimum.getValue()[1], 1.0e-10);
Assert.assertEquals(1.0, optimum.getValue()[2], 1.0e-10);
}
@Test
public void testNoDependency() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 2, 0, 0, 0, 0, 0 },
{ 0, 2, 0, 0, 0, 0 },
{ 0, 0, 2, 0, 0, 0 },
{ 0, 0, 0, 2, 0, 0 },
{ 0, 0, 0, 0, 2, 0 },
{ 0, 0, 0, 0, 0, 2 }
}, new double[] { 0.0, 1.1, 2.2, 3.3, 4.4, 5.5 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum =
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1, 1, 1, 1 },
new double[] { 0, 0, 0, 0, 0, 0 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
for (int i = 0; i < problem.target.length; ++i) {
Assert.assertEquals(0.55 * i, optimum.getPoint()[i], 1.0e-10);
}
}
@Test
public void testOneSet() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 1, 0, 0 },
{ -1, 1, 0 },
{ 0, -1, 1 }
}, new double[] { 1, 1, 1});
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum =
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0, 0 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
Assert.assertEquals(1.0, optimum.getPoint()[0], 1.0e-10);
Assert.assertEquals(2.0, optimum.getPoint()[1], 1.0e-10);
Assert.assertEquals(3.0, optimum.getPoint()[2], 1.0e-10);
}
@Test
public void testTwoSets() {
double epsilon = 1.0e-7;
LinearProblem problem = new LinearProblem(new double[][] {
{ 2, 1, 0, 4, 0, 0 },
{ -4, -2, 3, -7, 0, 0 },
{ 4, 1, -2, 8, 0, 0 },
{ 0, -3, -12, -1, 0, 0 },
{ 0, 0, 0, 0, epsilon, 1 },
{ 0, 0, 0, 0, 1, 1 }
}, new double[] { 2, -9, 2, 2, 1 + epsilon * epsilon, 2});
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum =
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1, 1, 1, 1 },
new double[] { 0, 0, 0, 0, 0, 0 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
Assert.assertEquals( 3.0, optimum.getPoint()[0], 1.0e-10);
Assert.assertEquals( 4.0, optimum.getPoint()[1], 1.0e-10);
Assert.assertEquals(-1.0, optimum.getPoint()[2], 1.0e-10);
Assert.assertEquals(-2.0, optimum.getPoint()[3], 1.0e-10);
Assert.assertEquals( 1.0 + epsilon, optimum.getPoint()[4], 1.0e-10);
Assert.assertEquals( 1.0 - epsilon, optimum.getPoint()[5], 1.0e-10);
}
@Test(expected=ConvergenceException.class)
public void testNonInvertible() throws Exception {
LinearProblem problem = new LinearProblem(new double[][] {
{ 1, 2, -3 },
{ 2, 1, 3 },
{ -3, 0, -9 }
}, new double[] { 1, 1, 1 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 0, 0, 0 });
}
@Test
public void testIllConditioned() {
LinearProblem problem1 = new LinearProblem(new double[][] {
{ 10.0, 7.0, 8.0, 7.0 },
{ 7.0, 5.0, 6.0, 5.0 },
{ 8.0, 6.0, 10.0, 9.0 },
{ 7.0, 5.0, 9.0, 10.0 }
}, new double[] { 32, 23, 33, 31 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum1 =
optimizer.optimize(100, problem1, problem1.target, new double[] { 1, 1, 1, 1 },
new double[] { 0, 1, 2, 3 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
Assert.assertEquals(1.0, optimum1.getPoint()[0], 1.0e-10);
Assert.assertEquals(1.0, optimum1.getPoint()[1], 1.0e-10);
Assert.assertEquals(1.0, optimum1.getPoint()[2], 1.0e-10);
Assert.assertEquals(1.0, optimum1.getPoint()[3], 1.0e-10);
LinearProblem problem2 = new LinearProblem(new double[][] {
{ 10.00, 7.00, 8.10, 7.20 },
{ 7.08, 5.04, 6.00, 5.00 },
{ 8.00, 5.98, 9.89, 9.00 },
{ 6.99, 4.99, 9.00, 9.98 }
}, new double[] { 32, 23, 33, 31 });
PointVectorValuePair optimum2 =
optimizer.optimize(100, problem2, problem2.target, new double[] { 1, 1, 1, 1 },
new double[] { 0, 1, 2, 3 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
Assert.assertEquals(-81.0, optimum2.getPoint()[0], 1.0e-8);
Assert.assertEquals(137.0, optimum2.getPoint()[1], 1.0e-8);
Assert.assertEquals(-34.0, optimum2.getPoint()[2], 1.0e-8);
Assert.assertEquals( 22.0, optimum2.getPoint()[3], 1.0e-8);
}
@Test
public void testMoreEstimatedParametersSimple() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 3.0, 2.0, 0.0, 0.0 },
{ 0.0, 1.0, -1.0, 1.0 },
{ 2.0, 0.0, 1.0, 0.0 }
}, new double[] { 7.0, 3.0, 5.0 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1 },
new double[] { 7, 6, 5, 4 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
}
@Test
public void testMoreEstimatedParametersUnsorted() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 1.0, 1.0, 0.0, 0.0, 0.0, 0.0 },
{ 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 },
{ 0.0, 0.0, 0.0, 0.0, 1.0, -1.0 },
{ 0.0, 0.0, -1.0, 1.0, 0.0, 1.0 },
{ 0.0, 0.0, 0.0, -1.0, 1.0, 0.0 }
}, new double[] { 3.0, 12.0, -1.0, 7.0, 1.0 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum =
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1, 1, 1 },
new double[] { 2, 2, 2, 2, 2, 2 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
Assert.assertEquals(3.0, optimum.getPointRef()[2], 1.0e-10);
Assert.assertEquals(4.0, optimum.getPointRef()[3], 1.0e-10);
Assert.assertEquals(5.0, optimum.getPointRef()[4], 1.0e-10);
Assert.assertEquals(6.0, optimum.getPointRef()[5], 1.0e-10);
}
@Test
public void testRedundantEquations() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 1.0, 1.0 },
{ 1.0, -1.0 },
{ 1.0, 3.0 }
}, new double[] { 3.0, 1.0, 5.0 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum =
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1 },
new double[] { 1, 1 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
Assert.assertEquals(2.0, optimum.getPointRef()[0], 1.0e-10);
Assert.assertEquals(1.0, optimum.getPointRef()[1], 1.0e-10);
}
@Test
public void testInconsistentEquations() {
LinearProblem problem = new LinearProblem(new double[][] {
{ 1.0, 1.0 },
{ 1.0, -1.0 },
{ 1.0, 3.0 }
}, new double[] { 3.0, 1.0, 4.0 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1, 1 }, new double[] { 1, 1 });
Assert.assertTrue(optimizer.getRMS() > 0.1);
}
@Test(expected=DimensionMismatchException.class)
public void testInconsistentSizes1() {
LinearProblem problem =
new LinearProblem(new double[][] { { 1, 0 }, { 0, 1 } }, new double[] { -1, 1 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum =
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1 }, new double[] { 0, 0 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
Assert.assertEquals(-1, optimum.getPoint()[0], 1.0e-10);
Assert.assertEquals(+1, optimum.getPoint()[1], 1.0e-10);
optimizer.optimize(100, problem, problem.target,
new double[] { 1 },
new double[] { 0, 0 });
}
@Test(expected=DimensionMismatchException.class)
public void testInconsistentSizes2() {
LinearProblem problem =
new LinearProblem(new double[][] { { 1, 0 }, { 0, 1 } }, new double[] { -1, 1 });
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum =
optimizer.optimize(100, problem, problem.target, new double[] { 1, 1 }, new double[] { 0, 0 });
Assert.assertEquals(0, optimizer.getRMS(), 1.0e-10);
Assert.assertEquals(-1, optimum.getPoint()[0], 1.0e-10);
Assert.assertEquals(+1, optimum.getPoint()[1], 1.0e-10);
optimizer.optimize(100, problem, new double[] { 1 },
new double[] { 1 },
new double[] { 0, 0 });
}
@Test
public void testCircleFitting() {
CircleVectorial circle = new CircleVectorial();
circle.addPoint( 30.0, 68.0);
circle.addPoint( 50.0, -6.0);
circle.addPoint(110.0, -20.0);
circle.addPoint( 35.0, 15.0);
circle.addPoint( 45.0, 97.0);
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum
= optimizer.optimize(100, circle, new double[] { 0, 0, 0, 0, 0 }, new double[] { 1, 1, 1, 1, 1 },
new double[] { 98.680, 47.345 });
Assert.assertTrue(optimizer.getEvaluations() < 10);
Assert.assertTrue(optimizer.getJacobianEvaluations() < 10);
double rms = optimizer.getRMS();
Assert.assertEquals(1.768262623567235, FastMath.sqrt(circle.getN()) * rms, 1.0e-10);
Vector2D center = new Vector2D(optimum.getPointRef()[0], optimum.getPointRef()[1]);
Assert.assertEquals(69.96016176931406, circle.getRadius(center), 1.0e-6);
Assert.assertEquals(96.07590211815305, center.getX(), 1.0e-6);
Assert.assertEquals(48.13516790438953, center.getY(), 1.0e-6);
double[][] cov = optimizer.computeCovariances(optimum.getPoint(), 1e-14);
Assert.assertEquals(1.839, cov[0][0], 0.001);
Assert.assertEquals(0.731, cov[0][1], 0.001);
Assert.assertEquals(cov[0][1], cov[1][0], 1.0e-14);
Assert.assertEquals(0.786, cov[1][1], 0.001);
// add perfect measurements and check errors are reduced
double r = circle.getRadius(center);
for (double d= 0; d < 2 * FastMath.PI; d += 0.01) {
circle.addPoint(center.getX() + r * FastMath.cos(d), center.getY() + r * FastMath.sin(d));
}
double[] target = new double[circle.getN()];
Arrays.fill(target, 0.0);
double[] weights = new double[circle.getN()];
Arrays.fill(weights, 2.0);
optimum = optimizer.optimize(100, circle, target, weights, new double[] { 98.680, 47.345 });
cov = optimizer.computeCovariances(optimum.getPoint(), 1e-14);
Assert.assertEquals(0.0016, cov[0][0], 0.001);
Assert.assertEquals(3.2e-7, cov[0][1], 1.0e-9);
Assert.assertEquals(cov[0][1], cov[1][0], 1.0e-14);
Assert.assertEquals(0.0016, cov[1][1], 0.001);
}
@Test
public void testCircleFittingBadInit() {
CircleVectorial circle = new CircleVectorial();
double[][] points = circlePoints;
double[] target = new double[points.length];
Arrays.fill(target, 0.0);
double[] weights = new double[points.length];
Arrays.fill(weights, 2.0);
for (int i = 0; i < points.length; ++i) {
circle.addPoint(points[i][0], points[i][1]);
}
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum
= optimizer.optimize(100, circle, target, weights, new double[] { -12, -12 });
Vector2D center = new Vector2D(optimum.getPointRef()[0], optimum.getPointRef()[1]);
Assert.assertTrue(optimizer.getEvaluations() < 25);
Assert.assertTrue(optimizer.getJacobianEvaluations() < 20);
Assert.assertEquals( 0.043, optimizer.getRMS(), 1.0e-3);
Assert.assertEquals( 0.292235, circle.getRadius(center), 1.0e-6);
Assert.assertEquals(-0.151738, center.getX(), 1.0e-6);
Assert.assertEquals( 0.2075001, center.getY(), 1.0e-6);
}
@Test
public void testCircleFittingGoodInit() {
CircleVectorial circle = new CircleVectorial();
double[][] points = circlePoints;
double[] target = new double[points.length];
Arrays.fill(target, 0.0);
double[] weights = new double[points.length];
Arrays.fill(weights, 2.0);
for (int i = 0; i < points.length; ++i) {
circle.addPoint(points[i][0], points[i][1]);
}
AbstractLeastSquaresOptimizer optimizer = createOptimizer();
PointVectorValuePair optimum =
optimizer.optimize(100, circle, target, weights, new double[] { 0, 0 });
Assert.assertEquals(-0.1517383071957963, optimum.getPointRef()[0], 1.0e-6);
Assert.assertEquals(0.2074999736353867, optimum.getPointRef()[1], 1.0e-6);
Assert.assertEquals(0.04268731682389561, optimizer.getRMS(), 1.0e-8);
}
private final double[][] circlePoints = new double[][] {
{-0.312967, 0.072366}, {-0.339248, 0.132965}, {-0.379780, 0.202724},
{-0.390426, 0.260487}, {-0.361212, 0.328325}, {-0.346039, 0.392619},
{-0.280579, 0.444306}, {-0.216035, 0.470009}, {-0.149127, 0.493832},
{-0.075133, 0.483271}, {-0.007759, 0.452680}, { 0.060071, 0.410235},
{ 0.103037, 0.341076}, { 0.118438, 0.273884}, { 0.131293, 0.192201},
{ 0.115869, 0.129797}, { 0.072223, 0.058396}, { 0.022884, 0.000718},
{-0.053355, -0.020405}, {-0.123584, -0.032451}, {-0.216248, -0.032862},
{-0.278592, -0.005008}, {-0.337655, 0.056658}, {-0.385899, 0.112526},
{-0.405517, 0.186957}, {-0.415374, 0.262071}, {-0.387482, 0.343398},
{-0.347322, 0.397943}, {-0.287623, 0.458425}, {-0.223502, 0.475513},
{-0.135352, 0.478186}, {-0.061221, 0.483371}, { 0.003711, 0.422737},
{ 0.065054, 0.375830}, { 0.108108, 0.297099}, { 0.123882, 0.222850},
{ 0.117729, 0.134382}, { 0.085195, 0.056820}, { 0.029800, -0.019138},
{-0.027520, -0.072374}, {-0.102268, -0.091555}, {-0.200299, -0.106578},
{-0.292731, -0.091473}, {-0.356288, -0.051108}, {-0.420561, 0.014926},
{-0.471036, 0.074716}, {-0.488638, 0.182508}, {-0.485990, 0.254068},
{-0.463943, 0.338438}, {-0.406453, 0.404704}, {-0.334287, 0.466119},
{-0.254244, 0.503188}, {-0.161548, 0.495769}, {-0.075733, 0.495560},
{ 0.001375, 0.434937}, { 0.082787, 0.385806}, { 0.115490, 0.323807},
{ 0.141089, 0.223450}, { 0.138693, 0.131703}, { 0.126415, 0.049174},
{ 0.066518, -0.010217}, {-0.005184, -0.070647}, {-0.080985, -0.103635},
{-0.177377, -0.116887}, {-0.260628, -0.100258}, {-0.335756, -0.056251},
{-0.405195, -0.000895}, {-0.444937, 0.085456}, {-0.484357, 0.175597},
{-0.472453, 0.248681}, {-0.438580, 0.347463}, {-0.402304, 0.422428},
{-0.326777, 0.479438}, {-0.247797, 0.505581}, {-0.152676, 0.519380},
{-0.071754, 0.516264}, { 0.015942, 0.472802}, { 0.076608, 0.419077},
{ 0.127673, 0.330264}, { 0.159951, 0.262150}, { 0.153530, 0.172681},
{ 0.140653, 0.089229}, { 0.078666, 0.024981}, { 0.023807, -0.037022},
{-0.048837, -0.077056}, {-0.127729, -0.075338}, {-0.221271, -0.067526}
};
public void doTestStRD(final StatisticalReferenceDataset dataset,
final double errParams, final double errParamsSd) {
final AbstractLeastSquaresOptimizer optimizer = createOptimizer();
final double[] w = new double[dataset.getNumObservations()];
Arrays.fill(w, 1.0);
final double[][] data = dataset.getData();
final double[] initial = dataset.getStartingPoint(0);
final MultivariateDifferentiableVectorFunction problem;
problem = dataset.getLeastSquaresProblem();
final PointVectorValuePair optimum;
optimum = optimizer.optimize(100, problem, data[1], w, initial);
final double[] actual = optimum.getPoint();
for (int i = 0; i < actual.length; i++) {
double expected = dataset.getParameter(i);
double delta = FastMath.abs(errParams * expected);
Assert.assertEquals(dataset.getName() + ", param #" + i,
expected, actual[i], delta);
}
}
@Test
public void testKirby2() throws IOException {
doTestStRD(StatisticalReferenceDatasetFactory.createKirby2(), 1E-7, 1E-7);
}
@Test
public void testHahn1() throws IOException {
doTestStRD(StatisticalReferenceDatasetFactory.createHahn1(), 1E-7, 1E-4);
}
static class LinearProblem implements MultivariateDifferentiableVectorFunction, Serializable {
private static final long serialVersionUID = 703247177355019415L;
final RealMatrix factors;
final double[] target;
public LinearProblem(double[][] factors, double[] target) {
this.factors = new BlockRealMatrix(factors);
this.target = target;
}
public double[] value(double[] variables) {
return factors.operate(variables);
}
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure[] value = new DerivativeStructure[factors.getRowDimension()];
for (int i = 0; i < value.length; ++i) {
value[i] = variables[0].getField().getZero();
for (int j = 0; j < factors.getColumnDimension(); ++j) {
value[i] = value[i].add(variables[j].multiply(factors.getEntry(i, j)));
}
}
return value;
}
}
}
././@LongLink 100644 0 0 147 12126630646 10263 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/general/CircleVectorial.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/general/CircleVectorial.ja100644 1750 1750 6137 12126627671 32321 0 ustar luc luc 0 0 /*
* 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.math3.optimization.general;
import java.util.ArrayList;
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction;
import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
/**
* Class used in the tests.
*/
class CircleVectorial implements MultivariateDifferentiableVectorFunction {
private ArrayList
*
* Minpack Copyright Notice (1999) University of Chicago.
* All rights reserved
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
This product includes software developed by the University of
* Chicago, as Operator of Argonne National Laboratory.
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* The model functions are:
*
*
*/
class StraightLineProblem implements MultivariateDifferentiableVectorFunction {
/** Cloud of points assumed to be fitted by a straight line. */
private final ArrayList
*
*
*
* @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests)
* @author Burton S. Garbow (original fortran minpack tests)
* @author Kenneth E. Hillstrom (original fortran minpack tests)
* @author Jorge J. More (original fortran minpack tests)
* @author Luc Maisonobe (non-minpack tests and minpack tests Java translation)
*/
public class MinpackTest {
@Test
public void testMinpackLinearFullRank() {
minpackTest(new LinearFullRankFunction(10, 5, 1.0,
5.0, 2.23606797749979), false);
minpackTest(new LinearFullRankFunction(50, 5, 1.0,
8.06225774829855, 6.70820393249937), false);
}
@Test
public void testMinpackLinearRank1() {
minpackTest(new LinearRank1Function(10, 5, 1.0,
291.521868819476, 1.4638501094228), false);
minpackTest(new LinearRank1Function(50, 5, 1.0,
3101.60039334535, 3.48263016573496), false);
}
@Test
public void testMinpackLinearRank1ZeroColsAndRows() {
minpackTest(new LinearRank1ZeroColsAndRowsFunction(10, 5, 1.0), false);
minpackTest(new LinearRank1ZeroColsAndRowsFunction(50, 5, 1.0), false);
}
@Test
public void testMinpackRosenbrok() {
minpackTest(new RosenbrockFunction(new double[] { -1.2, 1.0 },
FastMath.sqrt(24.2)), false);
minpackTest(new RosenbrockFunction(new double[] { -12.0, 10.0 },
FastMath.sqrt(1795769.0)), false);
minpackTest(new RosenbrockFunction(new double[] { -120.0, 100.0 },
11.0 * FastMath.sqrt(169000121.0)), false);
}
@Test
public void testMinpackHelicalValley() {
minpackTest(new HelicalValleyFunction(new double[] { -1.0, 0.0, 0.0 },
50.0), false);
minpackTest(new HelicalValleyFunction(new double[] { -10.0, 0.0, 0.0 },
102.95630140987), false);
minpackTest(new HelicalValleyFunction(new double[] { -100.0, 0.0, 0.0},
991.261822123701), false);
}
@Test
public void testMinpackPowellSingular() {
minpackTest(new PowellSingularFunction(new double[] { 3.0, -1.0, 0.0, 1.0 },
14.6628782986152), false);
minpackTest(new PowellSingularFunction(new double[] { 30.0, -10.0, 0.0, 10.0 },
1270.9838708654), false);
minpackTest(new PowellSingularFunction(new double[] { 300.0, -100.0, 0.0, 100.0 },
126887.903284750), false);
}
@Test
public void testMinpackFreudensteinRoth() {
minpackTest(new FreudensteinRothFunction(new double[] { 0.5, -2.0 },
20.0124960961895, 6.99887517584575,
new double[] {
11.4124844654993,
-0.896827913731509
}), false);
minpackTest(new FreudensteinRothFunction(new double[] { 5.0, -20.0 },
12432.833948863, 6.9988751744895,
new double[] {
11.41300466147456,
-0.896796038685959
}), false);
minpackTest(new FreudensteinRothFunction(new double[] { 50.0, -200.0 },
11426454.595762, 6.99887517242903,
new double[] {
11.412781785788564,
-0.8968051074920405
}), false);
}
@Test
public void testMinpackBard() {
minpackTest(new BardFunction(1.0, 6.45613629515967, 0.0906359603390466,
new double[] {
0.0824105765758334,
1.1330366534715,
2.34369463894115
}), false);
minpackTest(new BardFunction(10.0, 36.1418531596785, 4.17476870138539,
new double[] {
0.840666673818329,
-158848033.259565,
-164378671.653535
}), false);
minpackTest(new BardFunction(100.0, 384.114678637399, 4.17476870135969,
new double[] {
0.840666673867645,
-158946167.205518,
-164464906.857771
}), false);
}
@Test
public void testMinpackKowalikOsborne() {
minpackTest(new KowalikOsborneFunction(new double[] { 0.25, 0.39, 0.415, 0.39 },
0.0728915102882945,
0.017535837721129,
new double[] {
0.192807810476249,
0.191262653354071,
0.123052801046931,
0.136053221150517
}), false);
minpackTest(new KowalikOsborneFunction(new double[] { 2.5, 3.9, 4.15, 3.9 },
2.97937007555202,
0.032052192917937,
new double[] {
728675.473768287,
-14.0758803129393,
-32977797.7841797,
-20571594.1977912
}), false);
minpackTest(new KowalikOsborneFunction(new double[] { 25.0, 39.0, 41.5, 39.0 },
29.9590617016037,
0.0175364017658228,
new double[] {
0.192948328597594,
0.188053165007911,
0.122430604321144,
0.134575665392506
}), false);
}
@Test
public void testMinpackMeyer() {
minpackTest(new MeyerFunction(new double[] { 0.02, 4000.0, 250.0 },
41153.4665543031, 9.37794514651874,
new double[] {
0.00560963647102661,
6181.34634628659,
345.223634624144
}), false);
minpackTest(new MeyerFunction(new double[] { 0.2, 40000.0, 2500.0 },
4168216.89130846, 792.917871779501,
new double[] {
1.42367074157994e-11,
33695.7133432541,
901.268527953801
}), true);
}
@Test
public void testMinpackWatson() {
minpackTest(new WatsonFunction(6, 0.0,
5.47722557505166, 0.0478295939097601,
new double[] {
-0.0157249615083782, 1.01243488232965,
-0.232991722387673, 1.26043101102818,
-1.51373031394421, 0.99299727291842
}), false);
minpackTest(new WatsonFunction(6, 10.0,
6433.12578950026, 0.0478295939096951,
new double[] {
-0.0157251901386677, 1.01243485860105,
-0.232991545843829, 1.26042932089163,
-1.51372776706575, 0.99299573426328
}), false);
minpackTest(new WatsonFunction(6, 100.0,
674256.040605213, 0.047829593911544,
new double[] {
-0.0157247019712586, 1.01243490925658,
-0.232991922761641, 1.26043292929555,
-1.51373320452707, 0.99299901922322
}), false);
minpackTest(new WatsonFunction(9, 0.0,
5.47722557505166, 0.00118311459212420,
new double[] {
-0.153070644166722e-4, 0.999789703934597,
0.0147639634910978, 0.146342330145992,
1.00082109454817, -2.61773112070507,
4.10440313943354, -3.14361226236241,
1.05262640378759
}), false);
minpackTest(new WatsonFunction(9, 10.0,
12088.127069307, 0.00118311459212513,
new double[] {
-0.153071334849279e-4, 0.999789703941234,
0.0147639629786217, 0.146342334818836,
1.00082107321386, -2.61773107084722,
4.10440307655564, -3.14361222178686,
1.05262639322589
}), false);
minpackTest(new WatsonFunction(9, 100.0,
1269109.29043834, 0.00118311459212384,
new double[] {
-0.153069523352176e-4, 0.999789703958371,
0.0147639625185392, 0.146342341096326,
1.00082104729164, -2.61773101573645,
4.10440301427286, -3.14361218602503,
1.05262638516774
}), false);
minpackTest(new WatsonFunction(12, 0.0,
5.47722557505166, 0.217310402535861e-4,
new double[] {
-0.660266001396382e-8, 1.00000164411833,
-0.000563932146980154, 0.347820540050756,
-0.156731500244233, 1.05281515825593,
-3.24727109519451, 7.2884347837505,
-10.271848098614, 9.07411353715783,
-4.54137541918194, 1.01201187975044
}), false);
minpackTest(new WatsonFunction(12, 10.0,
19220.7589790951, 0.217310402518509e-4,
new double[] {
-0.663710223017410e-8, 1.00000164411787,
-0.000563932208347327, 0.347820540486998,
-0.156731503955652, 1.05281517654573,
-3.2472711515214, 7.28843489430665,
-10.2718482369638, 9.07411364383733,
-4.54137546533666, 1.01201188830857
}), false);
minpackTest(new WatsonFunction(12, 100.0,
2018918.04462367, 0.217310402539845e-4,
new double[] {
-0.663806046485249e-8, 1.00000164411786,
-0.000563932210324959, 0.347820540503588,
-0.156731504091375, 1.05281517718031,
-3.24727115337025, 7.28843489775302,
-10.2718482410813, 9.07411364688464,
-4.54137546660822, 1.0120118885369
}), false);
}
@Test
public void testMinpackBox3Dimensional() {
minpackTest(new Box3DimensionalFunction(10, new double[] { 0.0, 10.0, 20.0 },
32.1115837449572), false);
}
@Test
public void testMinpackJennrichSampson() {
minpackTest(new JennrichSampsonFunction(10, new double[] { 0.3, 0.4 },
64.5856498144943, 11.1517793413499,
new double[] {
// 0.2578330049, 0.257829976764542
0.2578199266368004, 0.25782997676455244
}), false);
}
@Test
public void testMinpackBrownDennis() {
minpackTest(new BrownDennisFunction(20,
new double[] { 25.0, 5.0, -5.0, -1.0 },
2815.43839161816, 292.954288244866,
new double[] {
-11.59125141003, 13.2024883984741,
-0.403574643314272, 0.236736269844604
}), false);
minpackTest(new BrownDennisFunction(20,
new double[] { 250.0, 50.0, -50.0, -10.0 },
555073.354173069, 292.954270581415,
new double[] {
-11.5959274272203, 13.2041866926242,
-0.403417362841545, 0.236771143410386
}), false);
minpackTest(new BrownDennisFunction(20,
new double[] { 2500.0, 500.0, -500.0, -100.0 },
61211252.2338581, 292.954306151134,
new double[] {
-11.5902596937374, 13.2020628854665,
-0.403688070279258, 0.236665033746463
}), false);
}
@Test
public void testMinpackChebyquad() {
minpackTest(new ChebyquadFunction(1, 8, 1.0,
1.88623796907732, 1.88623796907732,
new double[] { 0.5 }), false);
minpackTest(new ChebyquadFunction(1, 8, 10.0,
5383344372.34005, 1.88424820499951,
new double[] { 0.9817314924684 }), false);
minpackTest(new ChebyquadFunction(1, 8, 100.0,
0.118088726698392e19, 1.88424820499347,
new double[] { 0.9817314852934 }), false);
minpackTest(new ChebyquadFunction(8, 8, 1.0,
0.196513862833975, 0.0593032355046727,
new double[] {
0.0431536648587336, 0.193091637843267,
0.266328593812698, 0.499999334628884,
0.500000665371116, 0.733671406187302,
0.806908362156733, 0.956846335141266
}), false);
minpackTest(new ChebyquadFunction(9, 9, 1.0,
0.16994993465202, 0.0,
new double[] {
0.0442053461357828, 0.199490672309881,
0.23561910847106, 0.416046907892598,
0.5, 0.583953092107402,
0.764380891528940, 0.800509327690119,
0.955794653864217
}), false);
minpackTest(new ChebyquadFunction(10, 10, 1.0,
0.183747831178711, 0.0806471004038253,
new double[] {
0.0596202671753563, 0.166708783805937,
0.239171018813509, 0.398885290346268,
0.398883667870681, 0.601116332129320,
0.60111470965373, 0.760828981186491,
0.833291216194063, 0.940379732824644
}), false);
}
@Test
public void testMinpackBrownAlmostLinear() {
minpackTest(new BrownAlmostLinearFunction(10, 0.5,
16.5302162063499, 0.0,
new double[] {
0.979430303349862, 0.979430303349862,
0.979430303349862, 0.979430303349862,
0.979430303349862, 0.979430303349862,
0.979430303349862, 0.979430303349862,
0.979430303349862, 1.20569696650138
}), false);
minpackTest(new BrownAlmostLinearFunction(10, 5.0,
9765624.00089211, 0.0,
new double[] {
0.979430303349865, 0.979430303349865,
0.979430303349865, 0.979430303349865,
0.979430303349865, 0.979430303349865,
0.979430303349865, 0.979430303349865,
0.979430303349865, 1.20569696650135
}), false);
minpackTest(new BrownAlmostLinearFunction(10, 50.0,
0.9765625e17, 0.0,
new double[] {
1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0
}), false);
minpackTest(new BrownAlmostLinearFunction(30, 0.5,
83.476044467848, 0.0,
new double[] {
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 0.997754216442807,
0.997754216442807, 1.06737350671578
}), false);
minpackTest(new BrownAlmostLinearFunction(40, 0.5,
128.026364472323, 0.0,
new double[] {
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
1.00000000000002, 1.00000000000002,
0.999999999999121
}), false);
}
@Test
public void testMinpackOsborne1() {
minpackTest(new Osborne1Function(new double[] { 0.5, 1.5, -1.0, 0.01, 0.02, },
0.937564021037838, 0.00739249260904843,
new double[] {
0.375410049244025, 1.93584654543108,
-1.46468676748716, 0.0128675339110439,
0.0221227011813076
}), false);
}
@Test
public void testMinpackOsborne2() {
minpackTest(new Osborne2Function(new double[] {
1.3, 0.65, 0.65, 0.7, 0.6,
3.0, 5.0, 7.0, 2.0, 4.5, 5.5
},
1.44686540984712, 0.20034404483314,
new double[] {
1.30997663810096, 0.43155248076,
0.633661261602859, 0.599428560991695,
0.754179768272449, 0.904300082378518,
1.36579949521007, 4.82373199748107,
2.39868475104871, 4.56887554791452,
5.67534206273052
}), false);
}
private void minpackTest(MinpackFunction function, boolean exceptionExpected) {
LevenbergMarquardtOptimizer optimizer
= new LevenbergMarquardtOptimizer(FastMath.sqrt(2.22044604926e-16),
FastMath.sqrt(2.22044604926e-16),
2.22044604926e-16);
// Assert.assertTrue(function.checkTheoreticalStartCost(optimizer.getRMS()));
try {
PointVectorValuePair optimum =
optimizer.optimize(400 * (function.getN() + 1), function,
function.getTarget(), function.getWeight(),
function.getStartPoint());
Assert.assertFalse(exceptionExpected);
function.checkTheoreticalMinCost(optimizer.getRMS());
function.checkTheoreticalMinParams(optimum);
} catch (TooManyEvaluationsException e) {
Assert.assertTrue(exceptionExpected);
}
}
private static abstract class MinpackFunction
implements MultivariateDifferentiableVectorFunction, Serializable {
private static final long serialVersionUID = -6209760235478794233L;
protected int n;
protected int m;
protected double[] startParams;
protected double theoreticalMinCost;
protected double[] theoreticalMinParams;
protected double costAccuracy;
protected double paramsAccuracy;
protected MinpackFunction(int m, double[] startParams,
double theoreticalMinCost, double[] theoreticalMinParams) {
this.m = m;
this.n = startParams.length;
this.startParams = startParams.clone();
this.theoreticalMinCost = theoreticalMinCost;
this.theoreticalMinParams = theoreticalMinParams;
this.costAccuracy = 1.0e-8;
this.paramsAccuracy = 1.0e-5;
}
protected static double[] buildArray(int n, double x) {
double[] array = new double[n];
Arrays.fill(array, x);
return array;
}
public double[] getTarget() {
return buildArray(m, 0.0);
}
public double[] getWeight() {
return buildArray(m, 1.0);
}
public double[] getStartPoint() {
return startParams.clone();
}
protected void setCostAccuracy(double costAccuracy) {
this.costAccuracy = costAccuracy;
}
protected void setParamsAccuracy(double paramsAccuracy) {
this.paramsAccuracy = paramsAccuracy;
}
public int getN() {
return startParams.length;
}
public void checkTheoreticalMinCost(double rms) {
double threshold = costAccuracy * (1.0 + theoreticalMinCost);
Assert.assertEquals(theoreticalMinCost, FastMath.sqrt(m) * rms, threshold);
}
public void checkTheoreticalMinParams(PointVectorValuePair optimum) {
double[] params = optimum.getPointRef();
if (theoreticalMinParams != null) {
for (int i = 0; i < theoreticalMinParams.length; ++i) {
double mi = theoreticalMinParams[i];
double vi = params[i];
Assert.assertEquals(mi, vi, paramsAccuracy * (1.0 + FastMath.abs(mi)));
}
}
}
public double[] value(double[] variables) {
DerivativeStructure[] dsV = new DerivativeStructure[variables.length];
for (int i = 0; i < variables.length; ++i) {
dsV[i] = new DerivativeStructure(0, 0, variables[i]);
}
DerivativeStructure[] dsY = value(dsV);
double[] y = new double[dsY.length];
for (int i = 0; i < dsY.length; ++i) {
y[i] = dsY[i].getValue();
}
return y;
}
public abstract DerivativeStructure[] value(DerivativeStructure[] variables);
}
private static class LinearFullRankFunction extends MinpackFunction {
private static final long serialVersionUID = -9030323226268039536L;
public LinearFullRankFunction(int m, int n, double x0,
double theoreticalStartCost,
double theoreticalMinCost) {
super(m, buildArray(n, x0), theoreticalMinCost,
buildArray(n, -1.0));
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure sum = variables[0].getField().getZero();
for (int i = 0; i < n; ++i) {
sum = sum.add(variables[i]);
}
DerivativeStructure t = sum.multiply(2.0 / m).add(1);
DerivativeStructure[] f = new DerivativeStructure[m];
for (int i = 0; i < n; ++i) {
f[i] = variables[i].subtract(t);
}
Arrays.fill(f, n, m, t.negate());
return f;
}
}
private static class LinearRank1Function extends MinpackFunction {
private static final long serialVersionUID = 8494863245104608300L;
public LinearRank1Function(int m, int n, double x0,
double theoreticalStartCost,
double theoreticalMinCost) {
super(m, buildArray(n, x0), theoreticalMinCost, null);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure[] f = new DerivativeStructure[m];
DerivativeStructure sum = variables[0].getField().getZero();
for (int i = 0; i < n; ++i) {
sum = sum.add(variables[i].multiply(i + 1));
}
for (int i = 0; i < m; ++i) {
f[i] = sum.multiply(i + 1).subtract(1);
}
return f;
}
}
private static class LinearRank1ZeroColsAndRowsFunction extends MinpackFunction {
private static final long serialVersionUID = -3316653043091995018L;
public LinearRank1ZeroColsAndRowsFunction(int m, int n, double x0) {
super(m, buildArray(n, x0),
FastMath.sqrt((m * (m + 3) - 6) / (2.0 * (2 * m - 3))),
null);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure[] f = new DerivativeStructure[m];
DerivativeStructure sum = variables[0].getField().getZero();
for (int i = 1; i < (n - 1); ++i) {
sum = sum.add(variables[i].multiply(i + 1));
}
for (int i = 0; i < (m - 1); ++i) {
f[i] = sum.multiply(i).subtract(1);
}
f[m - 1] = variables[0].getField().getOne().negate();
return f;
}
}
private static class RosenbrockFunction extends MinpackFunction {
private static final long serialVersionUID = 2893438180956569134L;
public RosenbrockFunction(double[] startParams, double theoreticalStartCost) {
super(2, startParams, 0.0, buildArray(2, 1.0));
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
return new DerivativeStructure[] {
x2.subtract(x1.multiply(x1)).multiply(10),
x1.negate().add(1)
};
}
}
private static class HelicalValleyFunction extends MinpackFunction {
private static final long serialVersionUID = 220613787843200102L;
public HelicalValleyFunction(double[] startParams,
double theoreticalStartCost) {
super(3, startParams, 0.0, new double[] { 1.0, 0.0, 0.0 });
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
DerivativeStructure x3 = variables[2];
DerivativeStructure tmp1 = variables[0].getField().getZero();
if (x1.getValue() == 0) {
tmp1 = tmp1.add((x2.getValue() >= 0) ? 0.25 : -0.25);
} else {
tmp1 = x2.divide(x1).atan().divide(twoPi);
if (x1.getValue() < 0) {
tmp1 = tmp1.add(0.5);
}
}
DerivativeStructure tmp2 = x1.multiply(x1).add(x2.multiply(x2)).sqrt();
return new DerivativeStructure[] {
x3.subtract(tmp1.multiply(10)).multiply(10),
tmp2.subtract(1).multiply(10),
x3
};
}
private static final double twoPi = 2.0 * FastMath.PI;
}
private static class PowellSingularFunction extends MinpackFunction {
private static final long serialVersionUID = 7298364171208142405L;
public PowellSingularFunction(double[] startParams,
double theoreticalStartCost) {
super(4, startParams, 0.0, buildArray(4, 0.0));
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
DerivativeStructure x3 = variables[2];
DerivativeStructure x4 = variables[3];
return new DerivativeStructure[] {
x1.add(x2.multiply(10)),
x3.subtract(x4).multiply(sqrt5),
x2.subtract(x3.multiply(2)).multiply(x2.subtract(x3.multiply(2))),
x1.subtract(x4).multiply(x1.subtract(x4)).multiply(sqrt10)
};
}
private static final double sqrt5 = FastMath.sqrt( 5.0);
private static final double sqrt10 = FastMath.sqrt(10.0);
}
private static class FreudensteinRothFunction extends MinpackFunction {
private static final long serialVersionUID = 2892404999344244214L;
public FreudensteinRothFunction(double[] startParams,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(2, startParams, theoreticalMinCost,
theoreticalMinParams);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
return new DerivativeStructure[] {
x1.subtract(13.0).add(x2.negate().add(5.0).multiply(x2).subtract(2).multiply(x2)),
x1.subtract(29.0).add(x2.add(1).multiply(x2).subtract(14).multiply(x2))
};
}
}
private static class BardFunction extends MinpackFunction {
private static final long serialVersionUID = 5990442612572087668L;
public BardFunction(double x0,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(15, buildArray(3, x0), theoreticalMinCost,
theoreticalMinParams);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
DerivativeStructure x3 = variables[2];
DerivativeStructure[] f = new DerivativeStructure[m];
for (int i = 0; i < m; ++i) {
double tmp1 = i + 1;
double tmp2 = 15 - i;
double tmp3 = (i <= 7) ? tmp1 : tmp2;
f[i] = x1.add(x2.multiply(tmp2).add(x3.multiply(tmp3)).reciprocal().multiply(tmp1)).negate().add(y[i]);
}
return f;
}
private static final double[] y = {
0.14, 0.18, 0.22, 0.25, 0.29,
0.32, 0.35, 0.39, 0.37, 0.58,
0.73, 0.96, 1.34, 2.10, 4.39
};
}
private static class KowalikOsborneFunction extends MinpackFunction {
private static final long serialVersionUID = -4867445739880495801L;
public KowalikOsborneFunction(double[] startParams,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(11, startParams, theoreticalMinCost,
theoreticalMinParams);
if (theoreticalStartCost > 20.0) {
setCostAccuracy(2.0e-4);
setParamsAccuracy(5.0e-3);
}
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
DerivativeStructure x3 = variables[2];
DerivativeStructure x4 = variables[3];
DerivativeStructure[] f = new DerivativeStructure[m];
for (int i = 0; i < m; ++i) {
f[i] = x1.multiply(x2.add(v[i]).multiply(v[i])).divide(x4.add(x3.add(v[i]).multiply(v[i]))).negate().add(y[i]);
}
return f;
}
private static final double[] v = {
4.0, 2.0, 1.0, 0.5, 0.25, 0.167, 0.125, 0.1, 0.0833, 0.0714, 0.0625
};
private static final double[] y = {
0.1957, 0.1947, 0.1735, 0.1600, 0.0844, 0.0627,
0.0456, 0.0342, 0.0323, 0.0235, 0.0246
};
}
private static class MeyerFunction extends MinpackFunction {
private static final long serialVersionUID = -838060619150131027L;
public MeyerFunction(double[] startParams,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(16, startParams, theoreticalMinCost,
theoreticalMinParams);
if (theoreticalStartCost > 1.0e6) {
setCostAccuracy(7.0e-3);
setParamsAccuracy(2.0e-2);
}
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
DerivativeStructure x3 = variables[2];
DerivativeStructure[] f = new DerivativeStructure[m];
for (int i = 0; i < m; ++i) {
f[i] = x1.multiply(x2.divide(x3.add(5.0 * (i + 1) + 45.0)).exp()).subtract(y[i]);
}
return f;
}
private static final double[] y = {
34780.0, 28610.0, 23650.0, 19630.0,
16370.0, 13720.0, 11540.0, 9744.0,
8261.0, 7030.0, 6005.0, 5147.0,
4427.0, 3820.0, 3307.0, 2872.0
};
}
private static class WatsonFunction extends MinpackFunction {
private static final long serialVersionUID = -9034759294980218927L;
public WatsonFunction(int n, double x0,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(31, buildArray(n, x0), theoreticalMinCost,
theoreticalMinParams);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure[] f = new DerivativeStructure[m];
for (int i = 0; i < (m - 2); ++i) {
double div = (i + 1) / 29.0;
DerivativeStructure s1 = variables[0].getField().getZero();
DerivativeStructure dx = variables[0].getField().getOne();
for (int j = 1; j < n; ++j) {
s1 = s1.add(dx.multiply(j).multiply(variables[j]));
dx = dx.multiply(div);
}
DerivativeStructure s2 = variables[0].getField().getZero();
dx = variables[0].getField().getOne();
for (int j = 0; j < n; ++j) {
s2 = s2.add(dx.multiply(variables[j]));
dx = dx.multiply(div);
}
f[i] = s1.subtract(s2.multiply(s2)).subtract(1);
}
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
f[m - 2] = x1;
f[m - 1] = x2.subtract(x1.multiply(x1)).subtract(1);
return f;
}
}
private static class Box3DimensionalFunction extends MinpackFunction {
private static final long serialVersionUID = 5511403858142574493L;
public Box3DimensionalFunction(int m, double[] startParams,
double theoreticalStartCost) {
super(m, startParams, 0.0,
new double[] { 1.0, 10.0, 1.0 });
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
DerivativeStructure x3 = variables[2];
DerivativeStructure[] f = new DerivativeStructure[m];
for (int i = 0; i < m; ++i) {
double tmp = (i + 1) / 10.0;
f[i] = x1.multiply(-tmp).exp().subtract(x2.multiply(-tmp).exp()).add(
x3.multiply(FastMath.exp(-i - 1) - FastMath.exp(-tmp)));
}
return f;
}
}
private static class JennrichSampsonFunction extends MinpackFunction {
private static final long serialVersionUID = -2489165190443352947L;
public JennrichSampsonFunction(int m, double[] startParams,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(m, startParams, theoreticalMinCost,
theoreticalMinParams);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
DerivativeStructure[] f = new DerivativeStructure[m];
for (int i = 0; i < m; ++i) {
double temp = i + 1;
f[i] = x1.multiply(temp).exp().add(x2.multiply(temp).exp()).subtract(2 + 2 * temp).negate();
}
return f;
}
}
private static class BrownDennisFunction extends MinpackFunction {
private static final long serialVersionUID = 8340018645694243910L;
public BrownDennisFunction(int m, double[] startParams,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(m, startParams, theoreticalMinCost,
theoreticalMinParams);
setCostAccuracy(2.5e-8);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
DerivativeStructure x3 = variables[2];
DerivativeStructure x4 = variables[3];
DerivativeStructure[] f = new DerivativeStructure[m];
for (int i = 0; i < m; ++i) {
double temp = (i + 1) / 5.0;
DerivativeStructure tmp1 = x1.add(x2.multiply(temp)).subtract(FastMath.exp(temp));
DerivativeStructure tmp2 = x3.add(x4.multiply(FastMath.sin(temp))).subtract(FastMath.cos(temp));
f[i] = tmp1.multiply(tmp1).add(tmp2.multiply(tmp2));
}
return f;
}
}
private static class ChebyquadFunction extends MinpackFunction {
private static final long serialVersionUID = -2394877275028008594L;
private static double[] buildChebyquadArray(int n, double factor) {
double[] array = new double[n];
double inv = factor / (n + 1);
for (int i = 0; i < n; ++i) {
array[i] = (i + 1) * inv;
}
return array;
}
public ChebyquadFunction(int n, int m, double factor,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(m, buildChebyquadArray(n, factor), theoreticalMinCost,
theoreticalMinParams);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure[] f = new DerivativeStructure[m];
Arrays.fill(f, variables[0].getField().getZero());
for (int j = 0; j < n; ++j) {
DerivativeStructure tmp1 = variables[0].getField().getOne();
DerivativeStructure tmp2 = variables[j].multiply(2).subtract(1);
DerivativeStructure temp = tmp2.multiply(2);
for (int i = 0; i < m; ++i) {
f[i] = f[i].add(tmp2);
DerivativeStructure ti = temp.multiply(tmp2).subtract(tmp1);
tmp1 = tmp2;
tmp2 = ti;
}
}
double dx = 1.0 / n;
boolean iev = false;
for (int i = 0; i < m; ++i) {
f[i] = f[i].multiply(dx);
if (iev) {
f[i] = f[i].add(1.0 / (i * (i + 2)));
}
iev = ! iev;
}
return f;
}
}
private static class BrownAlmostLinearFunction extends MinpackFunction {
private static final long serialVersionUID = 8239594490466964725L;
public BrownAlmostLinearFunction(int m, double factor,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(m, buildArray(m, factor), theoreticalMinCost,
theoreticalMinParams);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure[] f = new DerivativeStructure[m];
DerivativeStructure sum = variables[0].getField().getZero().subtract(n + 1);
DerivativeStructure prod = variables[0].getField().getOne();
for (int j = 0; j < n; ++j) {
sum = sum.add(variables[j]);
prod = prod.multiply(variables[j]);
}
for (int i = 0; i < n; ++i) {
f[i] = variables[i].add(sum);
}
f[n - 1] = prod.subtract(1);
return f;
}
}
private static class Osborne1Function extends MinpackFunction {
private static final long serialVersionUID = 4006743521149849494L;
public Osborne1Function(double[] startParams,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(33, startParams, theoreticalMinCost,
theoreticalMinParams);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x1 = variables[0];
DerivativeStructure x2 = variables[1];
DerivativeStructure x3 = variables[2];
DerivativeStructure x4 = variables[3];
DerivativeStructure x5 = variables[4];
DerivativeStructure[] f = new DerivativeStructure[m];
for (int i = 0; i < m; ++i) {
double temp = 10.0 * i;
DerivativeStructure tmp1 = x4.multiply(-temp).exp();
DerivativeStructure tmp2 = x5.multiply(-temp).exp();
f[i] = x1.add(x2.multiply(tmp1)).add(x3.multiply(tmp2)).negate().add(y[i]);
}
return f;
}
private static final double[] y = {
0.844, 0.908, 0.932, 0.936, 0.925, 0.908, 0.881, 0.850, 0.818, 0.784, 0.751,
0.718, 0.685, 0.658, 0.628, 0.603, 0.580, 0.558, 0.538, 0.522, 0.506, 0.490,
0.478, 0.467, 0.457, 0.448, 0.438, 0.431, 0.424, 0.420, 0.414, 0.411, 0.406
};
}
private static class Osborne2Function extends MinpackFunction {
private static final long serialVersionUID = -8418268780389858746L;
public Osborne2Function(double[] startParams,
double theoreticalStartCost,
double theoreticalMinCost,
double[] theoreticalMinParams) {
super(65, startParams, theoreticalMinCost,
theoreticalMinParams);
}
@Override
public DerivativeStructure[] value(DerivativeStructure[] variables) {
DerivativeStructure x01 = variables[0];
DerivativeStructure x02 = variables[1];
DerivativeStructure x03 = variables[2];
DerivativeStructure x04 = variables[3];
DerivativeStructure x05 = variables[4];
DerivativeStructure x06 = variables[5];
DerivativeStructure x07 = variables[6];
DerivativeStructure x08 = variables[7];
DerivativeStructure x09 = variables[8];
DerivativeStructure x10 = variables[9];
DerivativeStructure x11 = variables[10];
DerivativeStructure[] f = new DerivativeStructure[m];
for (int i = 0; i < m; ++i) {
double temp = i / 10.0;
DerivativeStructure tmp1 = x05.multiply(-temp).exp();
DerivativeStructure tmp2 = x06.negate().multiply(x09.subtract(temp).multiply(x09.subtract(temp))).exp();
DerivativeStructure tmp3 = x07.negate().multiply(x10.subtract(temp).multiply(x10.subtract(temp))).exp();
DerivativeStructure tmp4 = x08.negate().multiply(x11.subtract(temp).multiply(x11.subtract(temp))).exp();
f[i] = x01.multiply(tmp1).add(x02.multiply(tmp2)).add(x03.multiply(tmp3)).add(x04.multiply(tmp4)).negate().add(y[i]);
}
return f;
}
private static final double[] y = {
1.366, 1.191, 1.112, 1.013, 0.991,
0.885, 0.831, 0.847, 0.786, 0.725,
0.746, 0.679, 0.608, 0.655, 0.616,
0.606, 0.602, 0.626, 0.651, 0.724,
0.649, 0.649, 0.694, 0.644, 0.624,
0.661, 0.612, 0.558, 0.533, 0.495,
0.500, 0.423, 0.395, 0.375, 0.372,
0.391, 0.396, 0.405, 0.428, 0.429,
0.523, 0.562, 0.607, 0.653, 0.672,
0.708, 0.633, 0.668, 0.645, 0.632,
0.591, 0.559, 0.597, 0.625, 0.739,
0.710, 0.729, 0.720, 0.636, 0.581,
0.428, 0.292, 0.162, 0.098, 0.054
};
}
}
././@LongLink 100644 0 0 173 12126630646 10262 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/univariate/SimpleUnivariateValueCheckerTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/univariate/SimpleUnivariat100644 1750 1750 4133 12126627670 32515 0 ustar luc luc 0 0 /*
* 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.math3.optimization.univariate;
import org.apache.commons.math3.exception.NotStrictlyPositiveException;
import org.junit.Test;
import org.junit.Assert;
public class SimpleUnivariateValueCheckerTest {
@Test(expected=NotStrictlyPositiveException.class)
public void testIterationCheckPrecondition() {
new SimpleUnivariateValueChecker(1e-1, 1e-2, 0);
}
@Test
public void testIterationCheck() {
final int max = 10;
final SimpleUnivariateValueChecker checker = new SimpleUnivariateValueChecker(1e-1, 1e-2, max);
Assert.assertTrue(checker.converged(max, null, null));
Assert.assertTrue(checker.converged(max + 1, null, null));
}
@Test
public void testIterationCheckDisabled() {
final SimpleUnivariateValueChecker checker = new SimpleUnivariateValueChecker(1e-8, 1e-8);
final UnivariatePointValuePair a = new UnivariatePointValuePair(1d, 1d);
final UnivariatePointValuePair b = new UnivariatePointValuePair(10d, 10d);
Assert.assertFalse(checker.converged(-1, a, b));
Assert.assertFalse(checker.converged(0, a, b));
Assert.assertFalse(checker.converged(1000000, a, b));
Assert.assertTrue(checker.converged(-1, a, a));
Assert.assertTrue(checker.converged(-1, b, b));
}
}
././@LongLink 100644 0 0 174 12126630646 10263 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/univariate/UnivariateMultiStartOptimizerTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/optimization/univariate/UnivariateMulti100644 1750 1750 11077 12126627670 32550 0 ustar luc luc 0 0 /*
* 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.math3.optimization.univariate;
import org.apache.commons.math3.analysis.QuinticFunction;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.function.Sin;
import org.apache.commons.math3.optimization.GoalType;
import org.apache.commons.math3.random.JDKRandomGenerator;
import org.apache.commons.math3.util.FastMath;
import org.junit.Assert;
import org.junit.Test;
public class UnivariateMultiStartOptimizerTest {
@Test
public void testSinMin() {
UnivariateFunction f = new Sin();
UnivariateOptimizer underlying = new BrentOptimizer(1e-10, 1e-14);
JDKRandomGenerator g = new JDKRandomGenerator();
g.setSeed(44428400075l);
UnivariateMultiStartOptimizer
*
* Minpack Copyright Notice (1999) University of Chicago.
* All rights reserved
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
This product includes software developed by the University of
* Chicago, as Operator of Argonne National Laboratory.
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
* y' = 3x^5 - y
*
* when the initial condition is y(0) = -360, the solution of this
* equation degenerates to a simple quintic polynomial function :
*
* y (t) = 3x^5 - 15x^4 + 60x^3 - 180x^2 + 360x - 360
*
*
This specific problem is the following differential equation : *
* y' = t^3 - t y ** with the initial condition y (0) = 0. The solution of this equation * is the following function : *
* y (t) = t^2 + 2 (exp (- t^2 / 2) - 1) ** */ public class TestProblem2 extends TestProblemAbstract { /** theoretical state */ private double[] y; /** * Simple constructor. */ public TestProblem2() { super(); double[] y0 = { 0.0 }; setInitialConditions(0.0, y0); setFinalConditions(1.0); double[] errorScale = { 1.0 }; setErrorScale(errorScale); y = new double[y0.length]; } /** * Copy constructor. * @param problem problem to copy */ public TestProblem2(TestProblem2 problem) { super(problem); y = problem.y.clone(); } /** {@inheritDoc} */ @Override public TestProblem2 copy() { return new TestProblem2(this); } @Override public void doComputeDerivatives(double t, double[] y, double[] yDot) { // compute the derivatives for (int i = 0; i < n; ++i) yDot[i] = t * (t * t - y[i]); } @Override public double[] computeTheoreticalState(double t) { double t2 = t * t; double c = t2 + 2 * (FastMath.exp (-0.5 * t2) - 1); for (int i = 0; i < n; ++i) { y[i] = c; } return y; } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/JacobianMatricesTest.java 100644 1750 1750 57211 12126627673 30261 0 ustar luc luc 0 0 /* * 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.math3.ode; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.JacobianMatrices.MismatchedEquations; import org.apache.commons.math3.ode.nonstiff.DormandPrince54Integrator; import org.apache.commons.math3.stat.descriptive.SummaryStatistics; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class JacobianMatricesTest { @Test public void testLowAccuracyExternalDifferentiation() throws NumberIsTooSmallException, DimensionMismatchException, MaxCountExceededException, NoBracketingException { // this test does not really test JacobianMatrices, // it only shows that WITHOUT this class, attempting to recover // the jacobians from external differentiation on simple integration // results with low accuracy gives very poor results. In fact, // the curves dy/dp = g(b) when b varies from 2.88 to 3.08 are // essentially noise. // This test is taken from Hairer, Norsett and Wanner book // Solving Ordinary Differential Equations I (Nonstiff problems), // the curves dy/dp = g(b) are in figure 6.5 FirstOrderIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-4, 1.0e-4 }, new double[] { 1.0e-4, 1.0e-4 }); double hP = 1.0e-12; SummaryStatistics residualsP0 = new SummaryStatistics(); SummaryStatistics residualsP1 = new SummaryStatistics(); for (double b = 2.88; b < 3.08; b += 0.001) { Brusselator brusselator = new Brusselator(b); double[] y = { 1.3, b }; integ.integrate(brusselator, 0, y, 20.0, y); double[] yP = { 1.3, b + hP }; integ.integrate(brusselator, 0, yP, 20.0, yP); residualsP0.addValue((yP[0] - y[0]) / hP - brusselator.dYdP0()); residualsP1.addValue((yP[1] - y[1]) / hP - brusselator.dYdP1()); } Assert.assertTrue((residualsP0.getMax() - residualsP0.getMin()) > 500); Assert.assertTrue(residualsP0.getStandardDeviation() > 30); Assert.assertTrue((residualsP1.getMax() - residualsP1.getMin()) > 700); Assert.assertTrue(residualsP1.getStandardDeviation() > 40); } @Test public void testHighAccuracyExternalDifferentiation() throws NumberIsTooSmallException, DimensionMismatchException, MaxCountExceededException, NoBracketingException, UnknownParameterException { FirstOrderIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-10, 1.0e-10 }, new double[] { 1.0e-10, 1.0e-10 }); double hP = 1.0e-12; SummaryStatistics residualsP0 = new SummaryStatistics(); SummaryStatistics residualsP1 = new SummaryStatistics(); for (double b = 2.88; b < 3.08; b += 0.001) { ParamBrusselator brusselator = new ParamBrusselator(b); double[] y = { 1.3, b }; integ.integrate(brusselator, 0, y, 20.0, y); double[] yP = { 1.3, b + hP }; brusselator.setParameter("b", b + hP); integ.integrate(brusselator, 0, yP, 20.0, yP); residualsP0.addValue((yP[0] - y[0]) / hP - brusselator.dYdP0()); residualsP1.addValue((yP[1] - y[1]) / hP - brusselator.dYdP1()); } Assert.assertTrue((residualsP0.getMax() - residualsP0.getMin()) > 0.02); Assert.assertTrue((residualsP0.getMax() - residualsP0.getMin()) < 0.03); Assert.assertTrue(residualsP0.getStandardDeviation() > 0.003); Assert.assertTrue(residualsP0.getStandardDeviation() < 0.004); Assert.assertTrue((residualsP1.getMax() - residualsP1.getMin()) > 0.04); Assert.assertTrue((residualsP1.getMax() - residualsP1.getMin()) < 0.05); Assert.assertTrue(residualsP1.getStandardDeviation() > 0.007); Assert.assertTrue(residualsP1.getStandardDeviation() < 0.008); } @Test public void testInternalDifferentiation() throws NumberIsTooSmallException, DimensionMismatchException, MaxCountExceededException, NoBracketingException, UnknownParameterException, MismatchedEquations { AbstractIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-4, 1.0e-4 }, new double[] { 1.0e-4, 1.0e-4 }); double hP = 1.0e-12; double hY = 1.0e-12; SummaryStatistics residualsP0 = new SummaryStatistics(); SummaryStatistics residualsP1 = new SummaryStatistics(); for (double b = 2.88; b < 3.08; b += 0.001) { ParamBrusselator brusselator = new ParamBrusselator(b); brusselator.setParameter(ParamBrusselator.B, b); double[] z = { 1.3, b }; double[][] dZdZ0 = new double[2][2]; double[] dZdP = new double[2]; JacobianMatrices jacob = new JacobianMatrices(brusselator, new double[] { hY, hY }, ParamBrusselator.B); jacob.setParameterizedODE(brusselator); jacob.setParameterStep(ParamBrusselator.B, hP); jacob.setInitialParameterJacobian(ParamBrusselator.B, new double[] { 0.0, 1.0 }); ExpandableStatefulODE efode = new ExpandableStatefulODE(brusselator); efode.setTime(0); efode.setPrimaryState(z); jacob.registerVariationalEquations(efode); integ.setMaxEvaluations(5000); integ.integrate(efode, 20.0); jacob.getCurrentMainSetJacobian(dZdZ0); jacob.getCurrentParameterJacobian(ParamBrusselator.B, dZdP); // Assert.assertEquals(5000, integ.getMaxEvaluations()); // Assert.assertTrue(integ.getEvaluations() > 1500); // Assert.assertTrue(integ.getEvaluations() < 2100); // Assert.assertEquals(4 * integ.getEvaluations(), integ.getEvaluations()); residualsP0.addValue(dZdP[0] - brusselator.dYdP0()); residualsP1.addValue(dZdP[1] - brusselator.dYdP1()); } Assert.assertTrue((residualsP0.getMax() - residualsP0.getMin()) < 0.02); Assert.assertTrue(residualsP0.getStandardDeviation() < 0.003); Assert.assertTrue((residualsP1.getMax() - residualsP1.getMin()) < 0.05); Assert.assertTrue(residualsP1.getStandardDeviation() < 0.01); } @Test public void testAnalyticalDifferentiation() throws MaxCountExceededException, DimensionMismatchException, NumberIsTooSmallException, NoBracketingException, UnknownParameterException, MismatchedEquations { AbstractIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-4, 1.0e-4 }, new double[] { 1.0e-4, 1.0e-4 }); SummaryStatistics residualsP0 = new SummaryStatistics(); SummaryStatistics residualsP1 = new SummaryStatistics(); for (double b = 2.88; b < 3.08; b += 0.001) { Brusselator brusselator = new Brusselator(b); double[] z = { 1.3, b }; double[][] dZdZ0 = new double[2][2]; double[] dZdP = new double[2]; JacobianMatrices jacob = new JacobianMatrices(brusselator, Brusselator.B); jacob.addParameterJacobianProvider(brusselator); jacob.setInitialParameterJacobian(Brusselator.B, new double[] { 0.0, 1.0 }); ExpandableStatefulODE efode = new ExpandableStatefulODE(brusselator); efode.setTime(0); efode.setPrimaryState(z); jacob.registerVariationalEquations(efode); integ.setMaxEvaluations(5000); integ.integrate(efode, 20.0); jacob.getCurrentMainSetJacobian(dZdZ0); jacob.getCurrentParameterJacobian(Brusselator.B, dZdP); // Assert.assertEquals(5000, integ.getMaxEvaluations()); // Assert.assertTrue(integ.getEvaluations() > 350); // Assert.assertTrue(integ.getEvaluations() < 510); residualsP0.addValue(dZdP[0] - brusselator.dYdP0()); residualsP1.addValue(dZdP[1] - brusselator.dYdP1()); } Assert.assertTrue((residualsP0.getMax() - residualsP0.getMin()) < 0.014); Assert.assertTrue(residualsP0.getStandardDeviation() < 0.003); Assert.assertTrue((residualsP1.getMax() - residualsP1.getMin()) < 0.05); Assert.assertTrue(residualsP1.getStandardDeviation() < 0.01); } @Test public void testFinalResult() throws MaxCountExceededException, DimensionMismatchException, NumberIsTooSmallException, NoBracketingException, UnknownParameterException, MismatchedEquations { AbstractIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-10, 1.0e-10 }, new double[] { 1.0e-10, 1.0e-10 }); double[] y = new double[] { 0.0, 1.0 }; Circle circle = new Circle(y, 1.0, 1.0, 0.1); JacobianMatrices jacob = new JacobianMatrices(circle, Circle.CX, Circle.CY, Circle.OMEGA); jacob.addParameterJacobianProvider(circle); jacob.setInitialMainStateJacobian(circle.exactDyDy0(0)); jacob.setInitialParameterJacobian(Circle.CX, circle.exactDyDcx(0)); jacob.setInitialParameterJacobian(Circle.CY, circle.exactDyDcy(0)); jacob.setInitialParameterJacobian(Circle.OMEGA, circle.exactDyDom(0)); ExpandableStatefulODE efode = new ExpandableStatefulODE(circle); efode.setTime(0); efode.setPrimaryState(y); jacob.registerVariationalEquations(efode); integ.setMaxEvaluations(5000); double t = 18 * FastMath.PI; integ.integrate(efode, t); y = efode.getPrimaryState(); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(circle.exactY(t)[i], y[i], 1.0e-9); } double[][] dydy0 = new double[2][2]; jacob.getCurrentMainSetJacobian(dydy0); for (int i = 0; i < dydy0.length; ++i) { for (int j = 0; j < dydy0[i].length; ++j) { Assert.assertEquals(circle.exactDyDy0(t)[i][j], dydy0[i][j], 1.0e-9); } } double[] dydcx = new double[2]; jacob.getCurrentParameterJacobian(Circle.CX, dydcx); for (int i = 0; i < dydcx.length; ++i) { Assert.assertEquals(circle.exactDyDcx(t)[i], dydcx[i], 1.0e-7); } double[] dydcy = new double[2]; jacob.getCurrentParameterJacobian(Circle.CY, dydcy); for (int i = 0; i < dydcy.length; ++i) { Assert.assertEquals(circle.exactDyDcy(t)[i], dydcy[i], 1.0e-7); } double[] dydom = new double[2]; jacob.getCurrentParameterJacobian(Circle.OMEGA, dydom); for (int i = 0; i < dydom.length; ++i) { Assert.assertEquals(circle.exactDyDom(t)[i], dydom[i], 1.0e-7); } } @Test public void testParameterizable() throws MaxCountExceededException, DimensionMismatchException, NumberIsTooSmallException, NoBracketingException, UnknownParameterException, MismatchedEquations { AbstractIntegrator integ = new DormandPrince54Integrator(1.0e-8, 100.0, new double[] { 1.0e-10, 1.0e-10 }, new double[] { 1.0e-10, 1.0e-10 }); double[] y = new double[] { 0.0, 1.0 }; ParameterizedCircle pcircle = new ParameterizedCircle(y, 1.0, 1.0, 0.1); double hP = 1.0e-12; double hY = 1.0e-12; JacobianMatrices jacob = new JacobianMatrices(pcircle, new double[] { hY, hY }, ParameterizedCircle.CX, ParameterizedCircle.CY, ParameterizedCircle.OMEGA); jacob.setParameterizedODE(pcircle); jacob.setParameterStep(ParameterizedCircle.CX, hP); jacob.setParameterStep(ParameterizedCircle.CY, hP); jacob.setParameterStep(ParameterizedCircle.OMEGA, hP); jacob.setInitialMainStateJacobian(pcircle.exactDyDy0(0)); jacob.setInitialParameterJacobian(ParameterizedCircle.CX, pcircle.exactDyDcx(0)); jacob.setInitialParameterJacobian(ParameterizedCircle.CY, pcircle.exactDyDcy(0)); jacob.setInitialParameterJacobian(ParameterizedCircle.OMEGA, pcircle.exactDyDom(0)); ExpandableStatefulODE efode = new ExpandableStatefulODE(pcircle); efode.setTime(0); efode.setPrimaryState(y); jacob.registerVariationalEquations(efode); integ.setMaxEvaluations(50000); double t = 18 * FastMath.PI; integ.integrate(efode, t); y = efode.getPrimaryState(); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(pcircle.exactY(t)[i], y[i], 1.0e-9); } double[][] dydy0 = new double[2][2]; jacob.getCurrentMainSetJacobian(dydy0); for (int i = 0; i < dydy0.length; ++i) { for (int j = 0; j < dydy0[i].length; ++j) { Assert.assertEquals(pcircle.exactDyDy0(t)[i][j], dydy0[i][j], 5.0e-4); } } double[] dydp0 = new double[2]; jacob.getCurrentParameterJacobian(ParameterizedCircle.CX, dydp0); for (int i = 0; i < dydp0.length; ++i) { Assert.assertEquals(pcircle.exactDyDcx(t)[i], dydp0[i], 5.0e-4); } double[] dydp1 = new double[2]; jacob.getCurrentParameterJacobian(ParameterizedCircle.OMEGA, dydp1); for (int i = 0; i < dydp1.length; ++i) { Assert.assertEquals(pcircle.exactDyDom(t)[i], dydp1[i], 1.0e-2); } } private static class Brusselator extends AbstractParameterizable implements MainStateJacobianProvider, ParameterJacobianProvider { public static final String B = "b"; private double b; public Brusselator(double b) { super(B); this.b = b; } public int getDimension() { return 2; } public void computeDerivatives(double t, double[] y, double[] yDot) { double prod = y[0] * y[0] * y[1]; yDot[0] = 1 + prod - (b + 1) * y[0]; yDot[1] = b * y[0] - prod; } public void computeMainStateJacobian(double t, double[] y, double[] yDot, double[][] dFdY) { double p = 2 * y[0] * y[1]; double y02 = y[0] * y[0]; dFdY[0][0] = p - (1 + b); dFdY[0][1] = y02; dFdY[1][0] = b - p; dFdY[1][1] = -y02; } public void computeParameterJacobian(double t, double[] y, double[] yDot, String paramName, double[] dFdP) { if (isSupported(paramName)) { dFdP[0] = -y[0]; dFdP[1] = y[0]; } else { dFdP[0] = 0; dFdP[1] = 0; } } public double dYdP0() { return -1088.232716447743 + (1050.775747149553 + (-339.012934631828 + 36.52917025056327 * b) * b) * b; } public double dYdP1() { return 1502.824469929139 + (-1438.6974831849952 + (460.959476642384 - 49.43847385647082 * b) * b) * b; } } private static class ParamBrusselator extends AbstractParameterizable implements FirstOrderDifferentialEquations, ParameterizedODE { public static final String B = "b"; private double b; public ParamBrusselator(double b) { super(B); this.b = b; } public int getDimension() { return 2; } /** {@inheritDoc} */ public double getParameter(final String name) throws UnknownParameterException { complainIfNotSupported(name); return b; } /** {@inheritDoc} */ public void setParameter(final String name, final double value) throws UnknownParameterException { complainIfNotSupported(name); b = value; } public void computeDerivatives(double t, double[] y, double[] yDot) { double prod = y[0] * y[0] * y[1]; yDot[0] = 1 + prod - (b + 1) * y[0]; yDot[1] = b * y[0] - prod; } public double dYdP0() { return -1088.232716447743 + (1050.775747149553 + (-339.012934631828 + 36.52917025056327 * b) * b) * b; } public double dYdP1() { return 1502.824469929139 + (-1438.6974831849952 + (460.959476642384 - 49.43847385647082 * b) * b) * b; } } /** ODE representing a point moving on a circle with provided center and angular rate. */ private static class Circle extends AbstractParameterizable implements MainStateJacobianProvider, ParameterJacobianProvider { public static final String CX = "cx"; public static final String CY = "cy"; public static final String OMEGA = "omega"; private final double[] y0; private double cx; private double cy; private double omega; public Circle(double[] y0, double cx, double cy, double omega) { super(CX,CY,OMEGA); this.y0 = y0.clone(); this.cx = cx; this.cy = cy; this.omega = omega; } public int getDimension() { return 2; } public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = omega * (cy - y[1]); yDot[1] = omega * (y[0] - cx); } public void computeMainStateJacobian(double t, double[] y, double[] yDot, double[][] dFdY) { dFdY[0][0] = 0; dFdY[0][1] = -omega; dFdY[1][0] = omega; dFdY[1][1] = 0; } public void computeParameterJacobian(double t, double[] y, double[] yDot, String paramName, double[] dFdP) throws UnknownParameterException { complainIfNotSupported(paramName); if (paramName.equals(CX)) { dFdP[0] = 0; dFdP[1] = -omega; } else if (paramName.equals(CY)) { dFdP[0] = omega; dFdP[1] = 0; } else { dFdP[0] = cy - y[1]; dFdP[1] = y[0] - cx; } } public double[] exactY(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); double dx0 = y0[0] - cx; double dy0 = y0[1] - cy; return new double[] { cx + cos * dx0 - sin * dy0, cy + sin * dx0 + cos * dy0 }; } public double[][] exactDyDy0(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); return new double[][] { { cos, -sin }, { sin, cos } }; } public double[] exactDyDcx(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); return new double[] {1 - cos, -sin}; } public double[] exactDyDcy(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); return new double[] {sin, 1 - cos}; } public double[] exactDyDom(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); double dx0 = y0[0] - cx; double dy0 = y0[1] - cy; return new double[] { -t * (sin * dx0 + cos * dy0) , t * (cos * dx0 - sin * dy0) }; } } /** ODE representing a point moving on a circle with provided center and angular rate. */ private static class ParameterizedCircle extends AbstractParameterizable implements FirstOrderDifferentialEquations, ParameterizedODE { public static final String CX = "cx"; public static final String CY = "cy"; public static final String OMEGA = "omega"; private final double[] y0; private double cx; private double cy; private double omega; public ParameterizedCircle(double[] y0, double cx, double cy, double omega) { super(CX,CY,OMEGA); this.y0 = y0.clone(); this.cx = cx; this.cy = cy; this.omega = omega; } public int getDimension() { return 2; } public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = omega * (cy - y[1]); yDot[1] = omega * (y[0] - cx); } public double getParameter(final String name) throws UnknownParameterException { if (name.equals(CX)) { return cx; } else if (name.equals(CY)) { return cy; } else if (name.equals(OMEGA)) { return omega; } else { throw new UnknownParameterException(name); } } public void setParameter(final String name, final double value) throws UnknownParameterException { if (name.equals(CX)) { cx = value; } else if (name.equals(CY)) { cy = value; } else if (name.equals(OMEGA)) { omega = value; } else { throw new UnknownParameterException(name); } } public double[] exactY(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); double dx0 = y0[0] - cx; double dy0 = y0[1] - cy; return new double[] { cx + cos * dx0 - sin * dy0, cy + sin * dx0 + cos * dy0 }; } public double[][] exactDyDy0(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); return new double[][] { { cos, -sin }, { sin, cos } }; } public double[] exactDyDcx(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); return new double[] {1 - cos, -sin}; } public double[] exactDyDcy(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); return new double[] {sin, 1 - cos}; } public double[] exactDyDom(double t) { double cos = FastMath.cos(omega * t); double sin = FastMath.sin(omega * t); double dx0 = y0[0] - cx; double dy0 = y0[1] - cy; return new double[] { -t * (sin * dx0 + cos * dy0) , t * (cos * dx0 - sin * dy0) }; } } } ././@LongLink 100644 0 0 150 12126630646 10255 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/StepNormalizerOutputTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/StepNormalizerOutputTest.j100644 1750 1750 4732 12126627673 32364 0 ustar luc luc 0 0 /* * 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.math3.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}}; } } ././@LongLink 100644 0 0 157 12126630646 10264 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/StepNormalizerOutputOverlapTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/StepNormalizerOutputOverla100644 1750 1750 4731 12126627673 32444 0 ustar luc luc 0 0 /* * 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.math3.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}}; } } ././@LongLink 100644 0 0 151 12126630646 10256 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/StepInterpolatorTestUtils.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/StepInterpolatorTestUtils.100644 1750 1750 10275 12126627673 32371 0 ustar luc luc 0 0 /* * 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.math3.ode.sampling; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblemAbstract; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; public class StepInterpolatorTestUtils { public static void checkDerivativesConsistency(final FirstOrderIntegrator integrator, final TestProblemAbstract problem, final double threshold) throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { integrator.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { final double h = 0.001 * (interpolator.getCurrentTime() - interpolator.getPreviousTime()); final double t = interpolator.getCurrentTime() - 300 * h; if (FastMath.abs(h) < 10 * FastMath.ulp(t)) { return; } interpolator.setInterpolatedTime(t - 4 * h); final double[] yM4h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t - 3 * h); final double[] yM3h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t - 2 * h); final double[] yM2h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t - h); final double[] yM1h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t + h); final double[] yP1h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t + 2 * h); final double[] yP2h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t + 3 * h); final double[] yP3h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t + 4 * h); final double[] yP4h = interpolator.getInterpolatedState().clone(); interpolator.setInterpolatedTime(t); final double[] yDot = interpolator.getInterpolatedDerivatives(); for (int i = 0; i < yDot.length; ++i) { final double approYDot = ( -3 * (yP4h[i] - yM4h[i]) + 32 * (yP3h[i] - yM3h[i]) + -168 * (yP2h[i] - yM2h[i]) + 672 * (yP1h[i] - yM1h[i])) / (840 * h); Assert.assertEquals(approYDot, yDot[i], threshold); } } public void init(double t0, double[] y0, double t) { } }); integrator.integrate(problem, problem.getInitialTime(), problem.getInitialState(), problem.getFinalTime(), new double[problem.getDimension()]); } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/StepNormalizerTest.java 100644 1750 1750 12242 12126627673 31646 0 ustar luc luc 0 0 /* * 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.math3.ode.sampling; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.nonstiff.DormandPrince54Integrator; import org.apache.commons.math3.util.FastMath; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class StepNormalizerTest { public StepNormalizerTest() { pb = null; integ = null; } @Test public void testBoundaries() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { double range = pb.getFinalTime() - pb.getInitialTime(); setLastSeen(false); integ.addStepHandler(new StepNormalizer(range / 10.0, new FixedStepHandler() { private boolean firstCall = true; public void init(double t0, double[] y0, double t) { } public void handleStep(double t, double[] y, double[] yDot, boolean isLast) { if (firstCall) { checkValue(t, pb.getInitialTime()); firstCall = false; } if (isLast) { setLastSeen(true); checkValue(t, pb.getFinalTime()); } } })); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(lastSeen); } @Test public void testBeforeEnd() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final double range = pb.getFinalTime() - pb.getInitialTime(); setLastSeen(false); integ.addStepHandler(new StepNormalizer(range / 10.5, new FixedStepHandler() { public void init(double t0, double[] y0, double t) { } public void handleStep(double t, double[] y, double[] yDot, boolean isLast) { if (isLast) { setLastSeen(true); checkValue(t, pb.getFinalTime() - range / 21.0); } } })); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(lastSeen); } public void checkValue(double value, double reference) { Assert.assertTrue(FastMath.abs(value - reference) < 1.0e-10); } public void setLastSeen(boolean lastSeen) { this.lastSeen = lastSeen; } @Before public void setUp() { pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); integ = new DormandPrince54Integrator(minStep, maxStep, 10.e-8, 1.0e-8); lastSeen = false; } @After public void tearDown() { pb = null; integ = null; } TestProblem3 pb; FirstOrderIntegrator integ; boolean lastSeen; } ././@LongLink 100644 0 0 154 12126630646 10261 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/StepNormalizerOutputTestBase.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/StepNormalizerOutputTestBa100644 1750 1750 25560 12126627673 32421 0 ustar luc luc 0 0 /* * 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.math3.ode.sampling; import static org.junit.Assert.assertArrayEquals; import java.util.ArrayList; import java.util.List; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.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
This class is used when the {@link StepHandler "step handler"} * set up by the user does not need step interpolation. It does not * recompute the state when {@link AbstractStepInterpolator#setInterpolatedTime * setInterpolatedTime} is called. This implies the interpolated state * is always the state at the end of the current step.
* * @see StepHandler * * @version $Id: DummyStepInterpolator.java 1302386 2012-03-19 11:59:25Z sebb $ * @since 1.2 */ public class DummyStepInterpolator extends AbstractStepInterpolator { /** Serializable version identifier. */ private static final long serialVersionUID = 1708010296707839488L; /** Current derivative. */ private double[] currentDerivative; /** Simple constructor. * This constructor builds an instance that is not usable yet, the *AbstractStepInterpolator.reinitialize
protected method
* should be called before using the instance in order to initialize
* the internal arrays. This constructor is used only in order to delay
* the initialization in some cases. As an example, the {@link
* org.apache.commons.math3.ode.nonstiff.EmbeddedRungeKuttaIntegrator} uses
* the prototyping design pattern to create the step interpolators by
* cloning an uninitialized model and latter initializing the copy.
*/
public DummyStepInterpolator() {
super();
currentDerivative = null;
}
/** Simple constructor.
* @param y reference to the integrator array holding the state at
* the end of the step
* @param yDot reference to the integrator array holding the state
* derivative at some arbitrary point within the step
* @param forward integration direction indicator
*/
public DummyStepInterpolator(final double[] y, final double[] yDot, final boolean forward) {
super(y, forward, new EquationsMapper(0, y.length), new EquationsMapper[0]);
currentDerivative = yDot;
}
/** Copy constructor.
* @param interpolator interpolator to copy from. The copy is a deep
* copy: its arrays are separated from the original arrays of the
* instance
*/
public DummyStepInterpolator(final DummyStepInterpolator interpolator) {
super(interpolator);
currentDerivative = interpolator.currentDerivative.clone();
}
/** Really copy the finalized instance.
* @return a copy of the finalized instance
*/
@Override
protected StepInterpolator doCopy() {
return new DummyStepInterpolator(this);
}
/** Compute the state at the interpolated time.
* In this class, this method does nothing: the interpolated state
* is always the state at the end of the current step.
* @param theta normalized interpolation abscissa within the step
* (theta is zero at the previous time step and one at the current time step)
* @param oneMinusThetaH time gap between the interpolated time and
* the current time
*/
@Override
protected void computeInterpolatedStateAndDerivatives(final double theta, final double oneMinusThetaH) {
System.arraycopy(currentState, 0, interpolatedState, 0, currentState.length);
System.arraycopy(currentDerivative, 0, interpolatedDerivatives, 0, currentDerivative.length);
}
/** Write the instance to an output channel.
* @param out output channel
* @exception IOException if the instance cannot be written
*/
@Override
public void writeExternal(final ObjectOutput out)
throws IOException {
// save the state of the base class
writeBaseExternal(out);
if (currentDerivative != null) {
for (int i = 0; i < currentDerivative.length; ++i) {
out.writeDouble(currentDerivative[i]);
}
}
}
/** Read the instance from an input channel.
* @param in input channel
* @exception IOException if the instance cannot be read
*/
@Override
public void readExternal(final ObjectInput in)
throws IOException, ClassNotFoundException {
// read the base class
final double t = readBaseExternal(in);
if (currentState == null) {
currentDerivative = null;
} else {
currentDerivative = new double[currentState.length];
for (int i = 0; i < currentDerivative.length; ++i) {
currentDerivative[i] = in.readDouble();
}
}
// we can now set the interpolated time and state
setInterpolatedTime(t);
}
}
././@LongLink 100644 0 0 155 12126630646 10262 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/NordsieckStepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/NordsieckStepInterpolatorT100644 1750 1750 7611 12126627673 32400 0 ustar luc luc 0 0 /*
* 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.math3.ode.sampling;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Random;
import org.apache.commons.math3.exception.DimensionMismatchException;
import org.apache.commons.math3.exception.MaxCountExceededException;
import org.apache.commons.math3.exception.NoBracketingException;
import org.apache.commons.math3.exception.NumberIsTooSmallException;
import org.apache.commons.math3.ode.ContinuousOutputModel;
import org.apache.commons.math3.ode.TestProblem1;
import org.apache.commons.math3.ode.TestProblem3;
import org.apache.commons.math3.ode.nonstiff.AdamsBashforthIntegrator;
import org.junit.Assert;
import org.junit.Test;
public class NordsieckStepInterpolatorTest {
@Test
public void derivativesConsistency()
throws NumberIsTooSmallException, DimensionMismatchException,
MaxCountExceededException, NoBracketingException {
TestProblem3 pb = new TestProblem3();
AdamsBashforthIntegrator integ = new AdamsBashforthIntegrator(4, 0.0, 1.0, 1.0e-10, 1.0e-10);
StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 5e-9);
}
@Test
public void serialization()
throws IOException, ClassNotFoundException,
NumberIsTooSmallException, DimensionMismatchException,
MaxCountExceededException, NoBracketingException {
TestProblem1 pb = new TestProblem1();
AdamsBashforthIntegrator integ = new AdamsBashforthIntegrator(4, 0.0, 1.0, 1.0e-10, 1.0e-10);
integ.addStepHandler(new ContinuousOutputModel());
integ.integrate(pb,
pb.getInitialTime(), pb.getInitialState(),
pb.getFinalTime(), new double[pb.getDimension()]);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
for (StepHandler handler : integ.getStepHandlers()) {
oos.writeObject(handler);
}
Assert.assertTrue(bos.size () > 25500);
Assert.assertTrue(bos.size () < 26500);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject();
Random random = new Random(347588535632l);
double maxError = 0.0;
for (int i = 0; i < 1000; ++i) {
double r = random.nextDouble();
double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime();
cm.setInterpolatedTime(time);
double[] interpolatedY = cm.getInterpolatedState ();
double[] theoreticalY = pb.computeTheoreticalState(time);
double dx = interpolatedY[0] - theoreticalY[0];
double dy = interpolatedY[1] - theoreticalY[1];
double error = dx * dx + dy * dy;
if (error > maxError) {
maxError = error;
}
}
Assert.assertTrue(maxError < 1.0e-6);
}
}
././@LongLink 100644 0 0 151 12126630646 10256 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/DummyStepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/sampling/DummyStepInterpolatorTest.100644 1750 1750 10742 12126627673 32363 0 ustar luc luc 0 0 /*
* 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.math3.ode.sampling;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.apache.commons.math3.exception.MaxCountExceededException;
import org.apache.commons.math3.util.FastMath;
import org.junit.Assert;
import org.junit.Test;
public class DummyStepInterpolatorTest {
@Test
public void testNoReset() throws MaxCountExceededException {
double[] y = { 0.0, 1.0, -2.0 };
DummyStepInterpolator interpolator = new DummyStepInterpolator(y, new double[y.length], true);
interpolator.storeTime(0);
interpolator.shift();
interpolator.storeTime(1);
double[] result = interpolator.getInterpolatedState();
for (int i = 0; i < result.length; ++i) {
Assert.assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10);
}
}
@Test
public void testFixedState() throws MaxCountExceededException {
double[] y = { 1.0, 3.0, -4.0 };
DummyStepInterpolator interpolator = new DummyStepInterpolator(y, new double[y.length], true);
interpolator.storeTime(0);
interpolator.shift();
interpolator.storeTime(1);
interpolator.setInterpolatedTime(0.1);
double[] result = interpolator.getInterpolatedState();
for (int i = 0; i < result.length; ++i) {
Assert.assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10);
}
interpolator.setInterpolatedTime(0.5);
result = interpolator.getInterpolatedState();
for (int i = 0; i < result.length; ++i) {
Assert.assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10);
}
}
@Test
public void testSerialization()
throws IOException, ClassNotFoundException, MaxCountExceededException {
double[] y = { 0.0, 1.0, -2.0 };
DummyStepInterpolator interpolator = new DummyStepInterpolator(y, new double[y.length], true);
interpolator.storeTime(0);
interpolator.shift();
interpolator.storeTime(1);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(interpolator);
Assert.assertTrue(bos.size () > 300);
Assert.assertTrue(bos.size () < 500);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
DummyStepInterpolator dsi = (DummyStepInterpolator) ois.readObject();
dsi.setInterpolatedTime(0.5);
double[] result = dsi.getInterpolatedState();
for (int i = 0; i < result.length; ++i) {
Assert.assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10);
}
}
@Test
public void testImpossibleSerialization()
throws IOException {
double[] y = { 0.0, 1.0, -2.0 };
AbstractStepInterpolator interpolator = new BadStepInterpolator(y, true);
interpolator.storeTime(0);
interpolator.shift();
interpolator.storeTime(1);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
try {
oos.writeObject(interpolator);
Assert.fail("an exception should have been thrown");
} catch (LocalException le) {
// expected behavior
}
}
private static class BadStepInterpolator extends DummyStepInterpolator {
@SuppressWarnings("unused")
public BadStepInterpolator() {
}
public BadStepInterpolator(double[] y, boolean forward) {
super(y, new double[y.length], forward);
}
@Override
protected void doFinalize() {
throw new LocalException();
}
}
private static class LocalException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
}
commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/TestProblem4.java 100644 1750 1750 7404 12126627673 26526 0 ustar luc luc 0 0 /*
* 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.math3.ode;
import org.apache.commons.math3.ode.events.EventHandler;
import org.apache.commons.math3.util.FastMath;
/**
* This class is used in the junit tests for the ODE integrators.
* This specific problem is the following differential equation : *
* x'' = -x ** And when x decreases down to 0, the state should be changed as follows : *
* x' -> -x' ** The theoretical solution of this problem is x = |sin(t+a)| * */ public class TestProblem4 extends TestProblemAbstract { /** Time offset. */ private double a; /** theoretical state */ private double[] y; /** Simple constructor. */ public TestProblem4() { super(); a = 1.2; double[] y0 = { FastMath.sin(a), FastMath.cos(a) }; setInitialConditions(0.0, y0); setFinalConditions(15); double[] errorScale = { 1.0, 0.0 }; setErrorScale(errorScale); y = new double[y0.length]; } /** * Copy constructor. * @param problem problem to copy */ public TestProblem4(TestProblem4 problem) { super(problem); a = problem.a; y = problem.y.clone(); } /** {@inheritDoc} */ @Override public TestProblem4 copy() { return new TestProblem4(this); } @Override public EventHandler[] getEventsHandlers() { return new EventHandler[] { new Bounce(), new Stop() }; } /** * Get the theoretical events times. * @return theoretical events times */ @Override public double[] getTheoreticalEventsTimes() { return new double[] { 1 * FastMath.PI - a, 2 * FastMath.PI - a, 3 * FastMath.PI - a, 4 * FastMath.PI - a, 12.0 }; } @Override public void doComputeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = y[1]; yDot[1] = -y[0]; } @Override public double[] computeTheoreticalState(double t) { double sin = FastMath.sin(t + a); double cos = FastMath.cos(t + a); y[0] = FastMath.abs(sin); y[1] = (sin >= 0) ? cos : -cos; return y; } private static class Bounce implements EventHandler { private int sign; public Bounce() { sign = +1; } public void init(double t0, double[] y0, double t) { } public double g(double t, double[] y) { return sign * y[0]; } public Action eventOccurred(double t, double[] y, boolean increasing) { // this sign change is needed because the state will be reset soon sign = -sign; return Action.RESET_STATE; } public void resetState(double t, double[] y) { y[0] = -y[0]; y[1] = -y[1]; } } private static class Stop implements EventHandler { public Stop() { } public void init(double t0, double[] y0, double t) { } public double g(double t, double[] y) { return t - 12.0; } public Action eventOccurred(double t, double[] y, boolean increasing) { return Action.STOP; } public void resetState(double t, double[] y) { } } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/FirstOrderConverterTest.java 100644 1750 1750 7615 12126627673 31021 0 ustar luc luc 0 0 /* * 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.math3.ode; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.nonstiff.ClassicalRungeKuttaIntegrator; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class FirstOrderConverterTest { @Test public void testDoubleDimension() { for (int i = 1; i < 10; ++i) { SecondOrderDifferentialEquations eqn2 = new Equations(i, 0.2); FirstOrderConverter eqn1 = new FirstOrderConverter(eqn2); Assert.assertTrue(eqn1.getDimension() == (2 * eqn2.getDimension())); } } @Test public void testDecreasingSteps() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { double previousError = Double.NaN; for (int i = 0; i < 10; ++i) { double step = FastMath.pow(2.0, -(i + 1)); double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, step) - FastMath.sin(4.0); if (i > 0) { Assert.assertTrue(FastMath.abs(error) < FastMath.abs(previousError)); } previousError = error; } } @Test public void testSmallStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, 1.0e-4) - FastMath.sin(4.0); Assert.assertTrue(FastMath.abs(error) < 1.0e-10); } @Test public void testBigStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { double error = integrateWithSpecifiedStep(4.0, 0.0, 1.0, 0.5) - FastMath.sin(4.0); Assert.assertTrue(FastMath.abs(error) > 0.1); } private static class Equations implements SecondOrderDifferentialEquations { private int n; private double omega2; public Equations(int n, double omega) { this.n = n; omega2 = omega * omega; } public int getDimension() { return n; } public void computeSecondDerivatives(double t, double[] y, double[] yDot, double[] yDDot) { for (int i = 0; i < n; ++i) { yDDot[i] = -omega2 * y[i]; } } } private double integrateWithSpecifiedStep(double omega, double t0, double t, double step) throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { double[] y0 = new double[2]; y0[0] = FastMath.sin(omega * t0); y0[1] = omega * FastMath.cos(omega * t0); ClassicalRungeKuttaIntegrator i = new ClassicalRungeKuttaIntegrator(step); double[] y = new double[2]; i.integrate(new FirstOrderConverter(new Equations(1, omega)), t0, y0, t, y); return y[0]; } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/TestProblem1.java 100644 1750 1750 4260 12126627673 26520 0 ustar luc luc 0 0 /* * 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.math3.ode; import org.apache.commons.math3.util.FastMath; /** * This class is used in the junit tests for the ODE integrators. *
This specific problem is the following differential equation : *
* y' = -y ** the solution of this equation is a simple exponential function : *
* y (t) = y (t0) exp (t0-t) ** */ public class TestProblem1 extends TestProblemAbstract { /** theoretical state */ private double[] y; /** * Simple constructor. */ public TestProblem1() { super(); double[] y0 = { 1.0, 0.1 }; setInitialConditions(0.0, y0); setFinalConditions(4.0); double[] errorScale = { 1.0, 1.0 }; setErrorScale(errorScale); y = new double[y0.length]; } /** * Copy constructor. * @param problem problem to copy */ public TestProblem1(TestProblem1 problem) { super(problem); y = problem.y.clone(); } /** {@inheritDoc} */ @Override public TestProblem1 copy() { return new TestProblem1(this); } @Override public void doComputeDerivatives(double t, double[] y, double[] yDot) { // compute the derivatives for (int i = 0; i < n; ++i) yDot[i] = -y[i]; } @Override public double[] computeTheoreticalState(double t) { double c = FastMath.exp (t0 - t); for (int i = 0; i < n; ++i) { y[i] = c * y0[i]; } return y; } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/TestProblemAbstract.java 100644 1750 1750 10305 12126627673 30140 0 ustar luc luc 0 0 /* * 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.math3.ode; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.events.EventHandler; /** * This class is used as the base class of the problems that are * integrated during the junit tests for the ODE integrators. */ public abstract class TestProblemAbstract implements FirstOrderDifferentialEquations { /** Dimension of the problem. */ protected int n; /** Number of functions calls. */ protected int calls; /** Initial time */ protected double t0; /** Initial state */ protected double[] y0; /** Final time */ protected double t1; /** Error scale */ protected double[] errorScale; /** * Simple constructor. */ protected TestProblemAbstract() { n = 0; calls = 0; t0 = 0; y0 = null; t1 = 0; errorScale = null; } /** * Copy constructor. * @param problem problem to copy */ protected TestProblemAbstract(TestProblemAbstract problem) { n = problem.n; calls = problem.calls; t0 = problem.t0; if (problem.y0 == null) { y0 = null; } else { y0 = problem.y0.clone(); } if (problem.errorScale == null) { errorScale = null; } else { errorScale = problem.errorScale.clone(); } t1 = problem.t1; } /** * Copy operation. * @return a copy of the instance */ public abstract TestProblemAbstract copy(); /** * Set the initial conditions * @param t0 initial time * @param y0 initial state vector */ protected void setInitialConditions(double t0, double[] y0) { calls = 0; n = y0.length; this.t0 = t0; this.y0 = y0.clone(); } /** * Set the final conditions. * @param t1 final time */ protected void setFinalConditions(double t1) { this.t1 = t1; } /** * Set the error scale * @param errorScale error scale */ protected void setErrorScale(double[] errorScale) { this.errorScale = errorScale.clone(); } public int getDimension() { return n; } /** * Get the initial time. * @return initial time */ public double getInitialTime() { return t0; } /** * Get the initial state vector. * @return initial state vector */ public double[] getInitialState() { return y0; } /** * Get the final time. * @return final time */ public double getFinalTime() { return t1; } /** * Get the error scale. * @return error scale */ public double[] getErrorScale() { return errorScale; } /** * Get the events handlers. * @return events handlers */ public EventHandler[] getEventsHandlers() { return new EventHandler[0]; } /** * Get the theoretical events times. * @return theoretical events times */ public double[] getTheoreticalEventsTimes() { return new double[0]; } /** * Get the number of calls. * @return nuber of calls */ public int getCalls() { return calls; } public void computeDerivatives(double t, double[] y, double[] yDot) { ++calls; doComputeDerivatives(t, y, yDot); } abstract public void doComputeDerivatives(double t, double[] y, double[] yDot); /** * Compute the theoretical state at the specified time. * @param t time at which the state is required * @return state vector at time t */ abstract public double[] computeTheoreticalState(double t); } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/TestProblem3.java 100644 1750 1750 6315 12126627673 26525 0 ustar luc luc 0 0 /* * 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.math3.ode; import org.apache.commons.math3.util.FastMath; /** * This class is used in the junit tests for the ODE integrators. *
This specific problem is the following differential equation : *
* y1'' = -y1/r^3 y1 (0) = 1-e y1' (0) = 0 * y2'' = -y2/r^3 y2 (0) = 0 y2' (0) =sqrt((1+e)/(1-e)) * r = sqrt (y1^2 + y2^2), e = 0.9 ** This is a two-body problem in the plane which can be solved by * Kepler's equation *
* y1 (t) = ... ** */ public class TestProblem3 extends TestProblemAbstract { /** Eccentricity */ double e; /** theoretical state */ private double[] y; /** * Simple constructor. * @param e eccentricity */ public TestProblem3(double e) { super(); this.e = e; double[] y0 = { 1 - e, 0, 0, FastMath.sqrt((1+e)/(1-e)) }; setInitialConditions(0.0, y0); setFinalConditions(20.0); double[] errorScale = { 1.0, 1.0, 1.0, 1.0 }; setErrorScale(errorScale); y = new double[y0.length]; } /** * Simple constructor. */ public TestProblem3() { this(0.1); } /** * Copy constructor. * @param problem problem to copy */ public TestProblem3(TestProblem3 problem) { super(problem); e = problem.e; y = problem.y.clone(); } /** {@inheritDoc} */ @Override public TestProblem3 copy() { return new TestProblem3(this); } @Override public void doComputeDerivatives(double t, double[] y, double[] yDot) { // current radius double r2 = y[0] * y[0] + y[1] * y[1]; double invR3 = 1 / (r2 * FastMath.sqrt(r2)); // compute the derivatives yDot[0] = y[2]; yDot[1] = y[3]; yDot[2] = -invR3 * y[0]; yDot[3] = -invR3 * y[1]; } @Override public double[] computeTheoreticalState(double t) { // solve Kepler's equation double E = t; double d = 0; double corr = 999.0; for (int i = 0; (i < 50) && (FastMath.abs(corr) > 1.0e-12); ++i) { double f2 = e * FastMath.sin(E); double f0 = d - f2; double f1 = 1 - e * FastMath.cos(E); double f12 = f1 + f1; corr = f0 * f12 / (f1 * f12 - f0 * f2); d -= corr; E = t + d; } double cosE = FastMath.cos(E); double sinE = FastMath.sin(E); y[0] = cosE - e; y[1] = FastMath.sqrt(1 - e * e) * sinE; y[2] = -sinE / (1 - e * cosE); y[3] = FastMath.sqrt(1 - e * e) * cosE / (1 - e * cosE); return y; } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/TestProblem5.java 100644 1750 1750 2375 12126627673 26531 0 ustar luc luc 0 0 /* * 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.math3.ode; /** * This class is used in the junit tests for the ODE integrators. *
This is the same as problem 1 except integration is done * backward in time
*/ public class TestProblem5 extends TestProblem1 { /** * Simple constructor. */ public TestProblem5() { super(); setFinalConditions(2 * t0 - t1); } /** {@inheritDoc} */ @Override public TestProblem5 copy() { return new TestProblem5(); } } ././@LongLink 100644 0 0 166 12126630646 10264 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/GraggBulirschStoerStepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/GraggBulirschStoerStepInte100644 1750 1750 14642 12126627673 32346 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.ContinuousOutputModel; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.ode.sampling.StepInterpolatorTestUtils; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class GraggBulirschStoerStepInterpolatorTest { @Test public void derivativesConsistency() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double absTolerance = 1.0e-8; double relTolerance = 1.0e-8; GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, absTolerance, relTolerance); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-8); } @Test public void serialization() throws IOException, ClassNotFoundException, DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double absTolerance = 1.0e-8; double relTolerance = 1.0e-8; GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, absTolerance, relTolerance); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } Assert.assertTrue(bos.size () > 35000); Assert.assertTrue(bos.size () < 36000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } Assert.assertTrue(maxError < 5.0e-10); } @Test public void checklone() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { StepInterpolator cloned = interpolator.copy(); double tA = cloned.getPreviousTime(); double tB = cloned.getCurrentTime(); double halfStep = FastMath.abs(tB - tA) / 2; Assert.assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12); Assert.assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12); for (int i = 0; i < 10; ++i) { double t = (i * tB + (9 - i) * tA) / 9; interpolator.setInterpolatedTime(t); Assert.assertTrue(FastMath.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10)); cloned.setInterpolatedTime(t); Assert.assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12); double[] referenceState = interpolator.getInterpolatedState(); double[] cloneState = cloned.getInterpolatedState(); for (int j = 0; j < referenceState.length; ++j) { Assert.assertEquals(referenceState[j], cloneState[j], 1.0e-12); } } } public void init(double t0, double[] y0, double t) { } }); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/GillIntegratorTest.java 100644 1750 1750 23023 12126627673 31631 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblemAbstract; import org.apache.commons.math3.ode.TestProblemFactory; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.ode.events.EventHandler; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class GillIntegratorTest { @Test(expected=DimensionMismatchException.class) public void testDimensionCheck() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); new GillIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); Assert.fail("an exception should have been thrown"); } @Test public void testDecreasingSteps() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblemAbstract[] problems = TestProblemFactory.getProblems(); for (int k = 0; k < problems.length; ++k) { double previousValueError = Double.NaN; double previousTimeError = Double.NaN; for (int i = 5; i < 10; ++i) { TestProblemAbstract pb = problems[k].copy(); double step = (pb.getFinalTime() - pb.getInitialTime()) * FastMath.pow(2.0, -i); FirstOrderIntegrator integ = new GillIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); } double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) { Assert.assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } double valueError = handler.getMaximalValueError(); if (i > 5) { Assert.assertTrue(valueError < 1.01 * FastMath.abs(previousValueError)); } previousValueError = valueError; double timeError = handler.getMaximalTimeError(); if (i > 5) { Assert.assertTrue(timeError <= FastMath.abs(previousTimeError)); } previousTimeError = timeError; } } } @Test public void testSmallStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new GillIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 2.0e-13); Assert.assertTrue(handler.getMaximalValueError() < 4.0e-12); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("Gill", integ.getName()); } @Test public void testBigStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2; FirstOrderIntegrator integ = new GillIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() > 0.0004); Assert.assertTrue(handler.getMaximalValueError() > 0.005); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); } @Test public void testBackward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double step = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new GillIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 5.0e-10); Assert.assertTrue(handler.getMaximalValueError() < 7.0e-10); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("Gill", integ.getName()); } @Test public void testKepler() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; FirstOrderIntegrator integ = new GillIntegrator(step); integ.addStepHandler(new KeplerStepHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } @Test public void testUnstableDerivative() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final StepProblem stepProblem = new StepProblem(0.0, 1.0, 2.0); FirstOrderIntegrator integ = new GillIntegrator(0.3); integ.addEventHandler(stepProblem, 1.0, 1.0e-12, 1000); double[] y = { Double.NaN }; integ.integrate(stepProblem, 0.0, new double[] { 0.0 }, 10.0, y); Assert.assertEquals(8.0, y[0], 1.0e-12); } private static class KeplerStepHandler implements StepHandler { public KeplerStepHandler(TestProblem3 pb) { this.pb = pb; } public void init(double t0, double[] y0, double t) { maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { double[] interpolatedY = interpolator.getInterpolatedState(); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getCurrentTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } if (isLast) { // even with more than 1000 evaluations per period, // RK4 is not able to integrate such an eccentric // orbit with a good accuracy Assert.assertTrue(maxError > 0.001); } } private double maxError; private TestProblem3 pb; } @Test public void testStepSize() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final double step = 1.23456; FirstOrderIntegrator integ = new GillIntegrator(step); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) { if (! isLast) { Assert.assertEquals(step, interpolator.getCurrentTime() - interpolator.getPreviousTime(), 1.0e-12); } } public void init(double t0, double[] y0, double t) { } }); integ.integrate(new FirstOrderDifferentialEquations() { public void computeDerivatives(double t, double[] y, double[] dot) { dot[0] = 1.0; } public int getDimension() { return 1; } }, 0.0, new double[] { 0.0 }, 5.0, new double[1]); } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/StepProblem.java 100644 1750 1750 3535 12126627673 30265 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.events.EventHandler; public class StepProblem implements FirstOrderDifferentialEquations, EventHandler { public StepProblem(double rateBefore, double rateAfter, double switchTime) { this.rateAfter = rateAfter; this.switchTime = switchTime; setRate(rateBefore); } public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = rate; } public int getDimension() { return 1; } public void setRate(double rate) { this.rate = rate; } public void init(double t0, double[] y0, double t) { } public Action eventOccurred(double t, double[] y, boolean increasing) { setRate(rateAfter); return Action.RESET_DERIVATIVES; } public double g(double t, double[] y) { return t - switchTime; } public void resetState(double t, double[] y) { } private double rate; private double rateAfter; private double switchTime; } ././@LongLink 100644 0 0 163 12126630646 10261 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54StepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54StepInterpo100644 1750 1750 15337 12126627673 32227 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.ContinuousOutputModel; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.ode.sampling.StepInterpolatorTestUtils; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class DormandPrince54StepInterpolatorTest { @Test public void derivativesConsistency() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.1); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince54Integrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws IOException, ClassNotFoundException, DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince54Integrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } Assert.assertTrue(bos.size () > 135000); Assert.assertTrue(bos.size () < 145000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } Assert.assertTrue(maxError < 7.0e-10); } @Test public void checkClone() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince54Integrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { StepInterpolator cloned = interpolator.copy(); double tA = cloned.getPreviousTime(); double tB = cloned.getCurrentTime(); double halfStep = FastMath.abs(tB - tA) / 2; Assert.assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12); Assert.assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12); for (int i = 0; i < 10; ++i) { double t = (i * tB + (9 - i) * tA) / 9; interpolator.setInterpolatedTime(t); Assert.assertTrue(FastMath.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10)); cloned.setInterpolatedTime(t); Assert.assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12); double[] referenceState = interpolator.getInterpolatedState(); double[] cloneState = cloned.getInterpolatedState(); for (int j = 0; j < referenceState.length; ++j) { Assert.assertEquals(referenceState[j], cloneState[j], 1.0e-12); } } } public void init(double t0, double[] y0, double t) { } }); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } } ././@LongLink 100644 0 0 160 12126630646 10256 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/GraggBulirschStoerIntegratorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/GraggBulirschStoerIntegrat100644 1750 1750 41011 12126627673 32356 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.TestProblem4; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblemAbstract; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.ode.events.EventHandler; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class GraggBulirschStoerIntegratorTest { @Test(expected=DimensionMismatchException.class) public void testDimensionCheck() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); AdaptiveStepsizeIntegrator integrator = new GraggBulirschStoerIntegrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); } @Test(expected=NumberIsTooSmallException.class) public void testNullIntervalCheck() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); GraggBulirschStoerIntegrator integrator = new GraggBulirschStoerIntegrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()], 0.0, new double[pb.getDimension()]); } @Test(expected=NumberIsTooSmallException.class) public void testMinStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double minStep = 0.1 * FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); double maxStep = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); double[] vecAbsoluteTolerance = { 1.0e-20, 1.0e-21 }; double[] vecRelativeTolerance = { 1.0e-20, 1.0e-21 }; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } @Test public void testBackward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 7.5e-9); Assert.assertTrue(handler.getMaximalValueError() < 8.1e-9); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("Gragg-Bulirsch-Stoer", integ.getName()); } @Test public void testIncreasingTolerance() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -4; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double absTolerance = FastMath.pow(10.0, i); double relTolerance = absTolerance; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, absTolerance, relTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); // the coefficients are only valid for this test // and have been obtained from trial and error // there is no general relation between local and global errors double ratio = handler.getMaximalValueError() / absTolerance; Assert.assertTrue(ratio < 2.4); Assert.assertTrue(ratio > 0.02); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); int calls = pb.getCalls(); Assert.assertEquals(integ.getEvaluations(), calls); Assert.assertTrue(calls <= previousCalls); previousCalls = calls; } } @Test public void testIntegratorControls() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.999); GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(0, pb.getFinalTime() - pb.getInitialTime(), 1.0e-8, 1.0e-10); double errorWithDefaultSettings = getMaxError(integ, pb); // stability control integ.setStabilityCheck(true, 2, 1, 0.99); Assert.assertTrue(errorWithDefaultSettings < getMaxError(integ, pb)); integ.setStabilityCheck(true, -1, -1, -1); integ.setControlFactors(0.5, 0.99, 0.1, 2.5); Assert.assertTrue(errorWithDefaultSettings < getMaxError(integ, pb)); integ.setControlFactors(-1, -1, -1, -1); integ.setOrderControl(10, 0.7, 0.95); Assert.assertTrue(errorWithDefaultSettings < getMaxError(integ, pb)); integ.setOrderControl(-1, -1, -1); integ.setInterpolationControl(true, 3); Assert.assertTrue(errorWithDefaultSettings < getMaxError(integ, pb)); integ.setInterpolationControl(true, -1); } private double getMaxError(FirstOrderIntegrator integrator, TestProblemAbstract pb) throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblemHandler handler = new TestProblemHandler(pb, integrator); integrator.addStepHandler(handler); integrator.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); return handler.getMaximalValueError(); } @Test public void testEvents() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem4 pb = new TestProblem4(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-10; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); double convergence = 1.0e-8 * maxStep; for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, convergence, 1000); } Assert.assertEquals(functions.length, integ.getEventHandlers().size()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getMaximalValueError() < 4.0e-7); Assert.assertEquals(0, handler.getMaximalTimeError(), convergence); Assert.assertEquals(12.0, handler.getLastTime(), convergence); integ.clearEventHandlers(); Assert.assertEquals(0, integ.getEventHandlers().size()); } @Test public void testKepler() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double absTolerance = 1.0e-6; double relTolerance = 1.0e-6; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, absTolerance, relTolerance); integ.addStepHandler(new KeplerStepHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertEquals(integ.getEvaluations(), pb.getCalls()); Assert.assertTrue(pb.getCalls() < 2150); } @Test public void testVariableSteps() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double absTolerance = 1.0e-8; double relTolerance = 1.0e-8; FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep, absTolerance, relTolerance); integ.addStepHandler(new VariableStepHandler()); double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); Assert.assertEquals("Gragg-Bulirsch-Stoer", integ.getName()); } @Test public void testTooLargeFirstStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { AdaptiveStepsizeIntegrator integ = new GraggBulirschStoerIntegrator(0, Double.POSITIVE_INFINITY, Double.NaN, Double.NaN); final double start = 0.0; final double end = 0.001; FirstOrderDifferentialEquations equations = new FirstOrderDifferentialEquations() { public int getDimension() { return 1; } public void computeDerivatives(double t, double[] y, double[] yDot) { Assert.assertTrue(t >= FastMath.nextAfter(start, Double.NEGATIVE_INFINITY)); Assert.assertTrue(t <= FastMath.nextAfter(end, Double.POSITIVE_INFINITY)); yDot[0] = -100.0 * y[0]; } }; integ.setStepSizeControl(0, 1.0, 1.0e-6, 1.0e-8); integ.integrate(equations, start, new double[] { 1.0 }, end, new double[1]); } @Test public void testUnstableDerivative() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final StepProblem stepProblem = new StepProblem(0.0, 1.0, 2.0); FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(0.1, 10, 1.0e-12, 0.0); integ.addEventHandler(stepProblem, 1.0, 1.0e-12, 1000); double[] y = { Double.NaN }; integ.integrate(stepProblem, 0.0, new double[] { 0.0 }, 10.0, y); Assert.assertEquals(8.0, y[0], 1.0e-12); } @Test public void testIssue596() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(1e-10, 100.0, 1e-7, 1e-7); integ.addStepHandler(new StepHandler() { public void init(double t0, double[] y0, double t) { } public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { double t = interpolator.getCurrentTime(); interpolator.setInterpolatedTime(t); double[] y = interpolator.getInterpolatedState(); double[] yDot = interpolator.getInterpolatedDerivatives(); Assert.assertEquals(3.0 * t - 5.0, y[0], 1.0e-14); Assert.assertEquals(3.0, yDot[0], 1.0e-14); } }); double[] y = {4.0}; double t0 = 3.0; double tend = 10.0; integ.integrate(new FirstOrderDifferentialEquations() { public int getDimension() { return 1; } public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = 3.0; } }, t0, y, tend, y); } private static class KeplerStepHandler implements StepHandler { public KeplerStepHandler(TestProblem3 pb) { this.pb = pb; } public void init(double t0, double[] y0, double t) { nbSteps = 0; maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { ++nbSteps; for (int a = 1; a < 100; ++a) { double prev = interpolator.getPreviousTime(); double curr = interpolator.getCurrentTime(); double interp = ((100 - a) * prev + a * curr) / 100; interpolator.setInterpolatedTime(interp); double[] interpolatedY = interpolator.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getInterpolatedTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } if (isLast) { Assert.assertTrue(maxError < 2.7e-6); Assert.assertTrue(nbSteps < 80); } } private int nbSteps; private double maxError; private TestProblem3 pb; } public static class VariableStepHandler implements StepHandler { public VariableStepHandler() { firstTime = true; minStep = 0; maxStep = 0; } public void init(double t0, double[] y0, double t) { firstTime = true; minStep = 0; maxStep = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) { double step = FastMath.abs(interpolator.getCurrentTime() - interpolator.getPreviousTime()); if (firstTime) { minStep = FastMath.abs(step); maxStep = minStep; firstTime = false; } else { if (step < minStep) { minStep = step; } if (step > maxStep) { maxStep = step; } } if (isLast) { Assert.assertTrue(minStep < 8.2e-3); Assert.assertTrue(maxStep > 1.5); } } private boolean firstTime; private double minStep; private double maxStep; } } ././@LongLink 100644 0 0 164 12126630646 10262 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853StepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853StepInterp100644 1750 1750 15247 12126627673 32137 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.ContinuousOutputModel; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.ode.sampling.StepInterpolatorTestUtils; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class DormandPrince853StepInterpolatorTest { @Test public void derivativesConsistency() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.1); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince853Integrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws IOException, ClassNotFoundException, DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince853Integrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } Assert.assertTrue(bos.size () > 90000); Assert.assertTrue(bos.size () < 100000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } Assert.assertTrue(maxError < 2.4e-10); } @Test public void checklone() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; DormandPrince853Integrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { StepInterpolator cloned = interpolator.copy(); double tA = cloned.getPreviousTime(); double tB = cloned.getCurrentTime(); double halfStep = FastMath.abs(tB - tA) / 2; Assert.assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12); Assert.assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12); for (int i = 0; i < 10; ++i) { double t = (i * tB + (9 - i) * tA) / 9; interpolator.setInterpolatedTime(t); Assert.assertTrue(FastMath.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10)); cloned.setInterpolatedTime(t); Assert.assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12); double[] referenceState = interpolator.getInterpolatedState(); double[] cloneState = cloned.getInterpolatedState(); for (int j = 0; j < referenceState.length; ++j) { Assert.assertEquals(referenceState[j], cloneState[j], 1.0e-12); } } } public void init(double t0, double[] y0, double t) { } }); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } } ././@LongLink 100644 0 0 161 12126630646 10257 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaIntegra100644 1750 1750 30245 12126627673 32351 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblemAbstract; import org.apache.commons.math3.ode.TestProblemFactory; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.ode.events.EventHandler; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class ClassicalRungeKuttaIntegratorTest { @Test public void testMissedEndEvent() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final double t0 = 1878250320.0000029; final double tEvent = 1878250379.9999986; final double[] k = { 1.0e-4, 1.0e-5, 1.0e-6 }; FirstOrderDifferentialEquations ode = new FirstOrderDifferentialEquations() { public int getDimension() { return k.length; } public void computeDerivatives(double t, double[] y, double[] yDot) { for (int i = 0; i < y.length; ++i) { yDot[i] = k[i] * y[i]; } } }; ClassicalRungeKuttaIntegrator integrator = new ClassicalRungeKuttaIntegrator(60.0); double[] y0 = new double[k.length]; for (int i = 0; i < y0.length; ++i) { y0[i] = i + 1; } double[] y = new double[k.length]; double finalT = integrator.integrate(ode, t0, y0, tEvent, y); Assert.assertEquals(tEvent, finalT, 5.0e-6); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(y0[i] * FastMath.exp(k[i] * (finalT - t0)), y[i], 1.0e-9); } integrator.addEventHandler(new EventHandler() { public void init(double t0, double[] y0, double t) { } public void resetState(double t, double[] y) { } public double g(double t, double[] y) { return t - tEvent; } public Action eventOccurred(double t, double[] y, boolean increasing) { Assert.assertEquals(tEvent, t, 5.0e-6); return Action.CONTINUE; } }, Double.POSITIVE_INFINITY, 1.0e-20, 100); finalT = integrator.integrate(ode, t0, y0, tEvent + 120, y); Assert.assertEquals(tEvent + 120, finalT, 5.0e-6); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(y0[i] * FastMath.exp(k[i] * (finalT - t0)), y[i], 1.0e-9); } } @Test public void testSanityChecks() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { try { TestProblem1 pb = new TestProblem1(); new ClassicalRungeKuttaIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } catch(DimensionMismatchException ie) { } try { TestProblem1 pb = new TestProblem1(); new ClassicalRungeKuttaIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()], 1.0, new double[pb.getDimension()+10]); Assert.fail("an exception should have been thrown"); } catch(DimensionMismatchException ie) { } try { TestProblem1 pb = new TestProblem1(); new ClassicalRungeKuttaIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()], 0.0, new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } catch(NumberIsTooSmallException ie) { } } @Test public void testDecreasingSteps() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblemAbstract[] problems = TestProblemFactory.getProblems(); for (int k = 0; k < problems.length; ++k) { double previousValueError = Double.NaN; double previousTimeError = Double.NaN; for (int i = 4; i < 10; ++i) { TestProblemAbstract pb = problems[k].copy(); double step = (pb.getFinalTime() - pb.getInitialTime()) * FastMath.pow(2.0, -i); FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); } Assert.assertEquals(functions.length, integ.getEventHandlers().size()); double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) { Assert.assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } double error = handler.getMaximalValueError(); if (i > 4) { Assert.assertTrue(error < 1.01 * FastMath.abs(previousValueError)); } previousValueError = error; double timeError = handler.getMaximalTimeError(); if (i > 4) { Assert.assertTrue(timeError <= FastMath.abs(previousTimeError)); } previousTimeError = timeError; integ.clearEventHandlers(); Assert.assertEquals(0, integ.getEventHandlers().size()); } } } @Test public void testSmallStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 2.0e-13); Assert.assertTrue(handler.getMaximalValueError() < 4.0e-12); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("classical Runge-Kutta", integ.getName()); } @Test public void testBigStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2; FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() > 0.0004); Assert.assertTrue(handler.getMaximalValueError() > 0.005); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); } @Test public void testBackward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double step = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 5.0e-10); Assert.assertTrue(handler.getMaximalValueError() < 7.0e-10); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("classical Runge-Kutta", integ.getName()); } @Test public void testKepler() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); integ.addStepHandler(new KeplerHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } private static class KeplerHandler implements StepHandler { public KeplerHandler(TestProblem3 pb) { this.pb = pb; maxError = 0; } public void init(double t0, double[] y0, double t) { maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { double[] interpolatedY = interpolator.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getCurrentTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } if (isLast) { // even with more than 1000 evaluations per period, // RK4 is not able to integrate such an eccentric // orbit with a good accuracy Assert.assertTrue(maxError > 0.005); } } private double maxError = 0; private TestProblem3 pb; } @Test public void testStepSize() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final double step = 1.23456; FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) { if (! isLast) { Assert.assertEquals(step, interpolator.getCurrentTime() - interpolator.getPreviousTime(), 1.0e-12); } } public void init(double t0, double[] y0, double t) { } }); integ.integrate(new FirstOrderDifferentialEquations() { public void computeDerivatives(double t, double[] y, double[] dot) { dot[0] = 1.0; } public int getDimension() { return 1; } }, 0.0, new double[] { 0.0 }, 5.0, new double[1]); } } ././@LongLink 100644 0 0 146 12126630646 10262 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/MidpointIntegratorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/MidpointIntegratorTest.jav100644 1750 1750 17045 12126627673 32373 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblemAbstract; import org.apache.commons.math3.ode.TestProblemFactory; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.ode.events.EventHandler; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class MidpointIntegratorTest { @Test(expected=DimensionMismatchException.class) public void testDimensionCheck() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); new MidpointIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); Assert.fail("an exception should have been thrown"); } @Test public void testDecreasingSteps() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblemAbstract[] problems = TestProblemFactory.getProblems(); for (int k = 0; k < problems.length; ++k) { double previousValueError = Double.NaN; double previousTimeError = Double.NaN; for (int i = 4; i < 10; ++i) { TestProblemAbstract pb = problems[k].copy(); double step = (pb.getFinalTime() - pb.getInitialTime()) * FastMath.pow(2.0, -i); FirstOrderIntegrator integ = new MidpointIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); } double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) { Assert.assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } double valueError = handler.getMaximalValueError(); if (i > 4) { Assert.assertTrue(valueError < FastMath.abs(previousValueError)); } previousValueError = valueError; double timeError = handler.getMaximalTimeError(); if (i > 4) { Assert.assertTrue(timeError <= FastMath.abs(previousTimeError)); } previousTimeError = timeError; } } } @Test public void testSmallStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new MidpointIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 2.0e-7); Assert.assertTrue(handler.getMaximalValueError() < 1.0e-6); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("midpoint", integ.getName()); } @Test public void testBigStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2; FirstOrderIntegrator integ = new MidpointIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() > 0.01); Assert.assertTrue(handler.getMaximalValueError() > 0.05); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); } @Test public void testBackward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double step = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new MidpointIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 6.0e-4); Assert.assertTrue(handler.getMaximalValueError() < 6.0e-4); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("midpoint", integ.getName()); } @Test public void testStepSize() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final double step = 1.23456; FirstOrderIntegrator integ = new MidpointIntegrator(step); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) { if (! isLast) { Assert.assertEquals(step, interpolator.getCurrentTime() - interpolator.getPreviousTime(), 1.0e-12); } } public void init(double t0, double[] y0, double t) { } }); integ.integrate(new FirstOrderDifferentialEquations() { public void computeDerivatives(double t, double[] y, double[] dot) { dot[0] = 1.0; } public int getDimension() { return 1; } }, 0.0, new double[] { 0.0 }, 5.0, new double[1]); } } ././@LongLink 100644 0 0 160 12126630646 10256 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54StepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54StepInterpolat100644 1750 1750 15135 12126627673 32175 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.ContinuousOutputModel; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.ode.sampling.StepInterpolatorTestUtils; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class HighamHall54StepInterpolatorTest { @Test public void derivativesConsistency() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.1); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; HighamHall54Integrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.1e-10); } @Test public void serialization() throws IOException, ClassNotFoundException, DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; HighamHall54Integrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } Assert.assertTrue(bos.size () > 185000); Assert.assertTrue(bos.size () < 195000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } Assert.assertTrue(maxError < 1.6e-10); } @Test public void checkClone() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; HighamHall54Integrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { StepInterpolator cloned = interpolator.copy(); double tA = cloned.getPreviousTime(); double tB = cloned.getCurrentTime(); double halfStep = FastMath.abs(tB - tA) / 2; Assert.assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12); Assert.assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12); for (int i = 0; i < 10; ++i) { double t = (i * tB + (9 - i) * tA) / 9; interpolator.setInterpolatedTime(t); Assert.assertTrue(FastMath.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10)); cloned.setInterpolatedTime(t); Assert.assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12); double[] referenceState = interpolator.getInterpolatedState(); double[] cloneState = cloned.getInterpolatedState(); for (int j = 0; j < referenceState.length; ++j) { Assert.assertEquals(referenceState[j], cloneState[j], 1.0e-12); } } } public void init(double t0, double[] y0, double t) { } }); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } } ././@LongLink 100644 0 0 155 12126630646 10262 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54IntegratorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54IntegratorT100644 1750 1750 33234 12126627673 32211 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.TestProblem4; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblemAbstract; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.ode.events.EventHandler; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class DormandPrince54IntegratorTest { @Test(expected=DimensionMismatchException.class) public void testDimensionCheck() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); DormandPrince54Integrator integrator = new DormandPrince54Integrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); } @Test(expected=NumberIsTooSmallException.class) public void testMinStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } @Test public void testSmallLastStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblemAbstract pb = new TestProblem5(); double minStep = 1.25; double maxStep = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); double scalAbsoluteTolerance = 6.0e-4; double scalRelativeTolerance = 6.0e-4; AdaptiveStepsizeIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); DP54SmallLastHandler handler = new DP54SmallLastHandler(minStep); integ.addStepHandler(handler); integ.setInitialStepSize(1.7); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.wasLastSeen()); Assert.assertEquals("Dormand-Prince 5(4)", integ.getName()); } @Test public void testBackward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 2.0e-7); Assert.assertTrue(handler.getMaximalValueError() < 2.0e-7); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("Dormand-Prince 5(4)", integ.getName()); } private static class DP54SmallLastHandler implements StepHandler { public DP54SmallLastHandler(double minStep) { lastSeen = false; this.minStep = minStep; } public void init(double t0, double[] y0, double t) { } public void handleStep(StepInterpolator interpolator, boolean isLast) { if (isLast) { lastSeen = true; double h = interpolator.getCurrentTime() - interpolator.getPreviousTime(); Assert.assertTrue(FastMath.abs(h) < minStep); } } public boolean wasLastSeen() { return lastSeen; } private boolean lastSeen; private double minStep; } @Test public void testIncreasingTolerance() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -2; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = FastMath.pow(10.0, i); double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; EmbeddedRungeKuttaIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.setSafety(0.8); integ.setMaxGrowth(5.0); integ.setMinReduction(0.3); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertEquals(0.8, integ.getSafety(), 1.0e-12); Assert.assertEquals(5.0, integ.getMaxGrowth(), 1.0e-12); Assert.assertEquals(0.3, integ.getMinReduction(), 1.0e-12); // the 0.7 factor is only valid for this test // and has been obtained from trial and error // there is no general relation between local and global errors Assert.assertTrue(handler.getMaximalValueError() < (0.7 * scalAbsoluteTolerance)); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); int calls = pb.getCalls(); Assert.assertEquals(integ.getEvaluations(), calls); Assert.assertTrue(calls <= previousCalls); previousCalls = calls; } } @Test public void testEvents() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem4 pb = new TestProblem4(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); double convergence = 1.0e-8 * maxStep; for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, convergence, 1000); } Assert.assertEquals(functions.length, integ.getEventHandlers().size()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getMaximalValueError() < 5.0e-6); Assert.assertEquals(0, handler.getMaximalTimeError(), convergence); Assert.assertEquals(12.0, handler.getLastTime(), convergence); integ.clearEventHandlers(); Assert.assertEquals(0, integ.getEventHandlers().size()); } @Test public void testKepler() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new KeplerHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertEquals(integ.getEvaluations(), pb.getCalls()); Assert.assertTrue(pb.getCalls() < 2800); } @Test public void testVariableSteps() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new VariableHandler()); double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } private static class KeplerHandler implements StepHandler { public KeplerHandler(TestProblem3 pb) { this.pb = pb; } public void init(double t0, double[] y0, double t) { nbSteps = 0; maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { ++nbSteps; for (int a = 1; a < 10; ++a) { double prev = interpolator.getPreviousTime(); double curr = interpolator.getCurrentTime(); double interp = ((10 - a) * prev + a * curr) / 10; interpolator.setInterpolatedTime(interp); double[] interpolatedY = interpolator.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getInterpolatedTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } if (isLast) { Assert.assertTrue(maxError < 7.0e-10); Assert.assertTrue(nbSteps < 400); } } private int nbSteps; private double maxError; private TestProblem3 pb; } private static class VariableHandler implements StepHandler { public VariableHandler() { firstTime = true; minStep = 0; maxStep = 0; } public void init(double t0, double[] y0, double t) { firstTime = true; minStep = 0; maxStep = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) { double step = FastMath.abs(interpolator.getCurrentTime() - interpolator.getPreviousTime()); if (firstTime) { minStep = FastMath.abs(step); maxStep = minStep; firstTime = false; } else { if (step < minStep) { minStep = step; } if (step > maxStep) { maxStep = step; } } if (isLast) { Assert.assertTrue(minStep < (1.0 / 450.0)); Assert.assertTrue(maxStep > (1.0 / 4.2)); } } private boolean firstTime; private double minStep; private double maxStep; } } ././@LongLink 100644 0 0 167 12126630646 10265 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaStepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaStepInt100644 1750 1750 7533 12126627673 32332 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.ContinuousOutputModel; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolatorTestUtils; import org.junit.Assert; import org.junit.Test; public class ClassicalRungeKuttaStepInterpolatorTest { @Test public void derivativesConsistency() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; ClassicalRungeKuttaIntegrator integ = new ClassicalRungeKuttaIntegrator(step); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws IOException, ClassNotFoundException, DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; ClassicalRungeKuttaIntegrator integ = new ClassicalRungeKuttaIntegrator(step); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } Assert.assertTrue(bos.size () > 880000); Assert.assertTrue(bos.size () < 900000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } Assert.assertTrue(maxError > 0.005); } } ././@LongLink 100644 0 0 150 12126630646 10255 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/GillStepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/GillStepInterpolatorTest.j100644 1750 1750 7423 12126627673 32327 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.ContinuousOutputModel; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolatorTestUtils; import org.junit.Assert; import org.junit.Test; public class GillStepInterpolatorTest { @Test public void testDerivativesConsistency() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; GillIntegrator integ = new GillIntegrator(step); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws IOException, ClassNotFoundException, DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; GillIntegrator integ = new GillIntegrator(step); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } Assert.assertTrue(bos.size () > 880000); Assert.assertTrue(bos.size () < 900000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } Assert.assertTrue(maxError < 0.003); } } ././@LongLink 100644 0 0 152 12126630646 10257 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/AdamsMoultonIntegratorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/AdamsMoultonIntegratorTest100644 1750 1750 17021 12126627673 32426 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblem6; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class AdamsMoultonIntegratorTest { @Test(expected=DimensionMismatchException.class) public void dimensionCheck() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); FirstOrderIntegrator integ = new AdamsMoultonIntegrator(2, 0.0, 1.0, 1.0e-10, 1.0e-10); integ.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); } @Test(expected=NumberIsTooSmallException.class) public void testMinStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; FirstOrderIntegrator integ = new AdamsMoultonIntegrator(4, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } @Test public void testIncreasingTolerance() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -2; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = FastMath.pow(10.0, i); double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new AdamsMoultonIntegrator(4, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); // the 0.5 and 11.0 factors are only valid for this test // and has been obtained from trial and error // there is no general relation between local and global errors Assert.assertTrue(handler.getMaximalValueError() > ( 0.5 * scalAbsoluteTolerance)); Assert.assertTrue(handler.getMaximalValueError() < (11.0 * scalAbsoluteTolerance)); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-16); int calls = pb.getCalls(); Assert.assertEquals(integ.getEvaluations(), calls); Assert.assertTrue(calls <= previousCalls); previousCalls = calls; } } @Test(expected = MaxCountExceededException.class) public void exceedMaxEvaluations() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double range = pb.getFinalTime() - pb.getInitialTime(); AdamsMoultonIntegrator integ = new AdamsMoultonIntegrator(2, 0, range, 1.0e-12, 1.0e-12); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.setMaxEvaluations(650); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } @Test public void backward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double range = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); FirstOrderIntegrator integ = new AdamsMoultonIntegrator(4, 0, range, 1.0e-12, 1.0e-12); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 1.0e-9); Assert.assertTrue(handler.getMaximalValueError() < 1.0e-9); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-16); Assert.assertEquals("Adams-Moulton", integ.getName()); } @Test public void polynomial() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem6 pb = new TestProblem6(); double range = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); for (int nSteps = 2; nSteps < 8; ++nSteps) { AdamsMoultonIntegrator integ = new AdamsMoultonIntegrator(nSteps, 1.0e-6 * range, 0.1 * range, 1.0e-5, 1.0e-5); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (nSteps < 4) { Assert.assertTrue(handler.getMaximalValueError() > 7.0e-04); } else { Assert.assertTrue(handler.getMaximalValueError() < 3.0e-13); } } } } ././@LongLink 100644 0 0 154 12126630646 10261 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/AdamsBashforthIntegratorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/AdamsBashforthIntegratorTe100644 1750 1750 16645 12126627673 32355 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblem6; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class AdamsBashforthIntegratorTest { @Test(expected=DimensionMismatchException.class) public void dimensionCheck() throws NumberIsTooSmallException, DimensionMismatchException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); FirstOrderIntegrator integ = new AdamsBashforthIntegrator(2, 0.0, 1.0, 1.0e-10, 1.0e-10); integ.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); } @Test(expected=NumberIsTooSmallException.class) public void testMinStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; FirstOrderIntegrator integ = new AdamsBashforthIntegrator(4, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } @Test public void testIncreasingTolerance() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -5; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = FastMath.pow(10.0, i); double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new AdamsBashforthIntegrator(4, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); // the 50 and 300 factors are only valid for this test // and has been obtained from trial and error // there is no general relation between local and global errors Assert.assertTrue(handler.getMaximalValueError() > (50.0 * scalAbsoluteTolerance)); Assert.assertTrue(handler.getMaximalValueError() < (300.0 * scalAbsoluteTolerance)); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-16); int calls = pb.getCalls(); Assert.assertEquals(integ.getEvaluations(), calls); Assert.assertTrue(calls <= previousCalls); previousCalls = calls; } } @Test(expected = MaxCountExceededException.class) public void exceedMaxEvaluations() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double range = pb.getFinalTime() - pb.getInitialTime(); AdamsBashforthIntegrator integ = new AdamsBashforthIntegrator(2, 0, range, 1.0e-12, 1.0e-12); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.setMaxEvaluations(650); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } @Test public void backward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double range = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); FirstOrderIntegrator integ = new AdamsBashforthIntegrator(4, 0, range, 1.0e-12, 1.0e-12); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 1.5e-8); Assert.assertTrue(handler.getMaximalValueError() < 1.5e-8); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-16); Assert.assertEquals("Adams-Bashforth", integ.getName()); } @Test public void polynomial() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem6 pb = new TestProblem6(); double range = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()); for (int nSteps = 2; nSteps < 8; ++nSteps) { AdamsBashforthIntegrator integ = new AdamsBashforthIntegrator(nSteps, 1.0e-6 * range, 0.1 * range, 1.0e-5, 1.0e-5); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (nSteps < 4) { Assert.assertTrue(handler.getMaximalValueError() > 1.0e-03); } else { Assert.assertTrue(handler.getMaximalValueError() < 4.0e-12); } } } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/EulerIntegratorTest.java 100644 1750 1750 17060 12126627673 32022 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblemAbstract; import org.apache.commons.math3.ode.TestProblemFactory; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.ode.events.EventHandler; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class EulerIntegratorTest { @Test(expected=DimensionMismatchException.class) public void testDimensionCheck() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); new EulerIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); Assert.fail("an exception should have been thrown"); } @Test public void testDecreasingSteps() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblemAbstract[] problems = TestProblemFactory.getProblems(); for (int k = 0; k < problems.length; ++k) { double previousValueError = Double.NaN; double previousTimeError = Double.NaN; for (int i = 4; i < 8; ++i) { TestProblemAbstract pb = problems[k].copy(); double step = (pb.getFinalTime() - pb.getInitialTime()) * FastMath.pow(2.0, -i); FirstOrderIntegrator integ = new EulerIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); } double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) { Assert.assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } double valueError = handler.getMaximalValueError(); if (i > 4) { Assert.assertTrue(valueError < FastMath.abs(previousValueError)); } previousValueError = valueError; double timeError = handler.getMaximalTimeError(); if (i > 4) { Assert.assertTrue(timeError <= FastMath.abs(previousTimeError)); } previousTimeError = timeError; } } } @Test public void testSmallStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new EulerIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 2.0e-4); Assert.assertTrue(handler.getMaximalValueError() < 1.0e-3); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("Euler", integ.getName()); } @Test public void testBigStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2; FirstOrderIntegrator integ = new EulerIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() > 0.01); Assert.assertTrue(handler.getMaximalValueError() > 0.2); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); } @Test public void testBackward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double step = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new EulerIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 0.45); Assert.assertTrue(handler.getMaximalValueError() < 0.45); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("Euler", integ.getName()); } @Test public void testStepSize() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final double step = 1.23456; FirstOrderIntegrator integ = new EulerIntegrator(step); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) { if (! isLast) { Assert.assertEquals(step, interpolator.getCurrentTime() - interpolator.getPreviousTime(), 1.0e-12); } } public void init(double t0, double[] y0, double t) { } }); integ.integrate(new FirstOrderDifferentialEquations() { public void computeDerivatives(double t, double[] y, double[] dot) { dot[0] = 1.0; } public int getDimension() { return 1; } }, 0.0, new double[] { 0.0 }, 5.0, new double[1]); } } ././@LongLink 100644 0 0 161 12126630646 10257 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesStepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesStepInterpola100644 1750 1750 7474 12126627673 32361 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.ContinuousOutputModel; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolatorTestUtils; import org.junit.Assert; import org.junit.Test; public class ThreeEighthesStepInterpolatorTest { @Test public void derivativesConsistency() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; ThreeEighthesIntegrator integ = new ThreeEighthesIntegrator(step); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws IOException, ClassNotFoundException, DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; ThreeEighthesIntegrator integ = new ThreeEighthesIntegrator(step); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } Assert.assertTrue(bos.size () > 880000); Assert.assertTrue(bos.size () < 900000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } Assert.assertTrue(maxError > 0.005); } } ././@LongLink 100644 0 0 154 12126630646 10261 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/MidpointStepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/MidpointStepInterpolatorTe100644 1750 1750 7526 12126627673 32430 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.ContinuousOutputModel; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolatorTestUtils; import org.junit.Assert; import org.junit.Test; public class MidpointStepInterpolatorTest { @Test public void testDerivativesConsistency() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; MidpointIntegrator integ = new MidpointIntegrator(step); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws IOException, ClassNotFoundException, DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; MidpointIntegrator integ = new MidpointIntegrator(step); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } Assert.assertTrue(bos.size () > 135000); Assert.assertTrue(bos.size () < 145000); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } Assert.assertTrue(maxError < 1.0e-6); } } ././@LongLink 100644 0 0 151 12126630646 10256 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/EulerStepInterpolatorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/EulerStepInterpolatorTest.100644 1750 1750 16204 12126627673 32357 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Random; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.ContinuousOutputModel; import org.apache.commons.math3.ode.EquationsMapper; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolatorTestUtils; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class EulerStepInterpolatorTest { @Test public void noReset() throws MaxCountExceededException { double[] y = { 0.0, 1.0, -2.0 }; double[][] yDot = { { 1.0, 2.0, -2.0 } }; EulerStepInterpolator interpolator = new EulerStepInterpolator(); interpolator.reinitialize(new DummyIntegrator(interpolator), y, yDot, true, new EquationsMapper(0, y.length), new EquationsMapper[0]); interpolator.storeTime(0); interpolator.shift(); interpolator.storeTime(1); double[] result = interpolator.getInterpolatedState(); for (int i = 0; i < result.length; ++i) { Assert.assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10); } } @Test public void interpolationAtBounds() throws MaxCountExceededException { double t0 = 0; double[] y0 = {0.0, 1.0, -2.0}; double[] y = y0.clone(); double[][] yDot = { new double[y0.length] }; EulerStepInterpolator interpolator = new EulerStepInterpolator(); interpolator.reinitialize(new DummyIntegrator(interpolator), y, yDot, true, new EquationsMapper(0, y.length), new EquationsMapper[0]); interpolator.storeTime(t0); double dt = 1.0; interpolator.shift(); y[0] = 1.0; y[1] = 3.0; y[2] = -4.0; yDot[0][0] = (y[0] - y0[0]) / dt; yDot[0][1] = (y[1] - y0[1]) / dt; yDot[0][2] = (y[2] - y0[2]) / dt; interpolator.storeTime(t0 + dt); interpolator.setInterpolatedTime(interpolator.getPreviousTime()); double[] result = interpolator.getInterpolatedState(); for (int i = 0; i < result.length; ++i) { Assert.assertTrue(FastMath.abs(result[i] - y0[i]) < 1.0e-10); } interpolator.setInterpolatedTime(interpolator.getCurrentTime()); result = interpolator.getInterpolatedState(); for (int i = 0; i < result.length; ++i) { Assert.assertTrue(FastMath.abs(result[i] - y[i]) < 1.0e-10); } } @Test public void interpolationInside() throws MaxCountExceededException { double[] y = { 0.0, 1.0, -2.0 }; double[][] yDot = { { 1.0, 2.0, -2.0 } }; EulerStepInterpolator interpolator = new EulerStepInterpolator(); interpolator.reinitialize(new DummyIntegrator(interpolator), y, yDot, true, new EquationsMapper(0, y.length), new EquationsMapper[0]); interpolator.storeTime(0); interpolator.shift(); y[0] = 1.0; y[1] = 3.0; y[2] = -4.0; interpolator.storeTime(1); interpolator.setInterpolatedTime(0.1); double[] result = interpolator.getInterpolatedState(); Assert.assertTrue(FastMath.abs(result[0] - 0.1) < 1.0e-10); Assert.assertTrue(FastMath.abs(result[1] - 1.2) < 1.0e-10); Assert.assertTrue(FastMath.abs(result[2] + 2.2) < 1.0e-10); interpolator.setInterpolatedTime(0.5); result = interpolator.getInterpolatedState(); Assert.assertTrue(FastMath.abs(result[0] - 0.5) < 1.0e-10); Assert.assertTrue(FastMath.abs(result[1] - 2.0) < 1.0e-10); Assert.assertTrue(FastMath.abs(result[2] + 3.0) < 1.0e-10); } @Test public void derivativesConsistency() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem3 pb = new TestProblem3(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; EulerIntegrator integ = new EulerIntegrator(step); StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); } @Test public void serialization() throws IOException, ClassNotFoundException, DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; EulerIntegrator integ = new EulerIntegrator(step); integ.addStepHandler(new ContinuousOutputModel()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); for (StepHandler handler : integ.getStepHandlers()) { oos.writeObject(handler); } ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject(); Random random = new Random(347588535632l); double maxError = 0.0; for (int i = 0; i < 1000; ++i) { double r = random.nextDouble(); double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime(); cm.setInterpolatedTime(time); double[] interpolatedY = cm.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(time); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } Assert.assertTrue(maxError < 0.001); } private static class DummyIntegrator extends RungeKuttaIntegrator { protected DummyIntegrator(RungeKuttaStepInterpolator prototype) { super("dummy", new double[0], new double[0][0], new double[0], prototype, Double.NaN); } } } ././@LongLink 100644 0 0 153 12126630646 10260 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesIntegratorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesIntegratorTes100644 1750 1750 22143 12126627673 32370 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblemAbstract; import org.apache.commons.math3.ode.TestProblemFactory; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.ode.events.EventHandler; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class ThreeEighthesIntegratorTest { @Test(expected=DimensionMismatchException.class) public void testDimensionCheck() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); new ThreeEighthesIntegrator(0.01).integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); Assert.fail("an exception should have been thrown"); } @Test public void testDecreasingSteps() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblemAbstract[] problems = TestProblemFactory.getProblems(); for (int k = 0; k < problems.length; ++k) { double previousValueError = Double.NaN; double previousTimeError = Double.NaN; for (int i = 4; i < 10; ++i) { TestProblemAbstract pb = problems[k].copy(); double step = (pb.getFinalTime() - pb.getInitialTime()) * FastMath.pow(2.0, -i); FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); } double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) { Assert.assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); } double error = handler.getMaximalValueError(); if (i > 4) { Assert.assertTrue(error < 1.01 * FastMath.abs(previousValueError)); } previousValueError = error; double timeError = handler.getMaximalTimeError(); if (i > 4) { Assert.assertTrue(timeError <= FastMath.abs(previousTimeError)); } previousTimeError = timeError; } } } @Test public void testSmallStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 2.0e-13); Assert.assertTrue(handler.getMaximalValueError() < 4.0e-12); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("3/8", integ.getName()); } @Test public void testBigStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2; FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() > 0.0004); Assert.assertTrue(handler.getMaximalValueError() > 0.005); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); } @Test public void testBackward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double step = FastMath.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001; FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 5.0e-10); Assert.assertTrue(handler.getMaximalValueError() < 7.0e-10); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("3/8", integ.getName()); } @Test public void testKepler() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003; FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); integ.addStepHandler(new KeplerHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } private static class KeplerHandler implements StepHandler { public KeplerHandler(TestProblem3 pb) { this.pb = pb; maxError = 0; } public void init(double t0, double[] y0, double t) { maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { double[] interpolatedY = interpolator.getInterpolatedState(); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getCurrentTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } if (isLast) { // even with more than 1000 evaluations per period, // RK4 is not able to integrate such an eccentric // orbit with a good accuracy Assert.assertTrue(maxError > 0.005); } } private TestProblem3 pb; private double maxError = 0; } @Test public void testStepSize() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final double step = 1.23456; FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step); integ.addStepHandler(new StepHandler() { public void handleStep(StepInterpolator interpolator, boolean isLast) { if (! isLast) { Assert.assertEquals(step, interpolator.getCurrentTime() - interpolator.getPreviousTime(), 1.0e-12); } } public void init(double t0, double[] y0, double t) { } }); integ.integrate(new FirstOrderDifferentialEquations() { public void computeDerivatives(double t, double[] y, double[] dot) { dot[0] = 1.0; } public int getDimension() { return 1; } }, 0.0, new double[] { 0.0 }, 5.0, new double[1]); } } ././@LongLink 100644 0 0 152 12126630646 10257 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54IntegratorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54IntegratorTest100644 1750 1750 35526 12126627673 32204 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.exception.TooManyEvaluationsException; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.TestProblem4; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.ode.events.EventHandler; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class HighamHall54IntegratorTest { @Test public void testWrongDerivative() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { HighamHall54Integrator integrator = new HighamHall54Integrator(0.0, 1.0, 1.0e-10, 1.0e-10); FirstOrderDifferentialEquations equations = new FirstOrderDifferentialEquations() { public void computeDerivatives(double t, double[] y, double[] dot) { if (t < -0.5) { throw new LocalException(); } else { throw new RuntimeException("oops"); } } public int getDimension() { return 1; } }; try { integrator.integrate(equations, -1.0, new double[1], 0.0, new double[1]); Assert.fail("an exception should have been thrown"); } catch(LocalException de) { // expected behavior } try { integrator.integrate(equations, 0.0, new double[1], 1.0, new double[1]); Assert.fail("an exception should have been thrown"); } catch(RuntimeException de) { // expected behavior } } @Test(expected=NumberIsTooSmallException.class) public void testMinStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } @Test public void testIncreasingTolerance() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { int previousCalls = Integer.MAX_VALUE; for (int i = -12; i < -2; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = FastMath.pow(10.0, i); double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); // the 1.3 factor is only valid for this test // and has been obtained from trial and error // there is no general relation between local and global errors Assert.assertTrue(handler.getMaximalValueError() < (1.3 * scalAbsoluteTolerance)); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); int calls = pb.getCalls(); Assert.assertEquals(integ.getEvaluations(), calls); Assert.assertTrue(calls <= previousCalls); previousCalls = calls; } } @Test public void testBackward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 5.0e-7); Assert.assertTrue(handler.getMaximalValueError() < 5.0e-7); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("Higham-Hall 5(4)", integ.getName()); } @Test public void testEvents() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem4 pb = new TestProblem4(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); double convergence = 1.0e-8 * maxStep; for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, convergence, 1000); } Assert.assertEquals(functions.length, integ.getEventHandlers().size()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getMaximalValueError() < 1.0e-7); Assert.assertEquals(0, handler.getMaximalTimeError(), convergence); Assert.assertEquals(12.0, handler.getLastTime(), convergence); integ.clearEventHandlers(); Assert.assertEquals(0, integ.getEventHandlers().size()); } @Test(expected=LocalException.class) public void testEventsErrors() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.addEventHandler(new EventHandler() { public void init(double t0, double[] y0, double t) { } public Action eventOccurred(double t, double[] y, boolean increasing) { return Action.CONTINUE; } public double g(double t, double[] y) { double middle = (pb.getInitialTime() + pb.getFinalTime()) / 2; double offset = t - middle; if (offset > 0) { throw new LocalException(); } return offset; } public void resetState(double t, double[] y) { } }, Double.POSITIVE_INFINITY, 1.0e-8 * maxStep, 1000); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); } private static class LocalException extends RuntimeException { private static final long serialVersionUID = 3041292643919807960L; } @Test public void testEventsNoConvergence() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.addEventHandler(new EventHandler() { public void init(double t0, double[] y0, double t) { } public Action eventOccurred(double t, double[] y, boolean increasing) { return Action.CONTINUE; } public double g(double t, double[] y) { double middle = (pb.getInitialTime() + pb.getFinalTime()) / 2; double offset = t - middle; return (offset > 0) ? (offset + 0.5) : (offset - 0.5); } public void resetState(double t, double[] y) { } }, Double.POSITIVE_INFINITY, 1.0e-8 * maxStep, 3); try { integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } catch (TooManyEvaluationsException tmee) { // Expected. } } @Test public void testSanityChecks() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); try { FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, new double[4], new double[4]); integ.integrate(pb, pb.getInitialTime(), new double[6], pb.getFinalTime(), new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException ie) { // expected behavior } try { FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, new double[4], new double[4]); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[6]); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException ie) { // expected behavior } try { FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, new double[2], new double[4]); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException ie) { // expected behavior } try { FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, new double[4], new double[2]); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } catch (DimensionMismatchException ie) { // expected behavior } try { FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, new double[4], new double[4]); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getInitialTime(), new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } catch (NumberIsTooSmallException ie) { // expected behavior } } @Test public void testKepler() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-8, 1.0e-8, 1.0e-10, 1.0e-10 }; double[] vecRelativeTolerance = { 1.0e-10, 1.0e-10, 1.0e-8, 1.0e-8 }; FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertEquals(0.0, handler.getMaximalValueError(), 1.5e-4); Assert.assertEquals("Higham-Hall 5(4)", integ.getName()); } } ././@LongLink 100644 0 0 156 12126630646 10263 L ustar 0 0 commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853IntegratorTest.java commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853Integrator100644 1750 1750 44473 12126627673 32163 0 ustar luc luc 0 0 /* * 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.math3.ode.nonstiff; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.exception.NoBracketingException; import org.apache.commons.math3.exception.NumberIsTooSmallException; import org.apache.commons.math3.ode.FirstOrderDifferentialEquations; import org.apache.commons.math3.ode.FirstOrderIntegrator; import org.apache.commons.math3.ode.TestProblem1; import org.apache.commons.math3.ode.TestProblem3; import org.apache.commons.math3.ode.TestProblem4; import org.apache.commons.math3.ode.TestProblem5; import org.apache.commons.math3.ode.TestProblemHandler; import org.apache.commons.math3.ode.events.EventHandler; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; public class DormandPrince853IntegratorTest { @Test public void testMissedEndEvent() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final double t0 = 1878250320.0000029; final double tEvent = 1878250379.9999986; final double[] k = { 1.0e-4, 1.0e-5, 1.0e-6 }; FirstOrderDifferentialEquations ode = new FirstOrderDifferentialEquations() { public int getDimension() { return k.length; } public void computeDerivatives(double t, double[] y, double[] yDot) { for (int i = 0; i < y.length; ++i) { yDot[i] = k[i] * y[i]; } } }; DormandPrince853Integrator integrator = new DormandPrince853Integrator(0.0, 100.0, 1.0e-10, 1.0e-10); double[] y0 = new double[k.length]; for (int i = 0; i < y0.length; ++i) { y0[i] = i + 1; } double[] y = new double[k.length]; integrator.setInitialStepSize(60.0); double finalT = integrator.integrate(ode, t0, y0, tEvent, y); Assert.assertEquals(tEvent, finalT, 5.0e-6); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(y0[i] * FastMath.exp(k[i] * (finalT - t0)), y[i], 1.0e-9); } integrator.setInitialStepSize(60.0); integrator.addEventHandler(new EventHandler() { public void init(double t0, double[] y0, double t) { } public void resetState(double t, double[] y) { } public double g(double t, double[] y) { return t - tEvent; } public Action eventOccurred(double t, double[] y, boolean increasing) { Assert.assertEquals(tEvent, t, 5.0e-6); return Action.CONTINUE; } }, Double.POSITIVE_INFINITY, 1.0e-20, 100); finalT = integrator.integrate(ode, t0, y0, tEvent + 120, y); Assert.assertEquals(tEvent + 120, finalT, 5.0e-6); for (int i = 0; i < y.length; ++i) { Assert.assertEquals(y0[i] * FastMath.exp(k[i] * (finalT - t0)), y[i], 1.0e-9); } } @Test(expected=DimensionMismatchException.class) public void testDimensionCheck() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); DormandPrince853Integrator integrator = new DormandPrince853Integrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()+10], 1.0, new double[pb.getDimension()+10]); Assert.fail("an exception should have been thrown"); } @Test(expected=NumberIsTooSmallException.class) public void testNullIntervalCheck() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); DormandPrince853Integrator integrator = new DormandPrince853Integrator(0.0, 1.0, 1.0e-10, 1.0e-10); integrator.integrate(pb, 0.0, new double[pb.getDimension()], 0.0, new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } @Test(expected=NumberIsTooSmallException.class) public void testMinStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem1 pb = new TestProblem1(); double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime()); double maxStep = pb.getFinalTime() - pb.getInitialTime(); double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 }; double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 }; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.fail("an exception should have been thrown"); } @Test public void testIncreasingTolerance() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { int previousCalls = Integer.MAX_VALUE; AdaptiveStepsizeIntegrator integ = new DormandPrince853Integrator(0, Double.POSITIVE_INFINITY, Double.NaN, Double.NaN); for (int i = -12; i < -2; ++i) { TestProblem1 pb = new TestProblem1(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = FastMath.pow(10.0, i); double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; integ.setStepSizeControl(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); // the 1.3 factor is only valid for this test // and has been obtained from trial and error // there is no general relation between local and global errors Assert.assertTrue(handler.getMaximalValueError() < (1.3 * scalAbsoluteTolerance)); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); int calls = pb.getCalls(); Assert.assertEquals(integ.getEvaluations(), calls); Assert.assertTrue(calls <= previousCalls); previousCalls = calls; } } @Test public void testTooLargeFirstStep() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { AdaptiveStepsizeIntegrator integ = new DormandPrince853Integrator(0, Double.POSITIVE_INFINITY, Double.NaN, Double.NaN); final double start = 0.0; final double end = 0.001; FirstOrderDifferentialEquations equations = new FirstOrderDifferentialEquations() { public int getDimension() { return 1; } public void computeDerivatives(double t, double[] y, double[] yDot) { Assert.assertTrue(t >= FastMath.nextAfter(start, Double.NEGATIVE_INFINITY)); Assert.assertTrue(t <= FastMath.nextAfter(end, Double.POSITIVE_INFINITY)); yDot[0] = -100.0 * y[0]; } }; integ.setStepSizeControl(0, 1.0, 1.0e-6, 1.0e-8); integ.integrate(equations, start, new double[] { 1.0 }, end, new double[1]); } @Test public void testBackward() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem5 pb = new TestProblem5(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertTrue(handler.getLastError() < 1.1e-7); Assert.assertTrue(handler.getMaximalValueError() < 1.1e-7); Assert.assertEquals(0, handler.getMaximalTimeError(), 1.0e-12); Assert.assertEquals("Dormand-Prince 8 (5, 3)", integ.getName()); } @Test public void testEvents() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { TestProblem4 pb = new TestProblem4(); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-9; double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); TestProblemHandler handler = new TestProblemHandler(pb, integ); integ.addStepHandler(handler); EventHandler[] functions = pb.getEventsHandlers(); double convergence = 1.0e-8 * maxStep; for (int l = 0; l < functions.length; ++l) { integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, convergence, 1000); } Assert.assertEquals(functions.length, integ.getEventHandlers().size()); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertEquals(0, handler.getMaximalValueError(), 2.1e-7); Assert.assertEquals(0, handler.getMaximalTimeError(), convergence); Assert.assertEquals(12.0, handler.getLastTime(), convergence); integ.clearEventHandlers(); Assert.assertEquals(0, integ.getEventHandlers().size()); } @Test public void testKepler() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new KeplerHandler(pb)); integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertEquals(integ.getEvaluations(), pb.getCalls()); Assert.assertTrue(pb.getCalls() < 3300); } @Test public void testVariableSteps() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final TestProblem3 pb = new TestProblem3(0.9); double minStep = 0; double maxStep = pb.getFinalTime() - pb.getInitialTime(); double scalAbsoluteTolerance = 1.0e-8; double scalRelativeTolerance = scalAbsoluteTolerance; FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance); integ.addStepHandler(new VariableHandler()); double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]); Assert.assertEquals(pb.getFinalTime(), stopTime, 1.0e-10); Assert.assertEquals("Dormand-Prince 8 (5, 3)", integ.getName()); } @Test public void testUnstableDerivative() throws DimensionMismatchException, NumberIsTooSmallException, MaxCountExceededException, NoBracketingException { final StepProblem stepProblem = new StepProblem(0.0, 1.0, 2.0); FirstOrderIntegrator integ = new DormandPrince853Integrator(0.1, 10, 1.0e-12, 0.0); integ.addEventHandler(stepProblem, 1.0, 1.0e-12, 1000); double[] y = { Double.NaN }; integ.integrate(stepProblem, 0.0, new double[] { 0.0 }, 10.0, y); Assert.assertEquals(8.0, y[0], 1.0e-12); } @Test public void testEventsScheduling() { FirstOrderDifferentialEquations sincos = new FirstOrderDifferentialEquations() { public int getDimension() { return 2; } public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[0] = y[1]; yDot[1] = -y[0]; } }; SchedulingChecker sinChecker = new SchedulingChecker(0); // events at 0, PI, 2PI ... SchedulingChecker cosChecker = new SchedulingChecker(1); // events at PI/2, 3PI/2, 5PI/2 ... FirstOrderIntegrator integ = new DormandPrince853Integrator(0.001, 1.0, 1.0e-12, 0.0); integ.addEventHandler(sinChecker, 0.01, 1.0e-7, 100); integ.addStepHandler(sinChecker); integ.addEventHandler(cosChecker, 0.01, 1.0e-7, 100); integ.addStepHandler(cosChecker); double t0 = 0.5; double[] y0 = new double[] { FastMath.sin(t0), FastMath.cos(t0) }; double t = 10.0; double[] y = new double[2]; integ.integrate(sincos, t0, y0, t, y); } private static class SchedulingChecker implements StepHandler, EventHandler { int index; double tMin; public SchedulingChecker(int index) { this.index = index; } public void init(double t0, double[] y0, double t) { tMin = t0; } public void handleStep(StepInterpolator interpolator, boolean isLast) { tMin = interpolator.getCurrentTime(); } public double g(double t, double[] y) { // once a step has been handled by handleStep, // events checking should only refer to dates after the step Assert.assertTrue(t >= tMin); return y[index]; } public Action eventOccurred(double t, double[] y, boolean increasing) { return Action.RESET_STATE; } public void resetState(double t, double[] y) { // in fact, we don't need to reset anything for the test } } private static class KeplerHandler implements StepHandler { public KeplerHandler(TestProblem3 pb) { this.pb = pb; } public void init(double t0, double[] y0, double t) { nbSteps = 0; maxError = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { ++nbSteps; for (int a = 1; a < 10; ++a) { double prev = interpolator.getPreviousTime(); double curr = interpolator.getCurrentTime(); double interp = ((10 - a) * prev + a * curr) / 10; interpolator.setInterpolatedTime(interp); double[] interpolatedY = interpolator.getInterpolatedState (); double[] theoreticalY = pb.computeTheoreticalState(interpolator.getInterpolatedTime()); double dx = interpolatedY[0] - theoreticalY[0]; double dy = interpolatedY[1] - theoreticalY[1]; double error = dx * dx + dy * dy; if (error > maxError) { maxError = error; } } if (isLast) { Assert.assertTrue(maxError < 2.4e-10); Assert.assertTrue(nbSteps < 150); } } private int nbSteps; private double maxError; private TestProblem3 pb; } private static class VariableHandler implements StepHandler { public VariableHandler() { firstTime = true; minStep = 0; maxStep = 0; } public void init(double t0, double[] y0, double t) { firstTime = true; minStep = 0; maxStep = 0; } public void handleStep(StepInterpolator interpolator, boolean isLast) { double step = FastMath.abs(interpolator.getCurrentTime() - interpolator.getPreviousTime()); if (firstTime) { minStep = FastMath.abs(step); maxStep = minStep; firstTime = false; } else { if (step < minStep) { minStep = step; } if (step > maxStep) { maxStep = step; } } if (isLast) { Assert.assertTrue(minStep < (1.0 / 100.0)); Assert.assertTrue(maxStep > (1.0 / 2.0)); } } private boolean firstTime = true; private double minStep = 0; private double maxStep = 0; } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/TestProblemFactory.java 100644 1750 1750 2677 12126627673 30001 0 ustar luc luc 0 0 /* * 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.math3.ode; /** * This class is used in the junit tests for the ODE integrators. */ public class TestProblemFactory { /** Problems pool. */ private static final TestProblemAbstract[] pool = { new TestProblem1(), new TestProblem2(), new TestProblem3(), new TestProblem4(), new TestProblem5(), new TestProblem6() }; /** * Private constructor. * This is a utility class, so there are no instance at all. */ private TestProblemFactory() { } /** * Get the problems. * @return array of problems to solve */ public static TestProblemAbstract[] getProblems() { return pool; } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/ode/TestProblemHandler.java 100644 1750 1750 12122 12126627673 27751 0 ustar luc luc 0 0 /* * 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.math3.ode; import org.apache.commons.math3.exception.MaxCountExceededException; import org.apache.commons.math3.ode.sampling.StepHandler; import org.apache.commons.math3.ode.sampling.StepInterpolator; import org.apache.commons.math3.util.FastMath; /** * This class is used to handle steps for the test problems * integrated during the junit tests for the ODE integrators. */ public class TestProblemHandler implements StepHandler { /** Associated problem. */ private TestProblemAbstract problem; /** Maximal errors encountered during the integration. */ private double maxValueError; private double maxTimeError; /** Error at the end of the integration. */ private double lastError; /** Time at the end of integration. */ private double lastTime; /** ODE solver used. */ private ODEIntegrator integrator; /** Expected start for step. */ private double expectedStepStart; /** * Simple constructor. * @param problem problem for which steps should be handled * @param integrator ODE solver used */ public TestProblemHandler(TestProblemAbstract problem, ODEIntegrator integrator) { this.problem = problem; this.integrator = integrator; maxValueError = 0; maxTimeError = 0; lastError = 0; expectedStepStart = Double.NaN; } public void init(double t0, double[] y0, double t) { maxValueError = 0; maxTimeError = 0; lastError = 0; expectedStepStart = Double.NaN; } public void handleStep(StepInterpolator interpolator, boolean isLast) throws MaxCountExceededException { double start = integrator.getCurrentStepStart(); if (FastMath.abs((start - problem.getInitialTime()) / integrator.getCurrentSignedStepsize()) > 0.001) { // multistep integrators do not handle the first steps themselves // so we have to make sure the integrator we look at has really started its work if (!Double.isNaN(expectedStepStart)) { // the step should either start at the end of the integrator step // or at an event if the step is split into several substeps double stepError = FastMath.max(maxTimeError, FastMath.abs(start - expectedStepStart)); for (double eventTime : problem.getTheoreticalEventsTimes()) { stepError = FastMath.min(stepError, FastMath.abs(start - eventTime)); } maxTimeError = FastMath.max(maxTimeError, stepError); } expectedStepStart = start + integrator.getCurrentSignedStepsize(); } double pT = interpolator.getPreviousTime(); double cT = interpolator.getCurrentTime(); double[] errorScale = problem.getErrorScale(); // store the error at the last step if (isLast) { double[] interpolatedY = interpolator.getInterpolatedState(); double[] theoreticalY = problem.computeTheoreticalState(cT); for (int i = 0; i < interpolatedY.length; ++i) { double error = FastMath.abs(interpolatedY[i] - theoreticalY[i]); lastError = FastMath.max(error, lastError); } lastTime = cT; } // walk through the step for (int k = 0; k <= 20; ++k) { double time = pT + (k * (cT - pT)) / 20; interpolator.setInterpolatedTime(time); double[] interpolatedY = interpolator.getInterpolatedState(); double[] theoreticalY = problem.computeTheoreticalState(interpolator.getInterpolatedTime()); // update the errors for (int i = 0; i < interpolatedY.length; ++i) { double error = errorScale[i] * FastMath.abs(interpolatedY[i] - theoreticalY[i]); maxValueError = FastMath.max(error, maxValueError); } } } /** * Get the maximal value error encountered during integration. * @return maximal value error */ public double getMaximalValueError() { return maxValueError; } /** * Get the maximal time error encountered during integration. * @return maximal time error */ public double getMaximalTimeError() { return maxTimeError; } /** * Get the error at the end of the integration. * @return error at the end of the integration */ public double getLastError() { return lastError; } /** * Get the time at the end of the integration. * @return time at the end of the integration. */ public double getLastTime() { return lastTime; } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/complex/ComplexFieldTest.java 100644 1750 1750 2710 12126627672 30307 0 ustar luc luc 0 0 /* * 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.math3.complex; import org.apache.commons.math3.TestUtils; import org.junit.Assert; import org.junit.Test; public class ComplexFieldTest { @Test public void testZero() { Assert.assertEquals(Complex.ZERO, ComplexField.getInstance().getZero()); } @Test public void testOne() { Assert.assertEquals(Complex.ONE, ComplexField.getInstance().getOne()); } @Test public void testSerial() { // deserializing the singleton should give the singleton itself back ComplexField field = ComplexField.getInstance(); Assert.assertTrue(field == TestUtils.serializeAndRecover(field)); } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/complex/FrenchComplexFormatTest.java 100644 1750 1750 2137 12126627672 31645 0 ustar luc luc 0 0 /* * 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.math3.complex; import java.util.Locale; public class FrenchComplexFormatTest extends ComplexFormatAbstractTest { @Override protected char getDecimalCharacter() { return ','; } @Override protected Locale getLocale() { return Locale.FRENCH; } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/complex/RootsOfUnityTest.java 100644 1750 1750 7102 12126627672 30360 0 ustar luc luc 0 0 /* * 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.math3.complex; import org.apache.commons.math3.exception.MathIllegalStateException; import org.apache.commons.math3.exception.ZeroException; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; /** * Unit tests for the {@link RootsOfUnity} class. * * @version $Id: RootsOfUnityTest.java 1244107 2012-02-14 16:17:55Z erans $ */ public class RootsOfUnityTest { @Test(expected = MathIllegalStateException.class) public void testMathIllegalState1() { final RootsOfUnity roots = new RootsOfUnity(); roots.getReal(0); } @Test(expected = MathIllegalStateException.class) public void testMathIllegalState2() { final RootsOfUnity roots = new RootsOfUnity(); roots.getImaginary(0); } @Test(expected = MathIllegalStateException.class) public void testMathIllegalState3() { final RootsOfUnity roots = new RootsOfUnity(); roots.isCounterClockWise(); } @Test(expected = ZeroException.class) public void testZeroNumberOfRoots() { final RootsOfUnity roots = new RootsOfUnity(); roots.computeRoots(0); } @Test public void testGetNumberOfRoots() { final RootsOfUnity roots = new RootsOfUnity(); Assert.assertEquals("", 0, roots.getNumberOfRoots()); roots.computeRoots(5); Assert.assertEquals("", 5, roots.getNumberOfRoots()); /* * Testing -5 right after 5 is important, as the roots in this case are * not recomputed. */ roots.computeRoots(-5); Assert.assertEquals("", 5, roots.getNumberOfRoots()); roots.computeRoots(6); Assert.assertEquals("", 6, roots.getNumberOfRoots()); } @Test public void testComputeRoots() { final RootsOfUnity roots = new RootsOfUnity(); for (int n = -10; n < 11; n++) { /* * Testing -n right after n is important, as the roots in this case * are not recomputed. */ if (n != 0) { roots.computeRoots(n); doTestComputeRoots(roots); roots.computeRoots(-n); doTestComputeRoots(roots); } } } private void doTestComputeRoots(final RootsOfUnity roots) { final int n = roots.isCounterClockWise() ? roots.getNumberOfRoots() : -roots.getNumberOfRoots(); final double tol = 10 * Math.ulp(1.0); for (int k = 0; k < n; k++) { final double t = 2.0 * FastMath.PI * k / n; final String msg = String.format("n = %d, k = %d", n, k); Assert.assertEquals(msg, FastMath.cos(t), roots.getReal(k), tol); Assert.assertEquals(msg, FastMath.sin(t), roots.getImaginary(k), tol); } } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/complex/QuaternionTest.java 100644 1750 1750 42437 12126627672 30113 0 ustar luc luc 0 0 /* * 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.math3.complex; import java.util.Random; import org.apache.commons.math3.complex.Quaternion; import org.apache.commons.math3.exception.DimensionMismatchException; import org.apache.commons.math3.exception.ZeroException; import org.apache.commons.math3.geometry.euclidean.threed.Rotation; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.util.FastMath; import org.junit.Test; import org.junit.Assert; public class QuaternionTest { /** Epsilon for double comparison. */ private static final double EPS = Math.ulp(1d); /** Epsilon for double comparison. */ private static final double COMPARISON_EPS = 1e-14; @Test public final void testAccessors1() { final double q0 = 2; final double q1 = 5.4; final double q2 = 17; final double q3 = 0.0005; final Quaternion q = new Quaternion(q0, q1, q2, q3); Assert.assertEquals(q0, q.getQ0(), 0); Assert.assertEquals(q1, q.getQ1(), 0); Assert.assertEquals(q2, q.getQ2(), 0); Assert.assertEquals(q3, q.getQ3(), 0); } @Test public final void testAccessors2() { final double q0 = 2; final double q1 = 5.4; final double q2 = 17; final double q3 = 0.0005; final Quaternion q = new Quaternion(q0, q1, q2, q3); final double sP = q.getScalarPart(); final double[] vP = q.getVectorPart(); Assert.assertEquals(q0, sP, 0); Assert.assertEquals(q1, vP[0], 0); Assert.assertEquals(q2, vP[1], 0); Assert.assertEquals(q3, vP[2], 0); } @Test public final void testAccessors3() { final double q0 = 2; final double q1 = 5.4; final double q2 = 17; final double q3 = 0.0005; final Quaternion q = new Quaternion(q0, new double[] { q1, q2, q3 }); final double sP = q.getScalarPart(); final double[] vP = q.getVectorPart(); Assert.assertEquals(q0, sP, 0); Assert.assertEquals(q1, vP[0], 0); Assert.assertEquals(q2, vP[1], 0); Assert.assertEquals(q3, vP[2], 0); } @Test(expected=DimensionMismatchException.class) public void testWrongDimension() { new Quaternion(new double[] { 1, 2 }); } @Test public final void testConjugate() { final double q0 = 2; final double q1 = 5.4; final double q2 = 17; final double q3 = 0.0005; final Quaternion q = new Quaternion(q0, q1, q2, q3); final Quaternion qConjugate = q.getConjugate(); Assert.assertEquals(q0, qConjugate.getQ0(), 0); Assert.assertEquals(-q1, qConjugate.getQ1(), 0); Assert.assertEquals(-q2, qConjugate.getQ2(), 0); Assert.assertEquals(-q3, qConjugate.getQ3(), 0); } @Test public final void testProductQuaternionQuaternion() { // Case : analytic test case final Quaternion qA = new Quaternion(1, 0.5, -3, 4); final Quaternion qB = new Quaternion(6, 2, 1, -9); final Quaternion qResult = Quaternion.multiply(qA, qB); Assert.assertEquals(44, qResult.getQ0(), EPS); Assert.assertEquals(28, qResult.getQ1(), EPS); Assert.assertEquals(-4.5, qResult.getQ2(), EPS); Assert.assertEquals(21.5, qResult.getQ3(), EPS); // comparison with the result given by the formula : // qResult = (scalarA * scalarB - vectorA . vectorB) + (scalarA * vectorB + scalarB * vectorA + vectorA ^ // vectorB) final Vector3D vectorA = new Vector3D(qA.getVectorPart()); final Vector3D vectorB = new Vector3D(qB.getVectorPart()); final Vector3D vectorResult = new Vector3D(qResult.getVectorPart()); final double scalarPartRef = qA.getScalarPart() * qB.getScalarPart() - Vector3D.dotProduct(vectorA, vectorB); Assert.assertEquals(scalarPartRef, qResult.getScalarPart(), EPS); final Vector3D vectorPartRef = ((vectorA.scalarMultiply(qB.getScalarPart())).add(vectorB.scalarMultiply(qA .getScalarPart()))).add(Vector3D.crossProduct(vectorA, vectorB)); final double norm = (vectorResult.subtract(vectorPartRef)).getNorm(); Assert.assertEquals(0, norm, EPS); // Conjugate of the product of two quaternions and product of their conjugates : // Conj(qA * qB) = Conj(qB) * Conj(qA) final Quaternion conjugateOfProduct = qB.getConjugate().multiply(qA.getConjugate()); final Quaternion productOfConjugate = (qA.multiply(qB)).getConjugate(); Assert.assertEquals(conjugateOfProduct.getQ0(), productOfConjugate.getQ0(), EPS); Assert.assertEquals(conjugateOfProduct.getQ1(), productOfConjugate.getQ1(), EPS); Assert.assertEquals(conjugateOfProduct.getQ2(), productOfConjugate.getQ2(), EPS); Assert.assertEquals(conjugateOfProduct.getQ3(), productOfConjugate.getQ3(), EPS); } @Test public final void testProductQuaternionVector() { // Case : Product between a vector and a quaternion : QxV final Quaternion quaternion = new Quaternion(4, 7, -1, 2); final double[] vector = {2.0, 1.0, 3.0}; final Quaternion qResultQxV = Quaternion.multiply(quaternion, new Quaternion(vector)); Assert.assertEquals(-19, qResultQxV.getQ0(), EPS); Assert.assertEquals(3, qResultQxV.getQ1(), EPS); Assert.assertEquals(-13, qResultQxV.getQ2(), EPS); Assert.assertEquals(21, qResultQxV.getQ3(), EPS); // comparison with the result given by the formula : // qResult = (- vectorQ . vector) + (scalarQ * vector + vectorQ ^ vector) final double[] vectorQ = quaternion.getVectorPart(); final double[] vectorResultQxV = qResultQxV.getVectorPart(); final double scalarPartRefQxV = -Vector3D.dotProduct(new Vector3D(vectorQ), new Vector3D(vector)); Assert.assertEquals(scalarPartRefQxV, qResultQxV.getScalarPart(), EPS); final Vector3D vectorPartRefQxV = (new Vector3D(vector).scalarMultiply(quaternion.getScalarPart())).add(Vector3D .crossProduct(new Vector3D(vectorQ), new Vector3D(vector))); final double normQxV = (new Vector3D(vectorResultQxV).subtract(vectorPartRefQxV)).getNorm(); Assert.assertEquals(0, normQxV, EPS); // Case : Product between a vector and a quaternion : VxQ final Quaternion qResultVxQ = Quaternion.multiply(new Quaternion(vector), quaternion); Assert.assertEquals(-19, qResultVxQ.getQ0(), EPS); Assert.assertEquals(13, qResultVxQ.getQ1(), EPS); Assert.assertEquals(21, qResultVxQ.getQ2(), EPS); Assert.assertEquals(3, qResultVxQ.getQ3(), EPS); final double[] vectorResultVxQ = qResultVxQ.getVectorPart(); // comparison with the result given by the formula : // qResult = (- vector . vectorQ) + (scalarQ * vector + vector ^ vectorQ) final double scalarPartRefVxQ = -Vector3D.dotProduct(new Vector3D(vectorQ), new Vector3D(vector)); Assert.assertEquals(scalarPartRefVxQ, qResultVxQ.getScalarPart(), EPS); final Vector3D vectorPartRefVxQ = (new Vector3D(vector).scalarMultiply(quaternion.getScalarPart())).add(Vector3D .crossProduct(new Vector3D(vector), new Vector3D(vectorQ))); final double normVxQ = (new Vector3D(vectorResultVxQ).subtract(vectorPartRefVxQ)).getNorm(); Assert.assertEquals(0, normVxQ, EPS); } @Test public final void testDotProductQuaternionQuaternion() { // expected output final double expected = -6.; // inputs final Quaternion q1 = new Quaternion(1, 2, 2, 1); final Quaternion q2 = new Quaternion(3, -2, -1, -3); final double actual1 = Quaternion.dotProduct(q1, q2); final double actual2 = q1.dotProduct(q2); Assert.assertEquals(expected, actual1, EPS); Assert.assertEquals(expected, actual2, EPS); } @Test public final void testScalarMultiplyDouble() { // expected outputs final double w = 1.6; final double x = -4.8; final double y = 11.20; final double z = 2.56; // inputs final Quaternion q1 = new Quaternion(0.5, -1.5, 3.5, 0.8); final double a = 3.2; final Quaternion q = q1.multiply(a); Assert.assertEquals(w, q.getQ0(), COMPARISON_EPS); Assert.assertEquals(x, q.getQ1(), COMPARISON_EPS); Assert.assertEquals(y, q.getQ2(), COMPARISON_EPS); Assert.assertEquals(z, q.getQ3(), COMPARISON_EPS); } @Test public final void testAddQuaternionQuaternion() { // expected outputs final double w = 4; final double x = -1; final double y = 2; final double z = -4; // inputs final Quaternion q1 = new Quaternion(1., 2., -2., -1.); final Quaternion q2 = new Quaternion(3., -3., 4., -3.); final Quaternion qa = Quaternion.add(q1, q2); final Quaternion qb = q1.add(q2); Assert.assertEquals(w, qa.getQ0(), EPS); Assert.assertEquals(x, qa.getQ1(), EPS); Assert.assertEquals(y, qa.getQ2(), EPS); Assert.assertEquals(z, qa.getQ3(), EPS); Assert.assertEquals(w, qb.getQ0(), EPS); Assert.assertEquals(x, qb.getQ1(), EPS); Assert.assertEquals(y, qb.getQ2(), EPS); Assert.assertEquals(z, qb.getQ3(), EPS); } @Test public final void testSubtractQuaternionQuaternion() { // expected outputs final double w = -2.; final double x = 5.; final double y = -6.; final double z = 2.; // inputs final Quaternion q1 = new Quaternion(1., 2., -2., -1.); final Quaternion q2 = new Quaternion(3., -3., 4., -3.); final Quaternion qa = Quaternion.subtract(q1, q2); final Quaternion qb = q1.subtract(q2); Assert.assertEquals(w, qa.getQ0(), EPS); Assert.assertEquals(x, qa.getQ1(), EPS); Assert.assertEquals(y, qa.getQ2(), EPS); Assert.assertEquals(z, qa.getQ3(), EPS); Assert.assertEquals(w, qb.getQ0(), EPS); Assert.assertEquals(x, qb.getQ1(), EPS); Assert.assertEquals(y, qb.getQ2(), EPS); Assert.assertEquals(z, qb.getQ3(), EPS); } @Test public final void testNorm() { final double q0 = 2; final double q1 = 1; final double q2 = -4; final double q3 = 3; final Quaternion q = new Quaternion(q0, q1, q2, q3); final double norm = q.getNorm(); Assert.assertEquals(Math.sqrt(30), norm, 0); final double normSquareRef = Quaternion.multiply(q, q.getConjugate()).getScalarPart(); Assert.assertEquals(Math.sqrt(normSquareRef), norm, 0); } @Test public final void testNormalize() { final Quaternion q = new Quaternion(2, 1, -4, -2); final Quaternion versor = q.normalize(); Assert.assertEquals(2.0 / 5.0, versor.getQ0(), 0); Assert.assertEquals(1.0 / 5.0, versor.getQ1(), 0); Assert.assertEquals(-4.0 / 5.0, versor.getQ2(), 0); Assert.assertEquals(-2.0 / 5.0, versor.getQ3(), 0); Assert.assertEquals(1, versor.getNorm(), 0); } @Test(expected=ZeroException.class) public final void testNormalizeFail() { final Quaternion zeroQ = new Quaternion(0, 0, 0, 0); zeroQ.normalize(); } @Test public final void testObjectEquals() { final double one = 1; final Quaternion q1 = new Quaternion(one, one, one, one); Assert.assertTrue(q1.equals(q1)); final Quaternion q2 = new Quaternion(one, one, one, one); Assert.assertTrue(q2.equals(q1)); final Quaternion q3 = new Quaternion(one, FastMath.nextUp(one), one, one); Assert.assertFalse(q3.equals(q1)); } @Test public final void testQuaternionEquals() { final double inc = 1e-5; final Quaternion q1 = new Quaternion(2, 1, -4, -2); final Quaternion q2 = new Quaternion(q1.getQ0() + inc, q1.getQ1(), q1.getQ2(), q1.getQ3()); final Quaternion q3 = new Quaternion(q1.getQ0(), q1.getQ1() + inc, q1.getQ2(), q1.getQ3()); final Quaternion q4 = new Quaternion(q1.getQ0(), q1.getQ1(), q1.getQ2() + inc, q1.getQ3()); final Quaternion q5 = new Quaternion(q1.getQ0(), q1.getQ1(), q1.getQ2(), q1.getQ3() + inc); Assert.assertFalse(q1.equals(q2, 0.9 * inc)); Assert.assertFalse(q1.equals(q3, 0.9 * inc)); Assert.assertFalse(q1.equals(q4, 0.9 * inc)); Assert.assertFalse(q1.equals(q5, 0.9 * inc)); Assert.assertTrue(q1.equals(q2, 1.1 * inc)); Assert.assertTrue(q1.equals(q3, 1.1 * inc)); Assert.assertTrue(q1.equals(q4, 1.1 * inc)); Assert.assertTrue(q1.equals(q5, 1.1 * inc)); } @Test public final void testQuaternionEquals2() { final Quaternion q1 = new Quaternion(1, 4, 2, 3); final double gap = 1e-5; final Quaternion q2 = new Quaternion(1 + gap, 4 + gap, 2 + gap, 3 + gap); Assert.assertTrue(q1.equals(q2, 10 * gap)); Assert.assertFalse(q1.equals(q2, gap)); Assert.assertFalse(q1.equals(q2, gap / 10)); } @Test public final void testIsUnitQuaternion() { final Random r = new Random(48); final int numberOfTrials = 1000; for (int i = 0; i < numberOfTrials; i++) { final Quaternion q1 = new Quaternion(r.nextDouble(), r.nextDouble(), r.nextDouble(), r.nextDouble()); final Quaternion q2 = q1.normalize(); Assert.assertTrue(q2.isUnitQuaternion(COMPARISON_EPS)); } final Quaternion q = new Quaternion(1, 1, 1, 1); Assert.assertFalse(q.isUnitQuaternion(COMPARISON_EPS)); } @Test public final void testIsPureQuaternion() { final Quaternion q1 = new Quaternion(0, 5, 4, 8); Assert.assertTrue(q1.isPureQuaternion(EPS)); final Quaternion q2 = new Quaternion(0 - EPS, 5, 4, 8); Assert.assertTrue(q2.isPureQuaternion(EPS)); final Quaternion q3 = new Quaternion(0 - 1.1 * EPS, 5, 4, 8); Assert.assertFalse(q3.isPureQuaternion(EPS)); final Random r = new Random(48); final double[] v = {r.nextDouble(), r.nextDouble(), r.nextDouble()}; final Quaternion q4 = new Quaternion(v); Assert.assertTrue(q4.isPureQuaternion(0)); final Quaternion q5 = new Quaternion(0, v); Assert.assertTrue(q5.isPureQuaternion(0)); } @Test public final void testPolarForm() { final Random r = new Random(48); final int numberOfTrials = 1000; for (int i = 0; i < numberOfTrials; i++) { final Quaternion q = new Quaternion(2 * (r.nextDouble() - 0.5), 2 * (r.nextDouble() - 0.5), 2 * (r.nextDouble() - 0.5), 2 * (r.nextDouble() - 0.5)); final Quaternion qP = q.getPositivePolarForm(); Assert.assertTrue(qP.isUnitQuaternion(COMPARISON_EPS)); Assert.assertTrue(qP.getQ0() >= 0); final Rotation rot = new Rotation(q.getQ0(), q.getQ1(), q.getQ2(), q.getQ3(), true); final Rotation rotP = new Rotation(qP.getQ0(), qP.getQ1(), qP.getQ2(), qP.getQ3(), true); Assert.assertEquals(rot.getAngle(), rotP.getAngle(), COMPARISON_EPS); Assert.assertEquals(rot.getAxis().getX(), rot.getAxis().getX(), COMPARISON_EPS); Assert.assertEquals(rot.getAxis().getY(), rot.getAxis().getY(), COMPARISON_EPS); Assert.assertEquals(rot.getAxis().getZ(), rot.getAxis().getZ(), COMPARISON_EPS); } } @Test public final void testGetInverse() { final Quaternion q = new Quaternion(1.5, 4, 2, -2.5); final Quaternion inverseQ = q.getInverse(); Assert.assertEquals(1.5 / 28.5, inverseQ.getQ0(), 0); Assert.assertEquals(-4.0 / 28.5, inverseQ.getQ1(), 0); Assert.assertEquals(-2.0 / 28.5, inverseQ.getQ2(), 0); Assert.assertEquals(2.5 / 28.5, inverseQ.getQ3(), 0); final Quaternion product = Quaternion.multiply(inverseQ, q); Assert.assertEquals(1, product.getQ0(), EPS); Assert.assertEquals(0, product.getQ1(), EPS); Assert.assertEquals(0, product.getQ2(), EPS); Assert.assertEquals(0, product.getQ3(), EPS); final Quaternion qNul = new Quaternion(0, 0, 0, 0); try { final Quaternion inverseQNul = qNul.getInverse(); Assert.fail("expecting ZeroException but got : " + inverseQNul); } catch (ZeroException ex) { // expected } } @Test public final void testToString() { final Quaternion q = new Quaternion(1, 2, 3, 4); Assert.assertTrue(q.toString().equals("[1.0 2.0 3.0 4.0]")); } } commons-math3-3.2-src/src/test/java/org/apache/commons/math3/complex/ComplexTest.java 100644 1750 1750 132575 12126627672 27420 0 ustar luc luc 0 0 /* * 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.math3.complex; import org.apache.commons.math3.TestUtils; import org.apache.commons.math3.exception.NullArgumentException; import org.apache.commons.math3.util.FastMath; import org.junit.Assert; import org.junit.Test; import java.util.List; /** * @version $Id: ComplexTest.java 1459927 2013-03-22 18:55:58Z luc $ */ public class ComplexTest { private double inf = Double.POSITIVE_INFINITY; private double neginf = Double.NEGATIVE_INFINITY; private double nan = Double.NaN; private double pi = FastMath.PI; private Complex oneInf = new Complex(1, inf); private Complex oneNegInf = new Complex(1, neginf); private Complex infOne = new Complex(inf, 1); private Complex infZero = new Complex(inf, 0); private Complex infNaN = new Complex(inf, nan); private Complex infNegInf = new Complex(inf, neginf); private Complex infInf = new Complex(inf, inf); private Complex negInfInf = new Complex(neginf, inf); private Complex negInfZero = new Complex(neginf, 0); private Complex negInfOne = new Complex(neginf, 1); private Complex negInfNaN = new Complex(neginf, nan); private Complex negInfNegInf = new Complex(neginf, neginf); private Complex oneNaN = new Complex(1, nan); private Complex zeroInf = new Complex(0, inf); private Complex zeroNaN = new Complex(0, nan); private Complex nanInf = new Complex(nan, inf); private Complex nanNegInf = new Complex(nan, neginf); private Complex nanZero = new Complex(nan, 0); @Test public void testConstructor() { Complex z = new Complex(3.0, 4.0); Assert.assertEquals(3.0, z.getReal(), 1.0e-5); Assert.assertEquals(4.0, z.getImaginary(), 1.0e-5); } @Test public void testConstructorNaN() { Complex z = new Complex(3.0, Double.NaN); Assert.assertTrue(z.isNaN()); z = new Complex(nan, 4.0); Assert.assertTrue(z.isNaN()); z = new Complex(3.0, 4.0); Assert.assertFalse(z.isNaN()); } @Test public void testAbs() { Complex z = new Complex(3.0, 4.0); Assert.assertEquals(5.0, z.abs(), 1.0e-5); } @Test public void testAbsNaN() { Assert.assertTrue(Double.isNaN(Complex.NaN.abs())); Complex z = new Complex(inf, nan); Assert.assertTrue(Double.isNaN(z.abs())); } @Test public void testAbsInfinite() { Complex z = new Complex(inf, 0); Assert.assertEquals(inf, z.abs(), 0); z = new Complex(0, neginf); Assert.assertEquals(inf, z.abs(), 0); z = new Complex(inf, neginf); Assert.assertEquals(inf, z.abs(), 0); } @Test public void testAdd() { Complex x = new Complex(3.0, 4.0); Complex y = new Complex(5.0, 6.0); Complex z = x.add(y); Assert.assertEquals(8.0, z.getReal(), 1.0e-5); Assert.assertEquals(10.0, z.getImaginary(), 1.0e-5); } @Test public void testAddNaN() { Complex x = new Complex(3.0, 4.0); Complex z = x.add(Complex.NaN); Assert.assertSame(Complex.NaN, z); z = new Complex(1, nan); Complex w = x.add(z); Assert.assertSame(Complex.NaN, w); } @Test public void testAddInf() { Complex x = new Complex(1, 1); Complex z = new Complex(inf, 0); Complex w = x.add(z); Assert.assertEquals(w.getImaginary(), 1, 0); Assert.assertEquals(inf, w.getReal(), 0); x = new Complex(neginf, 0); Assert.assertTrue(Double.isNaN(x.add(z).getReal())); } @Test public void testScalarAdd() { Complex x = new Complex(3.0, 4.0); double yDouble = 2.0; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.add(yComplex), x.add(yDouble)); } @Test public void testScalarAddNaN() { Complex x = new Complex(3.0, 4.0); double yDouble = Double.NaN; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.add(yComplex), x.add(yDouble)); } @Test public void testScalarAddInf() { Complex x = new Complex(1, 1); double yDouble = Double.POSITIVE_INFINITY; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.add(yComplex), x.add(yDouble)); x = new Complex(neginf, 0); Assert.assertEquals(x.add(yComplex), x.add(yDouble)); } @Test public void testConjugate() { Complex x = new Complex(3.0, 4.0); Complex z = x.conjugate(); Assert.assertEquals(3.0, z.getReal(), 1.0e-5); Assert.assertEquals(-4.0, z.getImaginary(), 1.0e-5); } @Test public void testConjugateNaN() { Complex z = Complex.NaN.conjugate(); Assert.assertTrue(z.isNaN()); } @Test public void testConjugateInfiinite() { Complex z = new Complex(0, inf); Assert.assertEquals(neginf, z.conjugate().getImaginary(), 0); z = new Complex(0, neginf); Assert.assertEquals(inf, z.conjugate().getImaginary(), 0); } @Test public void testDivide() { Complex x = new Complex(3.0, 4.0); Complex y = new Complex(5.0, 6.0); Complex z = x.divide(y); Assert.assertEquals(39.0 / 61.0, z.getReal(), 1.0e-5); Assert.assertEquals(2.0 / 61.0, z.getImaginary(), 1.0e-5); } @Test public void testDivideReal() { Complex x = new Complex(2d, 3d); Complex y = new Complex(2d, 0d); Assert.assertEquals(new Complex(1d, 1.5), x.divide(y)); } @Test public void testDivideImaginary() { Complex x = new Complex(2d, 3d); Complex y = new Complex(0d, 2d); Assert.assertEquals(new Complex(1.5d, -1d), x.divide(y)); } @Test public void testDivideInf() { Complex x = new Complex(3, 4); Complex w = new Complex(neginf, inf); Assert.assertTrue(x.divide(w).equals(Complex.ZERO)); Complex z = w.divide(x); Assert.assertTrue(Double.isNaN(z.getReal())); Assert.assertEquals(inf, z.getImaginary(), 0); w = new Complex(inf, inf); z = w.divide(x); Assert.assertTrue(Double.isNaN(z.getImaginary())); Assert.assertEquals(inf, z.getReal(), 0); w = new Complex(1, inf); z = w.divide(w); Assert.assertTrue(Double.isNaN(z.getReal())); Assert.assertTrue(Double.isNaN(z.getImaginary())); } @Test public void testDivideZero() { Complex x = new Complex(3.0, 4.0); Complex z = x.divide(Complex.ZERO); // Assert.assertEquals(z, Complex.INF); // See MATH-657 Assert.assertEquals(z, Complex.NaN); } @Test public void testDivideZeroZero() { Complex x = new Complex(0.0, 0.0); Complex z = x.divide(Complex.ZERO); Assert.assertEquals(z, Complex.NaN); } @Test public void testDivideNaN() { Complex x = new Complex(3.0, 4.0); Complex z = x.divide(Complex.NaN); Assert.assertTrue(z.isNaN()); } @Test public void testDivideNaNInf() { Complex z = oneInf.divide(Complex.ONE); Assert.assertTrue(Double.isNaN(z.getReal())); Assert.assertEquals(inf, z.getImaginary(), 0); z = negInfNegInf.divide(oneNaN); Assert.assertTrue(Double.isNaN(z.getReal())); Assert.assertTrue(Double.isNaN(z.getImaginary())); z = negInfInf.divide(Complex.ONE); Assert.assertTrue(Double.isNaN(z.getReal())); Assert.assertTrue(Double.isNaN(z.getImaginary())); } @Test public void testScalarDivide() { Complex x = new Complex(3.0, 4.0); double yDouble = 2.0; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.divide(yComplex), x.divide(yDouble)); } @Test public void testScalarDivideNaN() { Complex x = new Complex(3.0, 4.0); double yDouble = Double.NaN; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.divide(yComplex), x.divide(yDouble)); } @Test public void testScalarDivideInf() { Complex x = new Complex(1,1); double yDouble = Double.POSITIVE_INFINITY; Complex yComplex = new Complex(yDouble); TestUtils.assertEquals(x.divide(yComplex), x.divide(yDouble), 0); yDouble = Double.NEGATIVE_INFINITY; yComplex = new Complex(yDouble); TestUtils.assertEquals(x.divide(yComplex), x.divide(yDouble), 0); x = new Complex(1, Double.NEGATIVE_INFINITY); TestUtils.assertEquals(x.divide(yComplex), x.divide(yDouble), 0); } @Test public void testScalarDivideZero() { Complex x = new Complex(1,1); TestUtils.assertEquals(x.divide(Complex.ZERO), x.divide(0), 0); } @Test public void testReciprocal() { Complex z = new Complex(5.0, 6.0); Complex act = z.reciprocal(); double expRe = 5.0 / 61.0; double expIm = -6.0 / 61.0; Assert.assertEquals(expRe, act.getReal(), FastMath.ulp(expRe)); Assert.assertEquals(expIm, act.getImaginary(), FastMath.ulp(expIm)); } @Test public void testReciprocalReal() { Complex z = new Complex(-2.0, 0.0); Assert.assertEquals(new Complex(-0.5, 0.0), z.reciprocal()); } @Test public void testReciprocalImaginary() { Complex z = new Complex(0.0, -2.0); Assert.assertEquals(new Complex(0.0, 0.5), z.reciprocal()); } @Test public void testReciprocalInf() { Complex z = new Complex(neginf, inf); Assert.assertTrue(z.reciprocal().equals(Complex.ZERO)); z = new Complex(1, inf).reciprocal(); Assert.assertEquals(z, Complex.ZERO); } @Test public void testReciprocalZero() { Assert.assertEquals(Complex.ZERO.reciprocal(), Complex.INF); } @Test public void testReciprocalNaN() { Assert.assertTrue(Complex.NaN.reciprocal().isNaN()); } @Test public void testMultiply() { Complex x = new Complex(3.0, 4.0); Complex y = new Complex(5.0, 6.0); Complex z = x.multiply(y); Assert.assertEquals(-9.0, z.getReal(), 1.0e-5); Assert.assertEquals(38.0, z.getImaginary(), 1.0e-5); } @Test public void testMultiplyNaN() { Complex x = new Complex(3.0, 4.0); Complex z = x.multiply(Complex.NaN); Assert.assertSame(Complex.NaN, z); z = Complex.NaN.multiply(5); Assert.assertSame(Complex.NaN, z); } @Test public void testMultiplyInfInf() { // Assert.assertTrue(infInf.multiply(infInf).isNaN()); // MATH-620 Assert.assertTrue(infInf.multiply(infInf).isInfinite()); } @Test public void testMultiplyNaNInf() { Complex z = new Complex(1,1); Complex w = z.multiply(infOne); Assert.assertEquals(w.getReal(), inf, 0); Assert.assertEquals(w.getImaginary(), inf, 0); // [MATH-164] Assert.assertTrue(new Complex( 1,0).multiply(infInf).equals(Complex.INF)); Assert.assertTrue(new Complex(-1,0).multiply(infInf).equals(Complex.INF)); Assert.assertTrue(new Complex( 1,0).multiply(negInfZero).equals(Complex.INF)); w = oneInf.multiply(oneNegInf); Assert.assertEquals(w.getReal(), inf, 0); Assert.assertEquals(w.getImaginary(), inf, 0); w = negInfNegInf.multiply(oneNaN); Assert.assertTrue(Double.isNaN(w.getReal())); Assert.assertTrue(Double.isNaN(w.getImaginary())); z = new Complex(1, neginf); Assert.assertSame(Complex.INF, z.multiply(z)); } @Test public void testScalarMultiply() { Complex x = new Complex(3.0, 4.0); double yDouble = 2.0; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.multiply(yComplex), x.multiply(yDouble)); int zInt = -5; Complex zComplex = new Complex(zInt); Assert.assertEquals(x.multiply(zComplex), x.multiply(zInt)); } @Test public void testScalarMultiplyNaN() { Complex x = new Complex(3.0, 4.0); double yDouble = Double.NaN; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.multiply(yComplex), x.multiply(yDouble)); } @Test public void testScalarMultiplyInf() { Complex x = new Complex(1, 1); double yDouble = Double.POSITIVE_INFINITY; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.multiply(yComplex), x.multiply(yDouble)); yDouble = Double.NEGATIVE_INFINITY; yComplex = new Complex(yDouble); Assert.assertEquals(x.multiply(yComplex), x.multiply(yDouble)); } @Test public void testNegate() { Complex x = new Complex(3.0, 4.0); Complex z = x.negate(); Assert.assertEquals(-3.0, z.getReal(), 1.0e-5); Assert.assertEquals(-4.0, z.getImaginary(), 1.0e-5); } @Test public void testNegateNaN() { Complex z = Complex.NaN.negate(); Assert.assertTrue(z.isNaN()); } @Test public void testSubtract() { Complex x = new Complex(3.0, 4.0); Complex y = new Complex(5.0, 6.0); Complex z = x.subtract(y); Assert.assertEquals(-2.0, z.getReal(), 1.0e-5); Assert.assertEquals(-2.0, z.getImaginary(), 1.0e-5); } @Test public void testSubtractNaN() { Complex x = new Complex(3.0, 4.0); Complex z = x.subtract(Complex.NaN); Assert.assertSame(Complex.NaN, z); z = new Complex(1, nan); Complex w = x.subtract(z); Assert.assertSame(Complex.NaN, w); } @Test public void testSubtractInf() { Complex x = new Complex(1, 1); Complex z = new Complex(neginf, 0); Complex w = x.subtract(z); Assert.assertEquals(w.getImaginary(), 1, 0); Assert.assertEquals(inf, w.getReal(), 0); x = new Complex(neginf, 0); Assert.assertTrue(Double.isNaN(x.subtract(z).getReal())); } @Test public void testScalarSubtract() { Complex x = new Complex(3.0, 4.0); double yDouble = 2.0; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.subtract(yComplex), x.subtract(yDouble)); } @Test public void testScalarSubtractNaN() { Complex x = new Complex(3.0, 4.0); double yDouble = Double.NaN; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.subtract(yComplex), x.subtract(yDouble)); } @Test public void testScalarSubtractInf() { Complex x = new Complex(1, 1); double yDouble = Double.POSITIVE_INFINITY; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.subtract(yComplex), x.subtract(yDouble)); x = new Complex(neginf, 0); Assert.assertEquals(x.subtract(yComplex), x.subtract(yDouble)); } @Test public void testEqualsNull() { Complex x = new Complex(3.0, 4.0); Assert.assertFalse(x.equals(null)); } @Test public void testEqualsClass() { Complex x = new Complex(3.0, 4.0); Assert.assertFalse(x.equals(this)); } @Test public void testEqualsSame() { Complex x = new Complex(3.0, 4.0); Assert.assertTrue(x.equals(x)); } @Test public void testEqualsTrue() { Complex x = new Complex(3.0, 4.0); Complex y = new Complex(3.0, 4.0); Assert.assertTrue(x.equals(y)); } @Test public void testEqualsRealDifference() { Complex x = new Complex(0.0, 0.0); Complex y = new Complex(0.0 + Double.MIN_VALUE, 0.0); Assert.assertFalse(x.equals(y)); } @Test public void testEqualsImaginaryDifference() { Complex x = new Complex(0.0, 0.0); Complex y = new Complex(0.0, 0.0 + Double.MIN_VALUE); Assert.assertFalse(x.equals(y)); } @Test public void testEqualsNaN() { Complex realNaN = new Complex(Double.NaN, 0.0); Complex imaginaryNaN = new Complex(0.0, Double.NaN); Complex complexNaN = Complex.NaN; Assert.assertTrue(realNaN.equals(imaginaryNaN)); Assert.assertTrue(imaginaryNaN.equals(complexNaN)); Assert.assertTrue(realNaN.equals(complexNaN)); } @Test public void testHashCode() { Complex x = new Complex(0.0, 0.0); Complex y = new Complex(0.0, 0.0 + Double.MIN_VALUE); Assert.assertFalse(x.hashCode()==y.hashCode()); y = new Complex(0.0 + Double.MIN_VALUE, 0.0); Assert.assertFalse(x.hashCode()==y.hashCode()); Complex realNaN = new Complex(Double.NaN, 0.0); Complex imaginaryNaN = new Complex(0.0, Double.NaN); Assert.assertEquals(realNaN.hashCode(), imaginaryNaN.hashCode()); Assert.assertEquals(imaginaryNaN.hashCode(), Complex.NaN.hashCode()); } @Test public void testAcos() { Complex z = new Complex(3, 4); Complex expected = new Complex(0.936812, -2.30551); TestUtils.assertEquals(expected, z.acos(), 1.0e-5); TestUtils.assertEquals(new Complex(FastMath.acos(0), 0), Complex.ZERO.acos(), 1.0e-12); } @Test public void testAcosInf() { TestUtils.assertSame(Complex.NaN, oneInf.acos()); TestUtils.assertSame(Complex.NaN, oneNegInf.acos()); TestUtils.assertSame(Complex.NaN, infOne.acos()); TestUtils.assertSame(Complex.NaN, negInfOne.acos()); TestUtils.assertSame(Complex.NaN, infInf.acos()); TestUtils.assertSame(Complex.NaN, infNegInf.acos()); TestUtils.assertSame(Complex.NaN, negInfInf.acos()); TestUtils.assertSame(Complex.NaN, negInfNegInf.acos()); } @Test public void testAcosNaN() { Assert.assertTrue(Complex.NaN.acos().isNaN()); } @Test public void testAsin() { Complex z = new Complex(3, 4); Complex expected = new Complex(0.633984, 2.30551); TestUtils.assertEquals(expected, z.asin(), 1.0e-5); } @Test public void testAsinNaN() { Assert.assertTrue(Complex.NaN.asin().isNaN()); } @Test public void testAsinInf() { TestUtils.assertSame(Complex.NaN, oneInf.asin()); TestUtils.assertSame(Complex.NaN, oneNegInf.asin()); TestUtils.assertSame(Complex.NaN, infOne.asin()); TestUtils.assertSame(Complex.NaN, negInfOne.asin()); TestUtils.assertSame(Complex.NaN, infInf.asin()); TestUtils.assertSame(Complex.NaN, infNegInf.asin()); TestUtils.assertSame(Complex.NaN, negInfInf.asin()); TestUtils.assertSame(Complex.NaN, negInfNegInf.asin()); } @Test public void testAtan() { Complex z = new Complex(3, 4); Complex expected = new Complex(1.44831, 0.158997); TestUtils.assertEquals(expected, z.atan(), 1.0e-5); } @Test public void testAtanInf() { TestUtils.assertSame(Complex.NaN, oneInf.atan()); TestUtils.assertSame(Complex.NaN, oneNegInf.atan()); TestUtils.assertSame(Complex.NaN, infOne.atan()); TestUtils.assertSame(Complex.NaN, negInfOne.atan()); TestUtils.assertSame(Complex.NaN, infInf.atan()); TestUtils.assertSame(Complex.NaN, infNegInf.atan()); TestUtils.assertSame(Complex.NaN, negInfInf.atan()); TestUtils.assertSame(Complex.NaN, negInfNegInf.atan()); } @Test public void testAtanI() { Assert.assertTrue(Complex.I.atan().isNaN()); } @Test public void testAtanNaN() { Assert.assertTrue(Complex.NaN.atan().isNaN()); } @Test public void testCos() { Complex z = new Complex(3, 4); Complex expected = new Complex(-27.03495, -3.851153); TestUtils.assertEquals(expected, z.cos(), 1.0e-5); } @Test public void testCosNaN() { Assert.assertTrue(Complex.NaN.cos().isNaN()); } @Test public void testCosInf() { TestUtils.assertSame(infNegInf, oneInf.cos()); TestUtils.assertSame(infInf, oneNegInf.cos()); TestUtils.assertSame(Complex.NaN, infOne.cos()); TestUtils.assertSame(Complex.NaN, negInfOne.cos()); TestUtils.assertSame(Complex.NaN, infInf.cos()); TestUtils.assertSame(Complex.NaN, infNegInf.cos()); TestUtils.assertSame(Complex.NaN, negInfInf.cos()); TestUtils.assertSame(Complex.NaN, negInfNegInf.cos()); } @Test public void testCosh() { Complex z = new Complex(3, 4); Complex expected = new Complex(-6.58066, -7.58155); TestUtils.assertEquals(expected, z.cosh(), 1.0e-5); } @Test public void testCoshNaN() { Assert.assertTrue(Complex.NaN.cosh().isNaN()); } @Test public void testCoshInf() { TestUtils.assertSame(Complex.NaN, oneInf.cosh()); TestUtils.assertSame(Complex.NaN, oneNegInf.cosh()); TestUtils.assertSame(infInf, infOne.cosh()); TestUtils.assertSame(infNegInf, negInfOne.cosh()); TestUtils.assertSame(Complex.NaN, infInf.cosh()); TestUtils.assertSame(Complex.NaN, infNegInf.cosh()); TestUtils.assertSame(Complex.NaN, negInfInf.cosh()); TestUtils.assertSame(Complex.NaN, negInfNegInf.cosh()); } @Test public void testExp() { Complex z = new Complex(3, 4); Complex expected = new Complex(-13.12878, -15.20078); TestUtils.assertEquals(expected, z.exp(), 1.0e-5); TestUtils.assertEquals(Complex.ONE, Complex.ZERO.exp(), 10e-12); Complex iPi = Complex.I.multiply(new Complex(pi,0)); TestUtils.assertEquals(Complex.ONE.negate(), iPi.exp(), 10e-12); } @Test public void testExpNaN() { Assert.assertTrue(Complex.NaN.exp().isNaN()); } @Test public void testExpInf() { TestUtils.assertSame(Complex.NaN, oneInf.exp()); TestUtils.assertSame(Complex.NaN, oneNegInf.exp()); TestUtils.assertSame(infInf, infOne.exp()); TestUtils.assertSame(Complex.ZERO, negInfOne.exp()); TestUtils.assertSame(Complex.NaN, infInf.exp()); TestUtils.assertSame(Complex.NaN, infNegInf.exp()); TestUtils.assertSame(Complex.NaN, negInfInf.exp()); TestUtils.assertSame(Complex.NaN, negInfNegInf.exp()); } @Test public void testLog() { Complex z = new Complex(3, 4); Complex expected = new Complex(1.60944, 0.927295); TestUtils.assertEquals(expected, z.log(), 1.0e-5); } @Test public void testLogNaN() { Assert.assertTrue(Complex.NaN.log().isNaN()); } @Test public void testLogInf() { TestUtils.assertEquals(new Complex(inf, pi / 2), oneInf.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, -pi / 2), oneNegInf.log(), 10e-12); TestUtils.assertEquals(infZero, infOne.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, pi), negInfOne.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, pi / 4), infInf.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, -pi / 4), infNegInf.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, 3d * pi / 4), negInfInf.log(), 10e-12); TestUtils.assertEquals(new Complex(inf, - 3d * pi / 4), negInfNegInf.log(), 10e-12); } @Test public void testLogZero() { TestUtils.assertSame(negInfZero, Complex.ZERO.log()); } @Test public void testPow() { Complex x = new Complex(3, 4); Complex y = new Complex(5, 6); Complex expected = new Complex(-1.860893, 11.83677); TestUtils.assertEquals(expected, x.pow(y), 1.0e-5); } @Test public void testPowNaNBase() { Complex x = new Complex(3, 4); Assert.assertTrue(Complex.NaN.pow(x).isNaN()); } @Test public void testPowNaNExponent() { Complex x = new Complex(3, 4); Assert.assertTrue(x.pow(Complex.NaN).isNaN()); } @Test public void testPowInf() { TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(oneInf)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(oneNegInf)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infOne)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infInf)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(infNegInf)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(negInfInf)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(negInfNegInf)); TestUtils.assertSame(Complex.NaN,infOne.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,negInfOne.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,infInf.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,negInfInf.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(infNegInf)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(negInfNegInf)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(infInf)); TestUtils.assertSame(Complex.NaN,infInf.pow(infNegInf)); TestUtils.assertSame(Complex.NaN,infInf.pow(negInfNegInf)); TestUtils.assertSame(Complex.NaN,infInf.pow(infInf)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(infNegInf)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(negInfNegInf)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(infInf)); } @Test public void testPowZero() { TestUtils.assertSame(Complex.NaN, Complex.ZERO.pow(Complex.ONE)); TestUtils.assertSame(Complex.NaN, Complex.ZERO.pow(Complex.ZERO)); TestUtils.assertSame(Complex.NaN, Complex.ZERO.pow(Complex.I)); TestUtils.assertEquals(Complex.ONE, Complex.ONE.pow(Complex.ZERO), 10e-12); TestUtils.assertEquals(Complex.ONE, Complex.I.pow(Complex.ZERO), 10e-12); TestUtils.assertEquals(Complex.ONE, new Complex(-1, 3).pow(Complex.ZERO), 10e-12); } @Test public void testScalarPow() { Complex x = new Complex(3, 4); double yDouble = 5.0; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.pow(yComplex), x.pow(yDouble)); } @Test public void testScalarPowNaNBase() { Complex x = Complex.NaN; double yDouble = 5.0; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.pow(yComplex), x.pow(yDouble)); } @Test public void testScalarPowNaNExponent() { Complex x = new Complex(3, 4); double yDouble = Double.NaN; Complex yComplex = new Complex(yDouble); Assert.assertEquals(x.pow(yComplex), x.pow(yDouble)); } @Test public void testScalarPowInf() { TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(Double.POSITIVE_INFINITY)); TestUtils.assertSame(Complex.NaN,Complex.ONE.pow(Double.NEGATIVE_INFINITY)); TestUtils.assertSame(Complex.NaN,infOne.pow(1.0)); TestUtils.assertSame(Complex.NaN,negInfOne.pow(1.0)); TestUtils.assertSame(Complex.NaN,infInf.pow(1.0)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(1.0)); TestUtils.assertSame(Complex.NaN,negInfInf.pow(10)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(1.0)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(Double.POSITIVE_INFINITY)); TestUtils.assertSame(Complex.NaN,negInfNegInf.pow(Double.POSITIVE_INFINITY)); TestUtils.assertSame(Complex.NaN,infInf.pow(Double.POSITIVE_INFINITY)); TestUtils.assertSame(Complex.NaN,infInf.pow(Double.NEGATIVE_INFINITY)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(Double.NEGATIVE_INFINITY)); TestUtils.assertSame(Complex.NaN,infNegInf.pow(Double.POSITIVE_INFINITY)); } @Test public void testScalarPowZero() { TestUtils.assertSame(Complex.NaN, Complex.ZERO.pow(1.0)); TestUtils.assertSame(Complex.NaN, Complex.ZERO.pow(0.0)); TestUtils.assertEquals(Complex.ONE, Complex.ONE.pow(0.0), 10e-12); TestUtils.assertEquals(Complex.ONE, Complex.I.pow(0.0), 10e-12); TestUtils.assertEquals(Complex.ONE, new Complex(-1, 3).pow(0.0), 10e-12); } @Test(expected=NullArgumentException.class) public void testpowNull() { Complex.ONE.pow(null); } @Test public void testSin() { Complex z = new Complex(3, 4); Complex expected = new Complex(3.853738, -27.01681); TestUtils.assertEquals(expected, z.sin(), 1.0e-5); } @Test public void testSinInf() { TestUtils.assertSame(infInf, oneInf.sin()); TestUtils.assertSame(infNegInf, oneNegInf.sin()); TestUtils.assertSame(Complex.NaN, infOne.sin()); TestUtils.assertSame(Complex.NaN, negInfOne.sin()); TestUtils.assertSame(Complex.NaN, infInf.sin()); TestUtils.assertSame(Complex.NaN, infNegInf.sin()); TestUtils.assertSame(Complex.NaN, negInfInf.sin()); TestUtils.assertSame(Complex.NaN, negInfNegInf.sin()); } @Test public void testSinNaN() { Assert.assertTrue(Complex.NaN.sin().isNaN()); } @Test public void testSinh() { Complex z = new Complex(3, 4); Complex expected = new Complex(-6.54812, -7.61923); TestUtils.assertEquals(expected, z.sinh(), 1.0e-5); } @Test public void testSinhNaN() { Assert.assertTrue(Complex.NaN.sinh().isNaN()); } @Test public void testSinhInf() { TestUtils.assertSame(Complex.NaN, oneInf.sinh()); TestUtils.assertSame(Complex.NaN, oneNegInf.sinh()); TestUtils.assertSame(infInf, infOne.sinh()); TestUtils.assertSame(negInfInf, negInfOne.sinh()); TestUtils.assertSame(Complex.NaN, infInf.sinh()); TestUtils.assertSame(Complex.NaN, infNegInf.sinh()); TestUtils.assertSame(Complex.NaN, negInfInf.sinh()); TestUtils.assertSame(Complex.NaN, negInfNegInf.sinh()); } @Test public void testSqrtRealPositive() { Complex z = new Complex(3, 4); Complex expected = new Complex(2, 1); TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5); } @Test public void testSqrtRealZero() { Complex z = new Complex(0.0, 4); Complex expected = new Complex(1.41421, 1.41421); TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5); } @Test public void testSqrtRealNegative() { Complex z = new Complex(-3.0, 4); Complex expected = new Complex(1, 2); TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5); } @Test public void testSqrtImaginaryZero() { Complex z = new Complex(-3.0, 0.0); Complex expected = new Complex(0.0, 1.73205); TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5); } @Test public void testSqrtImaginaryNegative() { Complex z = new Complex(-3.0, -4.0); Complex expected = new Complex(1.0, -2.0); TestUtils.assertEquals(expected, z.sqrt(), 1.0e-5); } @Test public void testSqrtPolar() { double r = 1; for (int i = 0; i < 5; i++) { r += i; double theta = 0; for (int j =0; j < 11; j++) { theta += pi /12; Complex z = ComplexUtils.polar2Complex(r, theta); Complex sqrtz = ComplexUtils.polar2Complex(FastMath.sqrt(r), theta / 2); TestUtils.assertEquals(sqrtz, z.sqrt(), 10e-12); } } } @Test public void testSqrtNaN() { Assert.assertTrue(Complex.NaN.sqrt().isNaN()); } @Test public void testSqrtInf() { TestUtils.assertSame(infNaN, oneInf.sqrt()); TestUtils.assertSame(infNaN, oneNegInf.sqrt()); TestUtils.assertSame(infZero, infOne.sqrt()); TestUtils.assertSame(zeroInf, negInfOne.sqrt()); TestUtils.assertSame(infNaN, infInf.sqrt()); TestUtils.assertSame(infNaN, infNegInf.sqrt()); TestUtils.assertSame(nanInf, negInfInf.sqrt()); TestUtils.assertSame(nanNegInf, negInfNegInf.sqrt()); } @Test public void testSqrt1z() { Complex z = new Complex(3, 4); Complex expected = new Complex(4.08033, -2.94094); TestUtils.assertEquals(expected, z.sqrt1z(), 1.0e-5); } @Test public void testSqrt1zNaN() { Assert.assertTrue(Complex.NaN.sqrt1z().isNaN()); } @Test public void testTan() { Complex z = new Complex(3, 4); Complex expected = new Complex(-0.000187346, 0.999356); TestUtils.assertEquals(expected, z.tan(), 1.0e-5); /* Check that no overflow occurs (MATH-722) */ Complex actual = new Complex(3.0, 1E10).tan(); expected = new Complex(0, 1); TestUtils.assertEquals(expected, actual, 1.0e-5); actual = new Complex(3.0, -1E10).tan(); expected = new Complex(0, -1); TestUtils.assertEquals(expected, actual, 1.0e-5); } @Test public void testTanNaN() { Assert.assertTrue(Complex.NaN.tan().isNaN()); } @Test public void testTanInf() { TestUtils.assertSame(Complex.valueOf(0.0, 1.0), oneInf.tan()); TestUtils.assertSame(Complex.valueOf(0.0, -1.0), oneNegInf.tan()); TestUtils.assertSame(Complex.NaN, infOne.tan()); TestUtils.assertSame(Complex.NaN, negInfOne.tan()); TestUtils.assertSame(Complex.NaN, infInf.tan()); TestUtils.assertSame(Complex.NaN, infNegInf.tan()); TestUtils.assertSame(Complex.NaN, negInfInf.tan()); TestUtils.assertSame(Complex.NaN, negInfNegInf.tan()); } @Test public void testTanCritical() { TestUtils.assertSame(infNaN, new Complex(pi/2, 0).tan()); TestUtils.assertSame(negInfNaN, new Complex(-pi/2, 0).tan()); } @Test public void testTanh() { Complex z = new Complex(3, 4); Complex expected = new Complex(1.00071, 0.00490826); TestUtils.assertEquals(expected, z.tanh(), 1.0e-5); /* Check that no overflow occurs (MATH-722) */ Complex actual = new Complex(1E10, 3.0).tanh(); expected = new Complex(1, 0); TestUtils.assertEquals(expected, actual, 1.0e-5); actual = new Complex(-1E10, 3.0).tanh(); expected = new Complex(-1, 0); TestUtils.assertEquals(expected, actual, 1.0e-5); } @Test public void testTanhNaN() { Assert.assertTrue(Complex.NaN.tanh().isNaN()); } @Test public void testTanhInf() { TestUtils.assertSame(Complex.NaN, oneInf.tanh()); TestUtils.assertSame(Complex.NaN, oneNegInf.tanh()); TestUtils.assertSame(Complex.valueOf(1.0, 0.0), infOne.tanh()); TestUtils.assertSame(Complex.valueOf(-1.0, 0.0), negInfOne.tanh()); TestUtils.assertSame(Complex.NaN, infInf.tanh()); TestUtils.assertSame(Complex.NaN, infNegInf.tanh()); TestUtils.assertSame(Complex.NaN, negInfInf.tanh()); TestUtils.assertSame(Complex.NaN, negInfNegInf.tanh()); } @Test public void testTanhCritical() { TestUtils.assertSame(nanInf, new Complex(0, pi/2).tanh()); } /** test issue MATH-221 */ @Test public void testMath221() { Assert.assertEquals(new Complex(0,-1), new Complex(0,1).multiply(new Complex(-1,0))); } /** * Test: computing third roots of z. *
*
* z = -2 + 2 * i
* => z_0 = 1 + i
* => z_1 = -1.3660 + 0.3660 * i
* => z_2 = 0.3660 - 1.3660 * i
*
*
*/
@Test
public void testNthRoot_normal_thirdRoot() {
// The complex number we want to compute all third-roots for.
Complex z = new Complex(-2,2);
// The List holding all third roots
Complex[] thirdRootsOfZ = z.nthRoot(3).toArray(new Complex[0]);
// Returned Collection must not be empty!
Assert.assertEquals(3, thirdRootsOfZ.length);
// test z_0
Assert.assertEquals(1.0, thirdRootsOfZ[0].getReal(), 1.0e-5);
Assert.assertEquals(1.0, thirdRootsOfZ[0].getImaginary(), 1.0e-5);
// test z_1
Assert.assertEquals(-1.3660254037844386, thirdRootsOfZ[1].getReal(), 1.0e-5);
Assert.assertEquals(0.36602540378443843, thirdRootsOfZ[1].getImaginary(), 1.0e-5);
// test z_2
Assert.assertEquals(0.366025403784439, thirdRootsOfZ[2].getReal(), 1.0e-5);
Assert.assertEquals(-1.3660254037844384, thirdRootsOfZ[2].getImaginary(), 1.0e-5);
}
/**
* Test: computing fourth roots of z.
*
*
* z = 5 - 2 * i
* => z_0 = 1.5164 - 0.1446 * i
* => z_1 = 0.1446 + 1.5164 * i
* => z_2 = -1.5164 + 0.1446 * i
* => z_3 = -1.5164 - 0.1446 * i
*
*
*/
@Test
public void testNthRoot_normal_fourthRoot() {
// The complex number we want to compute all third-roots for.
Complex z = new Complex(5,-2);
// The List holding all fourth roots
Complex[] fourthRootsOfZ = z.nthRoot(4).toArray(new Complex[0]);
// Returned Collection must not be empty!
Assert.assertEquals(4, fourthRootsOfZ.length);
// test z_0
Assert.assertEquals(1.5164629308487783, fourthRootsOfZ[0].getReal(), 1.0e-5);
Assert.assertEquals(-0.14469266210702247, fourthRootsOfZ[0].getImaginary(), 1.0e-5);
// test z_1
Assert.assertEquals(0.14469266210702256, fourthRootsOfZ[1].getReal(), 1.0e-5);
Assert.assertEquals(1.5164629308487783, fourthRootsOfZ[1].getImaginary(), 1.0e-5);
// test z_2
Assert.assertEquals(-1.5164629308487783, fourthRootsOfZ[2].getReal(), 1.0e-5);
Assert.assertEquals(0.14469266210702267, fourthRootsOfZ[2].getImaginary(), 1.0e-5);
// test z_3
Assert.assertEquals(-0.14469266210702275, fourthRootsOfZ[3].getReal(), 1.0e-5);
Assert.assertEquals(-1.5164629308487783, fourthRootsOfZ[3].getImaginary(), 1.0e-5);
}
/**
* Test: computing third roots of z.
*
*
* z = 8
* => z_0 = 2
* => z_1 = -1 + 1.73205 * i
* => z_2 = -1 - 1.73205 * i
*
*
*/
@Test
public void testNthRoot_cornercase_thirdRoot_imaginaryPartEmpty() {
// The number 8 has three third roots. One we all already know is the number 2.
// But there are two more complex roots.
Complex z = new Complex(8,0);
// The List holding all third roots
Complex[] thirdRootsOfZ = z.nthRoot(3).toArray(new Complex[0]);
// Returned Collection must not be empty!
Assert.assertEquals(3, thirdRootsOfZ.length);
// test z_0
Assert.assertEquals(2.0, thirdRootsOfZ[0].getReal(), 1.0e-5);
Assert.assertEquals(0.0, thirdRootsOfZ[0].getImaginary(), 1.0e-5);
// test z_1
Assert.assertEquals(-1.0, thirdRootsOfZ[1].getReal(), 1.0e-5);
Assert.assertEquals(1.7320508075688774, thirdRootsOfZ[1].getImaginary(), 1.0e-5);
// test z_2
Assert.assertEquals(-1.0, thirdRootsOfZ[2].getReal(), 1.0e-5);
Assert.assertEquals(-1.732050807568877, thirdRootsOfZ[2].getImaginary(), 1.0e-5);
}
/**
* Test: computing third roots of z with real part 0.
*
*
* z = 2 * i
* => z_0 = 1.0911 + 0.6299 * i
* => z_1 = -1.0911 + 0.6299 * i
* => z_2 = -2.3144 - 1.2599 * i
*
*
*/
@Test
public void testNthRoot_cornercase_thirdRoot_realPartZero() {
// complex number with only imaginary part
Complex z = new Complex(0,2);
// The List holding all third roots
Complex[] thirdRootsOfZ = z.nthRoot(3).toArray(new Complex[0]);
// Returned Collection must not be empty!
Assert.assertEquals(3, thirdRootsOfZ.length);
// test z_0
Assert.assertEquals(1.0911236359717216, thirdRootsOfZ[0].getReal(), 1.0e-5);
Assert.assertEquals(0.6299605249474365, thirdRootsOfZ[0].getImaginary(), 1.0e-5);
// test z_1
Assert.assertEquals(-1.0911236359717216, thirdRootsOfZ[1].getReal(), 1.0e-5);
Assert.assertEquals(0.6299605249474365, thirdRootsOfZ[1].getImaginary(), 1.0e-5);
// test z_2
Assert.assertEquals(-2.3144374213981936E-16, thirdRootsOfZ[2].getReal(), 1.0e-5);
Assert.assertEquals(-1.2599210498948732, thirdRootsOfZ[2].getImaginary(), 1.0e-5);
}
/**
* Test cornercases with NaN and Infinity.
*/
@Test
public void testNthRoot_cornercase_NAN_Inf() {
// NaN + finite -> NaN
ListGaussianFitter
* instance.
*
* @param points data points where first dimension is a point index and
* second dimension is an array of length two representing the point
* with the first value corresponding to X and the second value
* corresponding to Y
* @param fitter fitter to which the points in points
should be
* added as observed points
*/
protected static void addDatasetToGaussianFitter(double[][] points,
GaussianFitter fitter) {
for (int i = 0; i < points.length; i++) {
fitter.addObservedPoint(points[i][0], points[i][1]);
}
}
}
commons-math3-3.2-src/src/test/java/org/apache/commons/math3/fitting/HarmonicFitterTest.java 100644 1750 1750 15466 12126627672 30703 0 ustar luc luc 0 0 /*
* 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.math3.fitting;
import java.util.Random;
import org.apache.commons.math3.optim.nonlinear.vector.jacobian.LevenbergMarquardtOptimizer;
import org.apache.commons.math3.analysis.function.HarmonicOscillator;
import org.apache.commons.math3.exception.NumberIsTooSmallException;
import org.apache.commons.math3.exception.MathIllegalStateException;
import org.apache.commons.math3.util.FastMath;
import org.apache.commons.math3.util.MathUtils;
import org.junit.Test;
import org.junit.Assert;
public class HarmonicFitterTest {
@Test(expected=NumberIsTooSmallException.class)
public void testPreconditions1() {
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
fitter.fit();
}
@Test
public void testNoError() {
final double a = 0.2;
final double w = 3.4;
final double p = 4.1;
HarmonicOscillator f = new HarmonicOscillator(a, w, p);
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
for (double x = 0.0; x < 1.3; x += 0.01) {
fitter.addObservedPoint(1, x, f.value(x));
}
final double[] fitted = fitter.fit();
Assert.assertEquals(a, fitted[0], 1.0e-13);
Assert.assertEquals(w, fitted[1], 1.0e-13);
Assert.assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1e-13);
HarmonicOscillator ff = new HarmonicOscillator(fitted[0], fitted[1], fitted[2]);
for (double x = -1.0; x < 1.0; x += 0.01) {
Assert.assertTrue(FastMath.abs(f.value(x) - ff.value(x)) < 1e-13);
}
}
@Test
public void test1PercentError() {
Random randomizer = new Random(64925784252l);
final double a = 0.2;
final double w = 3.4;
final double p = 4.1;
HarmonicOscillator f = new HarmonicOscillator(a, w, p);
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
for (double x = 0.0; x < 10.0; x += 0.1) {
fitter.addObservedPoint(1, x,
f.value(x) + 0.01 * randomizer.nextGaussian());
}
final double[] fitted = fitter.fit();
Assert.assertEquals(a, fitted[0], 7.6e-4);
Assert.assertEquals(w, fitted[1], 2.7e-3);
Assert.assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1.3e-2);
}
@Test
public void testTinyVariationsData() {
Random randomizer = new Random(64925784252l);
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
for (double x = 0.0; x < 10.0; x += 0.1) {
fitter.addObservedPoint(1, x, 1e-7 * randomizer.nextGaussian());
}
fitter.fit();
// This test serves to cover the part of the code of "guessAOmega"
// when the algorithm using integrals fails.
}
@Test
public void testInitialGuess() {
Random randomizer = new Random(45314242l);
final double a = 0.2;
final double w = 3.4;
final double p = 4.1;
HarmonicOscillator f = new HarmonicOscillator(a, w, p);
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
for (double x = 0.0; x < 10.0; x += 0.1) {
fitter.addObservedPoint(1, x,
f.value(x) + 0.01 * randomizer.nextGaussian());
}
final double[] fitted = fitter.fit(new double[] { 0.15, 3.6, 4.5 });
Assert.assertEquals(a, fitted[0], 1.2e-3);
Assert.assertEquals(w, fitted[1], 3.3e-3);
Assert.assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1.7e-2);
}
@Test
public void testUnsorted() {
Random randomizer = new Random(64925784252l);
final double a = 0.2;
final double w = 3.4;
final double p = 4.1;
HarmonicOscillator f = new HarmonicOscillator(a, w, p);
HarmonicFitter fitter =
new HarmonicFitter(new LevenbergMarquardtOptimizer());
// build a regularly spaced array of measurements
int size = 100;
double[] xTab = new double[size];
double[] yTab = new double[size];
for (int i = 0; i < size; ++i) {
xTab[i] = 0.1 * i;
yTab[i] = f.value(xTab[i]) + 0.01 * randomizer.nextGaussian();
}
// shake it
for (int i = 0; i < size; ++i) {
int i1 = randomizer.nextInt(size);
int i2 = randomizer.nextInt(size);
double xTmp = xTab[i1];
double yTmp = yTab[i1];
xTab[i1] = xTab[i2];
yTab[i1] = yTab[i2];
xTab[i2] = xTmp;
yTab[i2] = yTmp;
}
// pass it to the fitter
for (int i = 0; i < size; ++i) {
fitter.addObservedPoint(1, xTab[i], yTab[i]);
}
final double[] fitted = fitter.fit();
Assert.assertEquals(a, fitted[0], 7.6e-4);
Assert.assertEquals(w, fitted[1], 3.5e-3);
Assert.assertEquals(p, MathUtils.normalizeAngle(fitted[2], p), 1.5e-2);
}
@Test(expected=MathIllegalStateException.class)
public void testMath844() {
final double[] y = { 0, 1, 2, 3, 2, 1,
0, -1, -2, -3, -2, -1,
0, 1, 2, 3, 2, 1,
0, -1, -2, -3, -2, -1,
0, 1, 2, 3, 2, 1, 0 };
final int len = y.length;
final WeightedObservedPoint[] points = new WeightedObservedPoint[len];
for (int i = 0; i < len; i++) {
points[i] = new WeightedObservedPoint(1, i, y[i]);
}
// The guesser fails because the function is far from an harmonic
// function: It is a triangular periodic function with amplitude 3
// and period 12, and all sample points are taken at integer abscissae
// so function values all belong to the integer subset {-3, -2, -1, 0,
// 1, 2, 3}.
final HarmonicFitter.ParameterGuesser guesser
= new HarmonicFitter.ParameterGuesser(points);
}
}
commons-math3-3.2-src/src/test/java/org/apache/commons/math3/fitting/PolynomialFitterTest.java 100644 1750 1750 27705 12126627672 31265 0 ustar luc luc 0 0 /*
* 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.math3.fitting;
import java.util.Random;
import org.apache.commons.math3.analysis.polynomials.PolynomialFunction;
import org.apache.commons.math3.analysis.polynomials.PolynomialFunction.Parametric;
import org.apache.commons.math3.exception.ConvergenceException;
import org.apache.commons.math3.exception.TooManyEvaluationsException;
import org.apache.commons.math3.optim.nonlinear.vector.MultivariateVectorOptimizer;
import org.apache.commons.math3.optim.nonlinear.vector.jacobian.LevenbergMarquardtOptimizer;
import org.apache.commons.math3.optim.nonlinear.vector.jacobian.GaussNewtonOptimizer;
import org.apache.commons.math3.optim.SimpleVectorValueChecker;
import org.apache.commons.math3.util.FastMath;
import org.apache.commons.math3.distribution.RealDistribution;
import org.apache.commons.math3.distribution.UniformRealDistribution;
import org.apache.commons.math3.TestUtils;
import org.junit.Test;
import org.junit.Assert;
/**
* Test for class {@link CurveFitter} where the function to fit is a
* polynomial.
*/
public class PolynomialFitterTest {
@Test
public void testFit() {
final RealDistribution rng = new UniformRealDistribution(-100, 100);
rng.reseedRandomGenerator(64925784252L);
final LevenbergMarquardtOptimizer optim = new LevenbergMarquardtOptimizer();
final PolynomialFitter fitter = new PolynomialFitter(optim);
final double[] coeff = { 12.9, -3.4, 2.1 }; // 12.9 - 3.4 x + 2.1 x^2
final PolynomialFunction f = new PolynomialFunction(coeff);
// Collect data from a known polynomial.
for (int i = 0; i < 100; i++) {
final double x = rng.sample();
fitter.addObservedPoint(x, f.value(x));
}
// Start fit from initial guesses that are far from the optimal values.
final double[] best = fitter.fit(new double[] { -1e-20, 3e15, -5e25 });
TestUtils.assertEquals("best != coeff", coeff, best, 1e-12);
}
@Test
public void testNoError() {
Random randomizer = new Random(64925784252l);
for (int degree = 1; degree < 10; ++degree) {
PolynomialFunction p = buildRandomPolynomial(degree, randomizer);
PolynomialFitter fitter = new PolynomialFitter(new LevenbergMarquardtOptimizer());
for (int i = 0; i <= degree; ++i) {
fitter.addObservedPoint(1.0, i, p.value(i));
}
final double[] init = new double[degree + 1];
PolynomialFunction fitted = new PolynomialFunction(fitter.fit(init));
for (double x = -1.0; x < 1.0; x += 0.01) {
double error = FastMath.abs(p.value(x) - fitted.value(x)) /
(1.0 + FastMath.abs(p.value(x)));
Assert.assertEquals(0.0, error, 1.0e-6);
}
}
}
@Test
public void testSmallError() {
Random randomizer = new Random(53882150042l);
double maxError = 0;
for (int degree = 0; degree < 10; ++degree) {
PolynomialFunction p = buildRandomPolynomial(degree, randomizer);
PolynomialFitter fitter = new PolynomialFitter(new LevenbergMarquardtOptimizer());
for (double x = -1.0; x < 1.0; x += 0.01) {
fitter.addObservedPoint(1.0, x,
p.value(x) + 0.1 * randomizer.nextGaussian());
}
final double[] init = new double[degree + 1];
PolynomialFunction fitted = new PolynomialFunction(fitter.fit(init));
for (double x = -1.0; x < 1.0; x += 0.01) {
double error = FastMath.abs(p.value(x) - fitted.value(x)) /
(1.0 + FastMath.abs(p.value(x)));
maxError = FastMath.max(maxError, error);
Assert.assertTrue(FastMath.abs(error) < 0.1);
}
}
Assert.assertTrue(maxError > 0.01);
}
@Test
public void testMath798() {
final double tol = 1e-14;
final SimpleVectorValueChecker checker = new SimpleVectorValueChecker(tol, tol);
final double[] init = new double[] { 0, 0 };
final int maxEval = 3;
final double[] lm = doMath798(new LevenbergMarquardtOptimizer(checker), maxEval, init);
final double[] gn = doMath798(new GaussNewtonOptimizer(checker), maxEval, init);
for (int i = 0; i <= 1; i++) {
Assert.assertEquals(lm[i], gn[i], tol);
}
}
/**
* This test shows that the user can set the maximum number of iterations
* to avoid running for too long.
* But in the test case, the real problem is that the tolerance is way too
* stringent.
*/
@Test(expected=TooManyEvaluationsException.class)
public void testMath798WithToleranceTooLow() {
final double tol = 1e-100;
final SimpleVectorValueChecker checker = new SimpleVectorValueChecker(tol, tol);
final double[] init = new double[] { 0, 0 };
final int maxEval = 10000; // Trying hard to fit.
final double[] gn = doMath798(new GaussNewtonOptimizer(checker), maxEval, init);
}
/**
* This test shows that the user can set the maximum number of iterations
* to avoid running for too long.
* Even if the real problem is that the tolerance is way too stringent, it
* is possible to get the best solution so far, i.e. a checker will return
* the point when the maximum iteration count has been reached.
*/
@Test
public void testMath798WithToleranceTooLowButNoException() {
final double tol = 1e-100;
final double[] init = new double[] { 0, 0 };
final int maxEval = 10000; // Trying hard to fit.
final SimpleVectorValueChecker checker = new SimpleVectorValueChecker(tol, tol, maxEval);
final double[] lm = doMath798(new LevenbergMarquardtOptimizer(checker), maxEval, init);
final double[] gn = doMath798(new GaussNewtonOptimizer(checker), maxEval, init);
for (int i = 0; i <= 1; i++) {
Assert.assertEquals(lm[i], gn[i], 1e-15);
}
}
/**
* @param optimizer Optimizer.
* @param maxEval Maximum number of function evaluations.
* @param init First guess.
* @return the solution found by the given optimizer.
*/
private double[] doMath798(MultivariateVectorOptimizer optimizer,
int maxEval,
double[] init) {
final CurveFitter* FST algorithm is exact, the small tolerance number is used only * to account for round-off errors. * * @version $Id: FastSineTransformerTest.java 1374632 2012-08-18 18:11:11Z luc $ */ @RunWith(value = Parameterized.class) public final class FastSineTransformerTest extends RealTransformerAbstractTest { private final DstNormalization normalization; private final int[] invalidDataSize; private final double[] relativeTolerance; private final int[] validDataSize; public FastSineTransformerTest(final DstNormalization normalization) { this.normalization = normalization; this.validDataSize = new int[] { 1, 2, 4, 8, 16, 32, 64, 128 }; this.invalidDataSize = new int[] { 129 }; this.relativeTolerance = new double[] { 1E-15, 1E-15, 1E-14, 1E-14, 1E-13, 1E-12, 1E-11, 1E-11 }; } /** * Returns an array containing {@code true, false} in order to check both * standard and orthogonal DSTs. * * @return an array of parameters for this parameterized test */ @Parameters public static Collection