Skip to content

Commit 9ce0deb

Browse files
committed
complete reimplementation of powell's method
1 parent a3eb18e commit 9ce0deb

File tree

3 files changed

+450
-85
lines changed

3 files changed

+450
-85
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55

66
from .powells_method import PowellsMethod
7+
from .direction import Direction
78

89

910
__all__ = [
1011
"PowellsMethod",
12+
"Direction",
1113
]

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

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,86 @@
22
# Email: simon.blanke@yahoo.com
33
# License: MIT License
44

5+
import numpy as np
6+
57

68
class Direction:
7-
def __init__(self, position_1, position_2) -> None:
9+
"""
10+
Represents a search direction for Powell's method.
11+
12+
This class handles movement along an arbitrary direction vector in the
13+
search space, supporting line searches for 1D optimization.
14+
"""
15+
16+
def __init__(self, direction_vector: np.ndarray):
817
"""
9-
Parameters:
10-
- position_1: dict, starting point in the search-space
11-
- position_2: dict, end point in the search-space
18+
Initialize a direction for line search.
19+
20+
Parameters
21+
----------
22+
direction_vector : np.ndarray
23+
The direction vector to search along. Will be normalized.
1224
"""
25+
norm = np.linalg.norm(direction_vector)
26+
if norm < 1e-10:
27+
raise ValueError("Direction vector cannot be zero")
28+
self.direction = direction_vector / norm
29+
30+
def get_position_at(self, origin: np.ndarray, t: float) -> np.ndarray:
31+
"""
32+
Calculate position along the direction from an origin point.
33+
34+
Parameters
35+
----------
36+
origin : np.ndarray
37+
Starting position in search space
38+
t : float
39+
Step size along the direction (can be negative)
1340
14-
self.position_1 = position_1
15-
self.position_2 = position_2
41+
Returns
42+
-------
43+
np.ndarray
44+
New position: origin + t * direction
45+
"""
46+
return origin + t * self.direction
47+
48+
@classmethod
49+
def from_two_points(cls, position_1: np.ndarray, position_2: np.ndarray):
50+
"""
51+
Create a Direction from two points in the search space.
52+
53+
Parameters
54+
----------
55+
position_1 : np.ndarray
56+
Starting point
57+
position_2 : np.ndarray
58+
End point
59+
60+
Returns
61+
-------
62+
Direction
63+
Direction pointing from position_1 to position_2
64+
"""
65+
direction_vector = position_2 - position_1
66+
return cls(direction_vector)
1667

17-
def get_new_position(self, t):
68+
@classmethod
69+
def coordinate_axis(cls, dimension: int, n_dimensions: int):
1870
"""
19-
Calculate a position on the line (vector) between two positions using parameter t.
71+
Create a Direction along a coordinate axis.
2072
21-
Parameters:
22-
- t: float, parameter indicating the position along the line (0 <= t <= 1 for within the line segment)
73+
Parameters
74+
----------
75+
dimension : int
76+
Which axis (0-indexed)
77+
n_dimensions : int
78+
Total number of dimensions
2379
24-
Returns:
25-
- dict representing the new position in the search-space coordinate system
80+
Returns
81+
-------
82+
Direction
83+
Unit vector along the specified axis
2684
"""
27-
new_position = {}
28-
for dim in self.position_1:
29-
# Calculate the position along the line in each dimension
30-
new_position[dim] = self.position_1[dim] + t * (
31-
self.position_2[dim] - self.position_1[dim]
32-
)
33-
return new_position
85+
direction_vector = np.zeros(n_dimensions)
86+
direction_vector[dimension] = 1.0
87+
return cls(direction_vector)

0 commit comments

Comments
 (0)