Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Active-CMA-ES #235

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Implement Active-CMA-ES #235

wants to merge 3 commits into from

Conversation

egomeh
Copy link
Contributor

@egomeh egomeh commented Jun 17, 2018

This PR provides active updates in the CMA-ES algorithm.

The code is implemented and test with reference to the pycma code found at https://github.com/CMA-ES/pycma

Copy link
Member

@Ulfgard Ulfgard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think the code is not as unified as it could be. but my comments should make it a lot easier already. But i have the feeling that we can unify both cases just by setting the negative weights to 0 if no active updates are needed.

@@ -231,6 +238,7 @@ class CMA : public AbstractSingleObjectiveOptimizer<RealVector >

bool m_userSetMu; /// <The user set a value via setMu, do not overwrite with default
bool m_userSetLambda; /// <The user set a value via setMu, do not overwrite with default
bool m_useActiveUpdates = false; /// <Indicates if active updates should be applied
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please put that in the constructor, everything should be at one place.

@@ -79,6 +79,15 @@ class Individual {
}
};

///\brief Reverse ordering relation by the fitness of the individuals(only single objective)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could use a lambda function for that, we are trying to replace all those small functors with them.

m_weights(i) = (double)(mu-i);
negativeWeights(i) = static_cast<double>(mu - (m_lambda - i - 1.));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should not need the static_cast because subtracting a double from mu leads to a double, unlike the line before where an unsigned integral type is assigned to double.

double alphaMu = 2.;
double rankMuAlpha = 0.3;//but is it really?
m_cMu = std::min(1. - m_c1, alphaMu * ( rankMuAlpha + m_muEff - 2. + 1./m_muEff) / (sqr(m_numberOfVariables + 2) + alphaMu * m_muEff / 2)); // eq. (49)
m_cMu = std::min(1. - m_c1, 2. * (.25 + m_muEff + 1. / m_muEff - 2.) / (std::pow(m_numberOfVariables + 2., 2.) + 2. * m_muEff / 2.)); // eq. (49)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace std::pow(a,2.0) by sqr(a)

also this line should be the exact same as before when substitution alphaMu by 2 and changing rankMuAlpha to 0.25

row(vectors, weightIndex) = normalized;
}

m_evolutionPathC = (1. - m_cC) * m_evolutionPathC + hSig * (std::sqrt(m_cC * (2. - m_cC) * m_muEff) / m_sigma) * (m - m_mean);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the same as linke 382. (m-mean)/sigma is y. Please try to unify!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it should, I did have some weird error when I did it with y instead, but that might origin from somewhere else. I will try to update it!

@@ -314,8 +325,63 @@ void CMA::updatePopulation( std::vector<IndividualType> const& offspring ) {
if(hSigLHS < hSigRHS) hSig = 1.;
double deltaHSig = (1.-hSig*hSig) * m_cC * (2. - m_cC);

m_evolutionPathC = (1. - m_cC ) * m_evolutionPathC + hSig * std::sqrt( m_cC * (2. - m_cC) * m_muEff ) * y; // eq. (42)
noalias(C) = (1.-m_c1 - m_cMu) * C + m_c1 * ( blas::outer_prod( m_evolutionPathC, m_evolutionPathC ) + deltaHSig * C) + m_cMu * 1./sqr( m_sigma ) * Z; // eq. (43)
const double c1a = m_c1 * (1. - (1. - (hSig * hSig)) * m_cC * (2. - m_cC));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please move inside the if, if you don't use it in both branches (or later)


if (tempWeights[weightIndex] < 0.)
{
const double mahalanobisNorm = sqrt(sum(sqr((trans(B) % normalized) / D)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const double mahalanobisNorm = norm_2((trans(B) % normalized) / D)

or even simpler

const double mahalanobisNorm = norm_2(selectedOffspring[j].chromosome())

tempWeights[weightIndex] *= static_cast<double>(m_numberOfVariables) / sqr(mahalanobisNorm + 1e-9);
}

row(vectors, weightIndex) = normalized;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noalias(row(vectors,weightIndex)) = normalized;

we don't want to copy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants