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

Xnes issue 1294 #1515

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions pints/_optimisers/_xnes.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def __init__(self, x0, sigma0=None, boundaries=None):
self._bounded_ids = None # Indices of those xs

# Normalisation / distribution
self._mu = np.array(self._x0) # Mean
self._mu = pints.vector(x0) # Mean
self._A = None # Covariance

# Best solution seen
Expand Down Expand Up @@ -106,13 +106,13 @@ def _initialise(self):
d = self._n_parameters
n = self._population_size

# Learning rates
# Learning rates, see Table 1
# TODO Allow changing before run() with method call
self._eta_mu = 1
# TODO Allow changing before run() with method call
self._eta_A = 0.6 * (3 + np.log(d)) * d ** -1.5

# Pre-calculated utilities
# Pre-calculated utilities, see Table 1
self._us = np.maximum(0, np.log(n / 2 + 1) - np.log(1 + np.arange(n)))
self._us /= np.sum(self._us)
self._us -= 1 / n
Expand Down Expand Up @@ -162,10 +162,12 @@ def tell(self, fx):
self._mu += self._eta_mu * np.dot(self._A, Gd)

# Update root of covariance matrix
Gm = np.dot(
np.array([np.outer(z, z).T - self._I for z in self._zs]).T,
self._us)
self._A *= scipy.linalg.expm(np.dot(0.5 * self._eta_A, Gm))
# Note that this is equation 11 (for the eta-sigma=eta-B case), not the
# more general equations 9&10 version given in Algorithm 1
Gm = 0.5 * np.sum([
u * (np.outer(z, z.T) - self._I)
for u, z in zip(self._us, self._zs)], axis=0)
self._A *= scipy.linalg.expm(0.5 * self._eta_A * Gm)

# Update f_guessed on the assumption that the lowest value in our
# sample approximates f(mu)
Expand Down
82 changes: 82 additions & 0 deletions pints/cptests/xnes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env python3
#
# Change point tests for XNES.
#
# This file is part of PINTS (https://github.com/pints-team/pints/) which is
# released under the BSD 3-clause license. See accompanying LICENSE.md for
# copyright notice and full license details.
#
import pints
import pints.cptests as cpt


def bounded_fitzhugh_nagumo(n_iterations=100):
"""
Tests :class:`pints.XNES` on a bounded Fitzhugh-Nagumo model, and returns
a dictionary with ``error`` and ``distance``.

For details of the solved problem, see
:class:`pints.cptests.RunOptimiserOnBoundedUntransformedLogistic`.
"""
problem = cpt.RunOptimiserOnBoundedFitzhughNagumo(
_method, n_iterations, _fguess)
return {
'error': problem.error(),
'distance': problem.distance()
}


def bounded_untransformed_logistic(n_iterations=300):
"""
Tests :class:`pints.XNES` on a bounded logistic model without
transformations, and returns a dictionary with ``error`` and ``distance``.

For details of the solved problem, see
:class:`pints.cptests.RunOptimiserOnBoundedUntransformedLogistic`.
"""
problem = cpt.RunOptimiserOnBoundedUntransformedLogistic(
_method, n_iterations, _fguess)
return {
'error': problem.error(),
'distance': problem.distance()
}


def rosenbrock(n_iterations=100):
"""
Tests :class:`pints.XNES` on a Rosenbrock error and returns a dictionary
with ``error`` and ``distance``.

For details of the solved problem, see
:class:`pints.cptests.RunOptimiserOnRosenbrockError`.
"""
problem = cpt.RunOptimiserOnRosenbrockError(_method, n_iterations, _fguess)
return {
'error': problem.error(),
'distance': problem.distance()
}


def two_dim_parabola(n_iterations=50):
"""
Tests :class:`pints.XNES` on a two-dimensional parabolic error and returns
a dictionary with entries ``error`` and ``distance``.

For details of the solved problem, see
:class:`pints.cptests.RunOptimiserOnTwoDimParabola`.
"""
problem = cpt.RunOptimiserOnTwoDimParabola(_method, n_iterations, _fguess)
return {
'error': problem.error(),
'distance': problem.distance()
}


_method = pints.XNES
_fguess = True
_change_point_tests = [
bounded_fitzhugh_nagumo,
bounded_untransformed_logistic,
rosenbrock,
two_dim_parabola,
]