I'd like to optimize a sequence of 2 values, where each value has its own bound using simulated dual annealing from scipy:
Here's an example of sequence:
self.sequence_length = 10
self.action_space = [(Bounds(lb=np.pi/12, ub=5*np.pi/9), Bounds(lb=75.0, ub=200.0))] * self.sequence_length
Here's an example of output:
[((0.2617993877991494, 1.7453292519943295), (75.0, 200.0)), ((0.2617993877991494, 1.7453292519943295), (75.0, 200.0)), ((0.2617993877991494, 1.7453292519943295), (75.0, 200.0)), ((0.2617993877991494, 1.7453292519943295), (75.0, 200.0)), ((0.2617993877991494, 1.7453292519943295), (75.0, 200.0)), ((0.2617993877991494, 1.7453292519943295), (75.0, 200.0)), ((0.2617993877991494, 1.7453292519943295), (75.0, 200.0)), ((0.2617993877991494, 1.7453292519943295), (75.0, 200.0)), ((0.2617993877991494, 1.7453292519943295), (75.0, 200.0)), ((0.2617993877991494, 1.7453292519943295), (75.0, 200.0))]
As such, each tuple of the sequence has 2 values with its own bounds, and the goal is optimize the whole sequence:
result = dual_annealing(self.func, initial_temp=10000, bounds=self.action_space, maxfun=1000)
However, the following error arises:
Traceback (most recent call last):
File "main.py", line 98, in <module>
obj = Sim()
File "main.py", line 92, in __init__
result = dual_annealing(self.generate_sequence, initial_temp=10000, bounds=self.action_space, maxfun=1000)
File "/home/user/miniconda3/envs/sim/lib/python3.8/site-packages/scipy/optimize/_dual_annealing.py", line 639, in dual_annealing
if (np.any(np.isinf(lower)) or np.any(np.isinf(upper)) or np.any(
TypeError: ufunc 'isinf' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
Could someone come with a solution for that?
The problem is that dual_annealing expects a single Bounds object with lower and upper bounds for all variables, not a list of Bounds objects. You can solve this problem by creating a single Bounds object with bounds for all variables.
Try this snippet of code:
self.sequence_length = 10
lb = [np.pi/12, 75.0] * self.sequence_length
ub = [5*np.pi/9, 200.0] * self.sequence_length
self.action_space = Bounds(lb=lb, ub=ub)
result = dual_annealing(self.func, initial_temp=10000, bounds=self.action_space, maxfun=1000)