LipschitzFunction.find_best_slope()   B
last analyzed

Complexity

Conditions 6

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 13
dl 0
loc 17
rs 8.6666
c 0
b 0
f 0
cc 6
nop 3
1
# Author: Simon Blanke
2
# Email: [email protected]
3
# License: MIT License
4
5
import numpy as np
6
7
from ..smb_opt.smbo import SMBO
8
9
from scipy.spatial.distance import cdist
10
11
12
class LipschitzFunction:
13
    def __init__(self, position_l):
14
        self.position_l = position_l
15
16
    def find_best_slope(self, X_sample, Y_sample):
17
        slopes = []
18
19
        len_sample = len(X_sample)
20
        for i in range(len_sample):
21
            for j in range(i + 1, len_sample):
22
                x_sample1, y_sample1 = X_sample[i], Y_sample[i]
23
                x_sample2, y_sample2 = X_sample[j], Y_sample[j]
24
25
                if y_sample1 != y_sample2 and np.prod((x_sample1 - x_sample2)) != 0:
26
                    slopes.append(
27
                        abs(y_sample1 - y_sample2) / abs(x_sample1 - x_sample2)
28
                    )
29
30
        if not slopes:
31
            return 1
32
        return np.max(slopes)
33
34
    def calculate(self, X_sample, Y_sample, score_best):
35
        lip_c = self.find_best_slope(X_sample, Y_sample)
36
37
        positions_np = np.array(self.position_l)
38
        samples_np = np.array(X_sample)
39
40
        pos_dist = cdist(positions_np, samples_np) * lip_c
41
42
        upper_bound_l = pos_dist
43
        upper_bound_l += np.array(Y_sample)
44
45
        mx = np.ma.masked_array(upper_bound_l, mask=upper_bound_l == 0)
46
        upper_bound_l = mx.min(1).reshape(1, -1).T
47
        upper_bound_l[upper_bound_l <= score_best] = -np.inf
48
49
        return upper_bound_l
50
51
52
class LipschitzOptimizer(SMBO):
53
    name = "Lipschitz Optimizer"
54
    _name_ = "lipschitz_optimizer"
55
    __name__ = "LipschitzOptimizer"
56
57
    optimizer_type = "sequential"
58
    computationally_expensive = True
59
60 View Code Duplication
    def __init__(
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
61
        self,
62
        search_space,
63
        initialize={"grid": 4, "random": 2, "vertices": 4},
64
        constraints=[],
65
        random_state=None,
66
        rand_rest_p=0,
67
        nth_process=None,
68
        warm_start_smbo=None,
69
        max_sample_size=10000000,
70
        sampling={"random": 1000000},
71
        replacement=True,
72
    ):
73
        super().__init__(
74
            search_space=search_space,
75
            initialize=initialize,
76
            constraints=constraints,
77
            random_state=random_state,
78
            rand_rest_p=rand_rest_p,
79
            nth_process=nth_process,
80
            warm_start_smbo=warm_start_smbo,
81
            max_sample_size=max_sample_size,
82
            sampling=sampling,
83
            replacement=replacement,
84
        )
85
86
    def finish_initialization(self):
87
        self.all_pos_comb = self._all_possible_pos()
88
        return super().finish_initialization()
89
90
    @SMBO.track_new_pos
91
    @SMBO.track_X_sample
92
    def iterate(self):
93
        self.pos_comb = self._sampling(self.all_pos_comb)
94
95
        lip_func = LipschitzFunction(self.pos_comb)
96
        upper_bound_l = lip_func.calculate(
97
            self.X_sample, self.Y_sample, self.score_best
98
        )
99
100
        index_best = list(upper_bound_l.argsort()[::-1])
101
        all_pos_comb_sorted = self.pos_comb[index_best]
102
        pos_best = all_pos_comb_sorted[0]
103
104
        return pos_best
105