@@ -358,6 +358,7 @@ def test_selection_direction_backend(self, object_instance):
358358 """
359359 # Import backend bases to check optimizer type
360360 from hyperactive .opt ._adapters ._base_optuna_adapter import _BaseOptunaAdapter
361+ from hyperactive .opt ._adapters ._base_scipy_adapter import _BaseScipyAdapter
361362 from hyperactive .opt ._adapters ._gfo import _BaseGFOadapter
362363 from hyperactive .opt .gridsearch ._sk import GridSearchSk
363364 from hyperactive .opt .random_search import RandomSearchSk
@@ -460,5 +461,55 @@ def _assert_good(best_params):
460461 _assert_good (best_params )
461462 return None
462463
464+ # Scipy adapters: use continuous space (scipy doesn't support discrete)
465+ if isinstance (object_instance , _BaseScipyAdapter ):
466+ # Scipy requires continuous bounds, so use a small search space
467+ # around the known good point (0, 0)
468+ continuous_space = {"x0" : (- 1.0 , 1.0 ), "x1" : (- 1.0 , 1.0 )}
469+ continuous_cfg = _cfg_with_space (object_instance , exp , continuous_space )
470+ inst = object_instance .clone ().set_params (
471+ ** {
472+ ** continuous_cfg ,
473+ "n_iter" : 50 ,
474+ "random_state" : 0 ,
475+ }
476+ )
477+ best_params = inst .solve ()
478+ # Scipy should find params close to (0, 0) which is the optimum
479+ # Allow some tolerance since scipy uses continuous optimization
480+ assert isinstance (best_params , dict )
481+ assert abs (best_params ["x0" ]) < 0.5 , (
482+ f"Scipy optimizer should find x0 close to 0, got { best_params ['x0' ]} "
483+ )
484+ assert abs (best_params ["x1" ]) < 0.5 , (
485+ f"Scipy optimizer should find x1 close to 0, got { best_params ['x1' ]} "
486+ )
487+ return None
488+
463489 # For other backends, no-op here; targeted direction tests live elsewhere
464490 return None
491+
492+ def test_scipy_discrete_param_error (self , object_instance ):
493+ """Test that scipy optimizers raise clear error for discrete parameters."""
494+ from hyperactive .opt ._adapters ._base_scipy_adapter import _BaseScipyAdapter
495+
496+ if not isinstance (object_instance , _BaseScipyAdapter ):
497+ return None
498+
499+ import pytest
500+
501+ from hyperactive .experiment .bench import Ackley
502+
503+ exp = Ackley (d = 2 )
504+
505+ # Try to use discrete space (list) which scipy doesn't support
506+ discrete_space = {"x0" : [0.0 , 1.0 , 2.0 ], "x1" : [0.0 , 1.0 , 2.0 ]}
507+
508+ inst = object_instance .clone ().set_params (
509+ param_space = discrete_space ,
510+ n_iter = 10 ,
511+ experiment = exp ,
512+ )
513+
514+ with pytest .raises (ValueError , match = "only support continuous" ):
515+ inst .solve ()
0 commit comments