You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gr...@apache.org on 2011/10/01 04:01:04 UTC
svn commit: r1177884 -
/commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/BatteryNISTTest.java
Author: gregs
Date: Sat Oct 1 02:01:03 2011
New Revision: 1177884
URL: http://svn.apache.org/viewvc?rev=1177884&view=rev
Log:
JIRA:MATH-678 Adding this testfile as a record, most tests are commented out
Added:
commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/BatteryNISTTest.java
Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/BatteryNISTTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/BatteryNISTTest.java?rev=1177884&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/BatteryNISTTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/optimization/BatteryNISTTest.java Sat Oct 1 02:01:03 2011
@@ -0,0 +1,916 @@
+/*
+ * Copyright 2011 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.optimization;
+
+import java.util.Arrays;
+import junit.framework.Assert;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.TestUtils;
+import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+import org.apache.commons.math.analysis.MultivariateVectorialFunction;
+import org.apache.commons.math.exception.MathIllegalArgumentException;
+import org.apache.commons.math.exception.util.LocalizedFormats;
+import org.apache.commons.math.optimization.direct.BOBYQAOptimizer;
+import org.apache.commons.math.optimization.direct.PowellOptimizer;
+import org.apache.commons.math.optimization.general.AbstractScalarDifferentiableOptimizer;
+import org.apache.commons.math.optimization.general.ConjugateGradientFormula;
+import org.apache.commons.math.optimization.general.NonLinearConjugateGradientOptimizer;
+import org.apache.commons.math.util.FastMath;
+import org.junit.Test;
+
+/**
+ * an ever growing set of tests from NIST
+ * http://www.itl.nist.gov/div898/strd/nls/nls_main.shtml
+ * @author gregs
+ */
+public class BatteryNISTTest {
+
+ public static double[] lanczosNIST = {
+ 2.5134, 0.00000,
+ 2.0443, 5.00000e-2,
+ 1.6684, 1.00000e-1,
+ 1.3664, 1.50000e-1,
+ 1.1232, 2.00000e-1,
+ 0.9269, 2.50000e-1,
+ 0.7679, 3.00000e-1,
+ 0.6389, 3.50000e-1,
+ 0.5338, 4.00000e-1,
+ 0.4479, 4.50000e-1,
+ 0.3776, 5.00000e-1,
+ 0.3197, 5.50000e-1,
+ 0.2720, 6.00000e-1,
+ 0.2325, 6.50000e-1,
+ 0.1997, 7.00000e-1,
+ 0.1723, 7.50000e-1,
+ 0.1493, 8.00000e-1,
+ 0.1301, 8.50000e-1,
+ 0.1138, 9.00000e-1,
+ 0.1000, 9.50000e-1,
+ 0.0883, 1.00000,
+ 0.0783, 1.05000,
+ 0.0698, 1.10000,
+ 0.0624, 1.15000};
+ /* the lanzcos objective function -------------------------------*/
+ private final nistMVRF lanczosObjectFunc = new nistMVRF(lanczosNIST, 1, 24, 6) {
+
+ @Override
+ protected double partialDeriv(double[] point, int idx) {
+ double cy, cx, r, ret = 0.0, d;
+ int ptr = 0, ptr1;
+ for (int i = 0; i < this.nobs; i++) {
+ cy = data[ptr++];
+ cx = data[ptr++];
+ ptr1 = 0;
+ d = 0.0;
+ for (int j = 0; j < 3; j++) {
+ d += point[ptr1++] * FastMath.exp(-cx * point[ptr1++]);
+ }
+ r = cy - d;
+ if (idx == 0) {
+ ret -= (2.0 * r) * FastMath.exp(-cx * point[1]);
+ } else if (idx == 1) {
+ ret += (2.0 * r) * FastMath.exp(-cx * point[1]) * cx * point[0];
+ } else if (idx == 2) {
+ ret -= (2.0 * r) * FastMath.exp(-cx * point[3]);
+ } else if (idx == 3) {
+ ret += (2.0 * r) * FastMath.exp(-cx * point[3]) * cx * point[2];
+ } else if (idx == 4) {
+ ret -= (2.0 * r) * FastMath.exp(-cx * point[5]);
+ } else {
+ ret += (2.0 * r) * FastMath.exp(-cx * point[5]) * cx * point[4];
+ }
+ }
+ return (ret);
+ }
+
+ public double value(double[] point) {
+ double ret = 0.0, err, d, cx, cy;
+ int ptr = 0, ptr1 = 0;
+ for (int i = 0; i < this.nobs; i++) {
+ cy = data[ptr++];
+ cx = data[ptr++];
+ d = 0.0;
+ ptr1 = 0;
+ for (int j = 0; j < 3; j++) {
+ d += point[ptr1++] * FastMath.exp(-cx * point[ptr1++]);
+ }
+ err = cy - d;
+ ret += err * err;
+ }
+ return (ret);
+ }
+
+ @Override
+ protected double[] getGradient(double[] point) {
+ Arrays.fill(gradient, 0.0);
+ double cy, cx, r, d = 0;
+ int ptr = 0, ptr1;
+ for (int i = 0; i < this.nobs; i++) {
+ cy = data[ptr++];
+ cx = data[ptr++];
+ ptr1 = 0;
+ d = 0.0;
+ for (int j = 0; j < 3; j++) {
+ d += point[ptr1++] * FastMath.exp(-cx * point[ptr1++]);
+ }
+ r = cy - d;
+ gradient[0] -= (2.0 * r) * FastMath.exp(-cx * point[1]);
+ gradient[1] += (2.0 * r) * FastMath.exp(-cx * point[1]) * cx * point[0];
+
+ gradient[2] -= (2.0 * r) * FastMath.exp(-cx * point[3]);
+ gradient[3] += (2.0 * r) * FastMath.exp(-cx * point[3]) * cx * point[2];
+
+ gradient[4] -= (2.0 * r) * FastMath.exp(-cx * point[5]);
+ gradient[5] += (2.0 * r) * FastMath.exp(-cx * point[5]) * cx * point[4];
+ }
+ return this.gradient;
+ }
+ };
+
+ /* chwirut1 data ------------------------*/
+ public static double[] chwirut1NIST = {
+ 92.9000, 0.5000,
+ 78.7000, 0.6250,
+ 64.2000, 0.7500,
+ 64.9000, 0.8750,
+ 57.1000, 1.0000,
+ 43.3000, 1.2500,
+ 31.1000, 1.7500,
+ 23.6000, 2.2500,
+ 31.0500, 1.7500,
+ 23.7750, 2.2500,
+ 17.7375, 2.7500,
+ 13.8000, 3.2500,
+ 11.5875, 3.7500,
+ 9.4125, 4.2500,
+ 7.7250, 4.7500,
+ 7.3500, 5.2500,
+ 8.0250, 5.7500,
+ 90.6000, 0.5000,
+ 76.9000, 0.6250,
+ 71.6000, 0.7500,
+ 63.6000, 0.8750,
+ 54.0000, 1.0000,
+ 39.2000, 1.2500,
+ 29.3000, 1.7500,
+ 21.4000, 2.2500,
+ 29.1750, 1.7500,
+ 22.1250, 2.2500,
+ 17.5125, 2.7500,
+ 14.2500, 3.2500,
+ 9.4500, 3.7500,
+ 9.1500, 4.2500,
+ 7.9125, 4.7500,
+ 8.4750, 5.2500,
+ 6.1125, 5.7500,
+ 80.0000, 0.5000,
+ 79.0000, 0.6250,
+ 63.8000, 0.7500,
+ 57.2000, 0.8750,
+ 53.2000, 1.0000,
+ 42.5000, 1.2500,
+ 26.8000, 1.7500,
+ 20.4000, 2.2500,
+ 26.8500, 1.7500,
+ 21.0000, 2.2500,
+ 16.4625, 2.7500,
+ 12.5250, 3.2500,
+ 10.5375, 3.7500,
+ 8.5875, 4.2500,
+ 7.1250, 4.7500,
+ 6.1125, 5.2500,
+ 5.9625, 5.7500,
+ 74.1000, 0.5000,
+ 67.3000, 0.6250,
+ 60.8000, 0.7500,
+ 55.5000, 0.8750,
+ 50.3000, 1.0000,
+ 41.0000, 1.2500,
+ 29.4000, 1.7500,
+ 20.4000, 2.2500,
+ 29.3625, 1.7500,
+ 21.1500, 2.2500,
+ 16.7625, 2.7500,
+ 13.2000, 3.2500,
+ 10.8750, 3.7500,
+ 8.1750, 4.2500,
+ 7.3500, 4.7500,
+ 5.9625, 5.2500,
+ 5.6250, 5.7500,
+ 81.5000, .5000,
+ 62.4000, .7500,
+ 32.5000, 1.5000,
+ 12.4100, 3.0000,
+ 13.1200, 3.0000,
+ 15.5600, 3.0000,
+ 5.6300, 6.0000,
+ 78.0000, .5000,
+ 59.9000, .7500,
+ 33.2000, 1.5000,
+ 13.8400, 3.0000,
+ 12.7500, 3.0000,
+ 14.6200, 3.0000,
+ 3.9400, 6.0000,
+ 76.8000, .5000,
+ 61.0000, .7500,
+ 32.9000, 1.5000,
+ 13.8700, 3.0000,
+ 11.8100, 3.0000,
+ 13.3100, 3.0000,
+ 5.4400, 6.0000,
+ 78.0000, .5000,
+ 63.5000, .7500,
+ 33.8000, 1.5000,
+ 12.5600, 3.0000,
+ 5.6300, 6.0000,
+ 12.7500, 3.0000,
+ 13.1200, 3.0000,
+ 5.4400, 6.0000,
+ 76.8000, .5000,
+ 60.0000, .7500,
+ 47.8000, 1.0000,
+ 32.0000, 1.5000,
+ 22.2000, 2.0000,
+ 22.5700, 2.0000,
+ 18.8200, 2.5000,
+ 13.9500, 3.0000,
+ 11.2500, 4.0000,
+ 9.0000, 5.0000,
+ 6.6700, 6.0000,
+ 75.8000, .5000,
+ 62.0000, .7500,
+ 48.8000, 1.0000,
+ 35.2000, 1.5000,
+ 20.0000, 2.0000,
+ 20.3200, 2.0000,
+ 19.3100, 2.5000,
+ 12.7500, 3.0000,
+ 10.4200, 4.0000,
+ 7.3100, 5.0000,
+ 7.4200, 6.0000,
+ 70.5000, .5000,
+ 59.5000, .7500,
+ 48.5000, 1.0000,
+ 35.8000, 1.5000,
+ 21.0000, 2.0000,
+ 21.6700, 2.0000,
+ 21.0000, 2.5000,
+ 15.6400, 3.0000,
+ 8.1700, 4.0000,
+ 8.5500, 5.0000,
+ 10.1200, 6.0000,
+ 78.0000, .5000,
+ 66.0000, .6250,
+ 62.0000, .7500,
+ 58.0000, .8750,
+ 47.7000, 1.0000,
+ 37.8000, 1.2500,
+ 20.2000, 2.2500,
+ 21.0700, 2.2500,
+ 13.8700, 2.7500,
+ 9.6700, 3.2500,
+ 7.7600, 3.7500,
+ 5.4400, 4.2500,
+ 4.8700, 4.7500,
+ 4.0100, 5.2500,
+ 3.7500, 5.7500,
+ 24.1900, 3.0000,
+ 25.7600, 3.0000,
+ 18.0700, 3.0000,
+ 11.8100, 3.0000,
+ 12.0700, 3.0000,
+ 16.1200, 3.0000,
+ 70.8000, .5000,
+ 54.7000, .7500,
+ 48.0000, 1.0000,
+ 39.8000, 1.5000,
+ 29.8000, 2.0000,
+ 23.7000, 2.5000,
+ 29.6200, 2.0000,
+ 23.8100, 2.5000,
+ 17.7000, 3.0000,
+ 11.5500, 4.0000,
+ 12.0700, 5.0000,
+ 8.7400, 6.0000,
+ 80.7000, .5000,
+ 61.3000, .7500,
+ 47.5000, 1.0000,
+ 29.0000, 1.5000,
+ 24.0000, 2.0000,
+ 17.7000, 2.5000,
+ 24.5600, 2.0000,
+ 18.6700, 2.5000,
+ 16.2400, 3.0000,
+ 8.7400, 4.0000,
+ 7.8700, 5.0000,
+ 8.5100, 6.0000,
+ 66.7000, .5000,
+ 59.2000, .7500,
+ 40.8000, 1.0000,
+ 30.7000, 1.5000,
+ 25.7000, 2.0000,
+ 16.3000, 2.5000,
+ 25.9900, 2.0000,
+ 16.9500, 2.5000,
+ 13.3500, 3.0000,
+ 8.6200, 4.0000,
+ 7.2000, 5.0000,
+ 6.6400, 6.0000,
+ 13.6900, 3.0000,
+ 81.0000, .5000,
+ 64.5000, .7500,
+ 35.5000, 1.5000,
+ 13.3100, 3.0000,
+ 4.8700, 6.0000,
+ 12.9400, 3.0000,
+ 5.0600, 6.0000,
+ 15.1900, 3.0000,
+ 14.6200, 3.0000,
+ 15.6400, 3.0000,
+ 25.5000, 1.7500,
+ 25.9500, 1.7500,
+ 81.7000, .5000,
+ 61.6000, .7500,
+ 29.8000, 1.7500,
+ 29.8100, 1.7500,
+ 17.1700, 2.7500,
+ 10.3900, 3.7500,
+ 28.4000, 1.7500,
+ 28.6900, 1.7500,
+ 81.3000, .5000,
+ 60.9000, .7500,
+ 16.6500, 2.7500,
+ 10.0500, 3.7500,
+ 28.9000, 1.7500,
+ 28.9500, 1.7500
+ };
+
+ /* the chwirut1 objective function */
+ private final nistMVRF chwirut1ObjectFunc = new chwirut(chwirut1NIST, 1, 214, 3);
+
+ //http://www.itl.nist.gov/div898/strd/nls/data/LINKS/DATA/Chwirut2.dat
+ public static double[] chwirut2NIST = {
+ 92.9000, 0.500,
+ 57.1000, 1.000,
+ 31.0500, 1.750,
+ 11.5875, 3.750,
+ 8.0250, 5.750,
+ 63.6000, 0.875,
+ 21.4000, 2.250,
+ 14.2500, 3.250,
+ 8.4750, 5.250,
+ 63.8000, 0.750,
+ 26.8000, 1.750,
+ 16.4625, 2.750,
+ 7.1250, 4.750,
+ 67.3000, 0.625,
+ 41.0000, 1.250,
+ 21.1500, 2.250,
+ 8.1750, 4.250,
+ 81.5000, .500,
+ 13.1200, 3.000,
+ 59.9000, .750,
+ 14.6200, 3.000,
+ 32.9000, 1.500,
+ 5.4400, 6.000,
+ 12.5600, 3.000,
+ 5.4400, 6.000,
+ 32.0000, 1.500,
+ 13.9500, 3.000,
+ 75.8000, .500,
+ 20.0000, 2.000,
+ 10.4200, 4.000,
+ 59.5000, .750,
+ 21.6700, 2.000,
+ 8.5500, 5.000,
+ 62.0000, .750,
+ 20.2000, 2.250,
+ 7.7600, 3.750,
+ 3.7500, 5.750,
+ 11.8100, 3.000,
+ 54.7000, .750,
+ 23.7000, 2.500,
+ 11.5500, 4.000,
+ 61.3000, .750,
+ 17.7000, 2.500,
+ 8.7400, 4.000,
+ 59.2000, .750,
+ 16.3000, 2.500,
+ 8.6200, 4.000,
+ 81.0000, .500,
+ 4.8700, 6.000,
+ 14.6200, 3.000,
+ 81.7000, .500,
+ 17.1700, 2.750,
+ 81.3000, .500,
+ 28.9000, 1.750
+ };
+
+ /* the chwirut 2 objective --------------------------------------------------*/
+ private final nistMVRF chwirut2ObjectFunc = new chwirut(chwirut2NIST, 1, 54, 3);
+
+ //http://www.itl.nist.gov/div898/strd/nls/data/LINKS/DATA/Misra1a.dat
+ //y x
+ private static double[] misra1aNIST = {
+ 10.07, 77.6,
+ 14.73, 114.9,
+ 17.94, 141.1,
+ 23.93, 190.8,
+ 29.61, 239.9,
+ 35.18, 289.0,
+ 40.02, 332.8,
+ 44.82, 378.4,
+ 50.76, 434.8,
+ 55.05, 477.3,
+ 61.01, 536.8,
+ 66.40, 593.1,
+ 75.47, 689.1,
+ 81.78, 760.0
+ };
+
+ /* the misra1a objective function */
+ private final nistMVRF misra1aObjectFunc = new nistMVRF(misra1aNIST, 1, 14, 2) {
+
+ @Override
+ protected double partialDeriv(double[] point, int idx) {
+ double cy, cx, r, ret = 0.0;
+ int ptr = 0;
+ for (int i = 0; i < this.nobs; i++) {
+ cy = data[ptr++];
+ cx = data[ptr++];
+ r = cy - point[0] * (1.0 - FastMath.exp(-cx * point[1]));
+ if (idx == 0) {
+ ret -= (2.0 * r) * (1.0 - FastMath.exp(-cx * point[1]));
+ } else {
+ ret -= (2.0 * r) * cx * point[0] * FastMath.exp(-cx * point[1]);
+ }
+ }
+ return (ret);
+ }
+
+ public double value(double[] point) {
+ double ret = 0.0, err;
+ int ptr = 0;
+ for (int i = 0; i < this.nobs; i++) {
+ err = data[ptr++] - point[0] * (1.0 - FastMath.exp(-data[ptr++] * point[1]));
+ ret += err * err;
+ }
+ return (ret);
+ }
+
+ @Override
+ protected double[] getGradient(double[] point) {
+ Arrays.fill(gradient, 0.0);
+ double cy, cx, r;
+ int ptr = 0;
+ for (int i = 0; i < this.nobs; i++) {
+ cy = data[ptr++];
+ cx = data[ptr++];
+ r = cy - point[0] * (1.0 - FastMath.exp(-cx * point[1]));
+ gradient[0] -= (2.0 * r) * (1.0 - FastMath.exp(-cx * point[1]));
+ gradient[1] -= (2.0 * r) * cx * point[0] * FastMath.exp(-cx * point[1]);
+ }
+ return this.gradient;
+ }
+ };
+ private static double[] correctParamMisra1a = {2.3894212918e2, 5.5015643181E-4};
+ private static double[] correctParamChwirut2 = {1.6657666537e-1, 5.1653291286e-3, 1.2150007096e-2};
+ private static double[] correctParamChwirut1 = {1.9027818370e-1, 6.1314004477e-3, 1.0530908399e-2};
+ private static double[] correctParamLanczos = {8.6816414977e-2, 9.5498101505e-01, 8.4400777463E-01, 2.9515951832, 1.5825685901, 4.9863565084};
+
+ @Test
+ public void lanczosTest() {
+ //first check to see that the NIST Object function is being replicated correctly
+ double obj = this.lanczosObjectFunc.value(correctParamLanczos);
+ Assert.assertEquals(1.6117193594E-08, obj, 1.0e-8);
+
+ double[] grad = this.lanczosObjectFunc.getGradient(correctParamLanczos);
+ double[] grad2 = new double[6];
+ grad2[0] = this.lanczosObjectFunc.partialDeriv(correctParamLanczos, 0);
+ grad2[1] = this.lanczosObjectFunc.partialDeriv(correctParamLanczos, 1);
+ grad2[2] = this.lanczosObjectFunc.partialDeriv(correctParamLanczos, 2);
+ grad2[3] = this.lanczosObjectFunc.partialDeriv(correctParamLanczos, 3);
+ grad2[4] = this.lanczosObjectFunc.partialDeriv(correctParamLanczos, 4);
+ grad2[5] = this.lanczosObjectFunc.partialDeriv(correctParamLanczos, 5);
+ TestUtils.assertEquals("Grads...", grad, grad2, 1.0e-12);
+
+ double[] n_grad = this.getGradient(lanczosObjectFunc, correctParamLanczos, 1.0e-5);
+ //System.out.println("g = " + grad[0] + " ng = " + n_grad[0]);
+ //System.out.println("g = " + grad[1] + " ng = " + n_grad[1]);
+ if (FastMath.abs(grad[0] - n_grad[0]) > FastMath.max(1.0e-6, 1.0e-6 * (grad[0] + n_grad[0]) / 2.0)) {
+ Assert.fail("Check gradient at 1");
+ }
+ if (FastMath.abs(grad[1] - n_grad[1]) > FastMath.max(1.0e-6, 1.0e-6 * (grad[1] + n_grad[1]) / 2.0)) {
+ Assert.fail("Check gradient at 2");
+ }
+ if (FastMath.abs(grad[2] - n_grad[2]) > FastMath.max(1.0e-6, 1.0e-6 * (grad[2] + n_grad[2]) / 2.0)) {
+ Assert.fail("Check gradient at 2");
+ }
+ if (FastMath.abs(grad[3] - n_grad[3]) > FastMath.max(1.0e-6, 1.0e-6 * (grad[3] + n_grad[3]) / 2.0)) {
+ Assert.fail("Check gradient at 2");
+ }
+ if (FastMath.abs(grad[4] - n_grad[4]) > FastMath.max(1.0e-6, 1.0e-6 * (grad[4] + n_grad[4]) / 2.0)) {
+ Assert.fail("Check gradient at 2");
+ }
+ if (FastMath.abs(grad[5] - n_grad[5]) > FastMath.max(1.0e-6, 1.0e-6 * (grad[5] + n_grad[5]) / 2.0)) {
+ Assert.fail("Check gradient at 2");
+ }
+ return;
+ }
+
+ //@Test
+ public void lanczos_BOBYQA() {
+ double[] bobyqa = run(new BOBYQAOptimizer(10),
+ lanczosObjectFunc, new double[]{1.2,0.3,5.6,5.5,6.5,7.6});
+ TestUtils.assertEquals(correctParamLanczos, bobyqa, 1.0e-8);
+ }
+
+ //@Test
+ public void lanczosTest_cgPolakRibiere() {
+ double[] cgPolakRibiere = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE),
+ lanczosObjectFunc, new double[]{1.2,0.3,5.6,5.5,6.5,7.6});
+ TestUtils.assertEquals(correctParamLanczos, cgPolakRibiere, 1.0e-8);
+ }
+
+ //@Test
+ public void lanczosTest_cgPolakRibiere2() {
+ double[] cgPolakRibiere2 = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE),
+ lanczosObjectFunc, new double[]{0.5,0.7,3.6,4.2,4,6.3});
+ TestUtils.assertEquals(correctParamLanczos, cgPolakRibiere2, 1.0e-8);
+ }
+
+ //@Test
+ public void lanczosTest_cgFletcherReeves() {
+ double[] cgFletcherReeves = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.FLETCHER_REEVES),
+ lanczosObjectFunc, new double[]{1.2,0.3,5.6,5.5,6.5,7.6});
+ TestUtils.assertEquals(correctParamLanczos, cgFletcherReeves, 1.0e-8);
+ }
+
+ //@Test
+ public void lanczosTest_cgFletcherReeves2() {
+ double[] cgFletcherReeves2 = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.FLETCHER_REEVES),
+ lanczosObjectFunc, new double[]{0.5,0.7,3.6,4.2,4,6.3});
+ TestUtils.assertEquals(correctParamLanczos, cgFletcherReeves2, 1.0e-8);
+ }
+
+ //@Test
+ public void lanczosTest_powell() {
+ double[] resPowell = run(new PowellOptimizer(1.0e-8, 1.0e-8), lanczosObjectFunc,
+ new double[]{1.2,0.3,5.6,5.5,6.5,7.6});
+ TestUtils.assertEquals(correctParamLanczos, resPowell, 1.0e-8);
+ }
+
+ //@Test
+ public void lanczosTest_powell2() {
+ double[] resPowell2 = run(new PowellOptimizer(1.0e-8, 1.0e-8), lanczosObjectFunc,
+ new double[]{0.5,0.7,3.6,4.2,4,6.3});
+ TestUtils.assertEquals(correctParamLanczos, resPowell2, 1.0e-8);
+ }
+
+ @Test
+ public void chwirut1Test() {
+ //first check to see that the NIST Object function is being replicated correctly
+ double obj = this.chwirut1ObjectFunc.value(correctParamChwirut1);
+ Assert.assertEquals(2.3844771393e3, obj, 1.0e-8);
+
+ double[] grad = this.chwirut1ObjectFunc.getGradient(correctParamChwirut1);
+ double[] grad2 = new double[3];
+ grad2[0] = this.chwirut1ObjectFunc.partialDeriv(correctParamChwirut1, 0);
+ grad2[1] = this.chwirut1ObjectFunc.partialDeriv(correctParamChwirut1, 1);
+ grad2[2] = this.chwirut1ObjectFunc.partialDeriv(correctParamChwirut1, 2);
+ TestUtils.assertEquals("Grads...", grad, grad2, 1.0e-12);
+ return;
+ }
+
+ //@Test
+ public void chwirut1_BOBYQA() {
+ double[] bobyqa = run(new BOBYQAOptimizer(5),
+ chwirut1ObjectFunc, new double[]{0.1, 0.01, 0.02});
+ TestUtils.assertEquals(correctParamChwirut1, bobyqa, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut1Test_cgPolakRibiere() {
+ double[] cgPolakRibiere = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE),
+ chwirut1ObjectFunc, new double[]{0.1, 0.01, 0.02});
+ TestUtils.assertEquals(correctParamChwirut1, cgPolakRibiere, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut1Test_cgPolakRibiere2() {
+ double[] cgPolakRibiere2 = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE),
+ chwirut1ObjectFunc, new double[]{0.15, 0.008, 0.01});
+ TestUtils.assertEquals(correctParamChwirut1, cgPolakRibiere2, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut1Test_cgFletcherReeves() {
+ double[] cgFletcherReeves = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.FLETCHER_REEVES),
+ chwirut1ObjectFunc, new double[]{0.1, 0.01, 0.02});
+ TestUtils.assertEquals(correctParamChwirut1, cgFletcherReeves, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut1Test_cgFletcherReeves2() {
+ double[] cgFletcherReeves2 = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.FLETCHER_REEVES),
+ chwirut1ObjectFunc, new double[]{0.15, 0.008, 0.01});
+ TestUtils.assertEquals(correctParamChwirut1, cgFletcherReeves2, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut1Test_powell() {
+ double[] resPowell = run(new PowellOptimizer(1.0e-8, 1.0e-8), chwirut1ObjectFunc, new double[]{0.1, 0.01, 0.02});
+ TestUtils.assertEquals(correctParamChwirut1, resPowell, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut1Test_powell2() {
+ double[] resPowell2 = run(new PowellOptimizer(1.0e-8, 1.0e-8), chwirut1ObjectFunc, new double[]{0.15, 0.08, 0.01});
+ TestUtils.assertEquals(correctParamChwirut1, resPowell2, 1.0e-8);
+ }
+
+ @Test
+ public void chwirut2Test() {
+ //first check to see that the NIST Object function is being replicated correctly
+ double obj = this.chwirut2ObjectFunc.value(correctParamChwirut2);
+ Assert.assertEquals(5.1304802941e02, obj, 1.0e-8);
+
+ double[] grad = this.chwirut2ObjectFunc.getGradient(correctParamChwirut2);
+ double[] grad2 = new double[3];
+ grad2[0] = this.chwirut2ObjectFunc.partialDeriv(correctParamChwirut2, 0);
+ grad2[1] = this.chwirut2ObjectFunc.partialDeriv(correctParamChwirut2, 1);
+ grad2[2] = this.chwirut2ObjectFunc.partialDeriv(correctParamChwirut2, 2);
+ TestUtils.assertEquals("Grads...", grad, grad2, 1.0e-12);
+ return;
+ }
+
+ //@Test
+ public void chwirut2_BOBYQA() {
+ double[] bobyqa = run(new BOBYQAOptimizer(5),
+ chwirut2ObjectFunc, new double[]{0.1, 0.01, 0.02});
+ TestUtils.assertEquals(correctParamChwirut2, bobyqa, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut2Test_cgPolakRibiere() {
+ double[] cgPolakRibiere = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE),
+ chwirut2ObjectFunc, new double[]{0.1, 0.01, 0.02});
+ TestUtils.assertEquals(correctParamChwirut2, cgPolakRibiere, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut2Test_cgPolakRibiere2() {
+ double[] cgPolakRibiere2 = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE),
+ chwirut2ObjectFunc, new double[]{0.15, 0.008, 0.01});
+ TestUtils.assertEquals(correctParamChwirut2, cgPolakRibiere2, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut2Test_cgFletcherReeves() {
+ double[] cgFletcherReeves = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.FLETCHER_REEVES),
+ chwirut2ObjectFunc, new double[]{0.1, 0.01, 0.02});
+ TestUtils.assertEquals(correctParamChwirut2, cgFletcherReeves, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut2Test_cgFletcherReeves2() {
+ double[] cgFletcherReeves2 = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.FLETCHER_REEVES),
+ chwirut2ObjectFunc, new double[]{0.15, 0.008, 0.01});
+ TestUtils.assertEquals(correctParamChwirut2, cgFletcherReeves2, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut2Test_powell() {
+ double[] resPowell = run(new PowellOptimizer(1.0e-8, 1.0e-8), chwirut2ObjectFunc, new double[]{0.1, 0.01, 0.02});
+ TestUtils.assertEquals(correctParamChwirut2, resPowell, 1.0e-8);
+ }
+
+ //@Test
+ public void chwirut2Test_powell2() {
+ double[] resPowell2 = run(new PowellOptimizer(1.0e-8, 1.0e-8), chwirut2ObjectFunc, new double[]{0.15, 0.08, 0.01});
+ TestUtils.assertEquals(correctParamChwirut2, resPowell2, 1.0e-8);
+ }
+
+ @Test
+ public void misra1aTest() {
+ //first check to see that the NIST Object function is being replicated correctly
+ double obj = this.misra1aObjectFunc.value(correctParamMisra1a);
+ Assert.assertEquals(1.2455138894e-01, obj, 1.0e-8);
+
+ double[] grad = this.misra1aObjectFunc.getGradient(correctParamMisra1a);
+ double[] grad2 = new double[2];
+ grad2[0] = this.misra1aObjectFunc.partialDeriv(correctParamMisra1a, 0);
+ grad2[1] = this.misra1aObjectFunc.partialDeriv(correctParamMisra1a, 1);
+
+ TestUtils.assertEquals("Grads...", grad, grad2, 1.0e-12);
+
+// double[] n_grad = this.getGradient(misra1aObjectFunc, correctParamMisra1a, 1.0e-5);
+// System.out.println("g = " + grad[0] + " ng = " + n_grad[0]);
+// System.out.println("g = " + grad[1] + " ng = " + n_grad[1]);
+// if( FastMath.abs(grad[0] - n_grad[0] ) > FastMath.max(1.0e-6, 1.0e-6 * (grad[0]+n_grad[0])/2.0) ){
+// Assert.fail("Check gradient at 1");
+// }
+// if( FastMath.abs(grad[1] - n_grad[1] ) > FastMath.max(1.0e-6, 1.0e-6 * (grad[1]+n_grad[1])/2.0) ){
+// Assert.fail("Check gradient at 2");
+// }
+ return;
+ }
+
+ //@Test
+ public void misra1a_BOBYQA() {
+ double[] bobyqa = run(new BOBYQAOptimizer(4),
+ misra1aObjectFunc, new double[]{500.0, 0.0001});
+ TestUtils.assertEquals(correctParamMisra1a, bobyqa, 1.0e-8);
+ }
+
+ //@Test
+ public void misra1aTest_cgPolakRibiere() {
+ double[] cgPolakRibiere = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE),
+ misra1aObjectFunc, new double[]{500.0, 0.0001});
+ TestUtils.assertEquals(correctParamMisra1a, cgPolakRibiere, 1.0e-8);
+ }
+
+ //@Test
+ public void misra1aTest_cgPolakRibiere2() {
+ double[] cgPolakRibiere2 = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.POLAK_RIBIERE),
+ misra1aObjectFunc, new double[]{250.0, 0.0005});
+ TestUtils.assertEquals(correctParamMisra1a, cgPolakRibiere2, 1.0e-8);
+ }
+
+ //@Test
+ public void misra1aTest_cgFletcherReeves() {
+ double[] cgFletcherReeves = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.FLETCHER_REEVES),
+ misra1aObjectFunc, new double[]{500.0, 0.0001});
+ TestUtils.assertEquals(correctParamMisra1a, cgFletcherReeves, 1.0e-8);
+ }
+
+ //@Test
+ public void misra1aTest_cgFletcherReeves2() {
+ double[] cgFletcherReeves2 = run(new NonLinearConjugateGradientOptimizer(ConjugateGradientFormula.FLETCHER_REEVES),
+ misra1aObjectFunc, new double[]{250.0, 0.0005});
+ TestUtils.assertEquals(correctParamMisra1a, cgFletcherReeves2, 1.0e-8);
+ }
+
+ //@Test
+ public void misra1aTest_powell() {
+ double[] resPowell = run(new PowellOptimizer(1.0e-8, 1.0e-8), misra1aObjectFunc, new double[]{500.0, 0.0001});
+ TestUtils.assertEquals(correctParamMisra1a, resPowell, 1.0e-8);
+ }
+
+ //@Test
+ public void misra1aTest_powell2() {
+ double[] resPowell2 = run(new PowellOptimizer(1.0e-8, 1.0e-8), misra1aObjectFunc, new double[]{250.0, 0.0005});
+ TestUtils.assertEquals(correctParamMisra1a, resPowell2, 1.0e-8);
+ }
+
+ /* numerical gradients */
+ private double[] getGradient(nistMVRF func, double[] xo, double eps) {
+ double[] ret = new double[func.getNumberOfParameters()];
+ for (int i = 0; i < ret.length; i++) {
+ final double tmp = xo[i];
+ xo[i] += eps;
+ ret[i] = func.value(xo);
+ xo[i] = tmp - eps;
+ ret[i] -= func.value(xo);
+ ret[i] /= (2.0 * eps);
+ xo[i] = tmp;
+ }
+ return (ret);
+ }
+
+ /* generic test runner */
+ private double[] run(MultivariateRealOptimizer optim, DifferentiableMultivariateRealFunction func, double[] start) {
+ return (optim.optimize(1000000, func, GoalType.MINIMIZE, start).getPointRef());
+ }
+ /* generic test runner for AbstractScalarDifferentiableOptimizer */
+ private double[] run(AbstractScalarDifferentiableOptimizer optim, DifferentiableMultivariateRealFunction func, double[] start) {
+ return (optim.optimize(1000000, func, GoalType.MINIMIZE, start).getPointRef());
+ }
+
+ /* base objective function class for these tests */
+ private abstract static class nistMVRF implements DifferentiableMultivariateRealFunction {
+ protected final MultivariateRealFunction[] mrf;
+ protected final MultivariateVectorialFunction mvf = new MultivariateVectorialFunction() {
+
+ public double[] value(double[] point) throws IllegalArgumentException {
+ return getGradient(point);
+ }
+ };
+ protected double[] gradient;
+ protected double[] data;
+ protected int nvars;
+ protected int nobs;
+ protected int nparams;
+
+ public int getNumberOfParameters() {
+ return nparams;
+ }
+
+ public nistMVRF(double[] data, int nvars, int nobs, int nparams) {
+ if ((nvars + 1) * nobs != data.length) {
+ throw MathRuntimeException.createIllegalArgumentException(
+ LocalizedFormats.INVALID_REGRESSION_ARRAY, data.length, nobs, nvars);
+ }
+ this.nobs = nobs;
+ this.nvars = nvars;
+ this.gradient = new double[nparams];
+ this.nparams = nparams;
+ this.data = data;
+ mrf = new MultivariateRealFunction[nvars];
+ for (int i = 0; i < nvars; i++) {
+ final int idx = i;
+ mrf[i] = new MultivariateRealFunction() {
+
+ private int myIdx = idx;
+
+ public double value(double[] point) {
+ return partialDeriv(point, myIdx);
+ }
+ };
+ }
+ }
+
+ public MultivariateVectorialFunction gradient() {
+ return mvf;
+ }
+
+ public MultivariateRealFunction partialDerivative(int k) {
+ return mrf[k];
+ }
+
+ protected abstract double partialDeriv(double[] point, int idx);
+
+ protected abstract double[] getGradient(double[] point);
+ }
+
+ /* since there are multiple chwirut tests create an object */
+ private static class chwirut extends nistMVRF {
+
+ public chwirut(double[] data, int nvars, int nobs, int nparams) {
+ super(data, nvars, nobs, nparams);
+ }
+
+ @Override
+ protected double partialDeriv(double[] point, int idx) {
+ double cy, cx, r, ret = 0.0, d;
+ int ptr = 0;
+ for (int i = 0; i < this.nobs; i++) {
+ cy = data[ptr++];
+ cx = data[ptr++];
+ d = (point[1] + point[2] * cx);
+ r = cy - FastMath.exp(-cx * point[0]) / d;
+ if (idx == 0) {
+ ret -= (2.0 * r * r) * cx;
+ } else if (idx == 1) {
+ ret += (2.0 * r * r) / d;
+ } else {
+ ret += (2.0 * r * r) * cx / d;
+ }
+ }
+ return (ret);
+ }
+
+ public double value(double[] point) {
+ double ret = 0.0, err, cx, cy;
+ int ptr = 0;
+ for (int i = 0; i < this.nobs; i++) {
+ cy = data[ptr++];
+ cx = data[ptr++];
+ err = cy - (FastMath.exp(-cx * point[0]) / (point[1] + point[2] * cx));
+ ret += err * err;
+ }
+ return (ret);
+ }
+
+ @Override
+ protected double[] getGradient(double[] point) {
+ Arrays.fill(gradient, 0.0);
+ double cy, cx, r, d;
+ int ptr = 0;
+ for (int i = 0; i < this.nobs; i++) {
+ cy = data[ptr++];
+ cx = data[ptr++];
+ d = (point[1] + point[2] * cx);
+ r = cy - FastMath.exp(-cx * point[0]) / d;
+ gradient[0] -= (2.0 * r * r) * cx;
+ gradient[1] += (2.0 * r * r) / d;
+ gradient[2] += (2.0 * r * r) * cx / d;
+ }
+ return this.gradient;
+ }
+ };
+}