Skip to content

Commit 93fc99f

Browse files
committed
fix 'golden section search'
1 parent 9ce0deb commit 93fc99f

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

src/gradient_free_optimizers/optimizers/global_opt/powells_method/powells_method.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ def finish_initialization(self):
117117

118118
# Line search state
119119
self.line_search_step = 0
120+
self.direction_search_active = False # Flag to track if search is in progress
120121
self.grid_positions = [] # Pre-generated positions for grid search
121122
self.evaluated_positions = [] # Positions that have been evaluated
122123
self.evaluated_scores = [] # Corresponding scores
@@ -211,6 +212,7 @@ def _start_direction_search(self):
211212
self.direction_start_pos = self.pos_current.copy()
212213
self.direction_start_score = self.score_current
213214
self.line_search_step = 0
215+
self.direction_search_active = True # Flag to track if search is in progress
214216

215217
# Separate lists: positions to evaluate vs evaluated results
216218
self.grid_positions = [] # Pre-generated positions for grid search
@@ -225,22 +227,31 @@ def _start_direction_search(self):
225227
)
226228
elif self.line_search_method == "golden":
227229
# Initialize golden section state
230+
# Standard golden section: a < c < d < b
231+
# c = a + (1-phi)(b-a), d = a + phi(b-a) where phi ≈ 0.618
228232
direction = self.directions[self.current_direction_idx]
229233
max_t = self._compute_max_step(
230234
self.direction_start_pos, direction.direction
231235
)
236+
a = -max_t
237+
b = max_t
238+
# Use 1-GOLDEN_RATIO for c so that c < d
239+
c = a + (1 - GOLDEN_RATIO) * (b - a) # ≈ a + 0.382*(b-a)
240+
d = a + GOLDEN_RATIO * (b - a) # ≈ a + 0.618*(b-a)
232241
self.golden_state = {
233-
"a": -max_t,
234-
"b": max_t,
235-
"c": -max_t + GOLDEN_RATIO * (2 * max_t),
236-
"d": max_t - GOLDEN_RATIO * (2 * max_t),
242+
"a": a,
243+
"b": b,
244+
"c": c,
245+
"d": d,
237246
"fc": None,
238247
"fd": None,
239248
"phase": "eval_c",
240249
}
241250

242251
def _finish_direction_search(self):
243252
"""Complete the search along current direction and move to best position."""
253+
self.direction_search_active = False # Mark search as complete
254+
244255
if self.evaluated_scores:
245256
best_idx = np.argmax(self.evaluated_scores)
246257
best_score = self.evaluated_scores[best_idx]
@@ -330,23 +341,32 @@ def _update_golden_state(self, score):
330341
self._golden_narrow_bracket()
331342

332343
def _golden_narrow_bracket(self):
333-
"""Narrow the bracket in golden section search."""
344+
"""Narrow the bracket in golden section search.
345+
346+
With c < d (standard golden section layout):
347+
- If f(c) > f(d): maximum in [a, d], narrow right side
348+
- If f(d) >= f(c): maximum in [c, b], narrow left side
349+
"""
334350
state = self.golden_state
335351

336352
if state["fc"] > state["fd"]:
337353
# Maximum is in [a, d], narrow from right
354+
# New bracket: [a, d], reuse c as new d
338355
state["b"] = state["d"]
339356
state["d"] = state["c"]
340357
state["fd"] = state["fc"]
341-
state["c"] = state["a"] + GOLDEN_RATIO * (state["b"] - state["a"])
358+
# Calculate new c: c = a + (1-phi)(b-a)
359+
state["c"] = state["a"] + (1 - GOLDEN_RATIO) * (state["b"] - state["a"])
342360
state["fc"] = None
343361
state["phase"] = "eval_c"
344362
else:
345363
# Maximum is in [c, b], narrow from left
364+
# New bracket: [c, b], reuse d as new c
346365
state["a"] = state["c"]
347366
state["c"] = state["d"]
348367
state["fc"] = state["fd"]
349-
state["d"] = state["b"] - GOLDEN_RATIO * (state["b"] - state["a"])
368+
# Calculate new d: d = a + phi(b-a)
369+
state["d"] = state["a"] + GOLDEN_RATIO * (state["b"] - state["a"])
350370
state["fd"] = None
351371
state["phase"] = "eval_d"
352372

@@ -383,7 +403,7 @@ def iterate(self):
383403
self._start_direction_search()
384404

385405
# Check if we need to start searching a new direction
386-
if self.line_search_step == 0 and not self.grid_positions:
406+
if not self.direction_search_active:
387407
if self.cycle_start_pos is None:
388408
self._start_new_cycle()
389409
self._start_direction_search()

0 commit comments

Comments
 (0)