You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2021/08/13 23:53:25 UTC

[commons-math] 04/04: MATH-1625: Add callback to generate debugging output (unit test).

This is an automated email from the ASF dual-hosted git repository.

erans pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-math.git

commit 5f36bf970a071a56fa1fa98e68455a8b07898889
Author: Gilles Sadowski <gi...@gmail.com>
AuthorDate: Sat Aug 14 01:36:44 2021 +0200

    MATH-1625: Add callback to generate debugging output (unit test).
    
    Debugging output is activated through specifying a file prefix in the CSV input file.
---
 .../scalar/noderiv/SimplexOptimizerTest.java       | 115 +++++++++++++++++++--
 .../std_test_func.simplex.hedar_fukushima.csv      |  50 ++++-----
 .../std_test_func.simplex.multidirectional.csv     |  49 ++++-----
 .../noderiv/std_test_func.simplex.nelder_mead.csv  |  49 ++++-----
 4 files changed, 182 insertions(+), 81 deletions(-)

diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/SimplexOptimizerTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/SimplexOptimizerTest.java
index 732ba42..0de9418 100644
--- a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/SimplexOptimizerTest.java
+++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/SimplexOptimizerTest.java
@@ -17,10 +17,12 @@
 package org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv;
 
 import java.util.Arrays;
+import java.util.List;
 import java.io.PrintWriter;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ParameterContext;
