Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
RWTH-EBC
GitHub Repository: RWTH-EBC/ebcpy
Path: blob/master/tests/test_optimizer.py
505 views
1
"""Test-module for all classes inside
2
ebcpy.optimization."""
3
import sys
4
import unittest
5
import os
6
import shutil
7
import pathlib
8
import logging
9
import numpy as np
10
from ebcpy.optimization import Optimizer
11
12
13
logger = logging.getLogger(__name__)
14
15
16
class TestOptimizer(unittest.TestCase):
17
"""Test-class for optimization class"""
18
19
def setUp(self):
20
"""Called before every test.
21
Used to setup relevant paths and APIs etc."""
22
self.example_opt_dir = os.path.normpath(os.path.join(os.path.dirname(__file__),
23
"test_optimization"))
24
25
def test_optimizer_choose_function(self):
26
"""Test-case for the base-class for optimization."""
27
# pylint: disable=protected-access
28
opt = Optimizer()
29
for _framework in opt.supported_frameworks:
30
if _framework == "scipy_minimize":
31
reference_function = opt._scipy_minimize
32
elif _framework == "dlib_minimize":
33
reference_function = opt._dlib_minimize
34
elif _framework == "scipy_differential_evolution":
35
reference_function = opt._scipy_differential_evolution
36
elif _framework == "pymoo":
37
reference_function = opt._pymoo
38
elif _framework == "bayesian_optimization":
39
reference_function = opt._bayesian_optimization
40
_minimize_func, required_method = opt._choose_framework(_framework)
41
self.assertEqual(_minimize_func, reference_function)
42
with self.assertRaises(TypeError):
43
opt._choose_framework("not_supported_framework")
44
45
def test_set_and_delete_working_directory(self):
46
"""Test the working_directory and delete functions"""
47
example_dir_as_pathlib_path = pathlib.Path(self.example_opt_dir)
48
opt = Optimizer()
49
self.assertIsNone(opt.working_directory)
50
opt = Optimizer(working_directory=self.example_opt_dir)
51
self.assertEqual(opt.working_directory, example_dir_as_pathlib_path)
52
opt = Optimizer(working_directory=example_dir_as_pathlib_path)
53
self.assertEqual(opt.working_directory, example_dir_as_pathlib_path)
54
shutil.rmtree(opt.working_directory)
55
56
def test_custom_optimizer(self):
57
"""Test-case for the customization of the optimization-base-class."""
58
# Define the customized class:
59
class CustomOptimizer(Optimizer):
60
"""Dummy class"""
61
62
x_goal = np.random.rand(3)
63
64
def obj(self, xk, *args):
65
x_data = np.linspace(-2, 2, 100)
66
param_1, param_2, param_3 = xk[0], xk[1], xk[2]
67
_param_1, _param_2, _param_3 = self.x_goal[0], self.x_goal[1], self.x_goal[2]
68
quadratic_func_should = _param_1*x_data**2 + _param_2*x_data + _param_3
69
quadratic_func_is = param_1*x_data**2 + param_2*x_data + param_3
70
# Return the MAE of the quadratic function.
71
return np.sum(np.abs(quadratic_func_should - quadratic_func_is))
72
73
my_custom_optimizer = CustomOptimizer()
74
# Test value error if no method is supplied
75
with self.assertRaises(ValueError):
76
my_custom_optimizer.optimize(framework="scipy_minimize")
77
# Test without x0
78
with self.assertRaises(KeyError):
79
my_custom_optimizer.optimize(framework="scipy_minimize",
80
method="L-BFGS-B")
81
# Test scipy minimize
82
res_min = my_custom_optimizer.optimize(framework="scipy_minimize",
83
method="L-BFGS-B",
84
x0=np.array([0, 0, 0]))
85
86
delta_solution = np.sum(res_min.x - my_custom_optimizer.x_goal)
87
self.assertEqual(0.0, np.round(delta_solution, 3))
88
# test wrong bounds in pymoo and sp_dif_evo
89
my_custom_optimizer.bounds = None
90
with self.assertRaises(ValueError):
91
my_custom_optimizer.optimize(framework="scipy_differential_evolution",
92
method="best2bin")
93
with self.assertRaises(ValueError):
94
my_custom_optimizer.optimize(framework="pymoo",
95
method="NSGA2")
96
97
# Test scipy differential evolution
98
# Bounds are necessary (here, 1 and 0 are sufficient,
99
# as the goal values are element of [0,1]
100
my_custom_optimizer.bounds = [(0, 1) for _ in range(3)]
101
res_de = my_custom_optimizer.optimize(framework="scipy_differential_evolution",
102
method="best2bin")
103
delta_solution = np.sum(res_de.x - my_custom_optimizer.x_goal)
104
self.assertEqual(0.0, np.round(delta_solution, 3))
105
#Skip dlib test as problems in ci occur.
106
# if sys.version_info.minor >= 10:
107
# self.skipTest("While pymoo is supported for python versions >= 3.10, the CI seems to have problems with it,"
108
# "not beeing able to import cma. Thefore skipping tests for those versions")
109
res_de = my_custom_optimizer.optimize(framework="pymoo",
110
method="NSGA2")
111
delta_solution = np.sum(res_de.x - my_custom_optimizer.x_goal)
112
self.assertEqual(0.0, np.round(delta_solution, 3))
113
114
115
def test_error_handler(self):
116
"""Test if error handling works for each framework"""
117
opt = Optimizer()
118
try:
119
raise KeyError("My own error")
120
except KeyError as error:
121
with self.assertRaises(KeyError):
122
opt._handle_error(error)
123
124
def test_get_cfg(self):
125
"""Test get the default config"""
126
opt = Optimizer()
127
for framework in opt.supported_frameworks:
128
cfg = opt.get_default_config(framework=framework)
129
self.assertGreater(len(cfg), 0)
130
self.assertEqual(opt.get_default_config("not supported"),
131
{})
132
133
def tearDown(self):
134
"""Remove all created folders while optimizing."""
135
try:
136
shutil.rmtree(self.example_opt_dir)
137
except (FileNotFoundError, PermissionError) as err:
138
logger.error("Could not delete files %s", err)
139
140
141
if __name__ == "__main__":
142
unittest.main()
143
144