class documentation

class GaussFullSampler(GaussSampler):

View In Hierarchy

Multi-variate normal distribution with zero mean.

Provides methods to sample from and update a multi-variate normal distribution with zero mean and full covariance matrix.

>>> import cma, numpy as np
>>> g = cma.sampler.GaussFullSampler(np.ones(4))
>>> z = g.sample(1)[0]
>>> assert g.norm([1,0,0,0]) == 1
>>> g.update([[1., 0., 0., 0]], [.9])
>>> g.update_now()
>>> assert g.norm([1,0,0,0]) == 1
>>> g.update([[4., 0., 0.,0]], [.5])
>>> g.update_now()
>>> g *= 2
>>> assert cma.utilities.math.Mh.equals_approximately(g.variances[0], 17)
>>> assert cma.utilities.math.Mh.equals_approximately(g.D[-1]**2, 17)

## TODO

o Clean up CMAEvolutionStrategy attributes related to sampling (like usage of B, C, D, dC, sigma_vec, these are pretty substantial changes). In particular this should become compatible with any StatisticalModelSampler. Plan: keep B, C, D, dC for the time being as output-info attributes, DONE: keep sigma_vec (55 appearances) as a class.

o combination of sigma_vec and C:
• update sigma_vec with y (this is wrong: use "z")
• rescale y according to the inverse update of sigma_vec (as if y is expressed in the new sigma_vec while C in the old)
• update C with the "new" y.
 Parameters dimension (required) define the dimensionality (attribute dimension) of the normal distribution. If dimension is a vector, it sets the diagonal of the initial covariance matrix. lazy_update_gap=0 is the number of iterations to wait between the O(n^3) updates of the sampler. All values <=1 behave identically. constant_trace='' 'arithmetic'/'aeigen' or 'geometric' or 'geigen' (geometric mean of eigenvalues) are available to be constant. randn=np.random.randn is used to generate N(0,1) numbers. eigenmethod=np.linalg.eigh function returning eigenvalues and -vectors of symmetric matrix
 Method __imul__ sm *= factor is a shortcut for sm = sm.__imul__(factor). Method __init__ declarative init, doesn't need to be executed Method correlation return correlation between variables i and j. Method inverse_hessian_scalar_correction return scalar correction alpha such that X and f fit to f(x) = (x-mean) (alpha * C)**-1 (x-mean) Method limit_condition bound condition number to limit by adding eps to the trace. Method multiply_C multiply self.C with factor updating internal states. Method norm compute the Mahalanobis norm that is induced by the statistical model / sample distribution, specifically by covariance matrix C. The expected Mahalanobis norm is about sqrt(dimension). Method reset reset distribution while keeping all other parameters. Method sample return list of i.i.d. samples. Method to_correlation_matrix "re-scale" C to a correlation matrix and return the scaling factors as standard deviations. Method to_linear_transformation return associated linear transformation. Method to_linear_transformation_inverse return inverse of associated linear transformation. Method transform apply linear transformation C**0.5 to x. Method transform_inverse apply inverse linear transformation C**-0.5 to x. Method update update/learn by natural gradient ascent. Method update_now update internal variables for sampling the distribution with the current covariance matrix C. Instance Variable B axis lengths, roots of eigenvalues, sorted Instance Variable C covariance matrix Instance Variable condition_limit Undocumented Instance Variable constant_trace Undocumented Instance Variable count_eigen Undocumented Instance Variable count_tell Undocumented Instance Variable D Undocumented Instance Variable dimension Undocumented Instance Variable eigenmethod Undocumented Instance Variable inverse_root_C Undocumented Instance Variable last_update Undocumented Instance Variable lazy_update_gap Undocumented Instance Variable randn Undocumented Property beta_diagonal_acceleration beta from Algorithm 1 line 16 in https://direct.mit.edu/evco/article/28/3/405/94999/Diagonal-Acceleration-for-Covariance-Matrix Property condition_number Undocumented Property corr_condition condition number of the correlation matrix Property correlation_matrix return correlation matrix of the distribution. Property covariance_matrix Undocumented Property variances vector of coordinate-wise (marginal) variances Method _decompose_C eigen-decompose self.C thereby updating self.B and self.D. Method _sortBD sort columns of B and D according to the values in D Method _updateC Undocumented Instance Variable _beta_diagonal_acceleration Undocumented Instance Variable _corr_condition Undocumented Instance Variable _corr_condition_count_eigen Undocumented Instance Variable _inverse_root_C Undocumented

Inherited from GaussSampler:

 Method set_H set Hessian w.r.t. which to compute the eigen spectrum. Method set_H_by_f set Hessian from f at x0. Property chin approximation of the expected length when isotropic with variance 1. Property eigenspectrum return eigen spectrum w.r.t. H like sqrt(H) C sqrt(H) Instance Variable _left Undocumented Instance Variable _right Undocumented

Inherited from StatisticalModelSamplerWithZeroMeanBaseClass (via GaussSampler):

 Method parameters return dict with (default) parameters, e.g., c1 and cmu. Instance Variable _lam Undocumented Instance Variable _mueff Undocumented Instance Variable _parameters Undocumented
def __imul__(self, factor):

sm *= factor is a shortcut for sm = sm.__imul__(factor).

Multiplies the covariance matrix with factor.

