2424import numpy .testing as npt
2525import pandas as pd
2626
27- from climada .util .calibrate import Input , BayesianOptimizer
27+ from climada .util .calibrate import Input , BayesianOptimizer , BayesianOptimizerController
2828
2929from .test_base import hazard , exposure
3030
3131
32+ def input ():
33+ """Return a mocked input"""
34+ return Input (
35+ hazard = hazard (),
36+ exposure = exposure (),
37+ data = pd .DataFrame (data = {"col1" : [1 , 2 ], "col2" : [2 , 3 ]}, index = [0 , 1 ]),
38+ cost_func = MagicMock (),
39+ impact_func_creator = MagicMock (),
40+ impact_to_dataframe = MagicMock (),
41+ )
42+
43+
44+ class TestBayesianOptimizerController (unittest .TestCase ):
45+ """Tests for the controller of the BayesianOptimizer"""
46+
47+ def test_kappa_decay (self ):
48+ """Check correct values for kappa_decay"""
49+ contr = BayesianOptimizerController (kappa = 3 , kappa_min = 3 , n_iter = 10 )
50+ self .assertAlmostEqual (contr .kappa_decay , 1.0 )
51+
52+ contr = BayesianOptimizerController (kappa = 3 , kappa_min = 1 , n_iter = 10 )
53+ self .assertAlmostEqual (contr .kappa * (contr .kappa_decay ** 10 ), 1.0 )
54+
55+ def test_from_input (self ):
56+ """Check if input data is used correctly to set up controller"""
57+ inp = input ()
58+ inp .bounds = {"a" : (0 , 1 ), "b" : (1 , 2 )}
59+
60+ contr = BayesianOptimizerController .from_input (inp , sampling_base = 3 , kappa = 3 )
61+ self .assertEqual (contr .kappa , 3 )
62+ self .assertEqual (contr .init_points , 3 ** 2 )
63+ self .assertEqual (contr .n_iter , 3 ** 2 )
64+
65+
3266class TestBayesianOptimizer (unittest .TestCase ):
3367 """Tests for the optimizer based on bayes_opt.BayesianOptimization"""
3468
3569 def setUp (self ):
3670 """Mock the input"""
37- self .input = Input (
38- hazard = hazard (),
39- exposure = exposure (),
40- data = pd .DataFrame (data = {"col1" : [1 , 2 ], "col2" : [2 , 3 ]}, index = [0 , 1 ]),
41- cost_func = MagicMock (),
42- impact_func_creator = MagicMock (),
43- impact_to_dataframe = MagicMock (),
44- )
71+ self .input = input ()
4572
4673 @patch ("climada.util.calibrate.base.ImpactCalc" , autospec = True )
4774 def test_kwargs_to_impact_func_creator (self , _ ):
@@ -54,11 +81,14 @@ def test_kwargs_to_impact_func_creator(self, _):
5481 self .input .bounds = {"x_2" : (0 , 1 ), "x 1" : (1 , 2 )}
5582 self .input .cost_func .return_value = 1.0
5683 self .optimizer = BayesianOptimizer (self .input )
84+ self .controller = BayesianOptimizerController (
85+ init_points = 2 , n_iter = 1 , max_iterations = 1
86+ )
5787
5888 # Call 'run'
5989 with patch .object (self .input , "impact_to_aligned_df" ) as align :
6090 align .return_value = (None , None )
61- self .optimizer .run (init_points = 2 , n_iter = 1 )
91+ self .optimizer .run (self . controller )
6292
6393 # Check call to '_kwargs_to_impact_func_gen'
6494 call_args = self .input .impact_func_creator .call_args_list
@@ -75,11 +105,14 @@ def test_target_func(self, _):
75105 self .input .bounds = {"x_2" : (0 , 1 ), "x 1" : (1 , 2 )}
76106 self .input .cost_func .side_effect = [1.0 , - 1.0 ]
77107 self .optimizer = BayesianOptimizer (self .input )
108+ self .controller = BayesianOptimizerController (
109+ init_points = 1 , n_iter = 1 , max_iterations = 1
110+ )
78111
79112 # Call 'run'
80113 with patch .object (self .input , "impact_to_aligned_df" ) as align :
81114 align .return_value = (None , None )
82- output = self .optimizer .run (init_points = 1 , n_iter = 1 )
115+ output = self .optimizer .run (self . controller )
83116
84117 # Check target space
85118 npt .assert_array_equal (output .p_space .target , [- 1.0 , 1.0 ])
0 commit comments