// Iterate mutates m and so for each iteration, the same, mutated m should be // passed in. func (m *Method) Iterate(o optim.Objectiver, mesh optim.Mesh) (best *optim.Point, n int, err error) { if m.count == 0 { m.origstep = mesh.Step() } else if mesh.Step() < m.ResetStep { mesh.SetStep(m.ResetStepSize) } var nevalsearch, nevalpoll int var success bool defer m.updateDb(&nevalsearch, &nevalpoll, mesh.Step()) m.count++ prevstep := mesh.Step() if !m.DiscreteSearch { mesh.SetStep(0) } success, best, nevalsearch, err = m.Searcher.Search(o, mesh, m.Curr) mesh.SetStep(prevstep) n += nevalsearch if success { m.Curr = best return best, n, err } // It is important to recenter mesh on new best point before polling. // This is necessary because the search may not be operating on the // current mesh grid. This doesn't need to happen if search succeeds // because search either always operates on the same grid, or always // operates in continuous space. mesh.SetOrigin(m.Curr.Pos) // TODO: test that this doesn't get set to Zero pos [0 0 0...] on first iteration. var err2 error success, best, nevalpoll, err2 = m.Poller.Poll(o, m.ev, mesh, m.Curr) m.Poller.Spanner.Update(mesh.Step(), success) n += nevalpoll if success { m.Curr = best m.nsuccess++ if m.nsuccess == m.NsuccessGrow { // == allows -1 to mean never grow mesh.SetStep(mesh.Step() / m.StepMult) m.nsuccess = 0 // reset after resize } // Important to recenter mesh on new best point. More particularly, // the mesh may have been resized and the new best may not lie on the // previous mesh grid. mesh.SetOrigin(best.Pos) return best, n, collect(err, err2) } else { m.nsuccess = 0 if nextstep := mesh.Step() * m.StepMult; nextstep > 0 { mesh.SetStep(mesh.Step() * m.StepMult) } return m.Curr, n, collect(err, err2) } }