@@ -132,6 +134,8 @@ public class SimplexOptimizerTest {
         private final double jitter;
         /** Whether to perform simulated annealing. */
         private final boolean withSA;
+        /** File prefix (for saving debugging info). */
+        private final String tracePrefix;
 
         /**
          * @param function Test function.
@@ -143,6 +147,8 @@ public class SimplexOptimizerTest {
          * @param simplexSideLength Side length of initial simplex.
          * @param jitter Size of random jitter.
          * @param withSA Whether to perform simulated annealing.
+         * @param tracePrefix Prefix of the file where to save simplex
+         * transformations during the optimization.
          */
         Task(MultivariateFunction function,
              double[] start,
@@ -151,7 +157,8 @@ public class SimplexOptimizerTest {
              int functionEvaluations,
              double simplexSideLength,
              double jitter,
-             boolean withSA) {
+             boolean withSA,
+             String tracePrefix) {
             this.function = function;
             this.start = start;
             this.optimum = optimum;
@@ -160,6 +167,7 @@ public class SimplexOptimizerTest {
             this.simplexSideLength = simplexSideLength;
             this.jitter = jitter;
             this.withSA = withSA;
+            this.tracePrefix = tracePrefix;
         }
 
         @Override
@@ -170,7 +178,7 @@ public class SimplexOptimizerTest {
         /**
          * @param factory Simplex transform factory.
          */
-        public void run(Simplex.TransformFactory factory) {
+        /* package-private */ void run(Simplex.TransformFactory factory) {
             // Let run with a maximum number of evaluations larger than expected
             // (as specified by "functionEvaluations") in order to have the unit
             // test failure message (see assertion below) report the actual number
@@ -199,6 +207,10 @@ public class SimplexOptimizerTest {
             }
 
             final SimplexOptimizer optim = new SimplexOptimizer(-1, CONVERGENCE_CHECK);
+            if (tracePrefix != null) {
+                optim.addObserver(createCallback(factory));
+            }
+
             final Simplex initialSimplex =
                 Simplex.alongAxes(OptimTestUtils.point(dim,
                                                        simplexSideLength,
@@ -228,6 +240,76 @@ public class SimplexOptimizerTest {
         }
 
         /**
+         * @param factory Simplex transform factory.
+         * @return a function to save the simplex's states to file.
+         */
+        private SimplexOptimizer.Observer createCallback(Simplex.TransformFactory factory) {
+            if (tracePrefix == null) {
+                throw new IllegalArgumentException("Missing file prefix");
+            }
+
+            final String sep = "__";
+            final String name = tracePrefix + sanitizeBasename(function + sep +
+                                                               factory + sep);
+
+            // Create file; write first data block (optimum) and columns header.
+            try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(Paths.get(name)))) {
+                out.println("# Function: " + function);
+                out.println("# Transform: " + factory);
+                out.println("#");
+
+                out.println("# Optimum");
+                for (double c : optimum) {
+                    out.print(c + " ");
+                }
+                out.println();
+                out.println();
+
+                out.println("#");
+                out.print("# <1: evaluations> <2: objective>");
+                for (int i = 0; i < start.length; i++) {
+                    out.print(" <" + (i + 3) + ": coordinate " + i + ">");
+                }
+                out.println();
+            } catch (IOException e) {
+                Assertions.fail(e.getMessage());
+            }
+
+            // Return callback function.
+            return (simplex, isInit, numEval) -> {
+                try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(Paths.get(name),
+                                                                               StandardOpenOption.APPEND))) {
+                    if (isInit) {
+                        // Blank line indicating the start of an optimization
+                        // (new data block).
+                        out.println();
+                        out.println("# [init]"); // Initial simplex.
+                    }
+
+                    final String fieldSep = " ";
+                    // 1 line per simplex point.
+                    final List<PointValuePair> points = simplex.asList();
+                    // Repeat first point on output (for plotting).
+                    points.add(points.get(0));
+                    for (PointValuePair p : points) {
+                        out.print(numEval + fieldSep +
+                                  p.getValue() + fieldSep);
+
+                        final double[] coord = p.getPoint();
+                        for (int i = 0; i < coord.length; i++) {
+                            out.print(coord[i] + fieldSep);
+                        }
+                        out.println();
+                    }
+                    // Blank line between simplexes.
+                    out.println();
+                } catch (IOException e) {
+                    Assertions.fail(e.getMessage());
+                }
+            };
+        }
+
+        /**
          * Asserts that the lowest function value (along a line starting at
          * {@link #start} is reached at the {@link #optimum}.
          *
@@ -305,9 +387,6 @@ public class SimplexOptimizerTest {
 
         /**
          * Generates a string suitable as a file name.
-         * <p>
-         * Brackets are removed; space, slash, "=" sign and comma
-         * characters are converted to underscores.
          *
          * @param f Function.
          * @param start Start point.
@@ -319,17 +398,33 @@ public class SimplexOptimizerTest {
                                                  double[] end) {
             final String s = f.toString() + "__" +
                 Arrays.toString(start) + "__" +
-                Arrays.toString(end) + ".dat";
+                Arrays.toString(end);
 
+            return sanitizeBasename(s) + ".dat";
+        }
+
+        /**
+         * Generates a string suitable as a file name:
+         * Brackets and parentheses are removed; space, slash, "=" sign and
+         * comma characters are converted to underscores.
+         *
+         * @param str String.
+         * @return a string.
+         */
+        private static String sanitizeBasename(String str) {
             final String repl = "_";
-            return s
+            return str
+                .replaceAll("\\(", "")
+                .replaceAll("\\)", "")
                 .replaceAll("\\[", "")
                 .replaceAll("\\]", "")
                 .replaceAll("=", repl)
                 .replaceAll(",\\s+", repl)
                 .replaceAll(",", repl)
                 .replaceAll("\\s", repl)
-                .replaceAll("/", repl);
+                .replaceAll("/", repl)
+                .replaceAll("^_+", "")
+                .replaceAll("_+$", "");
         }
     }
 
@@ -353,6 +448,7 @@ public class SimplexOptimizerTest {
             final double sideLength = a.getDouble(index++);
             final double jitter = a.getDouble(index++);
             final boolean withSA = a.getBoolean(index++);
+            final String tracePrefix = a.getString(index++);
 
             return new Task(funcGen.withDimension(dim),
                             start,
@@ -361,7 +457,8 @@ public class SimplexOptimizerTest {
                             funcEval,
                             sideLength,
                             jitter,
-                            withSA);
+                            withSA,
+                            tracePrefix);
         }
 
         /**
diff --git a/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.hedar_fukushima.csv b/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.hedar_fukushima.csv
index d3ba7dc..f007239 100644
--- a/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.hedar_fukushima.csv
+++ b/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.hedar_fukushima.csv
@@ -26,30 +26,32 @@
 #  6: length of the sides of the initial simplex
 #  7: size of the random noise (to generate slightly different initial conditions)
 #  8: whether to perform simulated annealing
+#  9: File prefix for debugging (or empty slot for no debugging)
 #
 # Caveat: Some tests are commented out (cf. JIRA: MATH-1552).
 #
-PARABOLA, 4, 2.5 3.1 4.6 5.8, 0 0 0 0, 1e-4, 820, 3, 2e-1, true
-ROSENBROCK, 2, -1.2 1, 1 1, 1e-4, 380, 3, 1e-1, true
-ROSENBROCK, 5, -4.4 -3.5 -2.6 -1.7 -0.8, 1 1 1 1 1, 1e-4, 3800, 5e-1, 1e-1, true
-ROSENBROCK, 10, -0.1 0.1 0.2 -0.1 -0.2 0.3 0.2 -0.1 0.2 -0.3, 1 1 1 1 1 1 1 1 1 1, 5e-5, 38000, 3, 5e-2, true
-POWELL, 4, 3 -1 -2 1, 0 0 0 0, 5e-3, 1100, 3, 1e-1, true
-CIGAR, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-5, 75000, 3, 1e-1, true
-SPHERE, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-4, 47000, 3, 1e-1, true
-ELLI, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 25000, 3, 1e-1, true
-#TWO_AXES, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 1000, 3, 1e-1, true
-#CIG_TAB, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 1000, 3, 1e-1, true
-TABLET, 11, 2 3 4 -3 -2 -1 2 3 4 3 -1, 0 0 0 0 0 0 0 0 0 0 0, 2e-4, 41000, 3, 1e-1, true
-#DIFF_POW, 7, 1 -1 1 -1 1 -1 1, 0 0 0 0 0 0 0, 1e-2, 2500, 3, 1e-1, true
-SS_DIFF_POW, 6, -3.2 2.1 1.2 -2.3 3.2 -2.1, 0 0 0 0 0 0, 1e-3, 10500, 3, 1e-1, true
-#ACKLEY, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 1100, 3, 5e-1, true
-#RASTRIGIN, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 10000, 3, 5e-1, true
-#GRIEWANK, 3, -210 123 -456, 0 0 0, 1e-1, 1000, 50, 100, true
-#LEVY, 4, 4 -6 -2 8, 1 1 1 1, 1e-3, 3000, 1, 1, true
-#SCHWEFEL, 2, 100 -200, 420.9687 420.9687, 1, 300, 100, 100, true
-ZAKHAROV, 5, -4 -2 3 5 7, 0 0 0 0 0, 1e-4, 2200, 1.5, 1, true
-PERM, 2, -2 -1, 1 2, 2e-3, 210, 5e-1, 1e-1, true
-#PERM, 3, -2 -3 -1, 1 2 3, 5e-5, 200, 5e-1, 1e-1, true
-#PERM, 4, -2 -3 -4 -1, 1 2 3 4, 5e-4, 2200, 5e-1, 1e-1, true
-#PERM, 5, -2 -3 -4 -5 -1, 1 2 3 4 5, 5e-4, 200, 5e-1, 1e-1, true
-#STYBLINSKI_TANG, 4, 1 2 3 4, -2.903534 -2.903534 -2.903534 -2.903534, 1e-4, 500, 1, 5e-1, true
+PARABOLA, 2, 4.6 5.8, 0 0, 1e-4, 820, 1, 2e-1, true,
+PARABOLA, 4, 2.5 3.1 4.6 5.8, 0 0 0 0, 1e-4, 820, 1, 2e-1, true,
+ROSENBROCK, 2, -1.2 1, 1 1, 1e-4, 380, 1, 1e-1, true,
+ROSENBROCK, 5, -4.4 -3.5 -2.6 -1.7 -0.8, 1 1 1 1 1, 1e-4, 3800, 5e-1, 1e-1, true,
+ROSENBROCK, 10, -0.1 0.1 0.2 -0.1 -0.2 0.3 0.2 -0.1 0.2 -0.3, 1 1 1 1 1 1 1 1 1 1, 5e-5, 38000, 3, 5e-2, true,
+POWELL, 4, 3 -1 -2 1, 0 0 0 0, 5e-3, 1100, 3, 1e-1, true,
+CIGAR, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-5, 75000, 3, 1e-1, true,
+SPHERE, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-4, 47000, 3, 1e-1, true,
+ELLI, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 25000, 3, 1e-1, true,
+#TWO_AXES, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 1000, 3, 1e-1, true,
+#CIG_TAB, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 1000, 3, 1e-1, true,
+TABLET, 11, 2 3 4 -3 -2 -1 2 3 4 3 -1, 0 0 0 0 0 0 0 0 0 0 0, 2e-4, 41000, 3, 1e-1, true,
+#DIFF_POW, 7, 1 -1 1 -1 1 -1 1, 0 0 0 0 0 0 0, 1e-2, 2500, 3, 1e-1, true,
+SS_DIFF_POW, 6, -3.2 2.1 1.2 -2.3 3.2 -2.1, 0 0 0 0 0 0, 1e-3, 10500, 3, 1e-1, true,
+#ACKLEY, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 1100, 3, 5e-1, true,
+#RASTRIGIN, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 10000, 3, 5e-1, true,
+#GRIEWANK, 3, -210 123 -456, 0 0 0, 1e-1, 1000, 50, 100, true,
+#LEVY, 4, 4 -6 -2 8, 1 1 1 1, 1e-3, 3000, 1, 1, true,
+#SCHWEFEL, 2, 100 -200, 420.9687 420.9687, 1, 300, 100, 100, true,
+ZAKHAROV, 5, -4 -2 3 5 7, 0 0 0 0 0, 1e-4, 2200, 1.5, 1, true,
+PERM, 2, -2 -1, 1 2, 2e-3, 210, 5e-1, 1e-1, true,
+#PERM, 3, -2 -3 -1, 1 2 3, 5e-5, 200, 5e-1, 1e-1, true,
+#PERM, 4, -2 -3 -4 -1, 1 2 3 4, 5e-4, 2200, 5e-1, 1e-1, true,
+#PERM, 5, -2 -3 -4 -5 -1, 1 2 3 4 5, 5e-4, 200, 5e-1, 1e-1, true,
+#STYBLINSKI_TANG, 4, 1 2 3 4, -2.903534 -2.903534 -2.903534 -2.903534, 1e-4, 500, 1, 5e-1, true,
diff --git a/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.multidirectional.csv b/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.multidirectional.csv
index 4be1bee..e9dbb19 100644
--- a/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.multidirectional.csv
+++ b/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.multidirectional.csv
@@ -26,30 +26,31 @@
 #  6: length of the sides of the initial simplex
 #  7: size of the random noise (to generate slightly different initial conditions)
 #  8: whether to perform simulated annealing
+#  9: File prefix for debugging (or empty slot for no debugging)
 #
 # Caveat: Some tests are commented out (cf. JIRA: MATH-1552).
 #
-PARABOLA, 4, 2.5 3.1 4.6 5.8, 0 0 0 0, 1e-4, 380, 1, 2e-1, false
-ROSENBROCK, 2, -1.2 1, 1 1, 2e-3, 11100, 1, 1e-1, false
-#ROSENBROCK, 5, -4.4 -3.5 -2.6 -1.7 -0.8, 1 1 1 1 1, 1e-4, 180, 5e-1, 1e-1, false
-ROSENBROCK, 10, -0.1 0.1 0.2 -0.1 -0.2 0.3 0.2 -0.1 0.2 -0.3, 1 1 1 1 1 1 1 1 1 1, 3e-3, 100000, 1, 5e-2, false
-#POWELL, 4, 3 -1 -2 1, 0 0 0 0, 5e-3, 420, 1, 1e-1, false
-CIGAR, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-6, 7000, 1, 1e-1, false
-SPHERE, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-5, 3600, 1, 1e-1, false
-ELLI, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 50000, 1, 1e-1, false
-TWO_AXES, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-6, 3200, 1, 1e-1, false
-CIG_TAB, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 5e-6, 2900, 1, 1e-1, false
-TABLET, 11, 2 3 4 -3 -2 -1 2 3 4 3 -1, 0 0 0 0 0 0 0 0 0 0 0, 5e-6, 3200, 1, 1e-1, false
-DIFF_POW, 7, 1 -1 1 -1 1 -1 1, 0 0 0 0 0 0 0, 5e-4, 2500, 1, 1e-1, false
-SS_DIFF_POW, 6, -3.2 2.1 1.2 -2.3 3.2 -2.1, 0 0 0 0 0 0, 1e-3, 4000, 1, 1e-1, false
-ACKLEY, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 770, 1, 5e-1, false
-#RASTRIGIN, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 10000, 1, 5e-1, false
-#GRIEWANK, 3, -210 123 -456, 0 0 0, 1e-1, 1000, 50, 100, false
-#LEVY, 4, 4 -6 -2 8, 1 1 1 1, 1e-3, 3000, 1, 1, false
-#SCHWEFEL, 2, 100 -200, 420.9687 420.9687, 1, 300, 100, 100, false
-ZAKHAROV, 5, -4 -2 3 5 7, 0 0 0 0 0, 1e-4, 3100, 1.5, 1, false
-PERM, 2, -2 -1, 1 2, 3e-2, 25000, 5e-1, 1e-1, false
-#PERM, 3, -2 -3 -1, 1 2 3, 5e-5, 200, 5e-1, 1e-1, false
-#PERM, 4, -2 -3 -4 -1, 1 2 3 4, 5e-4, 2200, 5e-1, 1e-1, false
-#PERM, 5, -2 -3 -4 -5 -1, 1 2 3 4 5, 5e-4, 200, 5e-1, 1e-1, false
-#STYBLINSKI_TANG, 4, 1 2 3 4, -2.903534 -2.903534 -2.903534 -2.903534, 1e-4, 500, 1, 5e-1, false
+PARABOLA, 4, 2.5 3.1 4.6 5.8, 0 0 0 0, 1e-4, 380, 1, 2e-1, false,
+ROSENBROCK, 2, -1.2 1, 1 1, 2e-3, 11100, 1, 1e-1, false,
+#ROSENBROCK, 5, -4.4 -3.5 -2.6 -1.7 -0.8, 1 1 1 1 1, 1e-4, 180, 5e-1, 1e-1, false,
+ROSENBROCK, 10, -0.1 0.1 0.2 -0.1 -0.2 0.3 0.2 -0.1 0.2 -0.3, 1 1 1 1 1 1 1 1 1 1, 3e-3, 100000, 1, 5e-2, false,
+#POWELL, 4, 3 -1 -2 1, 0 0 0 0, 5e-3, 420, 1, 1e-1, false,
+CIGAR, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-6, 7000, 1, 1e-1, false,
+SPHERE, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-5, 3600, 1, 1e-1, false,
+ELLI, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 50000, 1, 1e-1, false,
+TWO_AXES, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-6, 3200, 1, 1e-1, false,
+CIG_TAB, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 5e-6, 2900, 1, 1e-1, false,
+TABLET, 11, 2 3 4 -3 -2 -1 2 3 4 3 -1, 0 0 0 0 0 0 0 0 0 0 0, 5e-6, 3200, 1, 1e-1, false,
+DIFF_POW, 7, 1 -1 1 -1 1 -1 1, 0 0 0 0 0 0 0, 5e-4, 2500, 1, 1e-1, false,
+SS_DIFF_POW, 6, -3.2 2.1 1.2 -2.3 3.2 -2.1, 0 0 0 0 0 0, 1e-3, 4000, 1, 1e-1, false,
+ACKLEY, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 770, 1, 5e-1, false,
+#RASTRIGIN, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 10000, 1, 5e-1, false,
+#GRIEWANK, 3, -210 123 -456, 0 0 0, 1e-1, 1000, 50, 100, false,
+#LEVY, 4, 4 -6 -2 8, 1 1 1 1, 1e-3, 3000, 1, 1, false,
+#SCHWEFEL, 2, 100 -200, 420.9687 420.9687, 1, 300, 100, 100, false,
+ZAKHAROV, 5, -4 -2 3 5 7, 0 0 0 0 0, 1e-4, 3100, 1.5, 1, false,
+PERM, 2, -2 -1, 1 2, 3e-2, 25000, 5e-1, 1e-1, false,
+#PERM, 3, -2 -3 -1, 1 2 3, 5e-5, 200, 5e-1, 1e-1, false,
+#PERM, 4, -2 -3 -4 -1, 1 2 3 4, 5e-4, 2200, 5e-1, 1e-1, false,
+#PERM, 5, -2 -3 -4 -5 -1, 1 2 3 4 5, 5e-4, 200, 5e-1, 1e-1, false,
+#STYBLINSKI_TANG, 4, 1 2 3 4, -2.903534 -2.903534 -2.903534 -2.903534, 1e-4, 500, 1, 5e-1, false,
diff --git a/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.nelder_mead.csv b/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.nelder_mead.csv
index 49db4d8..477acfe 100644
--- a/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.nelder_mead.csv
+++ b/commons-math-legacy/src/test/resources/org/apache/commons/math4/legacy/optim/nonlinear/scalar/noderiv/std_test_func.simplex.nelder_mead.csv
@@ -26,30 +26,31 @@
 #  6: length of the sides of the initial simplex
 #  7: size of the random noise (to generate slightly different initial conditions)
 #  8: whether to perform simulated annealing
+#  9: File prefix for debugging (or empty slot for no debugging)
 #
 # Caveat: Some tests are commented out (cf. JIRA: MATH-1552).
 #
-PARABOLA, 4, 2.5 3.1 4.6 5.8, 0 0 0 0, 1e-4, 200, 1, 2e-1, false
-ROSENBROCK, 2, -1.2 1, 1 1, 1e-4, 180, 1, 1e-1, false
-ROSENBROCK, 5, -4.4 -3.5 -2.6 -1.7 -0.8, 1 1 1 1 1, 1e-4, 800, 5e-1, 1e-1, false
-ROSENBROCK, 10, -0.1 0.1 0.2 -0.1 -0.2 0.3 0.2 -0.1 0.2 -0.3, 1 1 1 1 1 1 1 1 1 1, 5e-5, 9000, 1, 5e-2, false
-POWELL, 4, 3 -1 -2 1, 0 0 0 0, 5e-3, 420, 1, 1e-1, false
-CIGAR, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-5, 7000, 1, 1e-1, false
-SPHERE, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-4, 3000, 1, 1e-1, false
-ELLI, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 50000, 1, 1e-1, false
-#TWO_AXES, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 5000, 1, 1e-1, false
-#CIG_TAB, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 7000, 1, 1e-1, false
-TABLET, 11, 2 3 4 -3 -2 -1 2 3 4 3 -1, 0 0 0 0 0 0 0 0 0 0 0, 2e-4, 3600, 1, 1e-1, false
-#DIFF_POW, 7, 1 -1 1 -1 1 -1 1, 0 0 0 0 0 0 0, 5e-4, 2500, 1, 1e-1, false
-SS_DIFF_POW, 6, -3.2 2.1 1.2 -2.3 3.2 -2.1, 0 0 0 0 0 0, 1e-3, 4000, 1, 1e-1, false
-ACKLEY, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 430, 1, 5e-1, false
-#RASTRIGIN, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 10000, 1, 5e-1, false
-#GRIEWANK, 3, -210 123 -456, 0 0 0, 1e-1, 1000, 50, 100, false
-#LEVY, 4, 4 -6 -2 8, 1 1 1 1, 1e-3, 3000, 1, 1, false
-#SCHWEFEL, 2, 100 -200, 420.9687 420.9687, 1, 300, 100, 100, false
-ZAKHAROV, 5, -4 -2 3 5 7, 0 0 0 0 0, 5e-5, 500, 1.5, 1, false
-PERM, 2, -2 -1, 1 2, 5e-5, 200, 5e-1, 1e-1, false
-#PERM, 3, -2 -3 -1, 1 2 3, 5e-5, 200, 5e-1, 1e-1, false
-PERM, 4, -2 -3 -4 -1, 1 2 3 4, 5e-3, 2800, 5e-1, 1e-1, false
-#PERM, 5, -2 -3 -4 -5 -1, 1 2 3 4 5, 5e-4, 200, 5e-1, 1e-1, false
-#STYBLINSKI_TANG, 4, 1 2 3 4, -2.903534 -2.903534 -2.903534 -2.903534, 1e-4, 500, 1, 5e-1, false
+PARABOLA, 4, 2.5 3.1 4.6 5.8, 0 0 0 0, 1e-4, 200, 1, 2e-1, false,
+ROSENBROCK, 2, -1.2 1, 1 1, 1e-4, 180, 1, 1e-1, false,
+ROSENBROCK, 5, -4.4 -3.5 -2.6 -1.7 -0.8, 1 1 1 1 1, 1e-4, 800, 5e-1, 1e-1, false,
+ROSENBROCK, 10, -0.1 0.1 0.2 -0.1 -0.2 0.3 0.2 -0.1 0.2 -0.3, 1 1 1 1 1 1 1 1 1 1, 5e-5, 9000, 1, 5e-2, false,
+POWELL, 4, 3 -1 -2 1, 0 0 0 0, 5e-3, 420, 1, 1e-1, false,
+CIGAR, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-5, 7000, 1, 1e-1, false,
+SPHERE, 13, -1.2 2.3 -3.2 2.1 1.2 -2.3 3.2 -2.1 -1.2 2.3 -3.2 2.1 -1.2, 0 0 0 0 0 0 0 0 0 0 0 0 0, 5e-4, 3000, 1, 1e-1, false,
+ELLI, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 50000, 1, 1e-1, false,
+#TWO_AXES, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 5000, 1, 1e-1, false,
+#CIG_TAB, 10, 2 3 4 -3 -2 -1 2 3 4 3, 0 0 0 0 0 0 0 0 0 0, 1e-4, 7000, 1, 1e-1, false,
+TABLET, 11, 2 3 4 -3 -2 -1 2 3 4 3 -1, 0 0 0 0 0 0 0 0 0 0 0, 2e-4, 3600, 1, 1e-1, false,
+#DIFF_POW, 7, 1 -1 1 -1 1 -1 1, 0 0 0 0 0 0 0, 5e-4, 2500, 1, 1e-1, false,
+SS_DIFF_POW, 6, -3.2 2.1 1.2 -2.3 3.2 -2.1, 0 0 0 0 0 0, 1e-3, 4000, 1, 1e-1, false,
+ACKLEY, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 430, 1, 5e-1, false,
+#RASTRIGIN, 4, 3 4 -3 -2, 0 0 0 0, 1e-6, 10000, 1, 5e-1, false,
+#GRIEWANK, 3, -210 123 -456, 0 0 0, 1e-1, 1000, 50, 100, false,
+#LEVY, 4, 4 -6 -2 8, 1 1 1 1, 1e-3, 3000, 1, 1, false,
+#SCHWEFEL, 2, 100 -200, 420.9687 420.9687, 1, 300, 100, 100, false,
+ZAKHAROV, 5, -4 -2 3 5 7, 0 0 0 0 0, 5e-5, 500, 1.5, 1, false,
+PERM, 2, -2 -1, 1 2, 5e-5, 200, 5e-1, 1e-1, false,
+#PERM, 3, -2 -3 -1, 1 2 3, 5e-5, 200, 5e-1, 1e-1, false,
+PERM, 4, -2 -3 -4 -1, 1 2 3 4, 5e-3, 2800, 5e-1, 1e-1, false,
+#PERM, 5, -2 -3 -4 -5 -1, 1 2 3 4 5, 5e-4, 200, 5e-1, 1e-1, false,
+#STYBLINSKI_TANG, 4, 1 2 3 4, -2.903534 -2.903534 -2.903534 -2.903534, 1e-4, 500, 1, 5e-1, false,