def __init__(self, dimension, lazy_update_gap=0, constant_trace='', condition_limit=None, randn=np.random.randn, eigenmethod=np.linalg.eigh):

declarative init, doesn't need to be executed

def correlation(self, i, j):

return correlation between variables i and j.

def inverse_hessian_scalar_correction(self, mean, sigma, f):

return scalar correction alpha such that X and f fit to f(x) = (x-mean) (alpha * C)**-1 (x-mean)

def limit_condition(self, limit=None):

bound condition number to limit by adding eps to the trace.

This method only changes the sampling distribution, but not the underlying covariance matrix.

We add eps = (a - limit * b) / (limit - 1) to the diagonal variances, derived from limit = (a + eps) / (b + eps) with a, b = lambda_max, lambda_min.

>>> import cma
>>> es = cma.CMAEvolutionStrategy(3 * [1], 1, {'CMA_diagonal_decoding':False, 'verbose':-9})
>>> _ = es.optimize(cma.ff.elli)
>>> assert es.sm.condition_number > 1e4
>>> es.sm.limit_condition(1e4 - 1)
>>> assert es.sm.condition_number < 1e4
def multiply_C(self, factor):

multiply self.C with factor updating internal states.

factor can be a scalar, a vector or a matrix. The vector is used as outer product and multiplied element-wise, i.e., multiply_C(diag(C)**-0.5) generates a correlation matrix.

Details:

def norm(self, x):

compute the Mahalanobis norm that is induced by the statistical model / sample distribution, specifically by covariance matrix C. The expected Mahalanobis norm is about sqrt(dimension).

## Example

>>> import cma, numpy as np
>>> sm = cma.sampler.GaussFullSampler(np.ones(10))
>>> x = np.random.randn(10)
>>> d = sm.norm(x)

d is the norm "in" the true sample distribution, sampled points have a typical distance of sqrt(2*sm.dim), where sm.dim is the dimension, and an expected distance of close to dim**0.5 to the sample mean zero. In the example, d is the Euclidean distance, because C = I.

def reset(self, standard_deviations=None):

reset distribution while keeping all other parameters.

If standard_deviations is not given, np.ones is used, which might not be the original initial setting.

def sample(self, number, lazy_update_gap=None, same_length=False):

return list of i.i.d. samples.

 Parameters number is the number of samples. lazy_update_gap Undocumented same_length Undocumented update controls a possibly lazy update of the sampler.
def to_correlation_matrix(self):

"re-scale" C to a correlation matrix and return the scaling factors as standard deviations.

def to_linear_transformation(self, reset=False):

return associated linear transformation.

If B = sm.to_linear_transformation() and z ~ N(0, I), then np.dot(B, z) ~ Normal(0, sm.C) and sm.C and B have the same eigenvectors. With reset=True, np.dot(B, sm.sample(1)[0]) obeys the same distribution after the call.

def to_linear_transformation_inverse(self, reset=False):

return inverse of associated linear transformation.

If B = sm.to_linear_transformation_inverse() and z ~ Normal(0, sm.C), then np.dot(B, z) ~ Normal(0, I) and sm.C and B have the same eigenvectors. With reset=True, also sm.sample(1)[0] ~ Normal(0, I) after the call.

def transform(self, x):

apply linear transformation C**0.5 to x.

def transform_inverse(self, x):

apply inverse linear transformation C**-0.5 to x.

def update(self, vectors, weights, c1_times_delta_hsigma=0):

The natural gradient used for the update is:

np.dot(weights * vectors.T, vectors)

and equivalently:

sum([outer(weights[i] * vec, vec)
for i, vec in enumerate(vectors)], axis=0)

Details:

• The weights include the learning rate and -1 <= sum( weights[idx]) <= 1 must be True for idx = weights > 0 and for idx = weights < 0.
• The content (length) of vectors with negative weights is changed!
def update_now(self, lazy_update_gap=None):

update internal variables for sampling the distribution with the current covariance matrix C.

This method is O(dim^3) by calling _decompose_C.

If lazy_update_gap is None the lazy_update_gap from init is taken. If lazy_update_gap < 0 the (possibly expensive) update is done even when the model seems to be up to date.

B =

axis lengths, roots of eigenvalues, sorted

C =

covariance matrix

condition_limit =

Undocumented

constant_trace =

Undocumented

count_eigen: int =

Undocumented

count_tell: int =

Undocumented

D =

Undocumented

dimension =

Undocumented

eigenmethod =

Undocumented

inverse_root_C =

Undocumented

last_update =

Undocumented

lazy_update_gap =

Undocumented

randn =

Undocumented

@property
beta_diagonal_acceleration =
@property
condition_number =

Undocumented

@property
corr_condition =

condition number of the correlation matrix

@property
correlation_matrix =

return correlation matrix of the distribution.

@property
covariance_matrix =

Undocumented

@property
variances =

vector of coordinate-wise (marginal) variances

def _decompose_C(self):

eigen-decompose self.C thereby updating self.B and self.D.

Know bugs: if update is not called before decompose, the state variables can get into an inconsistent state.

def _sortBD(self):

sort columns of B and D according to the values in D

def _updateC(self):

Undocumented

_beta_diagonal_acceleration: int =

Undocumented

_corr_condition: int =

Undocumented

_corr_condition_count_eigen: int =

Undocumented

_inverse_root_C =

Undocumented