Coverage for jetgp/hyperparameter_optimizers/powell.py: 88%

25 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2026-03-31 11:46 -0500

1import numpy as np 

2from scipy.optimize import minimize 

3 

4def powell(func, lb, ub, **kwargs): 

5 """ 

6 Powell's method with bounds and multi-start. 

7 

8 Parameters 

9 ---------- 

10 func : callable 

11 Function to minimize. 

12 lb, ub : array-like 

13 Lower and upper bounds. 

14 kwargs : dict 

15 Optional arguments: 

16 - x0 : initial guess for first restart 

17 - n_restart_optimizer : number of random restarts (default=10) 

18 - debug : bool, print intermediate results (default=False) 

19 - Any Powell-specific options: maxiter, xtol, ftol, disp 

20 """ 

21 x0 = kwargs.pop("x0", None) 

22 n_restart_optimizer = kwargs.pop("n_restart_optimizer", 10) 

23 debug = kwargs.pop("debug", False) 

24 

25 # Extract Powell-specific options 

26 options = {} 

27 for key in ["maxiter", "xtol", "ftol", "disp"]: 

28 if key in kwargs: 

29 options[key] = kwargs.pop(key) 

30 

31 lb = np.array(lb) 

32 ub = np.array(ub) 

33 best_x = None 

34 best_val = np.inf 

35 

36 for i in range(n_restart_optimizer): 

37 if x0 is not None and i == 0: 

38 x_init = np.array(x0) 

39 else: 

40 x_init = np.random.uniform(lb, ub) 

41 

42 res = minimize( 

43 func, 

44 x_init, 

45 method="Powell", 

46 bounds=list(zip(lb, ub)), 

47 options=options, 

48 **kwargs # extra kwargs forwarded 

49 ) 

50 

51 if res.fun < best_val: 

52 best_val = res.fun 

53 best_x = res.x 

54 

55 if debug: 

56 print(f"[Powell] Restart {i+1}/{n_restart_optimizer} -> best_val={best_val}") 

57 

58 return best_x, best_val