gonum.org/v1/gonum@v0.14.0/optimize/unconstrained_test.go (about)

     1  // Copyright ©2014 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package optimize
     6  
     7  import (
     8  	"fmt"
     9  	"math"
    10  	"testing"
    11  
    12  	"gonum.org/v1/gonum/floats"
    13  	"gonum.org/v1/gonum/mat"
    14  	"gonum.org/v1/gonum/optimize/functions"
    15  )
    16  
    17  type unconstrainedTest struct {
    18  	// name is the name of the test.
    19  	name string
    20  	// p is the optimization problem to be solved.
    21  	p Problem
    22  	// x is the initial guess.
    23  	x []float64
    24  	// gradTol is the absolute gradient tolerance for the test. If gradTol == 0,
    25  	// the default value of 1e-12 will be used.
    26  	gradTol float64
    27  	// fAbsTol is the absolute function convergence for the test. If fAbsTol == 0,
    28  	// the default value of 1e-12 will be used.
    29  	fAbsTol float64
    30  	// fIter is the number of iterations for function convergence. If fIter == 0,
    31  	// the default value of 20 will be used.
    32  	fIter int
    33  	// long indicates that the test takes long time to finish and will be
    34  	// excluded if testing.Short returns true.
    35  	long bool
    36  }
    37  
    38  func (t unconstrainedTest) String() string {
    39  	dim := len(t.x)
    40  	if dim <= 10 {
    41  		// Print the initial X only for small-dimensional problems.
    42  		return fmt.Sprintf("F: %v\nDim: %v\nInitial X: %v\nGradientThreshold: %v",
    43  			t.name, dim, t.x, t.gradTol)
    44  	}
    45  	return fmt.Sprintf("F: %v\nDim: %v\nGradientThreshold: %v",
    46  		t.name, dim, t.gradTol)
    47  }
    48  
    49  var gradFreeTests = []unconstrainedTest{
    50  	{
    51  		name: "Beale",
    52  		p: Problem{
    53  			Func: functions.Beale{}.Func,
    54  		},
    55  		x: []float64{1, 1},
    56  	},
    57  	{
    58  		name: "BiggsEXP6",
    59  		p: Problem{
    60  			Func: functions.BiggsEXP6{}.Func,
    61  		},
    62  		x: []float64{1, 2, 1, 1, 1, 1},
    63  	},
    64  	{
    65  		name: "BrownAndDennis",
    66  		p: Problem{
    67  			Func: functions.BrownAndDennis{}.Func,
    68  		},
    69  		x: []float64{25, 5, -5, -1},
    70  	},
    71  	{
    72  		name: "ExtendedRosenbrock",
    73  		p: Problem{
    74  			Func: functions.ExtendedRosenbrock{}.Func,
    75  		},
    76  		x: []float64{-10, 10},
    77  	},
    78  	{
    79  		name: "ExtendedRosenbrock",
    80  		p: Problem{
    81  			Func: functions.ExtendedRosenbrock{}.Func,
    82  		},
    83  		x: []float64{-5, 4, 16, 3},
    84  	},
    85  }
    86  
    87  var gradientDescentTests = []unconstrainedTest{
    88  	{
    89  		name: "Beale",
    90  		p: Problem{
    91  			Func: functions.Beale{}.Func,
    92  			Grad: functions.Beale{}.Grad,
    93  		},
    94  		x: []float64{1, 1},
    95  	},
    96  	{
    97  		name: "Beale",
    98  		p: Problem{
    99  			Func: functions.Beale{}.Func,
   100  			Grad: functions.Beale{}.Grad,
   101  		},
   102  		x: []float64{3.00001, 0.50001},
   103  	},
   104  	{
   105  		name: "BiggsEXP2",
   106  		p: Problem{
   107  			Func: functions.BiggsEXP2{}.Func,
   108  			Grad: functions.BiggsEXP2{}.Grad,
   109  		},
   110  		x: []float64{1, 2},
   111  	},
   112  	{
   113  		name: "BiggsEXP2",
   114  		p: Problem{
   115  			Func: functions.BiggsEXP2{}.Func,
   116  			Grad: functions.BiggsEXP2{}.Grad,
   117  		},
   118  		x: []float64{1.00001, 10.00001},
   119  	},
   120  	{
   121  		name: "BiggsEXP3",
   122  		p: Problem{
   123  			Func: functions.BiggsEXP3{}.Func,
   124  			Grad: functions.BiggsEXP3{}.Grad,
   125  		},
   126  		x: []float64{1, 2, 1},
   127  	},
   128  	{
   129  		name: "BiggsEXP3",
   130  		p: Problem{
   131  			Func: functions.BiggsEXP3{}.Func,
   132  			Grad: functions.BiggsEXP3{}.Grad,
   133  		},
   134  		x: []float64{1.00001, 10.00001, 3.00001},
   135  	},
   136  	{
   137  		name: "ExtendedRosenbrock",
   138  		p: Problem{
   139  			Func: functions.ExtendedRosenbrock{}.Func,
   140  			Grad: functions.ExtendedRosenbrock{}.Grad,
   141  		},
   142  		x:       []float64{-1.2, 1},
   143  		gradTol: 1e-10,
   144  	},
   145  	{
   146  		name: "ExtendedRosenbrock",
   147  		p: Problem{
   148  			Func: functions.ExtendedRosenbrock{}.Func,
   149  			Grad: functions.ExtendedRosenbrock{}.Grad,
   150  		},
   151  		x:       []float64{1.00001, 1.00001},
   152  		gradTol: 1e-10,
   153  	},
   154  	{
   155  		name: "ExtendedRosenbrock",
   156  		p: Problem{
   157  			Func: functions.ExtendedRosenbrock{}.Func,
   158  			Grad: functions.ExtendedRosenbrock{}.Grad,
   159  		},
   160  		x:       []float64{-1.2, 1, -1.2},
   161  		gradTol: 1e-10,
   162  	},
   163  	{
   164  		name: "ExtendedRosenbrock",
   165  		p: Problem{
   166  			Func: functions.ExtendedRosenbrock{}.Func,
   167  			Grad: functions.ExtendedRosenbrock{}.Grad,
   168  		},
   169  		x:    []float64{-120, 100, 50},
   170  		long: true,
   171  	},
   172  	{
   173  		name: "ExtendedRosenbrock",
   174  		p: Problem{
   175  			Func: functions.ExtendedRosenbrock{}.Func,
   176  			Grad: functions.ExtendedRosenbrock{}.Grad,
   177  		},
   178  		x: []float64{1, 1, 1},
   179  	},
   180  	{
   181  		name: "ExtendedRosenbrock",
   182  		p: Problem{
   183  			Func: functions.ExtendedRosenbrock{}.Func,
   184  			Grad: functions.ExtendedRosenbrock{}.Grad,
   185  		},
   186  		x:       []float64{1.00001, 1.00001, 1.00001},
   187  		gradTol: 1e-8,
   188  	},
   189  	{
   190  		name: "Gaussian",
   191  		p: Problem{
   192  			Func: functions.Gaussian{}.Func,
   193  			Grad: functions.Gaussian{}.Grad,
   194  		},
   195  		x:       []float64{0.4, 1, 0},
   196  		gradTol: 1e-9,
   197  	},
   198  	{
   199  		name: "Gaussian",
   200  		p: Problem{
   201  			Func: functions.Gaussian{}.Func,
   202  			Grad: functions.Gaussian{}.Grad,
   203  		},
   204  		x:       []float64{0.3989561, 1.0000191, 0},
   205  		gradTol: 1e-9,
   206  	},
   207  	{
   208  		name: "HelicalValley",
   209  		p: Problem{
   210  			Func: functions.HelicalValley{}.Func,
   211  			Grad: functions.HelicalValley{}.Grad,
   212  		},
   213  		x: []float64{-1, 0, 0},
   214  	},
   215  	{
   216  		name: "HelicalValley",
   217  		p: Problem{
   218  			Func: functions.HelicalValley{}.Func,
   219  			Grad: functions.HelicalValley{}.Grad,
   220  		},
   221  		x: []float64{1.00001, 0.00001, 0.00001},
   222  	},
   223  	{
   224  		name: "Trigonometric",
   225  		p: Problem{
   226  			Func: functions.Trigonometric{}.Func,
   227  			Grad: functions.Trigonometric{}.Grad,
   228  		},
   229  		x:       []float64{0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1},
   230  		gradTol: 1e-7,
   231  	},
   232  	{
   233  		name: "Trigonometric",
   234  		p: Problem{
   235  			Func: functions.Trigonometric{}.Func,
   236  			Grad: functions.Trigonometric{}.Grad,
   237  		},
   238  		x: []float64{0.042964, 0.043976, 0.045093, 0.046338, 0.047744,
   239  			0.049354, 0.051237, 0.195209, 0.164977, 0.060148},
   240  		gradTol: 1e-8,
   241  	},
   242  	newVariablyDimensioned(2, 0),
   243  	{
   244  		name: "VariablyDimensioned",
   245  		p: Problem{
   246  			Func: functions.VariablyDimensioned{}.Func,
   247  			Grad: functions.VariablyDimensioned{}.Grad,
   248  		},
   249  		x: []float64{1.00001, 1.00001},
   250  	},
   251  	newVariablyDimensioned(10, 0),
   252  	{
   253  		name: "VariablyDimensioned",
   254  		p: Problem{
   255  			Func: functions.VariablyDimensioned{}.Func,
   256  			Grad: functions.VariablyDimensioned{}.Grad,
   257  		},
   258  		x: []float64{1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001},
   259  	},
   260  }
   261  
   262  var cgTests = []unconstrainedTest{
   263  	{
   264  		name: "BiggsEXP4",
   265  		p: Problem{
   266  			Func: functions.BiggsEXP4{}.Func,
   267  			Grad: functions.BiggsEXP4{}.Grad,
   268  		},
   269  		x: []float64{1, 2, 1, 1},
   270  	},
   271  	{
   272  		name: "BiggsEXP4",
   273  		p: Problem{
   274  			Func: functions.BiggsEXP4{}.Func,
   275  			Grad: functions.BiggsEXP4{}.Grad,
   276  		},
   277  		x: []float64{1.00001, 10.00001, 1.00001, 5.00001},
   278  	},
   279  	{
   280  		name: "BiggsEXP5",
   281  		p: Problem{
   282  			Func: functions.BiggsEXP5{}.Func,
   283  			Grad: functions.BiggsEXP5{}.Grad,
   284  		},
   285  		x:       []float64{1, 2, 1, 1, 1},
   286  		gradTol: 1e-7,
   287  	},
   288  	{
   289  		name: "BiggsEXP5",
   290  		p: Problem{
   291  			Func: functions.BiggsEXP5{}.Func,
   292  			Grad: functions.BiggsEXP5{}.Grad,
   293  		},
   294  		x: []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001},
   295  	},
   296  	{
   297  		name: "BiggsEXP6",
   298  		p: Problem{
   299  			Func: functions.BiggsEXP6{}.Func,
   300  			Grad: functions.BiggsEXP6{}.Grad,
   301  		},
   302  		x:       []float64{1, 2, 1, 1, 1, 1},
   303  		gradTol: 1e-7,
   304  	},
   305  	{
   306  		name: "BiggsEXP6",
   307  		p: Problem{
   308  			Func: functions.BiggsEXP6{}.Func,
   309  			Grad: functions.BiggsEXP6{}.Grad,
   310  		},
   311  		x:       []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001, 3.00001},
   312  		gradTol: 1e-8,
   313  	},
   314  	{
   315  		name: "Box3D",
   316  		p: Problem{
   317  			Func: functions.Box3D{}.Func,
   318  			Grad: functions.Box3D{}.Grad,
   319  		},
   320  		x: []float64{0, 10, 20},
   321  	},
   322  	{
   323  		name: "Box3D",
   324  		p: Problem{
   325  			Func: functions.Box3D{}.Func,
   326  			Grad: functions.Box3D{}.Grad,
   327  		},
   328  		x: []float64{1.00001, 10.00001, 1.00001},
   329  	},
   330  	{
   331  		name: "Box3D",
   332  		p: Problem{
   333  			Func: functions.Box3D{}.Func,
   334  			Grad: functions.Box3D{}.Grad,
   335  		},
   336  		x: []float64{100.00001, 100.00001, 0.00001},
   337  	},
   338  	{
   339  		name: "ExtendedPowellSingular",
   340  		p: Problem{
   341  			Func: functions.ExtendedPowellSingular{}.Func,
   342  			Grad: functions.ExtendedPowellSingular{}.Grad,
   343  		},
   344  		x: []float64{3, -1, 0, 3},
   345  	},
   346  	{
   347  		name: "ExtendedPowellSingular",
   348  		p: Problem{
   349  			Func: functions.ExtendedPowellSingular{}.Func,
   350  			Grad: functions.ExtendedPowellSingular{}.Grad,
   351  		},
   352  		x: []float64{0.00001, 0.00001, 0.00001, 0.00001},
   353  	},
   354  	{
   355  		name: "ExtendedPowellSingular",
   356  		p: Problem{
   357  			Func: functions.ExtendedPowellSingular{}.Func,
   358  			Grad: functions.ExtendedPowellSingular{}.Grad,
   359  		},
   360  		x:       []float64{3, -1, 0, 3, 3, -1, 0, 3},
   361  		gradTol: 1e-8,
   362  	},
   363  	{
   364  		name: "ExtendedPowellSingular",
   365  		p: Problem{
   366  			Func: functions.ExtendedPowellSingular{}.Func,
   367  			Grad: functions.ExtendedPowellSingular{}.Grad,
   368  		},
   369  		x: []float64{0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001},
   370  	},
   371  	{
   372  		name: "ExtendedRosenbrock",
   373  		p: Problem{
   374  			Func: functions.ExtendedRosenbrock{}.Func,
   375  			Grad: functions.ExtendedRosenbrock{}.Grad,
   376  		},
   377  		x: []float64{-1.2, 1, -1.2, 1},
   378  	},
   379  	{
   380  		name: "ExtendedRosenbrock",
   381  		p: Problem{
   382  			Func: functions.ExtendedRosenbrock{}.Func,
   383  			Grad: functions.ExtendedRosenbrock{}.Grad,
   384  		},
   385  		x:       []float64{1e4, 1e4},
   386  		gradTol: 1e-10,
   387  	},
   388  	{
   389  		name: "ExtendedRosenbrock",
   390  		p: Problem{
   391  			Func: functions.ExtendedRosenbrock{}.Func,
   392  			Grad: functions.ExtendedRosenbrock{}.Grad,
   393  		},
   394  		x:       []float64{1.00001, 1.00001, 1.00001, 1.00001},
   395  		gradTol: 1e-10,
   396  	},
   397  	{
   398  		name: "PenaltyI",
   399  		p: Problem{
   400  			Func: functions.PenaltyI{}.Func,
   401  			Grad: functions.PenaltyI{}.Grad,
   402  		},
   403  		x:       []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
   404  		gradTol: 1e-9,
   405  	},
   406  	{
   407  		name: "PenaltyI",
   408  		p: Problem{
   409  			Func: functions.PenaltyI{}.Func,
   410  			Grad: functions.PenaltyI{}.Grad,
   411  		},
   412  		x:       []float64{0.250007, 0.250007, 0.250007, 0.250007},
   413  		gradTol: 1e-10,
   414  	},
   415  	{
   416  		name: "PenaltyI",
   417  		p: Problem{
   418  			Func: functions.PenaltyI{}.Func,
   419  			Grad: functions.PenaltyI{}.Grad,
   420  		},
   421  		x: []float64{0.1581, 0.1581, 0.1581, 0.1581, 0.1581, 0.1581,
   422  			0.1581, 0.1581, 0.1581, 0.1581},
   423  		gradTol: 1e-10,
   424  	},
   425  	{
   426  		name: "PenaltyII",
   427  		p: Problem{
   428  			Func: functions.PenaltyII{}.Func,
   429  			Grad: functions.PenaltyII{}.Grad,
   430  		},
   431  		x:       []float64{0.5, 0.5, 0.5, 0.5},
   432  		gradTol: 1e-8,
   433  	},
   434  	{
   435  		name: "PenaltyII",
   436  		p: Problem{
   437  			Func: functions.PenaltyII{}.Func,
   438  			Grad: functions.PenaltyII{}.Grad,
   439  		},
   440  		x:       []float64{0.19999, 0.19131, 0.4801, 0.51884},
   441  		gradTol: 1e-8,
   442  	},
   443  	{
   444  		name: "PenaltyII",
   445  		p: Problem{
   446  			Func: functions.PenaltyII{}.Func,
   447  			Grad: functions.PenaltyII{}.Grad,
   448  		},
   449  		x: []float64{0.19998, 0.01035, 0.01960, 0.03208, 0.04993, 0.07651,
   450  			0.11862, 0.19214, 0.34732, 0.36916},
   451  		gradTol: 1e-6,
   452  	},
   453  	{
   454  		name: "PowellBadlyScaled",
   455  		p: Problem{
   456  			Func: functions.PowellBadlyScaled{}.Func,
   457  			Grad: functions.PowellBadlyScaled{}.Grad,
   458  		},
   459  		x:       []float64{1.09815e-05, 9.10614},
   460  		gradTol: 1e-8,
   461  	},
   462  	newVariablyDimensioned(100, 1e-10),
   463  	newVariablyDimensioned(1000, 1e-7),
   464  	newVariablyDimensioned(10000, 1e-4),
   465  	{
   466  		name: "Watson",
   467  		p: Problem{
   468  			Func: functions.Watson{}.Func,
   469  			Grad: functions.Watson{}.Grad,
   470  		},
   471  		x:       []float64{0, 0, 0, 0, 0, 0},
   472  		gradTol: 1e-6,
   473  	},
   474  	{
   475  		name: "Watson",
   476  		p: Problem{
   477  			Func: functions.Watson{}.Func,
   478  			Grad: functions.Watson{}.Grad,
   479  		},
   480  		x:       []float64{-0.01572, 1.01243, -0.23299, 1.26043, -1.51372, 0.99299},
   481  		gradTol: 1e-6,
   482  	},
   483  	{
   484  		name: "Watson",
   485  		p: Problem{
   486  			Func: functions.Watson{}.Func,
   487  			Grad: functions.Watson{}.Grad,
   488  		},
   489  		x:       []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   490  		gradTol: 1e-6,
   491  		long:    true,
   492  	},
   493  	{
   494  		name: "Watson",
   495  		p: Problem{
   496  			Func: functions.Watson{}.Func,
   497  			Grad: functions.Watson{}.Grad,
   498  		},
   499  		x: []float64{-1.53070e-05, 0.99978, 0.01476, 0.14634, 1.00082,
   500  			-2.61773, 4.10440, -3.14361, 1.05262},
   501  		gradTol: 1e-6,
   502  	},
   503  	{
   504  		name: "Wood",
   505  		p: Problem{
   506  			Func: functions.Wood{}.Func,
   507  			Grad: functions.Wood{}.Grad,
   508  		},
   509  		x:       []float64{-3, -1, -3, -1},
   510  		gradTol: 1e-6,
   511  	},
   512  }
   513  
   514  var quasiNewtonTests = []unconstrainedTest{
   515  	{
   516  		name: "BiggsEXP4",
   517  		p: Problem{
   518  			Func: functions.BiggsEXP4{}.Func,
   519  			Grad: functions.BiggsEXP4{}.Grad,
   520  		},
   521  		x: []float64{1, 2, 1, 1},
   522  	},
   523  	{
   524  		name: "BiggsEXP4",
   525  		p: Problem{
   526  			Func: functions.BiggsEXP4{}.Func,
   527  			Grad: functions.BiggsEXP4{}.Grad,
   528  		},
   529  		x: []float64{1.00001, 10.00001, 1.00001, 5.00001},
   530  	},
   531  	{
   532  		name: "BiggsEXP5",
   533  		p: Problem{
   534  			Func: functions.BiggsEXP5{}.Func,
   535  			Grad: functions.BiggsEXP5{}.Grad,
   536  		},
   537  		x:       []float64{1, 2, 1, 1, 1},
   538  		gradTol: 1e-10,
   539  	},
   540  	{
   541  		name: "BiggsEXP5",
   542  		p: Problem{
   543  			Func: functions.BiggsEXP5{}.Func,
   544  			Grad: functions.BiggsEXP5{}.Grad,
   545  		},
   546  		x: []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001},
   547  	},
   548  	{
   549  		name: "BiggsEXP6",
   550  		p: Problem{
   551  			Func: functions.BiggsEXP6{}.Func,
   552  			Grad: functions.BiggsEXP6{}.Grad,
   553  		},
   554  		x:       []float64{1, 2, 1, 1, 1, 1},
   555  		gradTol: 1e-8,
   556  	},
   557  	{
   558  		name: "BiggsEXP6",
   559  		p: Problem{
   560  			Func: functions.BiggsEXP6{}.Func,
   561  			Grad: functions.BiggsEXP6{}.Grad,
   562  		},
   563  		x:       []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001, 3.00001},
   564  		gradTol: 1e-8,
   565  	},
   566  	{
   567  		name: "Box3D",
   568  		p: Problem{
   569  			Func: functions.Box3D{}.Func,
   570  			Grad: functions.Box3D{}.Grad,
   571  		},
   572  		x: []float64{0, 10, 20},
   573  	},
   574  	{
   575  		name: "Box3D",
   576  		p: Problem{
   577  			Func: functions.Box3D{}.Func,
   578  			Grad: functions.Box3D{}.Grad,
   579  		},
   580  		x: []float64{1.00001, 10.00001, 1.00001},
   581  	},
   582  	{
   583  		name: "Box3D",
   584  		p: Problem{
   585  			Func: functions.Box3D{}.Func,
   586  			Grad: functions.Box3D{}.Grad,
   587  		},
   588  		x: []float64{100.00001, 100.00001, 0.00001},
   589  	},
   590  	{
   591  		name: "BrownBadlyScaled",
   592  		p: Problem{
   593  			Func: functions.BrownBadlyScaled{}.Func,
   594  			Grad: functions.BrownBadlyScaled{}.Grad,
   595  		},
   596  		x:       []float64{1, 1},
   597  		gradTol: 1e-9,
   598  	},
   599  	{
   600  		name: "BrownBadlyScaled",
   601  		p: Problem{
   602  			Func: functions.BrownBadlyScaled{}.Func,
   603  			Grad: functions.BrownBadlyScaled{}.Grad,
   604  		},
   605  		x: []float64{1.000001e6, 2.01e-6},
   606  	},
   607  	{
   608  		name: "ExtendedPowellSingular",
   609  		p: Problem{
   610  			Func: functions.ExtendedPowellSingular{}.Func,
   611  			Grad: functions.ExtendedPowellSingular{}.Grad,
   612  		},
   613  		x: []float64{3, -1, 0, 3},
   614  	},
   615  	{
   616  		name: "ExtendedPowellSingular",
   617  		p: Problem{
   618  			Func: functions.ExtendedPowellSingular{}.Func,
   619  			Grad: functions.ExtendedPowellSingular{}.Grad,
   620  		},
   621  		x: []float64{0.00001, 0.00001, 0.00001, 0.00001},
   622  	},
   623  	{
   624  		name: "ExtendedPowellSingular",
   625  		p: Problem{
   626  			Func: functions.ExtendedPowellSingular{}.Func,
   627  			Grad: functions.ExtendedPowellSingular{}.Grad,
   628  		},
   629  		x: []float64{3, -1, 0, 3, 3, -1, 0, 3},
   630  	},
   631  	{
   632  		name: "ExtendedPowellSingular",
   633  		p: Problem{
   634  			Func: functions.ExtendedPowellSingular{}.Func,
   635  			Grad: functions.ExtendedPowellSingular{}.Grad,
   636  		},
   637  		x: []float64{0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001},
   638  	},
   639  	{
   640  		name: "ExtendedRosenbrock",
   641  		p: Problem{
   642  			Func: functions.ExtendedRosenbrock{}.Func,
   643  			Grad: functions.ExtendedRosenbrock{}.Grad,
   644  		},
   645  		x: []float64{-1.2, 1, -1.2, 1},
   646  	},
   647  	{
   648  		name: "ExtendedRosenbrock",
   649  		p: Problem{
   650  			Func: functions.ExtendedRosenbrock{}.Func,
   651  			Grad: functions.ExtendedRosenbrock{}.Grad,
   652  		},
   653  		x: []float64{1.00001, 1.00001, 1.00001, 1.00001},
   654  	},
   655  	{
   656  		name: "Gaussian",
   657  		p: Problem{
   658  			Func: functions.Gaussian{}.Func,
   659  			Grad: functions.Gaussian{}.Grad,
   660  		},
   661  		x:       []float64{0.4, 1, 0},
   662  		gradTol: 1e-11,
   663  	},
   664  	{
   665  		name: "GulfResearchAndDevelopment",
   666  		p: Problem{
   667  			Func: functions.GulfResearchAndDevelopment{}.Func,
   668  			Grad: functions.GulfResearchAndDevelopment{}.Grad,
   669  		},
   670  		x: []float64{5, 2.5, 0.15},
   671  	},
   672  	{
   673  		name: "GulfResearchAndDevelopment",
   674  		p: Problem{
   675  			Func: functions.GulfResearchAndDevelopment{}.Func,
   676  			Grad: functions.GulfResearchAndDevelopment{}.Grad,
   677  		},
   678  		x: []float64{50.00001, 25.00001, 1.50001},
   679  	},
   680  	{
   681  		name: "GulfResearchAndDevelopment",
   682  		p: Problem{
   683  			Func: functions.GulfResearchAndDevelopment{}.Func,
   684  			Grad: functions.GulfResearchAndDevelopment{}.Grad,
   685  		},
   686  		x: []float64{99.89529, 60.61453, 9.16124},
   687  	},
   688  	{
   689  		name: "GulfResearchAndDevelopment",
   690  		p: Problem{
   691  			Func: functions.GulfResearchAndDevelopment{}.Func,
   692  			Grad: functions.GulfResearchAndDevelopment{}.Grad,
   693  		},
   694  		x: []float64{201.66258, 60.61633, 10.22489},
   695  	},
   696  	{
   697  		name: "PenaltyI",
   698  		p: Problem{
   699  			Func: functions.PenaltyI{}.Func,
   700  			Grad: functions.PenaltyI{}.Grad,
   701  		},
   702  		x: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
   703  	},
   704  	{
   705  		name: "PenaltyI",
   706  		p: Problem{
   707  			Func: functions.PenaltyI{}.Func,
   708  			Grad: functions.PenaltyI{}.Grad,
   709  		},
   710  		x:       []float64{0.250007, 0.250007, 0.250007, 0.250007},
   711  		gradTol: 1e-9,
   712  	},
   713  	{
   714  		name: "PenaltyI",
   715  		p: Problem{
   716  			Func: functions.PenaltyI{}.Func,
   717  			Grad: functions.PenaltyI{}.Grad,
   718  		},
   719  		x: []float64{0.1581, 0.1581, 0.1581, 0.1581, 0.1581, 0.1581,
   720  			0.1581, 0.1581, 0.1581, 0.1581},
   721  	},
   722  	{
   723  		name: "PenaltyII",
   724  		p: Problem{
   725  			Func: functions.PenaltyII{}.Func,
   726  			Grad: functions.PenaltyII{}.Grad,
   727  		},
   728  		x:       []float64{0.5, 0.5, 0.5, 0.5},
   729  		gradTol: 1e-10,
   730  	},
   731  	{
   732  		name: "PenaltyII",
   733  		p: Problem{
   734  			Func: functions.PenaltyII{}.Func,
   735  			Grad: functions.PenaltyII{}.Grad,
   736  		},
   737  		x:       []float64{0.19999, 0.19131, 0.4801, 0.51884},
   738  		gradTol: 1e-10,
   739  	},
   740  	{
   741  		name: "PenaltyII",
   742  		p: Problem{
   743  			Func: functions.PenaltyII{}.Func,
   744  			Grad: functions.PenaltyII{}.Grad,
   745  		},
   746  		x:       []float64{0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
   747  		gradTol: 1e-9,
   748  	},
   749  	{
   750  		name: "PenaltyII",
   751  		p: Problem{
   752  			Func: functions.PenaltyII{}.Func,
   753  			Grad: functions.PenaltyII{}.Grad,
   754  		},
   755  		x: []float64{0.19998, 0.01035, 0.01960, 0.03208, 0.04993, 0.07651,
   756  			0.11862, 0.19214, 0.34732, 0.36916},
   757  		gradTol: 1e-9,
   758  	},
   759  	{
   760  		name: "PowellBadlyScaled",
   761  		p: Problem{
   762  			Func: functions.PowellBadlyScaled{}.Func,
   763  			Grad: functions.PowellBadlyScaled{}.Grad,
   764  		},
   765  		x:       []float64{0, 1},
   766  		gradTol: 1e-10,
   767  	},
   768  	{
   769  		name: "PowellBadlyScaled",
   770  		p: Problem{
   771  			Func: functions.PowellBadlyScaled{}.Func,
   772  			Grad: functions.PowellBadlyScaled{}.Grad,
   773  		},
   774  		x:       []float64{1.09815e-05, 9.10614},
   775  		gradTol: 1e-10,
   776  	},
   777  	newVariablyDimensioned(100, 1e-10),
   778  	{
   779  		name: "Watson",
   780  		p: Problem{
   781  			Func: functions.Watson{}.Func,
   782  			Grad: functions.Watson{}.Grad,
   783  		},
   784  		x:       []float64{0, 0, 0, 0, 0, 0},
   785  		gradTol: 1e-7,
   786  	},
   787  	{
   788  		name: "Watson",
   789  		p: Problem{
   790  			Func: functions.Watson{}.Func,
   791  			Grad: functions.Watson{}.Grad,
   792  		},
   793  		x:       []float64{-0.01572, 1.01243, -0.23299, 1.26043, -1.51372, 0.99299},
   794  		gradTol: 1e-7,
   795  	},
   796  	{
   797  		name: "Watson",
   798  		p: Problem{
   799  			Func: functions.Watson{}.Func,
   800  			Grad: functions.Watson{}.Grad,
   801  		},
   802  		x:       []float64{0, 0, 0, 0, 0, 0, 0, 0, 0},
   803  		gradTol: 1e-8,
   804  	},
   805  	{
   806  		name: "Watson",
   807  		p: Problem{
   808  			Func: functions.Watson{}.Func,
   809  			Grad: functions.Watson{}.Grad,
   810  		},
   811  		x: []float64{-1.53070e-05, 0.99978, 0.01476, 0.14634, 1.00082,
   812  			-2.61773, 4.10440, -3.14361, 1.05262},
   813  		gradTol: 1e-8,
   814  	},
   815  }
   816  
   817  var bfgsTests = []unconstrainedTest{
   818  	{
   819  		name: "BiggsEXP6",
   820  		p: Problem{
   821  			Func: functions.BiggsEXP6{}.Func,
   822  			Grad: functions.BiggsEXP6{}.Grad,
   823  		},
   824  		x:       []float64{1, 2, 1, 1, 1, 1},
   825  		gradTol: 1e-10,
   826  	},
   827  	{
   828  		name: "BiggsEXP6",
   829  		p: Problem{
   830  			Func: functions.BiggsEXP6{}.Func,
   831  			Grad: functions.BiggsEXP6{}.Grad,
   832  		},
   833  		x:       []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001, 3.00001},
   834  		gradTol: 1e-10,
   835  	},
   836  	{
   837  		name: "BrownAndDennis",
   838  		p: Problem{
   839  			Func: functions.BrownAndDennis{}.Func,
   840  			Grad: functions.BrownAndDennis{}.Grad,
   841  		},
   842  		x:       []float64{25, 5, -5, -1},
   843  		gradTol: 1e-3,
   844  	},
   845  	{
   846  		name: "ExtendedRosenbrock",
   847  		p: Problem{
   848  			Func: functions.ExtendedRosenbrock{}.Func,
   849  			Grad: functions.ExtendedRosenbrock{}.Grad,
   850  		},
   851  		x:       []float64{1e5, 1e5},
   852  		gradTol: 1e-10,
   853  	},
   854  	{
   855  		name: "Gaussian",
   856  		p: Problem{
   857  			Func: functions.Gaussian{}.Func,
   858  			Grad: functions.Gaussian{}.Grad,
   859  		},
   860  		x:       []float64{0.398, 1, 0},
   861  		gradTol: 1e-11,
   862  	},
   863  	{
   864  		name: "Wood",
   865  		p: Problem{
   866  			Func: functions.Wood{}.Func,
   867  			Grad: functions.Wood{}.Grad,
   868  		},
   869  		x: []float64{-3, -1, -3, -1},
   870  	},
   871  }
   872  
   873  var lbfgsTests = []unconstrainedTest{
   874  	{
   875  		name: "BiggsEXP6",
   876  		p: Problem{
   877  			Func: functions.BiggsEXP6{}.Func,
   878  			Grad: functions.BiggsEXP6{}.Grad,
   879  		},
   880  		x:       []float64{1, 2, 1, 1, 1, 1},
   881  		gradTol: 1e-8,
   882  	},
   883  	{
   884  		name: "BiggsEXP6",
   885  		p: Problem{
   886  			Func: functions.BiggsEXP6{}.Func,
   887  			Grad: functions.BiggsEXP6{}.Grad,
   888  		},
   889  		x:       []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001, 3.00001},
   890  		gradTol: 1e-8,
   891  	},
   892  	{
   893  		name: "ExtendedRosenbrock",
   894  		p: Problem{
   895  			Func: functions.ExtendedRosenbrock{}.Func,
   896  			Grad: functions.ExtendedRosenbrock{}.Grad,
   897  		},
   898  		x:       []float64{1e7, 1e6},
   899  		gradTol: 1e-10,
   900  	},
   901  	{
   902  		name: "Gaussian",
   903  		p: Problem{
   904  			Func: functions.Gaussian{}.Func,
   905  			Grad: functions.Gaussian{}.Grad,
   906  		},
   907  		x:       []float64{0.398, 1, 0},
   908  		gradTol: 1e-10,
   909  	},
   910  	newVariablyDimensioned(1000, 1e-8),
   911  	newVariablyDimensioned(10000, 1e-5),
   912  }
   913  
   914  var newtonTests = []unconstrainedTest{
   915  	{
   916  		name: "Beale",
   917  		p: Problem{
   918  			Func: functions.Beale{}.Func,
   919  			Grad: functions.Beale{}.Grad,
   920  			Hess: functions.Beale{}.Hess,
   921  		},
   922  		x: []float64{1, 1},
   923  	},
   924  	{
   925  		name: "BrownAndDennis",
   926  		p: Problem{
   927  			Func: functions.BrownAndDennis{}.Func,
   928  			Grad: functions.BrownAndDennis{}.Grad,
   929  			Hess: functions.BrownAndDennis{}.Hess,
   930  		},
   931  		x:       []float64{25, 5, -5, -1},
   932  		gradTol: 1e-10,
   933  	},
   934  	{
   935  		name: "BrownBadlyScaled",
   936  		p: Problem{
   937  			Func: functions.BrownBadlyScaled{}.Func,
   938  			Grad: functions.BrownBadlyScaled{}.Grad,
   939  			Hess: functions.BrownBadlyScaled{}.Hess,
   940  		},
   941  		x:       []float64{1, 1},
   942  		gradTol: 1e-9,
   943  	},
   944  	{
   945  		name: "PowellBadlyScaled",
   946  		p: Problem{
   947  			Func: functions.PowellBadlyScaled{}.Func,
   948  			Grad: functions.PowellBadlyScaled{}.Grad,
   949  			Hess: functions.PowellBadlyScaled{}.Hess,
   950  		},
   951  		x:       []float64{0, 1},
   952  		gradTol: 1e-10,
   953  	},
   954  	{
   955  		name: "Watson",
   956  		p: Problem{
   957  			Func: functions.Watson{}.Func,
   958  			Grad: functions.Watson{}.Grad,
   959  			Hess: functions.Watson{}.Hess,
   960  		},
   961  		x: []float64{0, 0, 0, 0, 0, 0},
   962  	},
   963  	{
   964  		name: "Watson",
   965  		p: Problem{
   966  			Func: functions.Watson{}.Func,
   967  			Grad: functions.Watson{}.Grad,
   968  			Hess: functions.Watson{}.Hess,
   969  		},
   970  		x: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
   971  	},
   972  	{
   973  		name: "Wood",
   974  		p: Problem{
   975  			Func: functions.Wood{}.Func,
   976  			Grad: functions.Wood{}.Grad,
   977  			Hess: functions.Wood{}.Hess,
   978  		},
   979  		x: []float64{-3, -1, -3, -1},
   980  	},
   981  }
   982  
   983  func newVariablyDimensioned(dim int, gradTol float64) unconstrainedTest {
   984  	x := make([]float64, dim)
   985  	for i := range x {
   986  		x[i] = float64(dim-i-1) / float64(dim)
   987  	}
   988  	return unconstrainedTest{
   989  		name: "VariablyDimensioned",
   990  		p: Problem{
   991  			Func: functions.VariablyDimensioned{}.Func,
   992  			Grad: functions.VariablyDimensioned{}.Grad,
   993  		},
   994  		x:       x,
   995  		gradTol: gradTol,
   996  	}
   997  }
   998  
   999  func TestLocal(t *testing.T) {
  1000  	t.Parallel()
  1001  	var tests []unconstrainedTest
  1002  	// Mix of functions with and without Grad method.
  1003  	tests = append(tests, gradFreeTests...)
  1004  	tests = append(tests, gradientDescentTests...)
  1005  	testLocal(t, tests, nil)
  1006  }
  1007  
  1008  func TestNelderMead(t *testing.T) {
  1009  	t.Parallel()
  1010  	var tests []unconstrainedTest
  1011  	// Mix of functions with and without Grad method.
  1012  	tests = append(tests, gradFreeTests...)
  1013  	tests = append(tests, gradientDescentTests...)
  1014  	testLocal(t, tests, &NelderMead{})
  1015  }
  1016  
  1017  func TestGradientDescent(t *testing.T) {
  1018  	t.Parallel()
  1019  	testLocal(t, gradientDescentTests, &GradientDescent{})
  1020  }
  1021  
  1022  func TestGradientDescentBacktracking(t *testing.T) {
  1023  	t.Parallel()
  1024  	testLocal(t, gradientDescentTests, &GradientDescent{
  1025  		Linesearcher: &Backtracking{
  1026  			DecreaseFactor: 0.1,
  1027  		},
  1028  	})
  1029  }
  1030  
  1031  func TestGradientDescentBisection(t *testing.T) {
  1032  	t.Parallel()
  1033  	testLocal(t, gradientDescentTests, &GradientDescent{
  1034  		Linesearcher: &Bisection{},
  1035  	})
  1036  }
  1037  
  1038  func TestCG(t *testing.T) {
  1039  	t.Parallel()
  1040  	var tests []unconstrainedTest
  1041  	tests = append(tests, gradientDescentTests...)
  1042  	tests = append(tests, cgTests...)
  1043  	testLocal(t, tests, &CG{})
  1044  }
  1045  
  1046  func TestFletcherReevesQuadStep(t *testing.T) {
  1047  	t.Parallel()
  1048  	var tests []unconstrainedTest
  1049  	tests = append(tests, gradientDescentTests...)
  1050  	tests = append(tests, cgTests...)
  1051  	testLocal(t, tests, &CG{
  1052  		Variant:     &FletcherReeves{},
  1053  		InitialStep: &QuadraticStepSize{},
  1054  	})
  1055  }
  1056  
  1057  func TestFletcherReevesFirstOrderStep(t *testing.T) {
  1058  	t.Parallel()
  1059  	var tests []unconstrainedTest
  1060  	tests = append(tests, gradientDescentTests...)
  1061  	tests = append(tests, cgTests...)
  1062  	testLocal(t, tests, &CG{
  1063  		Variant:     &FletcherReeves{},
  1064  		InitialStep: &FirstOrderStepSize{},
  1065  	})
  1066  }
  1067  
  1068  func TestHestenesStiefelQuadStep(t *testing.T) {
  1069  	t.Parallel()
  1070  	var tests []unconstrainedTest
  1071  	tests = append(tests, gradientDescentTests...)
  1072  	tests = append(tests, cgTests...)
  1073  	testLocal(t, tests, &CG{
  1074  		Variant:     &HestenesStiefel{},
  1075  		InitialStep: &QuadraticStepSize{},
  1076  	})
  1077  }
  1078  
  1079  func TestHestenesStiefelFirstOrderStep(t *testing.T) {
  1080  	t.Parallel()
  1081  	var tests []unconstrainedTest
  1082  	tests = append(tests, gradientDescentTests...)
  1083  	tests = append(tests, cgTests...)
  1084  	testLocal(t, tests, &CG{
  1085  		Variant:     &HestenesStiefel{},
  1086  		InitialStep: &FirstOrderStepSize{},
  1087  	})
  1088  }
  1089  
  1090  func TestPolakRibiereQuadStep(t *testing.T) {
  1091  	t.Parallel()
  1092  	var tests []unconstrainedTest
  1093  	tests = append(tests, gradientDescentTests...)
  1094  	tests = append(tests, cgTests...)
  1095  	testLocal(t, tests, &CG{
  1096  		Variant:     &PolakRibierePolyak{},
  1097  		InitialStep: &QuadraticStepSize{},
  1098  	})
  1099  }
  1100  
  1101  func TestPolakRibiereFirstOrderStep(t *testing.T) {
  1102  	t.Parallel()
  1103  	var tests []unconstrainedTest
  1104  	tests = append(tests, gradientDescentTests...)
  1105  	tests = append(tests, cgTests...)
  1106  	testLocal(t, tests, &CG{
  1107  		Variant:     &PolakRibierePolyak{},
  1108  		InitialStep: &FirstOrderStepSize{},
  1109  	})
  1110  }
  1111  
  1112  func TestDaiYuanQuadStep(t *testing.T) {
  1113  	t.Parallel()
  1114  	var tests []unconstrainedTest
  1115  	tests = append(tests, gradientDescentTests...)
  1116  	tests = append(tests, cgTests...)
  1117  	testLocal(t, tests, &CG{
  1118  		Variant:     &DaiYuan{},
  1119  		InitialStep: &QuadraticStepSize{},
  1120  	})
  1121  }
  1122  
  1123  func TestDaiYuanFirstOrderStep(t *testing.T) {
  1124  	t.Parallel()
  1125  	var tests []unconstrainedTest
  1126  	tests = append(tests, gradientDescentTests...)
  1127  	tests = append(tests, cgTests...)
  1128  	testLocal(t, tests, &CG{
  1129  		Variant:     &DaiYuan{},
  1130  		InitialStep: &FirstOrderStepSize{},
  1131  	})
  1132  }
  1133  
  1134  func TestHagerZhangQuadStep(t *testing.T) {
  1135  	t.Parallel()
  1136  	var tests []unconstrainedTest
  1137  	tests = append(tests, gradientDescentTests...)
  1138  	tests = append(tests, cgTests...)
  1139  	testLocal(t, tests, &CG{
  1140  		Variant:     &HagerZhang{},
  1141  		InitialStep: &QuadraticStepSize{},
  1142  	})
  1143  }
  1144  
  1145  func TestHagerZhangFirstOrderStep(t *testing.T) {
  1146  	t.Parallel()
  1147  	var tests []unconstrainedTest
  1148  	tests = append(tests, gradientDescentTests...)
  1149  	tests = append(tests, cgTests...)
  1150  	testLocal(t, tests, &CG{
  1151  		Variant:     &HagerZhang{},
  1152  		InitialStep: &FirstOrderStepSize{},
  1153  	})
  1154  }
  1155  
  1156  func TestBFGS(t *testing.T) {
  1157  	t.Parallel()
  1158  	var tests []unconstrainedTest
  1159  	tests = append(tests, gradientDescentTests...)
  1160  	tests = append(tests, quasiNewtonTests...)
  1161  	tests = append(tests, bfgsTests...)
  1162  	testLocal(t, tests, &BFGS{})
  1163  }
  1164  
  1165  func TestLBFGS(t *testing.T) {
  1166  	t.Parallel()
  1167  	var tests []unconstrainedTest
  1168  	tests = append(tests, gradientDescentTests...)
  1169  	tests = append(tests, quasiNewtonTests...)
  1170  	tests = append(tests, lbfgsTests...)
  1171  	testLocal(t, tests, &LBFGS{})
  1172  }
  1173  
  1174  func TestNewton(t *testing.T) {
  1175  	t.Parallel()
  1176  	testLocal(t, newtonTests, &Newton{})
  1177  }
  1178  
  1179  func testLocal(t *testing.T, tests []unconstrainedTest, method Method) {
  1180  	for cas, test := range tests {
  1181  		if test.long && testing.Short() {
  1182  			continue
  1183  		}
  1184  
  1185  		settings := &Settings{}
  1186  		settings.Converger = defaultFunctionConverge()
  1187  		var uses Available
  1188  		if method != nil {
  1189  			var err error
  1190  			has := availFromProblem(test.p)
  1191  			uses, err = method.Uses(has)
  1192  			if err != nil {
  1193  				t.Errorf("problem and method mismatch: %v", err)
  1194  				continue
  1195  			}
  1196  		}
  1197  		if method != nil {
  1198  			// Turn off function convergence checks for gradient-based methods.
  1199  			if uses.Grad {
  1200  				settings.Converger = NeverTerminate{}
  1201  			}
  1202  		} else {
  1203  			if test.fIter == 0 {
  1204  				test.fIter = 20
  1205  			}
  1206  			c := settings.Converger.(*FunctionConverge)
  1207  			c.Iterations = test.fIter
  1208  			if test.fAbsTol == 0 {
  1209  				test.fAbsTol = 1e-12
  1210  			}
  1211  			c.Absolute = test.fAbsTol
  1212  			settings.Converger = c
  1213  		}
  1214  		if test.gradTol == 0 {
  1215  			test.gradTol = 1e-12
  1216  		}
  1217  		settings.GradientThreshold = test.gradTol
  1218  
  1219  		result, err := Minimize(test.p, test.x, settings, method)
  1220  		if err != nil {
  1221  			t.Errorf("Case %d: error finding minimum (%v) for:\n%v", cas, err, test)
  1222  			continue
  1223  		}
  1224  		if result == nil {
  1225  			t.Errorf("Case %d: nil result without error for:\n%v", cas, test)
  1226  			continue
  1227  		}
  1228  
  1229  		// Check that the function value at the found optimum location is
  1230  		// equal to result.F.
  1231  		optF := test.p.Func(result.X)
  1232  		if optF != result.F {
  1233  			t.Errorf("Case %d: Function value at the optimum location %v not equal to the returned value %v for:\n%v",
  1234  				cas, optF, result.F, test)
  1235  		}
  1236  		if result.Gradient != nil {
  1237  			// Evaluate the norm of the gradient at the found optimum location.
  1238  			g := make([]float64, len(test.x))
  1239  			test.p.Grad(g, result.X)
  1240  
  1241  			if !floats.Equal(result.Gradient, g) {
  1242  				t.Errorf("Case %d: Gradient at the optimum location not equal to the returned value for:\n%v", cas, test)
  1243  			}
  1244  
  1245  			optNorm := floats.Norm(g, math.Inf(1))
  1246  			// Check that the norm of the gradient at the found optimum location is
  1247  			// smaller than the tolerance.
  1248  			if optNorm >= settings.GradientThreshold {
  1249  				t.Errorf("Case %d: Norm of the gradient at the optimum location %v not smaller than tolerance %v for:\n%v",
  1250  					cas, optNorm, settings.GradientThreshold, test)
  1251  			}
  1252  		}
  1253  
  1254  		if method == nil {
  1255  			// The tests below make sense only if the method used is known.
  1256  			continue
  1257  		}
  1258  
  1259  		if !uses.Grad && !uses.Hess {
  1260  			// Gradient-free tests can correctly terminate only with
  1261  			// FunctionConvergence status.
  1262  			if result.Status != FunctionConvergence {
  1263  				t.Errorf("Status not %v, %v instead", FunctionConvergence, result.Status)
  1264  			}
  1265  		}
  1266  
  1267  		// We are going to restart the solution using known initial data, so
  1268  		// evaluate them.
  1269  		settings.InitValues = &Location{}
  1270  		settings.InitValues.F = test.p.Func(test.x)
  1271  		if uses.Grad {
  1272  			settings.InitValues.Gradient = resize(settings.InitValues.Gradient, len(test.x))
  1273  			test.p.Grad(settings.InitValues.Gradient, test.x)
  1274  		}
  1275  		if uses.Hess {
  1276  			settings.InitValues.Hessian = mat.NewSymDense(len(test.x), nil)
  1277  			test.p.Hess(settings.InitValues.Hessian, test.x)
  1278  		}
  1279  
  1280  		// Rerun the test again to make sure that it gets the same answer with
  1281  		// the same starting condition. Moreover, we are using the initial data.
  1282  		result2, err2 := Minimize(test.p, test.x, settings, method)
  1283  		if err2 != nil {
  1284  			t.Errorf("error finding minimum second time (%v) for:\n%v", err2, test)
  1285  			continue
  1286  		}
  1287  		if result2 == nil {
  1288  			t.Errorf("second time nil result without error for:\n%v", test)
  1289  			continue
  1290  		}
  1291  
  1292  		// At the moment all the optimizers are deterministic, so check that we
  1293  		// get _exactly_ the same answer second time as well.
  1294  		if result.F != result2.F || !floats.Equal(result.X, result2.X) {
  1295  			t.Errorf("Different minimum second time for:\n%v", test)
  1296  		}
  1297  
  1298  		// Check that providing initial data reduces the number of evaluations exactly by one.
  1299  		if result.FuncEvaluations != result2.FuncEvaluations+1 {
  1300  			t.Errorf("Providing initial data does not reduce the number of Func calls for:\n%v", test)
  1301  			continue
  1302  		}
  1303  		if uses.Grad {
  1304  			if result.GradEvaluations != result2.GradEvaluations+1 {
  1305  				t.Errorf("Providing initial data does not reduce the number of Grad calls for:\n%v", test)
  1306  				continue
  1307  			}
  1308  		}
  1309  		if uses.Hess {
  1310  			if result.HessEvaluations != result2.HessEvaluations+1 {
  1311  				t.Errorf("Providing initial data does not reduce the number of Hess calls for:\n%v", test)
  1312  				continue
  1313  			}
  1314  		}
  1315  	}
  1316  }
  1317  
  1318  func TestIssue76(t *testing.T) {
  1319  	t.Parallel()
  1320  	p := Problem{
  1321  		Func: functions.BrownAndDennis{}.Func,
  1322  		Grad: functions.BrownAndDennis{}.Grad,
  1323  	}
  1324  	// Location very close to the minimum.
  1325  	x := []float64{-11.594439904886773, 13.203630051265385, -0.40343948776868443, 0.2367787746745986}
  1326  	s := &Settings{
  1327  		MajorIterations: 1000000,
  1328  	}
  1329  	m := &GradientDescent{
  1330  		GradStopThreshold: 1e-14,
  1331  		Linesearcher:      &Backtracking{},
  1332  	}
  1333  	// We are not interested in the error, only in the returned status.
  1334  	r, _ := Minimize(p, x, s, m)
  1335  	// With the above stringent tolerance, the optimizer will never
  1336  	// successfully reach the minimum. Check if it terminated in a finite
  1337  	// number of steps.
  1338  	if r.Status == IterationLimit {
  1339  		t.Error("Issue https://github.com/gonum/optimize/issues/76 not fixed")
  1340  	}
  1341  }
  1342  
  1343  func TestNelderMeadOneD(t *testing.T) {
  1344  	t.Parallel()
  1345  	p := Problem{
  1346  		Func: func(x []float64) float64 { return x[0] * x[0] },
  1347  	}
  1348  	x := []float64{10}
  1349  	m := &NelderMead{}
  1350  	var s *Settings
  1351  	result, err := Minimize(p, x, s, m)
  1352  	if err != nil {
  1353  		t.Errorf(err.Error())
  1354  	}
  1355  	if !floats.EqualApprox(result.X, []float64{0}, 1e-10) {
  1356  		t.Errorf("Minimum not found")
  1357  	}
  1358  	if m.reflection != 1 {
  1359  		t.Errorf("Wrong value of reflection")
  1360  	}
  1361  	if m.expansion != 2 {
  1362  		t.Errorf("Wrong value of expansion")
  1363  	}
  1364  	if m.contraction != 0.5 {
  1365  		t.Errorf("Wrong value of contraction")
  1366  	}
  1367  	if m.shrink != 0.5 {
  1368  		t.Errorf("Wrong value of shrink")
  1369  	}
  1370  }