@@ -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
0 commit comments