Skip to content

Commit e0c3b85

Browse files
committed
asa
1 parent fbe0047 commit e0c3b85

File tree

10 files changed

+61
-54
lines changed

10 files changed

+61
-54
lines changed

include/matrix_adaptation.hpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@ namespace matrix_adaptation
1313
Vector m, m_old, dm, ps;
1414
Float dd;
1515
Float expected_length_z;
16-
Matrix inv_C;
1716

1817
Adaptation(const size_t dim, const Vector& x0, const Vector& ps, const Float expected_length_z) :
1918
m(x0), m_old(dim), dm(Vector::Zero(dim)),
2019
ps(ps), dd(static_cast<Float>(dim)),
21-
expected_length_z(expected_length_z),
22-
inv_C(Matrix::Identity(dim, dim))
20+
expected_length_z(expected_length_z)
2321
{
2422
}
2523

@@ -28,7 +26,7 @@ namespace matrix_adaptation
2826
const parameters::Stats& stats, size_t mu, size_t lambda) = 0;
2927

3028
virtual bool adapt_matrix(const parameters::Weights& w, const parameters::Modules& m, const Population& pop,
31-
size_t mu, const parameters::Settings& settings, const parameters::Stats& stats) = 0;
29+
size_t mu, const parameters::Settings& settings, parameters::Stats& stats) = 0;
3230

3331
virtual void restart(const parameters::Settings& settings) = 0;
3432

@@ -47,7 +45,7 @@ namespace matrix_adaptation
4745
}
4846

4947
bool adapt_matrix(const parameters::Weights& w, const parameters::Modules& m, const Population& pop,
50-
const size_t mu, const parameters::Settings& settings, const parameters::Stats& stats) override
48+
const size_t mu, const parameters::Settings& settings, parameters::Stats& stats) override
5149
{
5250
return true;
5351
}
@@ -70,6 +68,7 @@ namespace matrix_adaptation
7068
Matrix inv_root_C;
7169

7270
bool hs = true;
71+
7372

7473
CovarianceAdaptation(const size_t dim, const Vector& x0, const Float expected_length_z) : Adaptation(dim, x0, Vector::Zero(dim), expected_length_z),
7574
pc(Vector::Zero(dim)),
@@ -90,7 +89,7 @@ namespace matrix_adaptation
9089
size_t mu, size_t lambda) override;
9190

9291
bool adapt_matrix(const parameters::Weights& w, const parameters::Modules& m, const Population& pop, size_t mu,
93-
const parameters::Settings& settings, const parameters::Stats& stats) override;
92+
const parameters::Settings& settings, parameters::Stats& stats) override;
9493

9594
void restart(const parameters::Settings& settings) override;
9695

@@ -107,8 +106,6 @@ namespace matrix_adaptation
107106
};
108107

109108

110-
111-
112109
struct OnePlusOneAdaptation: CovarianceAdaptation
113110
{
114111
constexpr static Float max_success_ratio = 0.44;
@@ -120,7 +117,7 @@ namespace matrix_adaptation
120117
size_t mu, size_t lambda) override;
121118

122119
bool adapt_matrix(const parameters::Weights& w, const parameters::Modules& m, const Population& pop, size_t mu,
123-
const parameters::Settings& settings, const parameters::Stats& stats) override;
120+
const parameters::Settings& settings, parameters::Stats& stats) override;
124121

125122
};
126123

@@ -141,7 +138,7 @@ namespace matrix_adaptation
141138
size_t mu, size_t lambda) override;
142139

143140
bool adapt_matrix(const parameters::Weights& w, const parameters::Modules& m, const Population& pop, size_t mu,
144-
const parameters::Settings& settings, const parameters::Stats& stats) override;
141+
const parameters::Settings& settings, parameters::Stats& stats) override;
145142

146143
void restart(const parameters::Settings& settings) override;
147144

include/repelling.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ namespace repelling
7272
int attempts = 0;
7373
Float coverage = 20.0;
7474
// Matrix C;
75-
// Matrix C_inv;
75+
Matrix C_inv;
7676

7777
virtual ~Repelling() = default;
7878

include/stats.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ namespace parameters
1717
bool has_improved = false;
1818
Float success_ratio = 2.0 / 11.0;
1919
Float cs = 1.0 / 12.0;
20+
size_t last_update = 0;
21+
size_t n_updates = 0;
2022

