Passed
Push — master ( 7ebd63...8bd9a3 )
by Simon
06:11
created

gradient_free_optimizers.optimizers.global_opt.powells_method.powells_method   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 13
eloc 97
dl 0
loc 138
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A PowellsMethod.evaluate() 0 7 2
A PowellsMethod.new_dim() 0 43 4
A PowellsMethod.iterate() 0 25 4
A PowellsMethod.__init__() 0 28 1
A PowellsMethod.finish_initialization() 0 4 1

1 Function

Rating   Name   Duplication   Size   Complexity  
A sort_list_idx() 0 4 1
1
# Author: Simon Blanke
2
# Email: [email protected]
3
# License: MIT License
4
5
import numpy as np
6
from collections import OrderedDict
7
8
from ...local_opt import HillClimbingOptimizer
9
10
11
def sort_list_idx(list_):
12
    list_np = np.array(list_)
13
    idx_sorted = list(list_np.argsort()[::-1])
14
    return idx_sorted
15
16
17
class PowellsMethod(HillClimbingOptimizer):
18
    name = "Powell's Method"
19
    _name_ = "powells_method"
20
    __name__ = "PowellsMethod"
21
22
    optimizer_type = "global"
23
    computationally_expensive = False
24
25
    def __init__(
26
        self,
27
        search_space,
28
        initialize={"grid": 4, "random": 2, "vertices": 4},
29
        constraints=[],
30
        random_state=None,
31
        rand_rest_p=0,
32
        nth_process=None,
33
        epsilon=0.03,
34
        distribution="normal",
35
        n_neighbours=3,
36
        iters_p_dim=10,
37
    ):
38
        super().__init__(
39
            search_space=search_space,
40
            initialize=initialize,
41
            constraints=constraints,
42
            random_state=random_state,
43
            rand_rest_p=rand_rest_p,
44
            nth_process=nth_process,
45
            epsilon=epsilon,
46
            distribution=distribution,
47
            n_neighbours=n_neighbours,
48
        )
49
50
        self.iters_p_dim = iters_p_dim
51
52
        self.current_search_dim = -1
53
54
    def finish_initialization(self):
55
        self.nth_iter_ = -1
56
        self.nth_iter_current_dim = 0
57
        self.search_state = "iter"
58
59
    def new_dim(self):
60
        self.current_search_dim += 1
61
62
        if self.current_search_dim >= self.conv.n_dimensions:
63
            self.current_search_dim = 0
64
65
        idx_sorted = sort_list_idx(self.scores_valid)
66
67
        self.powells_pos = [self.positions_valid[idx] for idx in idx_sorted][0]
68
        self.powells_scores = [self.scores_valid[idx] for idx in idx_sorted][0]
69
70
        self.nth_iter_current_dim = 0
71
72
        min_pos = []
73
        max_pos = []
74
        center_pos = []
75
76
        search_space_1D = OrderedDict()
77
        for idx, para_name in enumerate(self.conv.para_names):
78
            if self.current_search_dim == idx:
79
                # fill with range of values
80
                search_space_pos = self.conv.search_space_positions[idx]
81
                search_space_1D[para_name] = np.array(search_space_pos)
82
83
                min_pos.append(int(np.amin(search_space_pos)))
84
                max_pos.append(int(np.amax(search_space_pos)))
85
                center_pos.append(int(np.median(search_space_pos)))
86
            else:
87
                # fill with single value
88
                search_space_1D[para_name] = np.array([self.powells_pos[idx]])
89
90
                min_pos.append(self.powells_pos[idx])
91
                max_pos.append(self.powells_pos[idx])
92
                center_pos.append(self.powells_pos[idx])
93
94
        self.init_positions_ = [min_pos, center_pos, max_pos]
95
96
        self.hill_climb = HillClimbingOptimizer(
97
            search_space=search_space_1D,
98
            initialize={"random": 5},
99
            epsilon=self.epsilon,
100
            distribution=self.distribution,
101
            n_neighbours=self.n_neighbours,
102
        )
103
104
    @HillClimbingOptimizer.track_new_pos
105
    @HillClimbingOptimizer.random_iteration
106
    def iterate(self):
107
        self.nth_iter_ += 1
108
        self.nth_iter_current_dim += 1
109
110
        modZero = self.nth_iter_ % self.iters_p_dim == 0
111
        # nonZero = self.nth_iter_ != 0
112
113
        if modZero:
114
            self.new_dim()
115
116
        if self.nth_iter_current_dim < 5:
117
            pos_new = self.hill_climb.init_pos()
118
            pos_new = self.hill_climb.conv.position2value(pos_new)
119
120
        else:
121
            pos_new = self.hill_climb.iterate()
122
            pos_new = self.hill_climb.conv.position2value(pos_new)
123
        pos_new = np.array(pos_new)
124
125
        if self.conv.not_in_constraint(pos_new):
126
            return pos_new
127
        return self.move_climb(
128
            pos_new, epsilon=self.epsilon, distribution=self.distribution
129
        )
130
131
    @HillClimbingOptimizer.track_new_score
132
    def evaluate(self, score_new):
133
        if self.current_search_dim == -1:
134
            super(HillClimbingOptimizer, self).evaluate(score_new)
135
        else:
136
            self.hill_climb.evaluate(score_new)
137
            super(HillClimbingOptimizer, self).evaluate(score_new)
138