Remove InitMean from CmaEsChol and use the value passed to Minimize instead
MODIFY
optimize/cmaes.go
optimize/cmaes.go
@@ -31,7 +31,9 @@ import (
// normal distribution to generate a population of input locations. The input locations
// with the lowest function values are used to update the parameters of the normal
// distribution, a new set of input locations are generated, and this procedure
-// is iterated until convergence.
+// is iterated until convergence. The initial sampling distribution will have
+// a mean specified by the initial x location, and a covariance specified by
+// the InitCholesky field.
//
// As the normal distribution is progressively updated according to the best samples,
// it can be that the mean of the distribution is updated in a gradient-descent
@@ -57,10 +59,6 @@ type CmaEsChol struct {
// 0, a default value of 4 + math.Floor(3*math.Log(float64(dim))) is used.
// Population cannot be negative or CmaEsChol will panic.
Population int
- // InitMean is the initial mean of the multivariate normal for sampling
- // input locations. If InitMean is nil, the zero vector is used. If InitMean
- // is not nil, it must have length equal to the problem dimension.
- InitMean []float64
// InitCholesky specifies the Cholesky decomposition of the covariance
// matrix for the initial sampling distribution. If InitCholesky is nil,
// a default value of I is used. If it is non-nil, then it must have
@@ -151,10 +149,6 @@ func (cma *CmaEsChol) Init(dim, tasks int) int {
if tasks < 0 {
panic(negativeTasks)
}
- // Initialize the parameters
- if cma.InitMean != nil && len(cma.InitMean) != dim {
- panic("cma-es-chol: initial mean must be nil or have length equal to dimension")
- }
// Set fixed algorithm parameters.
// Parameter values are from https://arxiv.org/pdf/1604.00772.pdf .
@@ -207,10 +201,8 @@ func (cma *CmaEsChol) Init(dim, tasks int) int {
for i := range cma.ps {
cma.ps[i] = 0
}
- cma.mean = resize(cma.mean, dim)
- if cma.InitMean != nil {
- copy(cma.mean, cma.InitMean)
- }
+ cma.mean = resize(cma.mean, dim) // mean location initialized at the start of Run
+
if cma.InitCholesky != nil {
if cma.InitCholesky.Size() != dim {
panic("cma-es-chol: incorrect InitCholesky size")
@@ -302,6 +294,7 @@ func (cma *CmaEsChol) findBestAndUpdateTask(task Task) Task {
}
func (cma *CmaEsChol) Run(operations chan<- Task, results <-chan Task, tasks []Task) {
+ copy(cma.mean, tasks[0].X)
cma.operation = operations
// Send the initial tasks. We know there are at most as many tasks as elements
// of the population.

MODIFY
optimize/cmaes_test.go
optimize/cmaes_test.go
@@ -20,6 +20,7 @@ type cmaTestCase struct {
dim int
problem Problem
method *CmaEsChol
+ initX []float64
settings *Settings
good func(result *Result, err error, concurrent int) error
}
@@ -163,9 +164,9 @@ func cmaTestCases() []cmaTestCase {
problem: Problem{
Func: functions.Rastrigin{}.Func,
},
+ initX: localMinMean,
method: &CmaEsChol{
Population: 100, // Increase the population size to reduce noise.
- InitMean: localMinMean,
InitCholesky: &localMinChol,
ForgetBest: true, // So that if it accidentally finds a better place we still converge to the minimum.
},
@@ -190,7 +191,7 @@ func TestCmaEsChol(t *testing.T) {
src := rand.New(rand.NewSource(1))
method := test.method
method.Src = src
- initX := method.InitMean
+ initX := test.initX
if initX == nil {
initX = make([]float64, test.dim)
}

MODIFY
optimize/global.go
optimize/global.go
@@ -76,7 +76,7 @@ type Method interface {
Run(operation chan<- Task, result <-chan Task, tasks []Task)
}
-// Minimize uses an optimizer to search for the minimum of a function. A
+// Minimize uses an optimizer to search for a minimum of a function. A
// maximization problem can be transformed into a minimization problem by
// multiplying the function by -1.
//
@@ -97,9 +97,9 @@ type Method interface {
// specified for the dimension of the optimization problem.
//
// The third argument contains the settings for the minimization. The
-// DefaultLocalSettings and DefaultGlobalSettings functions can be called for
+// DefaultSettingsLocal and DefaultSettingsGlobal functions can be called for
// different default settings depending on the optimization method. If
-// settings == nil, the default settings are used. All settings will be honored
+// settings is nil, DefaultSettingsLocal is used. All settings will be honored
// for all Methods, even if that setting is counter-productive to the method.
// However, the information used to check the Settings, and the times at which
// they are checked, are controlled by the Method. For example, if the Method

MODIFY
optimize/types.go
optimize/types.go
@@ -166,7 +166,7 @@ func (p Problem) satisfies(method Needser) error {
//
// If Recorder is nil, no information will be recorded.
type Settings struct {
- // InitValues specifies properties (function value, gradient, etc.). known
+ // InitValues specifies properties (function value, gradient, etc.) known
// at the initial location passed to Minimize. If InitValues is non-nil, then
// the function value F must be provided, the location X must not be specified
// and other fields may be specified.

Remove InitMean from CmaEsChol and use the value passed to Minimize instead