2123
void update_best(const Vector &x, const Float y)
2224
{

include/weights.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ namespace parameters
1313

1414
Float mueff, mueff_neg;
1515
Float c1, cmu, cc;
16+
Float lazy_update_interval;
17+
Float sigma_path_scale;
1618

1719
Weights(const size_t dim, const size_t mu, const size_t lambda, const Settings &settings);
1820

src/interface.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ void define_repelling(py::module &main)
303303
.def("prepare_sampling", &Repelling::prepare_sampling, py::arg("p"))
304304
.def_readwrite("archive", &Repelling::archive)
305305
.def_readwrite("coverage", &Repelling::coverage)
306-
.def_readwrite("attempts", &Repelling::attempts);
306+
.def_readwrite("attempts", &Repelling::attempts)
307+
.def_readwrite("C_inv", &Repelling::C_inv);
307308

308309
py::class_<NoRepelling, Repelling, std::shared_ptr<NoRepelling>>(m, "NoRepelling")
309310
.def(py::init<>());
@@ -326,7 +327,6 @@ void define_matrix_adaptation(py::module &main)
326327
.def_readwrite("ps", &Adaptation::ps)
327328
.def_readwrite("dd", &Adaptation::dd)
328329
.def_readwrite("expected_length_z", &Adaptation::expected_length_z)
329-
.def_readwrite("inv_C", &CovarianceAdaptation::inv_C)
330330
.def("adapt_evolution_paths", &Adaptation::adapt_evolution_paths,
331331
py::arg("pop"),
332332
py::arg("weights"),
@@ -518,6 +518,8 @@ void define_parameters(py::module &main)
518518
.def_readwrite("global_best", &Stats::global_best)
519519
.def_readwrite("has_improved", &Stats::has_improved)
520520
.def_readwrite("success_ratio", &Stats::success_ratio)
521+
.def_readwrite("last_update", &Stats::last_update)
522+
.def_readwrite("n_updates", &Stats::n_updates)
521523
.def("__repr__", [](Stats &stats)
522524
{
523525
std::stringstream ss;

src/main.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ int main()
7171
//std::cout << "p_succ: " << sr->success_ratio << ", " << sr->max_success_ratio << std::endl;
7272
}
7373
std::cout << cma.p->stats.evaluations << std::endl;
74-
75-
74+
std::cout << cma.p->stats.t << std::endl;
75+
std::cout << cma.p->stats.n_updates << std::endl;
76+
std::cout << cma.p->stats << std::endl;
7677
}

src/matrix_adaptation.cpp

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace matrix_adaptation
1818

1919
const Float actual_ps_length = ps.norm() / sqrt(
2020
1.0 - pow(1.0 - mutation->cs, 2.0 * (stats.evaluations / lambda)));
21+
2122
const Float expected_ps_length = (1.4 + (2.0 / (dd + 1.0))) * expected_length_z;
2223

2324
hs = actual_ps_length < expected_ps_length;
@@ -31,22 +32,18 @@ namespace matrix_adaptation
3132
const auto dhs = (1 - hs) * w.cc * (2.0 - w.cc);
3233
const auto old_c = (1 - (w.c1 * dhs) - w.c1 - (w.cmu * w.positive.sum())) * C;
3334

34-
Matrix rank_mu;
3535
if (m.active)
3636
{
3737
auto weights = w.weights.topRows(pop.Y.cols());
38-
rank_mu = w.cmu * ((pop.Y.array().rowwise() * weights.array().transpose()).matrix() * pop.Y.transpose());
38+
C = old_c + rank_one + w.cmu * ((pop.Y.array().rowwise() * weights.array().transpose()).matrix() * pop.Y.transpose());
3939
}
4040
else
4141
{
42-
rank_mu = w.cmu * ((pop.Y.leftCols(mu).array().rowwise() * w.positive.array().transpose()).matrix() * pop.Y.
43-
leftCols(mu).transpose());
42+
C = old_c + rank_one + (w.cmu * ((pop.Y.leftCols(mu).array().rowwise() * w.positive.array().transpose()).matrix() * pop.Y.
43+
leftCols(mu).transpose()));
4444

4545
}
46-
C = old_c + rank_one + rank_mu;
47-
48-
C = C.triangularView<Eigen::Upper>().toDenseMatrix() +
49-
C.triangularView<Eigen::StrictlyUpper>().toDenseMatrix().transpose();
46+
C = 0.5 * (C + C.transpose().eval());
5047
}
5148

5249
bool CovarianceAdaptation::perform_eigendecomposition(const Settings& settings)
@@ -72,25 +69,33 @@ namespace matrix_adaptation
7269
}
7370
return false;
7471
}
75-
inv_C = ((B * d.cwiseInverse().asDiagonal()) * B.transpose());
72+
73+
7674
d = d.cwiseSqrt();
77-
inv_root_C = (B * d.cwiseInverse().asDiagonal()) * B.transpose();
75+
inv_root_C = B * d.cwiseInverse().asDiagonal() * B.transpose();
7876
return true;
7977
}
8078

