Skip to content

Commit e796e01

Browse files
authored
fix: Division-by-zero while initializing CMAES (#86)
While computing its default C decomposition frequency, under some conditions (e.g. with a problem of solution length 1000), initialization of CMAES failed due to division-by-zero. This commit aims to fix this issue.
1 parent 9d31d59 commit e796e01

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

src/evotorch/algorithms/cmaes.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
This namespace contains the CMAES class
1919
"""
2020

21-
from typing import Optional, Tuple
21+
from typing import Optional, Tuple, Union
2222

2323
import numpy as np
2424
import torch
@@ -80,6 +80,13 @@ def _limit_stdev(sigma: torch.Tensor, C: torch.Tensor, stdev_min: Optional[float
8080
return C
8181

8282

83+
def _safe_divide(a: Union[Real, torch.Tensor], b: Union[Real, torch.Tensor]) -> Union[torch.Tensor]:
84+
tolerance = 1e-8
85+
if abs(b) < tolerance:
86+
b = (-tolerance) if b < 0 else tolerance
87+
return a / b
88+
89+
8390
class CMAES(SearchAlgorithm, SinglePopulationAlgorithmMixin):
8491
"""
8592
CMAES: Covariance Matrix Adaptation Evolution Strategy.
@@ -360,9 +367,11 @@ def __init__(
360367
# Note that we could use the exact formulation with Gamma functions, but we'll retain this form for consistency
361368
self.unbiased_expectation = np.sqrt(d) * (1 - (1 / (4 * d)) + 1 / (21 * d**2))
362369

370+
self.last_ex = None
371+
363372
# How often to decompose C
364373
if limit_C_decomposition:
365-
self.decompose_C_freq = max(1, int(1 / np.floor(10 * d * (self.c_1.cpu() + self.c_mu.cpu()))))
374+
self.decompose_C_freq = max(1, int(np.floor(_safe_divide(1, 10 * d * (self.c_1.cpu() + self.c_mu.cpu())))))
366375
else:
367376
self.decompose_C_freq = 1
368377

0 commit comments

Comments
 (0)