Passed
Push — master ( e37ecf...2614a9 )
by Simon
04:19
created

LipschitzOptimizer.finish_initialization()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 1
dl 0
loc 3
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
from ..smb_opt.smbo import SMBO
8
from ...search import Search
9
10
from scipy.spatial.distance import cdist
11
12
13
class LipschitzFunction:
14
    def __init__(self, position_l):
15
        self.position_l = position_l
16
17
    def find_best_slope(self, X_sample, Y_sample):
18
        slopes = [
19
            abs(y_sample1 - y_sample2) / abs(x_sample1 - x_sample2)
20
            for x_sample1, y_sample1 in zip(X_sample, Y_sample)
21
            for x_sample2, y_sample2 in zip(X_sample, Y_sample)
22
            if y_sample1 is not y_sample2
23
            if np.prod((x_sample1 - x_sample2)) != 0
24
        ]
25
26
        if len(slopes) == 0:
27
            return 1
28
        return np.max(slopes)
29
30
    def calculate(self, X_sample, Y_sample, score_best):
31
        lip_c = self.find_best_slope(X_sample, Y_sample)
32
33
        positions_np = np.array(self.position_l)
34
        samples_np = np.array(X_sample)
35
36
        pos_dist = cdist(positions_np, samples_np) * lip_c
37
38
        upper_bound_l = pos_dist
39
        upper_bound_l += np.array(Y_sample)
40
41
        mx = np.ma.masked_array(upper_bound_l, mask=upper_bound_l == 0)
42
        upper_bound_l = mx.min(1).reshape(1, -1).T
43
        upper_bound_l[upper_bound_l <= score_best] = -np.inf
44
45
        return upper_bound_l
46
47
48
class LipschitzOptimizer(SMBO, Search):
49
    name = "Lipschitz Optimizer"
50
    _name_ = "lipschitz_optimizer"
51
    __name__ = "LipschitzOptimizer"
52
53
    optimizer_type = "sequential"
54
    computationally_expensive = True
55
56
    def __init__(self, *args, **kwargs):
57
        super().__init__(*args, **kwargs)
58
59
    def finish_initialization(self):
60
        self.all_pos_comb = self._all_possible_pos()
61
        return super().finish_initialization()
62
63
    @SMBO.track_new_pos
64
    @SMBO.track_X_sample
65
    def iterate(self):
66
        self.pos_comb = self._sampling(self.all_pos_comb)
67
68
        lip_func = LipschitzFunction(self.pos_comb)
69
        upper_bound_l = lip_func.calculate(
70
            self.X_sample, self.Y_sample, self.score_best
71
        )
72
73
        index_best = list(upper_bound_l.argsort()[::-1])
74
        all_pos_comb_sorted = self.pos_comb[index_best]
75
        pos_best = all_pos_comb_sorted[0]
76
77
        return pos_best
78