Description of the bug
Affects master (checked at commit 48b48c3), mealpy/swarm_based/WSO.py.
The persistent velocity state is initialized once (self.v = np.zeros(...), around l. 106) and the updated velocity is computed into a local variable v (around l. 133):
python
v = self.mu * (self.v + p1 * (...) * c1 + p2 * (...) * c2)
but v is never written back to self.v. The recurrent term self.v therefore remains exactly zero for the entire run, and the algorithm silently degrades from the momentum-based search of Braik et al. (2022) to a memoryless attraction toward the best-known positions.
Steps To Reproduce
-
Run this snippet (any recent mealpy):
python
import numpy as np
from mealpy import FloatVar
from mealpy.swarm_based.WSO import OriginalWSO
prob = {"obj_func": lambda x: float(np.sum(np.asarray(x)**2)),
"bounds": FloatVar(lb=[-5]*5, ub=[5]*5), "minmax": "min", "log_to": None}
m = OriginalWSO(epoch=30, pop_size=10)
m.solve(prob, seed=1)
print(np.abs(np.asarray(m.v)).max()) # prints 0.0 after 30 epochs
-
Observe the output 0.0: after 30 epochs the persistent velocity has never changed.
-
In the source, confirm no assignment self.v = ... exists after initialization.
Additional Information
Verified by defect injection in our audit. Note the direction is not uniformly harmful: on shifted unimodal problems the defective version is stronger (median log10 error −12.0 vs 3.3 for the faithful implementation on shifted sphere) — an accidental algorithmic change rather than a faithful port, which matters for anyone citing WSO results produced through the library. Suggested fix: self.v = v after the update (and confirm indexing per sub-population). A preprint with full methodology is available on request; happy to open a PR.
Description of the bug
Affects master (checked at commit 48b48c3), mealpy/swarm_based/WSO.py.
The persistent velocity state is initialized once (self.v = np.zeros(...), around l. 106) and the updated velocity is computed into a local variable v (around l. 133):
python
v = self.mu * (self.v + p1 * (...) * c1 + p2 * (...) * c2)
but v is never written back to self.v. The recurrent term self.v therefore remains exactly zero for the entire run, and the algorithm silently degrades from the momentum-based search of Braik et al. (2022) to a memoryless attraction toward the best-known positions.
Steps To Reproduce
Run this snippet (any recent mealpy):
python
import numpy as np
from mealpy import FloatVar
from mealpy.swarm_based.WSO import OriginalWSO
prob = {"obj_func": lambda x: float(np.sum(np.asarray(x)**2)),
"bounds": FloatVar(lb=[-5]*5, ub=[5]*5), "minmax": "min", "log_to": None}
m = OriginalWSO(epoch=30, pop_size=10)
m.solve(prob, seed=1)
print(np.abs(np.asarray(m.v)).max()) # prints 0.0 after 30 epochs
Observe the output 0.0: after 30 epochs the persistent velocity has never changed.
In the source, confirm no assignment self.v = ... exists after initialization.
Additional Information
Verified by defect injection in our audit. Note the direction is not uniformly harmful: on shifted unimodal problems the defective version is stronger (median log10 error −12.0 vs 3.3 for the faithful implementation on shifted sphere) — an accidental algorithmic change rather than a faithful port, which matters for anyone citing WSO results produced through the library. Suggested fix: self.v = v after the update (and confirm indexing per sub-population). A preprint with full methodology is available on request; happy to open a PR.