8179
bool CovarianceAdaptation::adapt_matrix(const Weights& w, const Modules& m, const Population& pop, const size_t mu,
82-
const Settings& settings, const parameters::Stats& stats)
80+
const Settings& settings, parameters::Stats& stats)
8381
{
84-
adapt_covariance_matrix(w, m, pop, mu);
85-
return perform_eigendecomposition(settings);
82+
83+
if (static_cast<Float>(stats.t) >= static_cast<Float>(stats.last_update) + w.lazy_update_interval)
84+
{
85+
stats.last_update = stats.t;
86+
stats.n_updates++;
87+
adapt_covariance_matrix(w, m, pop, mu);
88+
return perform_eigendecomposition(settings);
89+
}
90+
return true;
91+
8692
}
8793

8894
void CovarianceAdaptation::restart(const Settings& settings)
8995
{
9096
B = Matrix::Identity(settings.dim, settings.dim);
9197
C = Matrix::Identity(settings.dim, settings.dim);
9298
inv_root_C = Matrix::Identity(settings.dim, settings.dim);
93-
inv_C = Matrix::Identity(settings.dim, settings.dim);
9499
d.setOnes();
95100
m = settings.x0.value_or(Vector::Zero(settings.dim));
96101
m_old.setZero();
@@ -101,12 +106,12 @@ namespace matrix_adaptation
101106

102107
Vector CovarianceAdaptation::compute_y(const Vector& zi)
103108
{
104-
return B * (d.asDiagonal() * zi);
109+
return B * d.cwiseProduct(zi);
105110
}
106111

107112
Vector CovarianceAdaptation::invert_y(const Vector& yi)
108113
{
109-
return d.cwiseInverse().asDiagonal() * (B.transpose() * yi);
114+
return (B.transpose() * yi).cwiseQuotient(d);
110115
}
111116

112117
bool SeperableAdaptation::perform_eigendecomposition(const Settings& settings)
@@ -131,7 +136,7 @@ namespace matrix_adaptation
131136
}
132137

133138
bool OnePlusOneAdaptation::adapt_matrix(const parameters::Weights& w, const parameters::Modules& m, const Population& pop, size_t mu,
134-
const parameters::Settings& settings, const parameters::Stats& stats)
139+
const parameters::Settings& settings, parameters::Stats& stats)
135140
{
136141
if (!stats.has_improved)
137142
{
@@ -142,7 +147,6 @@ namespace matrix_adaptation
142147

143148

144149

145-
146150
void MatrixAdaptation::adapt_evolution_paths(const Population& pop, const Weights& w,
147151
const std::shared_ptr<mutation::Strategy>& mutation,
148152
const Stats& stats, const size_t mu, const size_t lambda)
@@ -155,33 +159,29 @@ namespace matrix_adaptation
155159
}
156160

157161
bool MatrixAdaptation::adapt_matrix(const Weights& w, const Modules& m, const Population& pop, const size_t mu,
158-
const Settings& settings, const parameters::Stats& stats)
162+
const Settings& settings, parameters::Stats& stats)
159163
{
160164
const auto old_m = (1. - (0.5 * w.c1) - (0.5 * w.cmu)) * M;
161165
const auto scaled_ps = (0.5 * w.c1) * (M * ps) * ps.transpose();
162166

163167
const auto old_m_inv = (1. + (0.5 * w.c1) + (0.5 * w.cmu)) * M_inv;
164168
const auto scaled_inv_ps = (0.5 * w.c1) * ps * (ps.transpose() * M);
165169

166-
Matrix new_m, new_m_inv;
167170
if (m.active)
168171
{
169-
// TODO: Check if we can do this like this
170172
const auto scaled_weights = ((0.5 * w.cmu) * w.weights.topRows(pop.Y.cols())).array().transpose();
171173
const auto scaled_y = (pop.Y.array().rowwise() * scaled_weights).matrix();
172-
new_m = scaled_y * pop.Z.transpose();
173-
new_m_inv = scaled_y * (pop.Z.transpose() * M_inv);
174+
175+
M = old_m + scaled_ps + scaled_y * pop.Z.transpose();
176+
M_inv = old_m_inv - scaled_inv_ps - scaled_y * (pop.Z.transpose() * M_inv);
174177
}
175178
else
176179
{
177180
const auto scaled_weights = ((0.5 * w.cmu) * w.positive).array().transpose();
178181
const auto scaled_y = (pop.Y.leftCols(mu).array().rowwise() * scaled_weights).matrix();
179-
new_m = scaled_y * pop.Z.leftCols(mu).transpose();
180-
new_m_inv = scaled_y * (pop.Z.leftCols(mu).transpose() * M_inv);
182+
M = old_m + scaled_ps + scaled_y * pop.Z.leftCols(mu).transpose();
183+
M_inv = old_m_inv - scaled_inv_ps - scaled_y * (pop.Z.leftCols(mu).transpose() * M_inv);
181184
}
182-
183-
M = old_m + scaled_ps + new_m;
184-
M_inv = old_m_inv - scaled_inv_ps - new_m_inv;
185185
return true;
186186
}
187187

