/*
 * 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.Arrays;

import org.apache.commons.math3.exception.TooManyEvaluationsException;
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.MultivariateDifferentiableVectorFunction;
import org.apache.commons.math3.optimization.PointVectorValuePair;
import org.apache.commons.math3.util.FastMath;
import org.junit.Assert;
import org.junit.Test;

/**
 * <p>Some of the unit tests are re-implementations of the MINPACK <a
 * href="http://www.netlib.org/minpack/ex/file17">file17</a> and <a
 * href="http://www.netlib.org/minpack/ex/file22">file22</a> test files.
 * The redistribution policy for MINPACK is available <a
 * href="http://www.netlib.org/minpack/disclaimer">here</a>, for
 * convenience, it is reproduced below.</p>

 * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
 * <tr><td>
 *    Minpack Copyright Notice (1999) University of Chicago.
 *    All rights reserved
 * </td></tr>
 * <tr><td>
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * <ol>
 *  <li>Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.</li>
 * <li>Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.</li>
 * <li>The end-user documentation included with the redistribution, if any,
 *     must include the following acknowledgment:
 *     <code>This product includes software developed by the University of
 *           Chicago, as Operator of Argonne National Laboratory.</code>
 *     Alternately, this acknowledgment may appear in the software itself,
 *     if and wherever such third-party acknowledgments normally appear.</li>
 * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"
 *     WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE
 *     UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND
 *     THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR
 *     IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES
 *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
 *     OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY
 *     OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
 *     USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF
 *     THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)
 *     DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION
 *     UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL
 *     BE CORRECTED.</strong></li>
 * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT
 *     HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF
 *     ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,
 *     INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF
 *     ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF
 *     PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER
 *     SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
 *     (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
 *     EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
 *     POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li>
 * <ol></td></tr>
 * </table>

 * @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)
 */
@Deprecated
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
    };

  }

}
