@@ -65,7 +65,6 @@ class COBYLA(BaseOptimizer):
6565 def _generate_initial_simplex (self , x_0_initial , rho_beg ):
6666 n = x_0_initial .shape [0 ]
6767 arr = np .ones ((n + 1 , 1 )) * x_0_initial + rho_beg * np .eye (n + 1 , n )
68- print (arr )
6968 return arr
7069
7170 def _vertices_to_oppsite_face_distances (self ):
@@ -76,9 +75,6 @@ def _vertices_to_oppsite_face_distances(self):
7675 For each vertex, the opposite hyperplane is obtained after removing the current
7776 vertex and then finding the projection on the subspace spanned by the hyperplane.
7877 The distance is then the L2 norm between projection and the current vertex.
79-
80- Args:
81- self: instance of current COBYLA class
8278
8379 Returns:
8480 distances: (n+1,) array of distances from each vertex to its opposite face.
@@ -96,27 +92,65 @@ def _vertices_to_oppsite_face_distances(self):
9692 return distances
9793
9894 def _is_simplex_acceptable (self ):
95+ """
96+ Determine whether the current simplex is acceptable according to COBYLA criteria.
97+
98+ In COBYLA, a simplex is acceptable if:
99+ 1. The distances between each vertex and the first vertex (η_j) do not exceed
100+ a threshold defined by `beta * rho`, controlling simplex edge lengths.
101+ 2. The distance from each vertex to its opposite (n-1)-dimensional face (σ_j)
102+ is not too small, ensuring the simplex is well-shaped. These distances must
103+ exceed a threshold given by `alpha * rho`.
104+
105+ This function enforces these two geometric conditions to ensure that the simplex
106+ maintains good numerical stability and approximation quality.
107+
108+ Returns:
109+ bool: True if both η and σ conditions are satisfied, False otherwise.
110+ """
99111 eta = [np .linalg .norm (x - self .simplex [0 ]) for x in self .simplex ]
100112 eta_constraint = self .beta * self ._rho
101113 for eta_j in eta :
102114 if eta_j > eta_constraint :
103115 return False
104116 sigma = self ._vertices_to_oppsite_face_distances ()
105117 sigma_constraint = self .alpha * self ._rho
106- print (sigma )
107118 for sigma_j in sigma :
108119 if sigma_j < sigma_constraint :
109120 return False
110121 return True
111122
112123 def _eval_constraints (self , pos ):
113- # TODO: evalute constraints in optimized way
114-
115- return None
124+ """
125+ Evaluates constraints for the given position
126+
127+ Returns:
128+ np.array: array containing the evaluated value of constraints
129+ """
130+ return [np .clip (f (pos ), 0 , np .inf ) for f in self .constraints ]
131+
132+ def _phi (self , pos ):
133+ """
134+ Compute the merit function Φ used in COBYLA to evaluate candidate points. Given by:
135+
136+ Φ(x) = f(x) + μ * max(c_i(x))
137+
138+ Args:
139+ pos (np.array): The point in parameter space at which to evaluate the merit function.
140+
141+ Returns:
142+ float: The value of the merit function Φ at the given point.
143+ """
144+ c = self ._eval_constraints (pos )
145+ return self .objective_function (pos ) + self .mu * np .max (c )
116146
117- def _merit_value (self , pos ):
118- # TODO: write the merit function using the _eval_constraints
119- return 0
147+ def _rearrange_optimum_to_top (self ):
148+ """
149+ Rearrages simplex vertices such that first row is the optimal position
150+ """
151+ opt_idx = np .argmin ([self ._phi (vert ) for vert in self .simplex ])
152+ if opt_idx != 0 :
153+ self .simplex [[0 , opt_idx ]] = self .simplex [[opt_idx , 0 ]]
120154
121155 def __init__ (
122156 self ,
@@ -130,7 +164,7 @@ def __init__(
130164 rand_rest_p = 0 ,
131165 nth_process = None ,
132166 alpha = 0.25 ,
133- beta = 2.1
167+ beta = 2.1 ,
134168 ):
135169 super ().__init__ (
136170 search_space = search_space ,
@@ -145,6 +179,8 @@ def __init__(
145179 self .rho_beg = rho_beg
146180 self .rho_end = rho_end
147181 self ._rho = rho_beg
182+
183+ self ._mu = 0
148184 self .state = 0
149185 self .FLAG = 0
150186
@@ -167,7 +203,7 @@ def _score(self, pos):
167203
168204 def evaluate (self , pos ):
169205 # TODO: Impl
170- return self ._merit_value (pos )
206+ return self ._phi (pos )
171207
172208 def finish_search (self ):
173209 # TODO: Impl
0 commit comments