src/mutation.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ namespace mutation
3838
size_t n_rej = 0;
3939
do
4040
{
41-
p.pop.Z.col(i) = p.mutation->tc->scale((*p.sampler)(), p.bounds->diameter, p.settings.budget, p.stats.evaluations);
42-
p.pop.Y.col(i) = p.adaptation->compute_y(p.pop.Z.col(i));
43-
p.pop.X.col(i) = p.pop.Y.col(i) * p.pop.s(i) + p.adaptation->m;
41+
p.pop.Z.col(i).noalias() = p.mutation->tc->scale((*p.sampler)(), p.bounds->diameter, p.settings.budget, p.stats.evaluations);
42+
p.pop.Y.col(i).noalias() = p.adaptation->compute_y(p.pop.Z.col(i));
43+
p.pop.X.col(i).noalias() = p.pop.Y.col(i) * p.pop.s(i) + p.adaptation->m;
4444
p.bounds->correct(i, p);
4545
} while (
4646
(p.settings.modules.bound_correction == parameters::CorrectionMethod::RESAMPLE && n_rej++ < 5*p.settings.dim && p.bounds->is_out_of_bounds(p.pop.X.col(i)).any()) || p.repelling->is_rejected(p.pop.X.col(i), p));

src/repelling.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ namespace repelling
6666
bool TabooPoint::rejects(const Vector &xi, const parameters::Parameters &p, const int attempts) const
6767
{
6868
const Float rejection_radius = std::pow(shrinkage, attempts) * radius;
69-
const Float delta_xi = distance::mahanolobis(xi, solution.x, p.adaptation->inv_C) / p.mutation->sigma;
69+
const Float delta_xi = distance::mahanolobis(xi, solution.x, p.repelling->C_inv) / p.mutation->sigma;
7070

7171
if (delta_xi < rejection_radius)
7272
return true;
@@ -81,7 +81,7 @@ namespace repelling
8181

8282
void TabooPoint::calculate_criticality(const parameters::Parameters &p)
8383
{
84-
const Float delta_m = distance::mahanolobis(p.adaptation->m, solution.x, p.adaptation->inv_C) / p.mutation->sigma;
84+
const Float delta_m = distance::mahanolobis(p.adaptation->m, solution.x, p.repelling->C_inv) / p.mutation->sigma;
8585
const auto u = delta_m + radius;
8686
const auto l = delta_m - radius;
8787
criticality = cdf(u) - cdf(l);
@@ -97,10 +97,8 @@ namespace repelling
9797
{ return a.criticality > b.criticality; });
9898

9999
//! If it is not intialized
100-
/*
101-
if (C.cols() != p.settings.dim)
100+
if (C_inv.cols() != p.settings.dim)
102101
{
103-
C = Matrix::Identity(p.settings.dim, p.settings.dim);
104102
C_inv = Matrix::Identity(p.settings.dim, p.settings.dim);
105103
}
106104

@@ -110,14 +108,16 @@ namespace repelling
110108
using namespace matrix_adaptation;
111109
const auto dynamic = std::dynamic_pointer_cast<CovarianceAdaptation>(p.adaptation);
112110

113-
const Float d_sigma = p.mutation->sigma / p.settings.sigma0;
111+
C_inv.noalias() = (dynamic->B * dynamic->d.cwiseInverse().asDiagonal()) * dynamic->B.transpose();
112+
113+
/*const Float d_sigma = p.mutation->sigma / p.settings.sigma0;
114114
if (d_sigma > constants::sigma_threshold)
115115
{
116116
C = dynamic->C / dynamic->C.maxCoeff();
117117
C_inv = dynamic->inv_C / dynamic->inv_C.maxCoeff();
118-
}
118+
}*/
119119
}
120-
*/
120+
121121
}
122122

123123
void Repelling::update_archive(FunctionType &objective, parameters::Parameters &p)

src/weights.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ namespace parameters
4949

5050
negative *= (neg_scaler / negative.cwiseAbs().sum());
5151
weights << positive, negative;
52+
53+
lazy_update_interval = 1.0 / (c1 + cmu + 1e-23) / d / 10.0;
54+
std::cout << lazy_update_interval << std::endl;
5255
}
5356

5457
void Weights::weights_default(const size_t lambda)

0 commit comments

Comments
 (0)