gt:                 fac = Math.pow(axisratio, (i - 1.) / (x.length - 1.));
context: /*
   * 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.direct;
  
  import java.util.Arrays;
  import java.util.Random;
  
  import org.apache.commons.math3.analysis.MultivariateFunction;
  import org.apache.commons.math3.exception.DimensionMismatchException;
  import org.apache.commons.math3.exception.TooManyEvaluationsException;
  import org.apache.commons.math3.exception.NumberIsTooLargeException;
  import org.apache.commons.math3.exception.NumberIsTooSmallException;
  import org.apache.commons.math3.optimization.GoalType;
  import org.apache.commons.math3.optimization.PointValuePair;
  import org.apache.commons.math3.optimization.InitialGuess;
  import org.apache.commons.math3.optimization.SimpleBounds;
  import org.junit.Assert;
  import org.junit.Ignore;
  import org.junit.Test;
  
  /**
   * Test for {@link BOBYQAOptimizer}.
   */
  public class BOBYQAOptimizerTest {
  
      static final int DIM = 13;
     
      @Test(expected=NumberIsTooLargeException.class)
      public void testInitOutOfBounds() {
          double[] startPoint = point(DIM, 3);
          double[][] boundaries = boundaries(DIM, -1, 2);
          doTest(new Rosen(), startPoint, boundaries,
                  GoalType.MINIMIZE, 
                  1e-13, 1e-6, 2000, null);
      }
      
      @Test(expected=DimensionMismatchException.class)
      public void testBoundariesDimensionMismatch() {
          double[] startPoint = point(DIM, 0.5);
          double[][] boundaries = boundaries(DIM + 1, -1, 2);
          doTest(new Rosen(), startPoint, boundaries,
                 GoalType.MINIMIZE, 
                 1e-13, 1e-6, 2000, null);
      }
  
      @Test(expected=NumberIsTooSmallException.class)
      public void testProblemDimensionTooSmall() {
          double[] startPoint = point(1, 0.5);
          doTest(new Rosen(), startPoint, null,
                 GoalType.MINIMIZE,
                 1e-13, 1e-6, 2000, null);
      }
  
      @Test(expected=TooManyEvaluationsException.class)
      public void testMaxEvaluations() {
          final int lowMaxEval = 2;
          double[] startPoint = point(DIM, 0.1);
          double[][] boundaries = null;
          doTest(new Rosen(), startPoint, boundaries,
                 GoalType.MINIMIZE, 
                 1e-13, 1e-6, lowMaxEval, null);
       }
  
      @Test
      public void testRosen() {
          double[] startPoint = point(DIM,0.1);
          double[][] boundaries = null;
          PointValuePair expected = new PointValuePair(point(DIM,1.0),0.0);
          doTest(new Rosen(), startPoint, boundaries,
                  GoalType.MINIMIZE, 
                  1e-13, 1e-6, 2000, expected);
       }
  
      @Test
      public void testMaximize() {
          double[] startPoint = point(DIM,1.0);
          double[][] boundaries = null;
          PointValuePair expected = new PointValuePair(point(DIM,0.0),1.0);
          doTest(new MinusElli(), startPoint, boundaries,
                  GoalType.MAXIMIZE, 
                  2e-10, 5e-6, 1000, expected);
          boundaries = boundaries(DIM,-0.3,0.3); 
          startPoint = point(DIM,0.1);
          doTest(new MinusElli(), startPoint, boundaries,
                  GoalType.MAXIMIZE, 
                  2e-10, 5e-6, 1000, expected);
      }
  
      @Test
      public void testEllipse() {
          double[] startPoint = point(DIM,1.0);
          double[][] boundaries = null;
          PointValuePair expected =
              new PointValuePair(point(DIM,0.0),0.0);
          doTest(new Elli(), startPoint, boundaries,
                  GoalType.MINIMIZE, 
                  1e-13, 1e-6, 1000, expected);
       }
  
      @Test
      public void testElliRotated() {
          double[] startPoint = point(DIM,1.0);
          double[][] boundaries = null;
          PointValuePair expected =
              new PointValuePair(point(DIM,0.0),0.0);
          doTest(new ElliRotated(), startPoint, boundaries,
                  GoalType.MINIMIZE, 
                  1e-12, 1e-6, 10000, expected);
      }
  
      @Test
      public void testCigar() {
          double[] startPoint = point(DIM,1.0);
          double[][] boundaries = null;
          PointValuePair expected =
              new PointValuePair(point(DIM,0.0),0.0);
          doTest(new Cigar(), startPoint, boundaries,
                  GoalType.MINIMIZE, 
                  1e-13, 1e-6, 100, expected);
      }
  
      @Test
      public void testTwoAxes() {
          double[] startPoint = point(DIM,1.0);
          double[][] boundaries = null;
          PointValuePair expected =
              new PointValuePair(point(DIM,0.0),0.0);
          doTest(new TwoAxes(), startPoint, boundaries,
                  GoalType.MINIMIZE, 2*
                  1e-13, 1e-6, 100, expected);
       }
  
      @Test
      public void testCigTab() {
          double[] startPoint = point(DIM,1.0);
          double[][] boundaries = null;
          PointValuePair expected =
              new PointValuePair(point(DIM,0.0),0.0);
          doTest(new CigTab(), startPoint, boundaries,
                  GoalType.MINIMIZE, 
                  1e-13, 5e-5, 100, expected);
       }
  
      @Test
      public void testSphere() {
          double[] startPoint = point(DIM,1.0);
          double[][] boundaries = null;
          PointValuePair expected =
              new PointValuePair(point(DIM,0.0),0.0);
          doTest(new Sphere(), startPoint, boundaries,
                  GoalType.MINIMIZE, 
                  1e-13, 1e-6, 100, expected);
      }
  
      @Test
      public void testTablet() {
          double[] startPoint = point(DIM,1.0); 
          double[][] boundaries = null;
          PointValuePair expected =
              new PointValuePair(point(DIM,0.0),0.0);
          doTest(new Tablet(), startPoint, boundaries,
                  GoalType.MINIMIZE, 
                  1e-13, 1e-6, 100, expected);
      }
  
      @Test
      public void testDiffPow() {}
  // Defects4J: flaky method
  //     @Test
  //     public void testDiffPow() {
  //         double[] startPoint = point(DIM/2,1.0);
  //         double[][] boundaries = null;
  //         PointValuePair expected =
  //             new PointValuePair(point(DIM/2,0.0),0.0);
  //         doTest(new DiffPow(), startPoint, boundaries,
  //                 GoalType.MINIMIZE, 
  //                 1e-8, 1e-1, 12000, expected);
  //     }
  
      @Test
      public void testSsDiffPow() {
          double[] startPoint = point(DIM/2,1.0);
          double[][] boundaries = null;
          PointValuePair expected =
              new PointValuePair(point(DIM/2,0.0),0.0);
          doTest(new SsDiffPow(), startPoint, boundaries,
                  GoalType.MINIMIZE, 
                  1e-2, 1.3e-1, 50000, expected);
      }
  
      @Test
      public void testAckley() {}
  // Defects4J: flaky method
  //     @Test
  //     public void testAckley() {
  //         double[] startPoint = point(DIM,0.1);
  //         double[][] boundaries = null;
  //         PointValuePair expected =
  //             new PointValuePair(point(DIM,0.0),0.0);
  //         doTest(new Ackley(), startPoint, boundaries,
  //                 GoalType.MINIMIZE,
  //                 1e-8, 1e-5, 1000, expected);
  //     }
  
      @Test
      public void testRastrigin() {
          double[] startPoint = point(DIM,1.0);
  
          double[][] boundaries = null;
          PointValuePair expected =
              new PointValuePair(point(DIM,0.0),0.0);
          doTest(new Rastrigin(), startPoint, boundaries,
                  GoalType.MINIMIZE, 
                  1e-13, 1e-6, 1000, expected);
      }
  
      @Test
      public void testConstrainedRosen() {
          double[] startPoint = point(DIM,0.1);
  
          double[][] boundaries = boundaries(DIM,-1,2);
          PointValuePair expected =
              new PointValuePair(point(DIM,1.0),0.0);
          doTest(new Rosen(), startPoint, boundaries,
                  GoalType.MINIMIZE,
                  1e-13, 1e-6, 2000, expected);
      }
  
      // See MATH-728
      // TODO: this test is temporarily disabled for 3.2 release as a bug in Cobertura
      //       makes it run for several hours before completing
      @Ignore @Test
      public void testConstrainedRosenWithMoreInterpolationPoints() {
          final double[] startPoint = point(DIM, 0.1);
          final double[][] boundaries = boundaries(DIM, -1, 2);
          final PointValuePair expected = new PointValuePair(point(DIM, 1.0), 0.0);
  
          // This should have been 78 because in the code the hard limit is
          // said to be
          //   ((DIM + 1) * (DIM + 2)) / 2 - (2 * DIM + 1)
          // i.e. 78 in this case, but the test fails for 48, 59, 62, 63, 64,
          // 65, 66, ...
          final int maxAdditionalPoints = 47;
  
          for (int num = 1; num <= maxAdditionalPoints; num++) {
              doTest(new Rosen(), startPoint, boundaries,
                     GoalType.MINIMIZE,
                     1e-12, 1e-6, 2000,
                     num,
                     expected,
                     "num=" + num);
          }
      }
  
      /**
       * @param func Function to optimize.
       * @param startPoint Starting point.
       * @param boundaries Upper / lower point limit.
       * @param goal Minimization or maximization.
       * @param fTol Tolerance relative error on the objective function.
       * @param pointTol Tolerance for checking that the optimum is correct.
       * @param maxEvaluations Maximum number of evaluations.
       * @param expected Expected point / value.
       */
      private void doTest(MultivariateFunction func,
                          double[] startPoint,
                          double[][] boundaries,
                          GoalType goal,
                          double fTol,
                          double pointTol,
                          int maxEvaluations,
                          PointValuePair expected) {
          doTest(func,
                 startPoint,
                 boundaries,
                 goal,
                 fTol,
                 pointTol,
                 maxEvaluations,
                 0,
                 expected,
                 "");
      }
  
      /**
       * @param func Function to optimize.
       * @param startPoint Starting point.
       * @param boundaries Upper / lower point limit.
       * @param goal Minimization or maximization.
       * @param fTol Tolerance relative error on the objective function.
       * @param pointTol Tolerance for checking that the optimum is correct.
       * @param maxEvaluations Maximum number of evaluations.
       * @param additionalInterpolationPoints Number of interpolation to used
       * in addition to the default (2 * dim + 1).
       * @param expected Expected point / value.
       */
      private void doTest(MultivariateFunction func,
                          double[] startPoint,
                          double[][] boundaries,
                          GoalType goal,
                          double fTol,
                          double pointTol,
                          int maxEvaluations,
                          int additionalInterpolationPoints,
                          PointValuePair expected,
                          String assertMsg) {
  
  //         System.out.println(func.getClass().getName() + " BEGIN"); // XXX
  
          int dim = startPoint.length;
  //        MultivariateOptimizer optim =
  //            new PowellOptimizer(1e-13, Math.ulp(1d));
  //        PointValuePair result = optim.optimize(100000, func, goal, startPoint);
          final double[] lB = boundaries == null ? null : boundaries[0];
          final double[] uB = boundaries == null ? null : boundaries[1];
          final int numIterpolationPoints = 2 * dim + 1 + additionalInterpolationPoints;
          BOBYQAOptimizer optim = new BOBYQAOptimizer(numIterpolationPoints);
          PointValuePair result = boundaries == null ?
              optim.optimize(maxEvaluations, func, goal,
                             new InitialGuess(startPoint)) :
              optim.optimize(maxEvaluations, func, goal,
                             new InitialGuess(startPoint),
                             new SimpleBounds(lB, uB));
  //        System.out.println(func.getClass().getName() + " = " 
  //              + optim.getEvaluations() + " f(");
  //        for (double x: result.getPoint())  System.out.print(x + " ");
  //        System.out.println(") = " +  result.getValue());
          Assert.assertEquals(assertMsg, expected.getValue(), result.getValue(), fTol);
          for (int i = 0; i < dim; i++) {
              Assert.assertEquals(expected.getPoint()[i],
                                  result.getPoint()[i], pointTol);
          }
  
  //         System.out.println(func.getClass().getName() + " END"); // XXX
      }
  
      private static double[] point(int n, double value) {
          double[] ds = new double[n];
          Arrays.fill(ds, value);
          return ds;
      }
  
      private static double[][] boundaries(int dim,
              double lower, double upper) {
          double[][] boundaries = new double[2][dim];
          for (int i = 0; i < dim; i++)
              boundaries[0][i] = lower;
          for (int i = 0; i < dim; i++)
              boundaries[1][i] = upper;
          return boundaries;
      }
  
      private static class Sphere implements MultivariateFunction {
  
          public double value(double[] x) {
              double f = 0;
              for (int i = 0; i < x.length; ++i)
                  f += x[i] * x[i];
              return f;
          }
      }
  
      private static class Cigar implements MultivariateFunction {
          private double factor;
  
          Cigar() {
              this(1e3);
          }
  
          Cigar(double axisratio) {
              factor = axisratio * axisratio;
          }
  
          public double value(double[] x) {
              double f = x[0] * x[0];
              for (int i = 1; i < x.length; ++i)
                  f += factor * x[i] * x[i];
              return f;
          }
      }
  
      private static class Tablet implements MultivariateFunction {
          private double factor;
  
          Tablet() {
              this(1e3);
          }
  
          Tablet(double axisratio) {
              factor = axisratio * axisratio;
          }
  
          public double value(double[] x) {
              double f = factor * x[0] * x[0];
              for (int i = 1; i < x.length; ++i)
                  f += x[i] * x[i];
              return f;
          }
      }
  
      private static class CigTab implements MultivariateFunction {
          private double factor;
  
          CigTab() {
              this(1e4);
          }
  
          CigTab(double axisratio) {
              factor = axisratio;
          }
  
          public double value(double[] x) {
              int end = x.length - 1;
              double f = x[0] * x[0] / factor + factor * x[end] * x[end];
              for (int i = 1; i < end; ++i)
                  f += x[i] * x[i];
              return f;
          }
      }
  
      private static class TwoAxes implements MultivariateFunction {
  
          private double factor;
  
          TwoAxes() {
              this(1e6);
          }
  
          TwoAxes(double axisratio) {
              factor = axisratio * axisratio;
          }
  
          public double value(double[] x) {
              double f = 0;
              for (int i = 0; i < x.length; ++i)
                  f += (i < x.length / 2 ? factor : 1) * x[i] * x[i];
              return f;
          }
      }
  
      private static class ElliRotated implements MultivariateFunction {
          private Basis B = new Basis();
          private double factor;
  
          ElliRotated() {
              this(1e3);
          }
  
          ElliRotated(double axisratio) {
              factor = axisratio * axisratio;
          }
  
          public double value(double[] x) {
              double f = 0;
              x = B.Rotate(x);
              for (int i = 0; i < x.length; ++i)
                  f += Math.pow(factor, i / (x.length - 1.)) * x[i] * x[i];
              return f;
          }
      }
  
      private static class Elli implements MultivariateFunction {
  
          private double factor;
  
          Elli() {
              this(1e3);
          }
  
          Elli(double axisratio) {
              factor = axisratio * axisratio;
          }
  
          public double value(double[] x) {
              double f = 0;
              for (int i = 0; i < x.length; ++i)
                  f += Math.pow(factor, i / (x.length - 1.)) * x[i] * x[i];
              return f;
          }
      }
  
      private static class MinusElli implements MultivariateFunction {
          private final Elli elli = new Elli();
          public double value(double[] x) {
              return 1.0 - elli.value(x);
          }
      }
  
      private static class DiffPow implements MultivariateFunction {
  //        private int fcount = 0;
          public double value(double[] x) {
              double f = 0;
              for (int i = 0; i < x.length; ++i)
                  f += Math.pow(Math.abs(x[i]), 2. + 10 * (double) i
                          / (x.length - 1.));
  //            System.out.print("" + (fcount++) + ") ");
  //            for (int i = 0; i < x.length; i++)
  //                System.out.print(x[i] +  " ");
  //            System.out.println(" = " + f);
              return f;
          }
      }
  
      private static class SsDiffPow implements MultivariateFunction {
  
          public double value(double[] x) {
              double f = Math.pow(new DiffPow().value(x), 0.25);
              return f;
          }
      }
  
      private static class Rosen implements MultivariateFunction {
  
          public double value(double[] x) {
              double f = 0;
              for (int i = 0; i < x.length - 1; ++i)
                  f += 1e2 * (x[i] * x[i] - x[i + 1]) * (x[i] * x[i] - x[i + 1])
                  + (x[i] - 1.) * (x[i] - 1.);
              return f;
          }
      }
  
      private static class Ackley implements MultivariateFunction {
          private double axisratio;
  
          Ackley(double axra) {
              axisratio = axra;
          }
  
          public Ackley() {
              this(1);
          }
  
          public double value(double[] x) {
              double f = 0;
              double res2 = 0;
              double fac = 0;
              for (int i = 0; i < x.length; ++i) {
                  fac = Math.pow(axisratio, (i - 1.) / (x.length - 1.));
                  f += fac * fac * x[i] * x[i];
                  res2 += Math.cos(2. * Math.PI * fac * x[i]);
              }
              f = (20. - 20. * Math.exp(-0.2 * Math.sqrt(f / x.length))
                      + Math.exp(1.) - Math.exp(res2 / x.length));
              return f;
          }
      }
  
      private static class Rastrigin implements MultivariateFunction {
  
          private double axisratio;
          private double amplitude;
  
          Rastrigin() {
              this(1, 10);
          }
  
          Rastrigin(double axisratio, double amplitude) {
              this.axisratio = axisratio;
              this.amplitude = amplitude;
          }
  
          public double value(double[] x) {
              double f = 0;
              double fac;
              for (int i = 0; i < x.length; ++i) {
  