LipschitzOptimizer.__init__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 24
Code Lines 23

Duplication

Lines 24
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 23
dl 24
loc 24
rs 9.328
c 0
b 0
f 0
cc 1
nop 11

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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