hyperactive.search_space.DictClass.__init__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 2
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
# Author: Simon Blanke
2
# Email: [email protected]
3
# License: MIT License
4
5
import numpy as np
6
7
8
class DictClass:
9
    def __init__(self, search_space):
10
        self.search_space = search_space
11
12
    def __getitem__(self, key):
13
        return self.search_space[key]
14
15
    def keys(self):
16
        return self.search_space.keys()
17
18
    def values(self):
19
        return self.search_space.values()
20
21
    def items(self):
22
        return self.search_space.items()
23
24
25
class SearchSpace(DictClass):
26
    def __init__(self, search_space):
27
        super().__init__(search_space)
28
        self.search_space = search_space
29
30
        self.dim_keys = list(search_space.keys())
31
        self.values_l = list(self.search_space.values())
32
33
        positions = {}
34
        for key in search_space.keys():
35
            positions[key] = np.array(range(len(search_space[key])))
36
        self.positions = positions
37
38
        self.check_list()
39
        self.check_non_num_values()
40
41
        self.data_types = self.dim_types()
42
        self.func2str = self._create_num_str_ss()
43
44
    def __call__(self):
45
        return self.search_space
46
47
    def dim_types(self):
48
        data_types = {}
49
        for dim_key in self.dim_keys:
50
            dim_values = np.array(list(self.search_space[dim_key]))
51
            try:
52
                np.subtract(dim_values, dim_values)
53
                np.array(dim_values).searchsorted(dim_values)
54
            except:
55
                _type_ = "object"
56
            else:
57
                _type_ = "number"
58
59
            data_types[dim_key] = _type_
60
        return data_types
61
62
    def _create_num_str_ss(self):
63
        func2str = {}
64
        for dim_key in self.dim_keys:
65
            if self.data_types[dim_key] == "number":
66
                func2str[dim_key] = self.search_space[dim_key]
67
            else:
68
                func2str[dim_key] = []
69
70
                dim_values = self.search_space[dim_key]
71
                for value in dim_values:
72
                    try:
73
                        func_name = value.__name__
74
                    except:
75
                        func_name = value
76
77
                    func2str[dim_key].append(func_name)
78
        return func2str
79
80
    def check_list(self):
81
        for dim_key in self.dim_keys:
82
            search_dim = self.search_space[dim_key]
83
84
            err_msg = "\n Value in '{}' of search space dictionary must be of type list \n".format(
85
                dim_key
86
            )
87
            if not isinstance(search_dim, list):
88
                raise ValueError(err_msg)
89
90
    @staticmethod
91
    def is_function(value):
92
        try:
93
            value.__name__
94
        except:
95
            return False
96
        else:
97
            return True
98
99
    @staticmethod
100
    def is_number(value):
101
        try:
102
            float(value)
103
            value * 0.1
104
            value - 0.1
105
            value / 0.1
106
        except:
107
            return False
108
        else:
109
            return True
110
111
    def _string_or_object(self, dim_key, dim_values):
112
        for dim_value in dim_values:
113
            is_str = isinstance(dim_value, str)
114
            is_func = self.is_function(dim_value)
115
            is_number = self.is_number(dim_value)
116
117
            if not is_str and not is_func and not is_number:
118
                msg = "\n The value '{}' of type '{}' in the search space dimension '{}' must be number, string or function \n".format(
119
                    dim_value, type(dim_value), dim_key
120
                )
121
                raise ValueError(msg)
122
123
    def check_non_num_values(self):
124
        for dim_key in self.dim_keys:
125
            dim_values = np.array(list(self.search_space[dim_key]))
126
127
            try:
128
                np.subtract(dim_values, dim_values)
129
                np.array(dim_values).searchsorted(dim_values)
130
            except:
131
                self._string_or_object(dim_key, dim_values)
132
            else:
133
                if dim_values.ndim != 1:
134
                    msg = "Array-like object in '{}' must be one dimensional".format(
135
                        dim_key
136
                    )
137
                    raise ValueError(msg)
138