diff --git a/doc/_build/doctrees/GPy.core.doctree b/doc/_build/doctrees/GPy.core.doctree new file mode 100644 index 00000000..e9ed8678 Binary files /dev/null and b/doc/_build/doctrees/GPy.core.doctree differ diff --git a/doc/_build/doctrees/GPy.core.parameterization.doctree b/doc/_build/doctrees/GPy.core.parameterization.doctree new file mode 100644 index 00000000..e493b79a Binary files /dev/null and b/doc/_build/doctrees/GPy.core.parameterization.doctree differ diff --git a/doc/_build/doctrees/GPy.doctree b/doc/_build/doctrees/GPy.doctree new file mode 100644 index 00000000..53170549 Binary files /dev/null and b/doc/_build/doctrees/GPy.doctree differ diff --git a/doc/_build/doctrees/GPy.examples.doctree b/doc/_build/doctrees/GPy.examples.doctree new file mode 100644 index 00000000..db46b57d Binary files /dev/null and b/doc/_build/doctrees/GPy.examples.doctree differ diff --git a/doc/_build/doctrees/GPy.inference.doctree b/doc/_build/doctrees/GPy.inference.doctree new file mode 100644 index 00000000..42162daa Binary files /dev/null and b/doc/_build/doctrees/GPy.inference.doctree differ diff --git a/doc/_build/doctrees/GPy.inference.latent_function_inference.doctree b/doc/_build/doctrees/GPy.inference.latent_function_inference.doctree new file mode 100644 index 00000000..bd09a240 Binary files /dev/null and b/doc/_build/doctrees/GPy.inference.latent_function_inference.doctree differ diff --git a/doc/_build/doctrees/GPy.inference.mcmc.doctree b/doc/_build/doctrees/GPy.inference.mcmc.doctree new file mode 100644 index 00000000..df137ca0 Binary files /dev/null and b/doc/_build/doctrees/GPy.inference.mcmc.doctree differ diff --git a/doc/_build/doctrees/GPy.inference.optimization.doctree b/doc/_build/doctrees/GPy.inference.optimization.doctree new file mode 100644 index 00000000..23042df5 Binary files /dev/null and b/doc/_build/doctrees/GPy.inference.optimization.doctree differ diff --git a/doc/_build/doctrees/GPy.kern._src.doctree b/doc/_build/doctrees/GPy.kern._src.doctree new file mode 100644 index 00000000..8f666e83 Binary files /dev/null and b/doc/_build/doctrees/GPy.kern._src.doctree differ diff --git a/doc/_build/doctrees/GPy.kern._src.psi_comp.doctree b/doc/_build/doctrees/GPy.kern._src.psi_comp.doctree new file mode 100644 index 00000000..9cbde4d1 Binary files /dev/null and b/doc/_build/doctrees/GPy.kern._src.psi_comp.doctree differ diff --git a/doc/_build/doctrees/GPy.kern.doctree b/doc/_build/doctrees/GPy.kern.doctree new file mode 100644 index 00000000..9310e96f Binary files /dev/null and b/doc/_build/doctrees/GPy.kern.doctree differ diff --git a/doc/_build/doctrees/GPy.likelihoods.doctree b/doc/_build/doctrees/GPy.likelihoods.doctree new file mode 100644 index 00000000..3f788400 Binary files /dev/null and b/doc/_build/doctrees/GPy.likelihoods.doctree differ diff --git a/doc/_build/doctrees/GPy.mappings.doctree b/doc/_build/doctrees/GPy.mappings.doctree new file mode 100644 index 00000000..ea6915ba Binary files /dev/null and b/doc/_build/doctrees/GPy.mappings.doctree differ diff --git a/doc/_build/doctrees/GPy.models.doctree b/doc/_build/doctrees/GPy.models.doctree new file mode 100644 index 00000000..02d86329 Binary files /dev/null and b/doc/_build/doctrees/GPy.models.doctree differ diff --git a/doc/_build/doctrees/GPy.plotting.doctree b/doc/_build/doctrees/GPy.plotting.doctree new file mode 100644 index 00000000..094aa9b7 Binary files /dev/null and b/doc/_build/doctrees/GPy.plotting.doctree differ diff --git a/doc/_build/doctrees/GPy.plotting.matplot_dep.doctree b/doc/_build/doctrees/GPy.plotting.matplot_dep.doctree new file mode 100644 index 00000000..d12ce442 Binary files /dev/null and b/doc/_build/doctrees/GPy.plotting.matplot_dep.doctree differ diff --git a/doc/_build/doctrees/GPy.plotting.matplot_dep.latent_space_visualizations.controllers.doctree b/doc/_build/doctrees/GPy.plotting.matplot_dep.latent_space_visualizations.controllers.doctree new file mode 100644 index 00000000..562938dc Binary files /dev/null and b/doc/_build/doctrees/GPy.plotting.matplot_dep.latent_space_visualizations.controllers.doctree differ diff --git a/doc/_build/doctrees/GPy.plotting.matplot_dep.latent_space_visualizations.doctree b/doc/_build/doctrees/GPy.plotting.matplot_dep.latent_space_visualizations.doctree new file mode 100644 index 00000000..5c9e38c7 Binary files /dev/null and b/doc/_build/doctrees/GPy.plotting.matplot_dep.latent_space_visualizations.doctree differ diff --git a/doc/_build/doctrees/GPy.testing.doctree b/doc/_build/doctrees/GPy.testing.doctree new file mode 100644 index 00000000..20aa61b8 Binary files /dev/null and b/doc/_build/doctrees/GPy.testing.doctree differ diff --git a/doc/_build/doctrees/GPy.util.doctree b/doc/_build/doctrees/GPy.util.doctree new file mode 100644 index 00000000..5c1e9efa Binary files /dev/null and b/doc/_build/doctrees/GPy.util.doctree differ diff --git a/doc/_build/doctrees/environment.pickle b/doc/_build/doctrees/environment.pickle new file mode 100644 index 00000000..14100e4a Binary files /dev/null and b/doc/_build/doctrees/environment.pickle differ diff --git a/doc/_build/doctrees/index.doctree b/doc/_build/doctrees/index.doctree new file mode 100644 index 00000000..04f4d028 Binary files /dev/null and b/doc/_build/doctrees/index.doctree differ diff --git a/doc/_build/doctrees/installation.doctree b/doc/_build/doctrees/installation.doctree new file mode 100644 index 00000000..195db464 Binary files /dev/null and b/doc/_build/doctrees/installation.doctree differ diff --git a/doc/_build/doctrees/kernel_implementation.doctree b/doc/_build/doctrees/kernel_implementation.doctree new file mode 100644 index 00000000..4d0d36e9 Binary files /dev/null and b/doc/_build/doctrees/kernel_implementation.doctree differ diff --git a/doc/_build/doctrees/modules.doctree b/doc/_build/doctrees/modules.doctree new file mode 100644 index 00000000..67728e5d Binary files /dev/null and b/doc/_build/doctrees/modules.doctree differ diff --git a/doc/_build/doctrees/tuto_GP_regression.doctree b/doc/_build/doctrees/tuto_GP_regression.doctree new file mode 100644 index 00000000..0865f87e Binary files /dev/null and b/doc/_build/doctrees/tuto_GP_regression.doctree differ diff --git a/doc/_build/doctrees/tuto_creating_new_kernels.doctree b/doc/_build/doctrees/tuto_creating_new_kernels.doctree new file mode 100644 index 00000000..e763c109 Binary files /dev/null and b/doc/_build/doctrees/tuto_creating_new_kernels.doctree differ diff --git a/doc/_build/doctrees/tuto_creating_new_models.doctree b/doc/_build/doctrees/tuto_creating_new_models.doctree new file mode 100644 index 00000000..0178e75c Binary files /dev/null and b/doc/_build/doctrees/tuto_creating_new_models.doctree differ diff --git a/doc/_build/doctrees/tuto_interacting_with_models.doctree b/doc/_build/doctrees/tuto_interacting_with_models.doctree new file mode 100644 index 00000000..a28bb06c Binary files /dev/null and b/doc/_build/doctrees/tuto_interacting_with_models.doctree differ diff --git a/doc/_build/doctrees/tuto_kernel_overview.doctree b/doc/_build/doctrees/tuto_kernel_overview.doctree new file mode 100644 index 00000000..e3c0c34e Binary files /dev/null and b/doc/_build/doctrees/tuto_kernel_overview.doctree differ diff --git a/doc/_build/doctrees/tuto_parameterized.doctree b/doc/_build/doctrees/tuto_parameterized.doctree new file mode 100644 index 00000000..c0417a75 Binary files /dev/null and b/doc/_build/doctrees/tuto_parameterized.doctree differ diff --git a/doc/_build/html/.buildinfo b/doc/_build/html/.buildinfo new file mode 100644 index 00000000..0885fbe1 --- /dev/null +++ b/doc/_build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: +tags: diff --git a/doc/_build/html/GPy.core.html b/doc/_build/html/GPy.core.html new file mode 100644 index 00000000..dc25a274 --- /dev/null +++ b/doc/_build/html/GPy.core.html @@ -0,0 +1,889 @@ + + + + + + + + GPy.core package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.core package

+ +
+

Submodules

+
+
+

GPy.core.gp module

+
+
+class GPy.core.gp.GP(X, Y, kernel, likelihood, inference_method=None, name='gp', Y_metadata=None, normalizer=False)[source]
+

Bases: GPy.core.model.Model

+

General purpose Gaussian process model

+ +++ + + + + + +
Parameters:
    +
  • X – input observations
  • +
  • Y – output observations
  • +
  • kernel – a GPy kernel, defaults to rbf+white
  • +
  • likelihood – a GPy likelihood
  • +
  • inference_method – The LatentFunctionInference inference method to use for this GP
  • +
  • normalizer (Norm) – normalize the outputs Y. +Prediction will be un-normalized using this normalizer. +If normalizer is None, we will normalize using MeanNorm. +If normalizer is False, no normalization will be done.
  • +
+
Return type:

model object

+
+
+

Note

+

Multiple independent outputs are allowed using columns of Y

+
+
+
+infer_newX(Y_new, optimize=True)[source]
+

Infer the distribution of X for the new observed data Y_new.

+ +++ + + + + + + + +
Parameters:
    +
  • Y_new (numpy.ndarray) – the new observed data for inference
  • +
  • optimize (boolean) – whether to optimize the location of new X (True by default)
  • +
+
Returns:

a tuple containing the posterior estimation of X and the model that optimize X

+
Return type:

(VariationalPosterior or numpy.ndarray, Model)

+
+
+ +
+
+input_sensitivity(summarize=True)[source]
+

Returns the sensitivity for each dimension of this model

+
+ +
+
+log_likelihood()[source]
+

The log marginal likelihood of the model, p(\mathbf{y}), this is the objective function of the model being optimised

+
+ +
+
+optimize(optimizer=None, start=None, **kwargs)[source]
+

Optimize the model using self.log_likelihood and self.log_likelihood_gradient, as well as self.priors. +kwargs are passed to the optimizer. They can be:

+ +++ + + + + + +
Parameters:
    +
  • max_f_eval (int) – maximum number of function evaluations
  • +
  • optimizer (string) – which optimizer to use (defaults to self.preferred optimizer), a range of optimisers can be found in :module:`~GPy.inference.optimization`, they include ‘scg’, ‘lbfgs’, ‘tnc’.
  • +
+
Messages:

whether to display during optimisation

+
+
+ +
+
+parameters_changed()[source]
+

Method that is called upon any changes to Param variables within the model. +In particular in the GP class this method reperforms inference, recalculating the posterior and log marginal likelihood and gradients of the model

+
+

Warning

+

This method is not designed to be called manually, the framework is set up to automatically call this method upon changes to parameters, if you call +this method yourself, there may be unexpected consequences.

+
+
+ +
+
+plot(plot_limits=None, which_data_rows='all', which_data_ycols='all', fixed_inputs=[], levels=20, samples=0, fignum=None, ax=None, resolution=None, plot_raw=False, linecol=None, fillcol=None, Y_metadata=None, data_symbol='kx')[source]
+
+
Plot the posterior of the GP.
+
    +
  • In one dimension, the function is plotted with a shaded region identifying two standard deviations.
  • +
  • In two dimsensions, a contour-plot shows the mean predicted function
  • +
  • In higher dimensions, use fixed_inputs to plot the GP with some of the inputs fixed.
  • +
+
+
+

Can plot only part of the data and part of the posterior functions +using which_data_rowsm which_data_ycols.

+ +++ + + + +
Parameters:
    +
  • plot_limits (np.array) – The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
  • +
  • which_data_rows (‘all’ or a slice object to slice model.X, model.Y) – which of the training data to plot (default all)
  • +
  • which_data_ycols (‘all’ or a list of integers) – when the data has several columns (independant outputs), only plot these
  • +
  • fixed_inputs (a list of tuples) – a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
  • +
  • resolution (int) – the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
  • +
  • levels (int) – number of levels to plot in a contour plot.
  • +
  • levels – for 2D plotting, the number of contour levels to use is ax is None, create a new figure
  • +
  • samples (int) – the number of a posteriori samples to plot
  • +
  • fignum (figure number) – figure to plot on.
  • +
  • ax (axes handle) – axes to plot on.
  • +
  • linecol (color either as Tango.colorsHex object or character (‘r’ is red, ‘g’ is green) as is standard in matplotlib) – color of line to plot [Tango.colorsHex[‘darkBlue’]]
  • +
  • fillcol (color either as Tango.colorsHex object or character (‘r’ is red, ‘g’ is green) as is standard in matplotlib) – color of fill [Tango.colorsHex[‘lightBlue’]]
  • +
  • Y_metadata (dict) – additional data associated with Y which may be needed
  • +
  • data_symbol (color either as Tango.colorsHex object or character (‘r’ is red, ‘g’ is green) alongside marker type, as is standard in matplotlib.) – symbol as used matplotlib, by default this is a black cross (‘kx’)
  • +
+
+
+ +
+
+plot_f(plot_limits=None, which_data_rows='all', which_data_ycols='all', fixed_inputs=[], levels=20, samples=0, fignum=None, ax=None, resolution=None, plot_raw=True, linecol=None, fillcol=None, Y_metadata=None, data_symbol='kx')[source]
+

Plot the GP’s view of the world, where the data is normalized and before applying a likelihood. +This is a call to plot with plot_raw=True. +Data will not be plotted in this, as the GP’s view of the world +may live in another space, or units then the data.

+

Can plot only part of the data and part of the posterior functions +using which_data_rowsm which_data_ycols.

+ +++ + + + +
Parameters:
    +
  • plot_limits (np.array) – The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
  • +
  • which_data_rows (‘all’ or a slice object to slice model.X, model.Y) – which of the training data to plot (default all)
  • +
  • which_data_ycols (‘all’ or a list of integers) – when the data has several columns (independant outputs), only plot these
  • +
  • fixed_inputs (a list of tuples) – a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
  • +
  • resolution (int) – the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
  • +
  • levels (int) – number of levels to plot in a contour plot.
  • +
  • levels – for 2D plotting, the number of contour levels to use is ax is None, create a new figure
  • +
  • samples (int) – the number of a posteriori samples to plot
  • +
  • fignum (figure number) – figure to plot on.
  • +
  • ax (axes handle) – axes to plot on.
  • +
  • linecol (color either as Tango.colorsHex object or character (‘r’ is red, ‘g’ is green) as is standard in matplotlib) – color of line to plot [Tango.colorsHex[‘darkBlue’]]
  • +
  • fillcol (color either as Tango.colorsHex object or character (‘r’ is red, ‘g’ is green) as is standard in matplotlib) – color of fill [Tango.colorsHex[‘lightBlue’]]
  • +
  • Y_metadata (dict) – additional data associated with Y which may be needed
  • +
  • data_symbol (color either as Tango.colorsHex object or character (‘r’ is red, ‘g’ is green) alongside marker type, as is standard in matplotlib.) – symbol as used matplotlib, by default this is a black cross (‘kx’)
  • +
+
+
+ +
+
+posterior_samples(X, size=10, full_cov=False, Y_metadata=None)[source]
+

Samples the posterior GP at the points X.

+ +++ + + + + + +
Parameters:
    +
  • X (np.ndarray (Nnew x self.input_dim.)) – the points at which to take the samples.
  • +
  • size (int.) – the number of a posteriori samples.
  • +
  • full_cov (bool.) – whether to return the full covariance matrix, or just the diagonal.
  • +
  • noise_model (integer.) – for mixed noise likelihood, the noise model to use in the samples.
  • +
+
Returns:

Ysim: set of simulations, a Numpy array (N x samples).

+
+
+ +
+
+posterior_samples_f(X, size=10, full_cov=True)[source]
+

Samples the posterior GP at the points X.

+ +++ + + + + + + + +
Parameters:
    +
  • X (np.ndarray (Nnew x self.input_dim)) – The points at which to take the samples.
  • +
  • size (int.) – the number of a posteriori samples.
  • +
  • full_cov (bool.) – whether to return the full covariance matrix, or just the diagonal.
  • +
+
Returns:

Ysim: set of simulations

+
Return type:

np.ndarray (N x samples)

+
+
+ +
+
+predict(Xnew, full_cov=False, Y_metadata=None, kern=None)[source]
+

Predict the function(s) at the new point(s) Xnew.

+ +++ + + + + + +
Parameters:
    +
  • Xnew (np.ndarray (Nnew x self.input_dim)) – The points at which to make a prediction
  • +
  • full_cov (bool) – whether to return the full covariance matrix, or just +the diagonal
  • +
  • Y_metadata – metadata about the predicting point to pass to the likelihood
  • +
  • kern – The kernel to use for prediction (defaults to the model +kern). this is useful for examining e.g. subprocesses.
  • +
+
Returns:

+
(mean, var, lower_upper):
+

mean: posterior mean, a Numpy array, Nnew x self.input_dim +var: posterior variance, a Numpy array, Nnew x 1 if full_cov=False, Nnew x Nnew otherwise +lower_upper: lower and upper boundaries of the 95% confidence intervals, Numpy arrays, Nnew x self.input_dim

+
+
+

If full_cov and self.input_dim > 1, the return shape of var is Nnew x Nnew x self.input_dim. If self.input_dim == 1, the return shape is Nnew x Nnew. +This is to allow for different normalizations of the output dimensions.

+

+
+
+ +
+
+predict_quantiles(X, quantiles=(2.5, 97.5), Y_metadata=None)[source]
+

Get the predictive quantiles around the prediction at X

+ +++ + + + + + + + +
Parameters:
    +
  • X (np.ndarray (Xnew x self.input_dim)) – The points at which to make a prediction
  • +
  • quantiles (tuple) – tuple of quantiles, default is (2.5, 97.5) which is the 95% interval
  • +
+
Returns:

list of quantiles for each X and predictive quantiles for interval combination

+
Return type:

[np.ndarray (Xnew x self.input_dim), np.ndarray (Xnew x self.input_dim)]

+
+
+ +
+
+predictive_gradients(Xnew)[source]
+

Compute the derivatives of the latent function with respect to X*

+

Given a set of points at which to predict X* (size [N*,Q]), compute the +derivatives of the mean and variance. Resulting arrays are sized:

+
+

dmu_dX* – [N*, Q ,D], where D is the number of output in this GP (usually one).

+

dv_dX* – [N*, Q], (since all outputs have the same variance)

+
+ +++ + + + + + + + +
Parameters:X (np.ndarray (Xnew x self.input_dim)) – The points at which to get the predictive gradients
Returns:dmu_dX, dv_dX
Return type:[np.ndarray (N*, Q ,D), np.ndarray (N*,Q) ]
+
+ +
+
+set_X(X)[source]
+

Set the input data of the model

+ +++ + + + +
Parameters:X (np.ndarray) – input observations
+
+ +
+
+set_XY(X=None, Y=None)[source]
+

Set the input / output data of the model +This is useful if we wish to change our existing data but maintain the same model

+ +++ + + + +
Parameters:
    +
  • X (np.ndarray) – input observations
  • +
  • Y (np.ndarray) – output observations
  • +
+
+
+ +
+
+set_Y(Y)[source]
+

Set the output data of the model

+ +++ + + + +
Parameters:X (np.ndarray) – output observations
+
+ +
+ +
+
+

GPy.core.mapping module

+
+
+class GPy.core.mapping.Bijective_mapping(input_dim, output_dim, name='bijective_mapping')[source]
+

Bases: GPy.core.mapping.Mapping

+

This is a mapping that is bijective, i.e. you can go from X to f and +also back from f to X. The inverse mapping is called g().

+
+
+g(f)[source]
+

Inverse mapping from output domain of the function to the inputs.

+
+ +
+ +
+
+class GPy.core.mapping.Mapping(input_dim, output_dim, name='mapping')[source]
+

Bases: GPy.core.parameterization.parameterized.Parameterized

+

Base model for shared behavior between models that can act like a mapping.

+
+
+df_dX(dL_df, X)[source]
+

Evaluate derivatives of mapping outputs with respect to inputs.

+ +++ + + + + + +
Parameters:
    +
  • dL_df (ndarray (num_data x output_dim)) – gradient of the objective with respect to the function.
  • +
  • X (ndarray (num_data x input_dim)) – the input locations where derivatives are to be evaluated.
  • +
+
Returns:

matrix containing gradients of the function with respect to the inputs.

+
+
+ +
+
+df_dtheta(dL_df, X)[source]
+

The gradient of the outputs of the mapping with respect to each of the parameters.

+ +++ + + + + + + + +
Parameters:
    +
  • dL_df (ndarray (num_data x output_dim)) – gradient of the objective with respect to the function.
  • +
  • X (ndarray (num_data x input_dim)) – input locations where the function is evaluated.
  • +
+
Returns:

Matrix containing gradients with respect to parameters of each output for each input data.

+
Return type:

ndarray (num_params length)

+
+
+ +
+
+f(X)[source]
+
+ +
+
+plot(*args)[source]
+
+
Plots the mapping associated with the model.
+
    +
  • In one dimension, the function is plotted.
  • +
  • In two dimensions, a contour-plot shows the function
  • +
  • In higher dimensions, we’ve not implemented this yet !TODO!
  • +
+
+
+

Can plot only part of the data and part of the posterior functions +using which_data and which_functions

+

This is a convenience function: arguments are passed to +GPy.plotting.matplot_dep.models_plots.plot_mapping

+
+ +
+ +
+
+class GPy.core.mapping.Mapping_check_df_dX(mapping=None, dL_df=None, X=None)[source]
+

Bases: GPy.core.mapping.Mapping_check_model

+

This class allows gradient checks for the gradient of a mapping with respect to X.

+
+ +
+
+class GPy.core.mapping.Mapping_check_df_dtheta(mapping=None, dL_df=None, X=None)[source]
+

Bases: GPy.core.mapping.Mapping_check_model

+

This class allows gradient checks for the gradient of a mapping with respect to parameters.

+
+ +
+
+class GPy.core.mapping.Mapping_check_model(mapping=None, dL_df=None, X=None)[source]
+

Bases: GPy.core.model.Model

+

This is a dummy model class used as a base class for checking that the +gradients of a given mapping are implemented correctly. It enables +checkgradient() to be called independently on each mapping.

+
+
+log_likelihood()[source]
+
+ +
+ +
+
+

GPy.core.model module

+
+
+class GPy.core.model.Model(name)[source]
+

Bases: GPy.core.parameterization.parameterized.Parameterized

+
+
+ensure_default_constraints(warning=True)[source]
+

Ensure that any variables which should clearly be positive +have been constrained somehow. The method performs a regular +expression search on parameter names looking for the terms +‘variance’, ‘lengthscale’, ‘precision’ and ‘kappa’. If any of +these terms are present in the name the parameter is +constrained positive.

+

DEPRECATED.

+
+ +
+
+log_likelihood()[source]
+
+ +
+
+objective_function()[source]
+

The objective function for the given algorithm.

+

This function is the true objective, which wants to be minimized. +Note that all parameters are already set and in place, so you just need +to return the objective function here.

+

For probabilistic models this is the negative log_likelihood +(including the MAP prior), so we return it here. If your model is not +probabilistic, just return your objective to minimize here!

+
+ +
+
+objective_function_gradients()[source]
+

The gradients for the objective function for the given algorithm. +The gradients are w.r.t. the negative objective function, as +this framework works with negative log-likelihoods as a default.

+

You can find the gradient for the parameters in self.gradient at all times. +This is the place, where gradients get stored for parameters.

+

This function is the true objective, which wants to be minimized. +Note that all parameters are already set and in place, so you just need +to return the gradient here.

+

For probabilistic models this is the gradient of the negative log_likelihood +(including the MAP prior), so we return it here. If your model is not +probabilistic, just return your negative gradient here!

+
+ +
+
+optimize(optimizer=None, start=None, **kwargs)[source]
+

Optimize the model using self.log_likelihood and self.log_likelihood_gradient, as well as self.priors.

+

kwargs are passed to the optimizer. They can be:

+ +++ + + + + + +
Parameters:
    +
  • max_f_eval (int) – maximum number of function evaluations
  • +
  • optimizer (string) – which optimizer to use (defaults to self.preferred optimizer)
  • +
+
Messages:

whether to display during optimisation

+
+
+
Valid optimizers are:
+
    +
  • +
    ‘scg’: scaled conjugate gradient method, recommended for stability.
    +

    See also GPy.inference.optimization.scg

    +
    +
    +
  • +
  • ‘fmin_tnc’: truncated Newton method (see scipy.optimize.fmin_tnc)

    +
  • +
  • ‘simplex’: the Nelder-Mead simplex method (see scipy.optimize.fmin),

    +
  • +
  • ‘lbfgsb’: the l-bfgs-b method (see scipy.optimize.fmin_l_bfgs_b),

    +
  • +
  • ‘sgd’: stochastic gradient decsent (see scipy.optimize.sgd). For experts only!

    +
  • +
+
+
+
+ +
+
+optimize_SGD(momentum=0.1, learning_rate=0.01, iterations=20, **kwargs)[source]
+
+ +
+
+optimize_restarts(num_restarts=10, robust=False, verbose=True, parallel=False, num_processes=None, **kwargs)[source]
+

Perform random restarts of the model, and set the model to the best +seen solution.

+

If the robust flag is set, exceptions raised during optimizations will +be handled silently. If _all_ runs fail, the model is reset to the +existing parameter values.

+

Notes

+ +++ + + + +
Parameters:
    +
  • num_restarts (int) – number of restarts to use (default 10)
  • +
  • robust (bool) – whether to handle exceptions silently or not (default False)
  • +
  • parallel (bool) – whether to run each restart as a separate process. It relies on the multiprocessing module.
  • +
  • num_processes – number of workers in the multiprocessing pool
  • +
+
+

**kwargs are passed to the optimizer. They can be:

+ +++ + + + +
Parameters:
    +
  • max_f_eval (int) – maximum number of function evaluations
  • +
  • max_iters (int) – maximum number of iterations
  • +
  • messages (bool) – whether to display during optimisation
  • +
+
+
+

Note

+

If num_processes is None, the number of workes in the

+
+

multiprocessing pool is automatically set to the number of processors +on the current machine.

+
+ +
+ +
+
+

GPy.core.sparse_gp module

+
+
+class GPy.core.sparse_gp.SparseGP(X, Y, Z, kernel, likelihood, inference_method=None, name='sparse gp', Y_metadata=None, normalizer=False)[source]
+

Bases: GPy.core.gp.GP

+

A general purpose Sparse GP model

+

This model allows (approximate) inference using variational DTC or FITC +(Gaussian likelihoods) as well as non-conjugate sparse methods based on +these.

+ +++ + + + +
Parameters:
    +
  • X (np.ndarray (num_data x input_dim)) – inputs
  • +
  • likelihood (GPy.likelihood.(Gaussian | EP | Laplace)) – a likelihood instance, containing the observed data
  • +
  • kernel (a GPy.kern.kern instance) – the kernel (covariance function). See link kernels
  • +
  • X_variance (np.ndarray (num_data x input_dim) | None) – The uncertainty in the measurements of X (Gaussian variance)
  • +
  • Z (np.ndarray (num_inducing x input_dim)) – inducing inputs
  • +
  • num_inducing (int) – Number of inducing points (optional, default 10. Ignored if Z is not None)
  • +
+
+
+
+has_uncertain_inputs()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+ +
+
+

GPy.core.sparse_gp_mpi module

+
+
+class GPy.core.sparse_gp_mpi.SparseGP_MPI(X, Y, Z, kernel, likelihood, variational_prior=None, inference_method=None, name='sparse gp mpi', Y_metadata=None, mpi_comm=None, normalizer=False)[source]
+

Bases: GPy.core.sparse_gp.SparseGP

+

A general purpose Sparse GP model with MPI parallelization support

+

This model allows (approximate) inference using variational DTC or FITC +(Gaussian likelihoods) as well as non-conjugate sparse methods based on +these.

+ +++ + + + +
Parameters:
    +
  • X (np.ndarray (num_data x input_dim)) – inputs
  • +
  • likelihood (GPy.likelihood.(Gaussian | EP | Laplace)) – a likelihood instance, containing the observed data
  • +
  • kernel (a GPy.kern.kern instance) – the kernel (covariance function). See link kernels
  • +
  • X_variance (np.ndarray (num_data x input_dim) | None) – The uncertainty in the measurements of X (Gaussian variance)
  • +
  • Z (np.ndarray (num_inducing x input_dim)) – inducing inputs
  • +
  • num_inducing (int) – Number of inducing points (optional, default 10. Ignored if Z is not None)
  • +
  • mpi_comm (mpi4py.MPI.Intracomm) – The communication group of MPI, e.g. mpi4py.MPI.COMM_WORLD
  • +
+
+
+
+optimize(optimizer=None, start=None, **kwargs)[source]
+
+ +
+
+optimizer_array
+

Array for the optimizer to work on. +This array always lives in the space for the optimizer. +Thus, it is untransformed, going from Transformations.

+

Setting this array, will make sure the transformed parameters for this model +will be set accordingly. It has to be set with an array, retrieved from +this method, as e.g. fixing will resize the array.

+

The optimizer should only interfere with this array, such that transformations +are secured.

+
+ +
+
+parameters_changed()[source]
+
+ +
+ +
+
+

GPy.core.svigp module

+
+
+

GPy.core.symbolic module

+
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.core.parameterization.html b/doc/_build/html/GPy.core.parameterization.html new file mode 100644 index 00000000..0a2a6db3 --- /dev/null +++ b/doc/_build/html/GPy.core.parameterization.html @@ -0,0 +1,2528 @@ + + + + + + + + GPy.core.parameterization package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.core.parameterization package

+
+

Submodules

+
+
+

GPy.core.parameterization.domains module

+

(Hyper-)Parameter domains defined for priors and kern. +These domains specify the legitimate realm of the parameters to live in.

+
+
_REAL :
+
real domain, all values in the real numbers are allowed
+
_POSITIVE:
+
positive domain, only positive real values are allowed
+
_NEGATIVE:
+
same as _POSITIVE, but only negative values are allowed
+
_BOUNDED:
+
only values within the bounded range are allowed, +the bounds are specified withing the object with the bounded range
+
+
+
+

GPy.core.parameterization.index_operations module

+
+
+class GPy.core.parameterization.index_operations.ParameterIndexOperations(constraints=None)[source]
+

Bases: object

+

This object wraps a dictionary, whos keys are _operations_ that we’d like +to apply to a parameter array, and whose values are np integer arrays which +index the parameter array appropriately.

+

A model instance will contain one instance of this class for each thing +that needs indexing (i.e. constraints, ties and priors). Parameters within +the model constain instances of the ParameterIndexOperationsView class, +which can map from a ‘local’ index (starting 0) to this global index.

+

Here’s an illustration:

+

#======================================================================= +model : 0 1 2 3 4 5 6 7 8 9 +key1: 4 5 +key2: 7 8

+

param1: 0 1 2 3 4 5 +key1: 2 3 +key2: 5

+

param2: 0 1 2 3 4 +key1: 0 +key2: 2 3 +#=======================================================================

+

The views of this global index have a subset of the keys in this global +(model) index.

+

Adding a new key (e.g. a constraint) to a view will cause the view to pass +the new key to the global index, along with the local index and an offset. +This global index then stores the key and the appropriate global index +(which can be seen by the view).

+

See also: +ParameterIndexOperationsView

+
+
+add(prop, indices)[source]
+
+ +
+
+clear()[source]
+
+ +
+
+copy()[source]
+
+ +
+
+indices()[source]
+
+ +
+
+items()[source]
+
+ +
+
+iterindices()[source]
+
+ +
+
+iteritems()[source]
+
+ +
+
+iterproperties()[source]
+
+ +
+
+properties()[source]
+
+ +
+
+properties_for(index)[source]
+

Returns a list of properties, such that each entry in the list corresponds +to the element of the index given.

+

Example: +let properties: ‘one’:[1,2,3,4], ‘two’:[3,5,6]

+
>>> properties_for([2,3,5])
+[['one'], ['one', 'two'], ['two']]
+
+
+
+ +
+
+properties_to_index_dict(index)[source]
+

Return a dictionary, containing properties as keys and indices as index +Thus, the indices for each constraint, which is contained will be collected as +one dictionary

+

Example: +let properties: ‘one’:[1,2,3,4], ‘two’:[3,5,6]

+
>>> properties_to_index_dict([2,3,5])
+{'one':[2,3], 'two':[3,5]}
+
+
+
+ +
+
+remove(prop, indices)[source]
+
+ +
+
+shift_left(start, size)[source]
+
+ +
+
+shift_right(start, size)[source]
+
+ +
+
+size
+
+ +
+
+update(parameter_index_view, offset=0)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.index_operations.ParameterIndexOperationsView(param_index_operations, offset, size)[source]
+

Bases: object

+
+
+add(prop, indices)[source]
+
+ +
+
+clear()[source]
+
+ +
+
+copy()[source]
+
+ +
+
+indices()[source]
+
+ +
+
+items()[source]
+
+ +
+
+iterindices()[source]
+
+ +
+
+iteritems()[source]
+
+ +
+
+iterproperties()[source]
+
+ +
+
+properties()[source]
+
+ +
+
+properties_for(index)[source]
+

Returns a list of properties, such that each entry in the list corresponds +to the element of the index given.

+

Example: +let properties: ‘one’:[1,2,3,4], ‘two’:[3,5,6]

+
>>> properties_for([2,3,5])
+[['one'], ['one', 'two'], ['two']]
+
+
+
+ +
+
+properties_to_index_dict(index)[source]
+

Return a dictionary, containing properties as keys and indices as index +Thus, the indices for each constraint, which is contained will be collected as +one dictionary

+

Example: +let properties: ‘one’:[1,2,3,4], ‘two’:[3,5,6]

+
>>> properties_to_index_dict([2,3,5])
+{'one':[2,3], 'two':[3,5]}
+
+
+
+ +
+
+remove(prop, indices)[source]
+
+ +
+
+shift_left(start, size)[source]
+
+ +
+
+shift_right(start, size)[source]
+
+ +
+
+size
+
+ +
+
+update(parameter_index_view, offset=0)[source]
+
+ +
+ +
+
+GPy.core.parameterization.index_operations.combine_indices(arr1, arr2)[source]
+
+ +
+
+GPy.core.parameterization.index_operations.extract_properties_to_index(index, props)[source]
+
+ +
+
+GPy.core.parameterization.index_operations.index_empty(index)[source]
+
+ +
+
+GPy.core.parameterization.index_operations.remove_indices(arr, to_remove)[source]
+
+ +
+
+

GPy.core.parameterization.lists_and_dicts module

+
+
+class GPy.core.parameterization.lists_and_dicts.ArrayList[source]
+

Bases: list

+

List to store ndarray-likes in. +It will look for ‘is’ instead of calling __eq__ on each element.

+
+
+index(item)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.lists_and_dicts.IntArrayDict(default_factory=None)[source]
+

Bases: collections.defaultdict

+
+ +
+
+class GPy.core.parameterization.lists_and_dicts.ObserverList[source]
+

Bases: object

+

A list which containts the observables. +It only holds weak references to observers, such that unbound +observers dont dangle in memory.

+
+
+add(priority, observer, callble)[source]
+

Add an observer with priority and callble

+
+ +
+
+flush()[source]
+

Make sure all weak references, which point to nothing are flushed (deleted)

+
+ +
+
+remove(priority, observer, callble)[source]
+

Remove one observer, which had priority and callble.

+
+ +
+ +
+
+GPy.core.parameterization.lists_and_dicts.intarray_default_factory()[source]
+
+ +
+
+

GPy.core.parameterization.observable_array module

+
+
+class GPy.core.parameterization.observable_array.ObsAr(*a, **kw)[source]
+

Bases: numpy.ndarray, GPy.core.parameterization.parameter_core.Pickleable, GPy.core.parameterization.observable.Observable

+

An ndarray which reports changes to its observers. +The observers can add themselves with a callable, which +will be called every time this array changes. The callable +takes exactly one argument, which is this array itself.

+
+
+copy()[source]
+
+ +
+
+values
+
+ +
+ +
+
+

GPy.core.parameterization.param module

+
+
+class GPy.core.parameterization.param.Param(name, input_array, default_constraint=None, *a, **kw)[source]
+

Bases: GPy.core.parameterization.parameter_core.Parameterizable, GPy.core.parameterization.observable_array.ObsAr

+

Parameter object for GPy models.

+ +++ + + + +
Parameters:
    +
  • name (str) – name of the parameter to be printed
  • +
  • input_array (numpy.ndarray) – array which this parameter handles
  • +
  • default_constraint – The default constraint for this parameter
  • +
+
+

You can add/remove constraints by calling constrain on the parameter itself, e.g:

+
+
    +
  • self[:,1].constrain_positive()
  • +
  • self[0].tie_to(other)
  • +
  • self.untie()
  • +
  • self[:3,:].unconstrain()
  • +
  • self[1].fix()
  • +
+
+

Fixing parameters will fix them to the value they are right now. If you change +the fixed value, it will be fixed to the new value!

+

See GPy.core.parameterized.Parameterized for more details on constraining etc.

+
+
+build_pydot(G)[source]
+
+ +
+
+copy()[source]
+
+ +
+
+flattened_parameters
+
+ +
+
+gradient
+

Return a view on the gradient, which is in the same shape as this parameter is. +Note: this is not the real gradient array, it is just a view on it.

+

To work on the real gradient array use: self.full_gradient

+
+ +
+
+is_fixed
+
+ +
+
+num_params
+
+ +
+
+param_array
+

As we are a leaf, this just returns self

+
+ +
+
+parameter_names(add_self=False, adjust_for_printing=False, recursive=True)[source]
+
+ +
+
+parameter_shapes
+
+ +
+
+parameters = []
+
+ +
+
+values
+

Return self as numpy array view

+
+ +
+ +
+
+class GPy.core.parameterization.param.ParamConcatenation(params)[source]
+

Bases: object

+
+
+checkgrad(verbose=0, step=1e-06, tolerance=0.001)[source]
+
+ +
+
+constrain(constraint, warning=True)[source]
+
+++ + + + +
Parameters:
    +
  • transform – the GPy.core.transformations.Transformation +to constrain the this parameter to.
  • +
  • warning – print a warning if re-constraining parameters.
  • +
+
+

Constrain the parameter to the given +GPy.core.transformations.Transformation.

+
+ +
+
+constrain_bounded(lower, upper, warning=True)[source]
+
+++ + + + +
Parameters:
    +
  • upper (lower,) – the limits to bound this parameter to
  • +
  • warning – print a warning if re-constraining parameters.
  • +
+
+

Constrain this parameter to lie within the given range.

+
+ +
+
+constrain_fixed(value=None, warning=True, trigger_parent=True)[source]
+

Constrain this parameter to be fixed to the current value it carries.

+ +++ + + + +
Parameters:warning – print a warning for overwriting constraints.
+
+ +
+
+constrain_negative(warning=True)[source]
+
+++ + + + +
Parameters:warning – print a warning if re-constraining parameters.
+

Constrain this parameter to the default negative constraint.

+
+ +
+
+constrain_positive(warning=True)[source]
+
+++ + + + +
Parameters:warning – print a warning if re-constraining parameters.
+

Constrain this parameter to the default positive constraint.

+
+ +
+
+fix(value=None, warning=True, trigger_parent=True)
+

Constrain this parameter to be fixed to the current value it carries.

+ +++ + + + +
Parameters:warning – print a warning for overwriting constraints.
+
+ +
+
+unconstrain(*constraints)[source]
+
+++ + + + +
Parameters:transforms – The transformations to unconstrain from.
+

remove all GPy.core.transformations.Transformation +transformats of this parameter object.

+
+ +
+
+unconstrain_bounded(lower, upper)[source]
+
+++ + + + +
Parameters:upper (lower,) – the limits to unbound this parameter from
+

Remove (lower, upper) bounded constrain from this parameter/

+
+ +
+
+unconstrain_fixed()[source]
+

This parameter will no longer be fixed.

+
+ +
+
+unconstrain_negative()[source]
+

Remove negative constraint of this parameter.

+
+ +
+
+unconstrain_positive()[source]
+

Remove positive constraint of this parameter.

+
+ +
+
+unfix()
+

This parameter will no longer be fixed.

+
+ +
+
+untie(*ties)[source]
+
+ +
+
+update_all_params()[source]
+
+ +
+
+values()[source]
+
+ +
+ +
+
+

GPy.core.parameterization.parameter_core module

+

Core module for parameterization. +This module implements all parameterization techniques, split up in modular bits.

+

HierarchyError: +raised when an error with the hierarchy occurs (circles etc.)

+

Observable: +Observable Pattern for patameterization

+
+
+class GPy.core.parameterization.parameter_core.Gradcheckable(*a, **kw)[source]
+

Bases: GPy.core.parameterization.parameter_core.Pickleable, GPy.core.parameterization.parameter_core.Parentable

+

Adds the functionality for an object to be gradcheckable. +It is just a thin wrapper of a call to the highest parent for now. +TODO: Can be done better, by only changing parameters of the current parameter handle, +such that object hierarchy only has to change for those.

+
+
+checkgrad(verbose=0, step=1e-06, tolerance=0.001, df_tolerance=1e-12)[source]
+

Check the gradient of this parameter with respect to the highest parent’s +objective function. +This is a three point estimate of the gradient, wiggling at the parameters +with a stepsize step. +The check passes if either the ratio or the difference between numerical and +analytical gradient is smaller then tolerance.

+ +++ + + + +
Parameters:
    +
  • verbose (bool) – whether each parameter shall be checked individually.
  • +
  • step (float) – the stepsize for the numerical three point gradient estimate.
  • +
  • tolerance (float) – the tolerance for the gradient ratio or difference.
  • +
  • df_tolerance (float) – the tolerance for df_tolerance
  • +
+
+
+
Note:-
+
The dF_ratio indicates the limit of accuracy of numerical gradients. +If it is too small, e.g., smaller than 1e-12, the numerical gradients +are usually not accurate enough for the tests (shown with blue).
+
+
+ +
+ +
+
+exception GPy.core.parameterization.parameter_core.HierarchyError[source]
+

Bases: exceptions.Exception

+

Gets thrown when something is wrong with the parameter hierarchy.

+
+ +
+
+class GPy.core.parameterization.parameter_core.Indexable(name, default_constraint=None, *a, **kw)[source]
+

Bases: GPy.core.parameterization.parameter_core.Nameable, GPy.core.parameterization.updateable.Updateable

+

Make an object constrainable with Priors and Transformations. +TODO: Mappings!! +Adding a constraint to a Parameter means to tell the highest parent that +the constraint was added and making sure that all parameters covered +by this object are indeed conforming to the constraint.

+

constrain() and unconstrain() are main methods here

+
+
+constrain(transform, warning=True, trigger_parent=True)[source]
+
+++ + + + +
Parameters:
    +
  • transform – the GPy.core.transformations.Transformation +to constrain the this parameter to.
  • +
  • warning – print a warning if re-constraining parameters.
  • +
+
+

Constrain the parameter to the given +GPy.core.transformations.Transformation.

+
+ +
+
+constrain_bounded(lower, upper, warning=True, trigger_parent=True)[source]
+
+++ + + + +
Parameters:
    +
  • upper (lower,) – the limits to bound this parameter to
  • +
  • warning – print a warning if re-constraining parameters.
  • +
+
+

Constrain this parameter to lie within the given range.

+
+ +
+
+constrain_fixed(value=None, warning=True, trigger_parent=True)[source]
+

Constrain this parameter to be fixed to the current value it carries.

+ +++ + + + +
Parameters:warning – print a warning for overwriting constraints.
+
+ +
+
+constrain_negative(warning=True, trigger_parent=True)[source]
+
+++ + + + +
Parameters:warning – print a warning if re-constraining parameters.
+

Constrain this parameter to the default negative constraint.

+
+ +
+
+constrain_positive(warning=True, trigger_parent=True)[source]
+
+++ + + + +
Parameters:warning – print a warning if re-constraining parameters.
+

Constrain this parameter to the default positive constraint.

+
+ +
+
+fix(value=None, warning=True, trigger_parent=True)
+

Constrain this parameter to be fixed to the current value it carries.

+ +++ + + + +
Parameters:warning – print a warning for overwriting constraints.
+
+ +
+
+is_fixed
+
+ +
+
+log_prior()[source]
+

evaluate the prior

+
+ +
+
+set_prior(prior, warning=True)[source]
+

Set the prior for this object to prior. +:param Prior prior: a prior to set for this parameter +:param bool warning: whether to warn if another prior was set for this parameter

+
+ +
+
+tie_together()[source]
+
+ +
+
+unconstrain(*transforms)[source]
+
+++ + + + +
Parameters:transforms – The transformations to unconstrain from.
+

remove all GPy.core.transformations.Transformation +transformats of this parameter object.

+
+ +
+
+unconstrain_bounded(lower, upper)[source]
+
+++ + + + +
Parameters:upper (lower,) – the limits to unbound this parameter from
+

Remove (lower, upper) bounded constrain from this parameter/

+
+ +
+
+unconstrain_fixed()[source]
+

This parameter will no longer be fixed.

+
+ +
+
+unconstrain_negative()[source]
+

Remove negative constraint of this parameter.

+
+ +
+
+unconstrain_positive()[source]
+

Remove positive constraint of this parameter.

+
+ +
+
+unfix()
+

This parameter will no longer be fixed.

+
+ +
+
+unset_priors(*priors)[source]
+

Un-set all priors given (in *priors) from this parameter handle.

+
+ +
+ +
+
+class GPy.core.parameterization.parameter_core.Nameable(name, *a, **kw)[source]
+

Bases: GPy.core.parameterization.parameter_core.Gradcheckable

+

Make an object nameable inside the hierarchy.

+
+
+hierarchy_name(adjust_for_printing=True)[source]
+

return the name for this object with the parents names attached by dots.

+ +++ + + + +
Parameters:adjust_for_printing (bool) – whether to call adjust_for_printing()
+

on the names, recursively

+
+ +
+
+name
+

The name of this object

+
+ +
+ +
+
+class GPy.core.parameterization.parameter_core.OptimizationHandlable(name, default_constraint=None, *a, **kw)[source]
+

Bases: GPy.core.parameterization.parameter_core.Indexable

+

This enables optimization handles on an Object as done in GPy 0.4.

+

..._optimizer_copy_transformed: make sure the transformations and constraints etc are handled

+
+
+gradient_full
+

Note to users: +This does not return the gradient in the right shape! Use self.gradient +for the right gradient array.

+

To work on the gradient array, use this as the gradient handle. +This method exists for in memory use of parameters. +When trying to access the true gradient array, use this.

+
+ +
+
+num_params
+

Return the number of parameters of this parameter_handle. +Param objects will always return 0.

+
+ +
+
+optimizer_array
+

Array for the optimizer to work on. +This array always lives in the space for the optimizer. +Thus, it is untransformed, going from Transformations.

+

Setting this array, will make sure the transformed parameters for this model +will be set accordingly. It has to be set with an array, retrieved from +this method, as e.g. fixing will resize the array.

+

The optimizer should only interfere with this array, such that transformations +are secured.

+
+ +
+
+parameter_names(add_self=False, adjust_for_printing=False, recursive=True)[source]
+

Get the names of all parameters of this model.

+ +++ + + + +
Parameters:
    +
  • add_self (bool) – whether to add the own name in front of names
  • +
  • adjust_for_printing (bool) – whether to call adjust_name_for_printing on names
  • +
  • recursive (bool) – whether to traverse through hierarchy and append leaf node names
  • +
+
+
+ +
+
+randomize(rand_gen=None, *args, **kwargs)[source]
+

Randomize the model. +Make this draw from the prior if one exists, else draw from given random generator

+ +++ + + + +
Parameters:
    +
  • rand_gen – np random number generator which takes args and kwargs
  • +
  • loc (flaot) – loc parameter for random number generator
  • +
  • scale (float) – scale parameter for random number generator
  • +
  • kwargs (args,) – will be passed through to random number generator
  • +
+
+
+ +
+ +
+
+class GPy.core.parameterization.parameter_core.Parameterizable(*args, **kwargs)[source]
+

Bases: GPy.core.parameterization.parameter_core.OptimizationHandlable

+

A parameterisable class.

+

This class provides the parameters list (ArrayList) and standard parameter handling, +such as {add|remove}_parameter(), traverse hierarchy and param_array, gradient_array +and the empty parameters_changed().

+

This class is abstract and should not be instantiated. +Use GPy.core.Parameterized() as node (or leaf) in the parameterized hierarchy. +Use GPy.core.Param() for a leaf in the parameterized hierarchy.

+
+
+gradient
+
+ +
+
+num_params
+
+ +
+
+param_array
+

Array representing the parameters of this class. +There is only one copy of all parameters in memory, two during optimization.

+

!WARNING!: setting the parameter array MUST always be done in memory: +m.param_array[:] = m_copy.param_array

+
+ +
+
+parameters_changed()[source]
+

This method gets called when parameters have changed. +Another way of listening to param changes is to +add self as a listener to the param, such that +updates get passed through. See :py:function:GPy.core.param.Observable.add_observer

+
+ +
+
+save(filename, ftype='HDF5')[source]
+

Save all the model parameters into a file (HDF5 by default).

+
+ +
+
+traverse(visit, *args, **kwargs)[source]
+

Traverse the hierarchy performing visit(self, *args, **kwargs) +at every node passed by downwards. This function includes self!

+

See “visitor pattern” in literature. This is implemented in pre-order fashion.

+

Example: +Collect all children:

+

children = [] +self.traverse(children.append) +print children

+
+ +
+
+traverse_parents(visit, *args, **kwargs)[source]
+

Traverse the hierarchy upwards, visiting all parents and their children except self. +See “visitor pattern” in literature. This is implemented in pre-order fashion.

+

Example:

+

parents = [] +self.traverse_parents(parents.append) +print parents

+
+ +
+
+unfixed_param_array
+

Array representing the parameters of this class. +There is only one copy of all parameters in memory, two during optimization.

+

!WARNING!: setting the parameter array MUST always be done in memory: +m.param_array[:] = m_copy.param_array

+
+ +
+ +
+
+class GPy.core.parameterization.parameter_core.Parentable(*args, **kwargs)[source]
+

Bases: object

+

Enable an Object to have a parent.

+

Additionally this adds the parent_index, which is the index for the parent +to look for in its parameter list.

+
+
+has_parent()[source]
+

Return whether this parentable object currently has a parent.

+
+ +
+ +
+
+class GPy.core.parameterization.parameter_core.Pickleable(*a, **kw)[source]
+

Bases: object

+

Make an object pickleable (See python doc ‘pickling’).

+

This class allows for pickling support by Memento pattern. +_getstate returns a memento of the class, which gets pickled. +_setstate(<memento>) (re-)sets the state of the class to the memento

+
+
+copy(memo=None, which=None)[source]
+

Returns a (deep) copy of the current parameter handle.

+

All connections to parents of the copy will be cut.

+ +++ + + + +
Parameters:
    +
  • memo (dict) – memo for deepcopy
  • +
  • which (Parameterized) – parameterized object which started the copy process [default: self]
  • +
+
+
+ +
+
+pickle(f, protocol=-1)[source]
+
+++ + + + +
Parameters:
    +
  • f – either filename or open file object to write to. +if it is an open buffer, you have to make sure to close +it properly.
  • +
  • protocol – pickling protocol to use, python-pickle for details.
  • +
+
+
+ +
+ +
+
+GPy.core.parameterization.parameter_core.adjust_name_for_printing(name)[source]
+

Make sure a name can be printed, alongside used as a variable name.

+
+ +
+
+

GPy.core.parameterization.parameterized module

+
+
+class GPy.core.parameterization.parameterized.Parameterized(name=None, parameters=[], *a, **kw)[source]
+

Bases: GPy.core.parameterization.parameter_core.Parameterizable

+

Parameterized class

+

Say m is a handle to a parameterized class.

+

Printing parameters:

+
+
    +
  • print m: prints a nice summary over all parameters

    +
  • +
  • print m.name: prints details for param with name ‘name’

    +
  • +
  • +
    print m[regexp]: prints details for all the parameters
    +

    which match (!) regexp

    +
    +
    +
  • +
  • print m[‘’]: prints details for all parameters

    +
  • +
+

Fields:

+
+

Name: The name of the param, can be renamed! +Value: Shape or value, if one-valued +Constrain: constraint of the param, curly “{c}” brackets indicate

+
+
some parameters are constrained by c. See detailed print +to get exact constraints.
+

Tied_to: which paramter it is tied to.

+
+
+

Getting and setting parameters:

+
+

Set all values in param to one:

+
+
m.name.to.param = 1
+
+

Handling of constraining, fixing and tieing parameters:

+
+

You can constrain parameters by calling the constrain on the param itself, e.g:

+
+
    +
  • m.name[:,1].constrain_positive()
  • +
  • m.name[0].tie_to(m.name[1])
  • +
+
+

Fixing parameters will fix them to the value they are right now. If you change +the parameters value, the param will be fixed to the new value!

+

If you want to operate on all parameters use m[‘’] to wildcard select all paramters +and concatenate them. Printing m[‘’] will result in printing of all parameters in detail.

+
+
+
+add_parameter(*args, **kwargs)[source]
+
+ +
+
+build_pydot(G=None)[source]
+
+ +
+
+copy(memo=None)[source]
+
+ +
+
+flattened_parameters
+
+ +
+
+grep_param_names(regexp)[source]
+

create a list of parameters, matching regular expression regexp

+
+ +
+ +
+++ + + + +
Parameters:
    +
  • parameters (list of or one GPy.core.param.Param) – the parameters to add
  • +
  • [index] – index of where to put parameters
  • +
  • _ignore_added_names (bool) – whether the name of the parameter overrides a possibly existing field
  • +
+
+

Add all parameters to this param class, you can insert parameters +at any given index using the list.insert() syntax

+
+ +
+ +

convenience method for adding several +parameters without gradient specification

+
+ +
+
+parameter_shapes
+
+ +
+
+remove_parameter(*args, **kwargs)[source]
+
+ +
+ +
+++ + + + +
Parameters:param – param object to remove from being a parameter of this parameterized object.
+
+ +
+ +
+
+class GPy.core.parameterization.parameterized.ParametersChangedMeta[source]
+

Bases: type

+
+ +
+
+

GPy.core.parameterization.priors module

+
+
+class GPy.core.parameterization.priors.DGPLVM(sigma2, lbl, x_shape)[source]
+

Bases: GPy.core.parameterization.priors.Prior

+

Implementation of the Discriminative Gaussian Process Latent Variable model paper, by Raquel.

+ +++ + + + +
Parameters:sigma2 – constant
+
+

Note

+

DGPLVM for Classification paper implementation

+
+
+
+compute_Mi(cls)[source]
+
+ +
+
+compute_Sb(cls, M_i, M_0)[source]
+
+ +
+
+compute_Sw(cls, M_i)[source]
+
+ +
+
+compute_cls(x)[source]
+
+ +
+
+compute_indices(x)[source]
+
+ +
+
+compute_listIndices(data_idx)[source]
+
+ +
+
+compute_sig_alpha_W(data_idx, lst_idx_all, W_i)[source]
+
+ +
+
+compute_sig_beta_Bi(data_idx, M_i, M_0, lst_idx_all)[source]
+
+ +
+
+compute_wj(data_idx, M_i)[source]
+
+ +
+
+domain = 'real'
+
+ +
+
+get_class_label(y)[source]
+
+ +
+
+lnpdf(x)[source]
+
+ +
+
+lnpdf_grad(x)[source]
+
+ +
+
+rvs(n)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.priors.DGPLVM_KFDA(lambdaa, sigma2, lbl, kern, x_shape)[source]
+

Bases: GPy.core.parameterization.priors.Prior

+

Implementation of the Discriminative Gaussian Process Latent Variable function using +Kernel Fisher Discriminant Analysis by Seung-Jean Kim for implementing Face paper +by Chaochao Lu.

+ +++ + + + +
Parameters:
    +
  • lambdaa – constant
  • +
  • sigma2 – constant
  • +
+
+
+

Note

+

Surpassing Human-Level Face paper dgplvm implementation

+
+
+
+compute_A(lst_ni)[source]
+
+ +
+
+compute_a(lst_ni)[source]
+
+ +
+
+compute_cls(x)[source]
+
+ +
+
+compute_lst_ni()[source]
+
+ +
+
+domain = 'real'
+
+ +
+
+get_class_label(y)[source]
+
+ +
+
+lnpdf(x)[source]
+
+ +
+
+lnpdf_grad(x)[source]
+
+ +
+
+rvs(n)[source]
+
+ +
+
+x_reduced(cls)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.priors.Gamma(a, b)[source]
+

Bases: GPy.core.parameterization.priors.Prior

+

Implementation of the Gamma probability function, coupled with random variables.

+ +++ + + + +
Parameters:
    +
  • a – shape parameter
  • +
  • b – rate parameter (warning: it’s the inverse of the scale)
  • +
+
+
+

Note

+

Bishop 2006 notation is used throughout the code

+
+
+
+domain = 'positive'
+
+ +
+
+static from_EV(E, V)[source]
+

Creates an instance of a Gamma Prior by specifying the Expected value(s) +and Variance(s) of the distribution.

+ +++ + + + +
Parameters:
    +
  • E – expected value
  • +
  • V – variance
  • +
+
+
+ +
+
+lnpdf(x)[source]
+
+ +
+
+lnpdf_grad(x)[source]
+
+ +
+
+rvs(n)[source]
+
+ +
+
+summary()[source]
+
+ +
+ +
+
+class GPy.core.parameterization.priors.Gaussian(mu, sigma)[source]
+

Bases: GPy.core.parameterization.priors.Prior

+

Implementation of the univariate Gaussian probability function, coupled with random variables.

+ +++ + + + +
Parameters:
    +
  • mu – mean
  • +
  • sigma – standard deviation
  • +
+
+
+

Note

+

Bishop 2006 notation is used throughout the code

+
+
+
+domain = 'real'
+
+ +
+
+lnpdf(x)[source]
+
+ +
+
+lnpdf_grad(x)[source]
+
+ +
+
+rvs(n)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.priors.HalfT(A, nu)[source]
+

Bases: GPy.core.parameterization.priors.Prior

+

Implementation of the half student t probability function, coupled with random variables.

+ +++ + + + +
Parameters:
    +
  • A – scale parameter
  • +
  • nu – degrees of freedom
  • +
+
+
+
+domain = 'positive'
+
+ +
+
+lnpdf(theta)[source]
+
+ +
+
+lnpdf_grad(theta)[source]
+
+ +
+
+rvs(n)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.priors.InverseGamma(a, b)[source]
+

Bases: GPy.core.parameterization.priors.Gamma

+

Implementation of the inverse-Gamma probability function, coupled with random variables.

+ +++ + + + +
Parameters:
    +
  • a – shape parameter
  • +
  • b – rate parameter (warning: it’s the inverse of the scale)
  • +
+
+
+

Note

+

Bishop 2006 notation is used throughout the code

+
+
+
+domain = 'positive'
+
+ +
+
+lnpdf(x)[source]
+
+ +
+
+lnpdf_grad(x)[source]
+
+ +
+
+rvs(n)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.priors.LogGaussian(mu, sigma)[source]
+

Bases: GPy.core.parameterization.priors.Gaussian

+

Implementation of the univariate log-Gaussian probability function, coupled with random variables.

+ +++ + + + +
Parameters:
    +
  • mu – mean
  • +
  • sigma – standard deviation
  • +
+
+
+

Note

+

Bishop 2006 notation is used throughout the code

+
+
+
+domain = 'positive'
+
+ +
+
+lnpdf(x)[source]
+
+ +
+
+lnpdf_grad(x)[source]
+
+ +
+
+rvs(n)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.priors.MultivariateGaussian(mu, var)[source]
+

Bases: GPy.core.parameterization.priors.Prior

+

Implementation of the multivariate Gaussian probability function, coupled with random variables.

+ +++ + + + +
Parameters:
    +
  • mu – mean (N-dimensional array)
  • +
  • var – covariance matrix (NxN)
  • +
+
+
+

Note

+

Bishop 2006 notation is used throughout the code

+
+
+
+domain = 'real'
+
+ +
+
+lnpdf(x)[source]
+
+ +
+
+lnpdf_grad(x)[source]
+
+ +
+
+pdf(x)[source]
+
+ +
+
+plot()[source]
+
+ +
+
+rvs(n)[source]
+
+ +
+
+summary()[source]
+
+ +
+ +
+
+class GPy.core.parameterization.priors.Prior[source]
+

Bases: object

+
+
+domain = None
+
+ +
+
+pdf(x)[source]
+
+ +
+
+plot()[source]
+
+ +
+ +
+
+class GPy.core.parameterization.priors.Uniform(lower, upper)[source]
+

Bases: GPy.core.parameterization.priors.Prior

+
+
+domain = 'real'
+
+ +
+
+lnpdf(x)[source]
+
+ +
+
+lnpdf_grad(x)[source]
+
+ +
+
+rvs(n)[source]
+
+ +
+ +
+
+GPy.core.parameterization.priors.gamma_from_EV(E, V)[source]
+
+ +
+
+

GPy.core.parameterization.ties_and_remappings module

+
+
+class GPy.core.parameterization.ties_and_remappings.Fix(name=None, parameters=[], *a, **kw)[source]
+

Bases: GPy.core.parameterization.ties_and_remappings.Remapping

+
+ +
+
+class GPy.core.parameterization.ties_and_remappings.Remapping(name=None, parameters=[], *a, **kw)[source]
+

Bases: GPy.core.parameterization.parameterized.Parameterized

+
+
+callback()[source]
+
+ +
+
+mapping()[source]
+

The return value of this function gives the values which the re-mapped +parameters should take. Implement in sub-classes.

+
+ +
+
+parameters_changed()[source]
+
+ +
+ +
+
+class GPy.core.parameterization.ties_and_remappings.Tie(name='tie')[source]
+

Bases: GPy.core.parameterization.parameterized.Parameterized

+

The new parameter tie framework. (under development)

+

All the parameters tied together get a new parameter inside the Tie object. +Its value should always be equal to all the tied parameters, and its gradient +is the sum of all the tied parameters.

+

=====Implementation Details===== +The Tie object should only exist on the top of param tree (the highest parent).

+

self.label_buf: +It uses a label buffer that has the same length as all the parameters (self._highest_parent_.param_array). +The buffer keeps track of all the tied parameters. All the tied parameters have a label (an interger) higher +than 0, and the parameters that have the same label are tied together.

+

self.buf_index: +An auxiliary index list for the global index of the tie parameter inside the Tie object.

+

TODO: +* EVERYTHING

+
+
+add_tied_parameter(p, p2=None)[source]
+

Tie the list of parameters p together (p2==None) or +Tie the list of parameters p with the list of parameters p2 (p2!=None)

+
+ +
+
+collate_gradient()[source]
+
+ +
+
+getTieFlag(p=None)[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+
+propagate_val()[source]
+
+ +
+ +
+
+

GPy.core.parameterization.transformations module

+
+
+class GPy.core.parameterization.transformations.Exponent[source]
+

Bases: GPy.core.parameterization.transformations.Transformation

+
+
+domain = 'positive'
+
+ +
+
+f(x)[source]
+
+ +
+
+finv(x)[source]
+
+ +
+
+gradfactor(f, df)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.Logexp[source]
+

Bases: GPy.core.parameterization.transformations.Transformation

+
+
+domain = 'positive'
+
+ +
+
+f(x)[source]
+
+ +
+
+finv(f)[source]
+
+ +
+
+gradfactor(f, df)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.LogexpClipped(lower=1e-06)[source]
+

Bases: GPy.core.parameterization.transformations.Logexp

+
+
+domain = 'positive'
+
+ +
+
+f(x)[source]
+
+ +
+
+finv(f)[source]
+
+ +
+
+gradfactor(f, df)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+
+log_max_bound = 230.25850929940458
+
+ +
+
+log_min_bound = -23.025850929940457
+
+ +
+
+max_bound = 1e+100
+
+ +
+
+min_bound = 1e-10
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.LogexpNeg[source]
+

Bases: GPy.core.parameterization.transformations.Transformation

+
+
+domain = 'positive'
+
+ +
+
+f(x)[source]
+
+ +
+
+finv(f)[source]
+
+ +
+
+gradfactor(f, df)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.Logistic(lower, upper)[source]
+

Bases: GPy.core.parameterization.transformations.Transformation

+
+
+domain = 'bounded'
+
+ +
+
+f(x)[source]
+
+ +
+
+finv(f)[source]
+
+ +
+
+gradfactor(f, df)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.NegativeExponent[source]
+

Bases: GPy.core.parameterization.transformations.Exponent

+
+
+domain = 'negative'
+
+ +
+
+f(x)[source]
+
+ +
+
+finv(f)[source]
+
+ +
+
+gradfactor(f, df)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.NegativeLogexp[source]
+

Bases: GPy.core.parameterization.transformations.Transformation

+
+
+domain = 'negative'
+
+ +
+
+f(x)[source]
+
+ +
+
+finv(f)[source]
+
+ +
+
+gradfactor(f, df)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+
+logexp = Logexp
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.NormalEta(mu_indices, var_indices)[source]
+

Bases: GPy.core.parameterization.transformations.Transformation

+
+
+f(theta)[source]
+
+ +
+
+finv(muvar)[source]
+
+ +
+
+gradfactor(muvar, dmuvar)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.NormalNaturalAntti(mu_indices, var_indices)[source]
+

Bases: GPy.core.parameterization.transformations.NormalTheta

+
+
+gradfactor(muvar, dmuvar)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.NormalNaturalThroughEta(mu_indices, var_indices)[source]
+

Bases: GPy.core.parameterization.transformations.NormalEta

+
+
+gradfactor(muvar, dmuvar)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.NormalNaturalThroughTheta(mu_indices, var_indices)[source]
+

Bases: GPy.core.parameterization.transformations.NormalTheta

+
+
+gradfactor(muvar, dmuvar)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.NormalTheta(mu_indices, var_indices)[source]
+

Bases: GPy.core.parameterization.transformations.Transformation

+
+
+f(theta)[source]
+
+ +
+
+finv(muvar)[source]
+
+ +
+
+gradfactor(muvar, dmuvar)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.Square[source]
+

Bases: GPy.core.parameterization.transformations.Transformation

+
+
+domain = 'positive'
+
+ +
+
+f(x)[source]
+
+ +
+
+finv(x)[source]
+
+ +
+
+gradfactor(f, df)[source]
+
+ +
+
+initialize(f)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.transformations.Transformation[source]
+

Bases: object

+
+
+domain = None
+
+ +
+
+f(opt_param)[source]
+
+ +
+
+finv(model_param)[source]
+
+ +
+
+gradfactor(model_param, dL_dmodel_param)[source]
+

df(opt_param)_dopt_param evaluated at self.f(opt_param)=model_param, times the gradient dL_dmodel_param,

+
+

i.e.: +define

+
+

+
+

rac{ +rac{partial L}{partial f}left(left.partial f(x)}{partial x} +ight|_{x=f^{-1}(f) +ight)}

+
+ +
+
+initialize(f)[source]
+

produce a sensible initial value for f(x)

+
+ +
+
+plot(xlabel='transformed $\\theta$', ylabel='$\\theta$', axes=None, *args, **kw)[source]
+
+ +
+ +
+
+

GPy.core.parameterization.variational module

+

Created on 6 Nov 2013

+

@author: maxz

+
+
+class GPy.core.parameterization.variational.NormalPosterior(means=None, variances=None, name='latent space', *a, **kw)[source]
+

Bases: GPy.core.parameterization.variational.VariationalPosterior

+

NormalPosterior distribution for variational approximations.

+

holds the means and variances for a factorizing multivariate normal distribution

+
+
+plot(*args)[source]
+

Plot latent space X in 1D:

+

See GPy.plotting.matplot_dep.variational_plots

+
+ +
+ +
+
+class GPy.core.parameterization.variational.NormalPrior(name='latent space', **kw)[source]
+

Bases: GPy.core.parameterization.variational.VariationalPrior

+
+
+KL_divergence(variational_posterior)[source]
+
+ +
+
+update_gradients_KL(variational_posterior)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.variational.SpikeAndSlabPosterior(means, variances, binary_prob, name='latent space')[source]
+

Bases: GPy.core.parameterization.variational.VariationalPosterior

+

The SpikeAndSlab distribution for variational approximations.

+
+
+gamma_log_prob = <functools.partial object>
+
+ +
+
+gamma_probabilities = <functools.partial object>
+
+ +
+
+plot(*args, **kwargs)[source]
+

Plot latent space X in 1D:

+

See GPy.plotting.matplot_dep.variational_plots

+
+ +
+
+set_gradients(grad)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.variational.SpikeAndSlabPrior(pi=None, learnPi=False, variance=1.0, name='SpikeAndSlabPrior', **kw)[source]
+

Bases: GPy.core.parameterization.variational.VariationalPrior

+
+
+KL_divergence(variational_posterior)[source]
+
+ +
+
+update_gradients_KL(variational_posterior)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.variational.VariationalPosterior(means=None, variances=None, name='latent space', *a, **kw)[source]
+

Bases: GPy.core.parameterization.parameterized.Parameterized

+
+
+has_uncertain_inputs()[source]
+
+ +
+
+set_gradients(grad)[source]
+
+ +
+ +
+
+class GPy.core.parameterization.variational.VariationalPrior(name='latent space', **kw)[source]
+

Bases: GPy.core.parameterization.parameterized.Parameterized

+
+
+KL_divergence(variational_posterior)[source]
+
+ +
+
+update_gradients_KL(variational_posterior)[source]
+

updates the gradients for mean and variance in place

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.examples.html b/doc/_build/html/GPy.examples.html new file mode 100644 index 00000000..029a1be4 --- /dev/null +++ b/doc/_build/html/GPy.examples.html @@ -0,0 +1,464 @@ + + + + + + + + GPy.examples package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.examples package

+
+

Submodules

+
+
+

GPy.examples.classification module

+

Gaussian Processes classification examples

+
+
+GPy.examples.classification.crescent_data(model_type='Full', num_inducing=10, seed=10000, kernel=None, optimize=True, plot=True)[source]
+

Run a Gaussian process classification on the crescent data. The demonstration calls the basic GP classification model and uses EP to approximate the likelihood.

+ +++ + + + +
Parameters:
    +
  • model_type – type of model to fit [‘Full’, ‘FITC’, ‘DTC’].
  • +
  • inducing (int) – number of inducing variables (only used for ‘FITC’ or ‘DTC’).
  • +
  • seed (int) – seed value for data generation.
  • +
  • kernel (a GPy kernel) – kernel to use in the model
  • +
+
+
+ +
+
+GPy.examples.classification.oil(num_inducing=50, max_iters=100, kernel=None, optimize=True, plot=True)[source]
+

Run a Gaussian process classification on the three phase oil data. The demonstration calls the basic GP classification model and uses EP to approximate the likelihood.

+
+ +
+
+GPy.examples.classification.sparse_toy_linear_1d_classification(num_inducing=10, seed=10000, optimize=True, plot=True)[source]
+

Sparse 1D classification example

+ +++ + + + +
Parameters:seed (int) – seed value for data generation (default is 4).
+
+ +
+
+GPy.examples.classification.toy_heaviside(seed=10000, max_iters=100, optimize=True, plot=True)[source]
+

Simple 1D classification example using a heavy side gp transformation

+ +++ + + + +
Parameters:seed (int) – seed value for data generation (default is 4).
+
+ +
+
+GPy.examples.classification.toy_linear_1d_classification(seed=10000, optimize=True, plot=True)[source]
+

Simple 1D classification example using EP approximation

+ +++ + + + +
Parameters:seed (int) – seed value for data generation (default is 4).
+
+ +
+
+GPy.examples.classification.toy_linear_1d_classification_laplace(seed=10000, optimize=True, plot=True)[source]
+

Simple 1D classification example using Laplace approximation

+ +++ + + + +
Parameters:seed (int) – seed value for data generation (default is 4).
+
+ +
+
+

GPy.examples.coreg_example module

+
+
+

GPy.examples.dimensionality_reduction module

+
+
+GPy.examples.dimensionality_reduction.bcgplvm_linear_stick(kernel=None, optimize=True, verbose=True, plot=True)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.bcgplvm_stick(kernel=None, optimize=True, verbose=True, plot=True)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.bgplvm_oil(optimize=True, verbose=1, plot=True, N=200, Q=7, num_inducing=40, max_iters=1000, **k)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.bgplvm_simulation(optimize=True, verbose=1, plot=True, plot_sim=False, max_iters=20000.0)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.bgplvm_simulation_missing_data(optimize=True, verbose=1, plot=True, plot_sim=False, max_iters=20000.0, percent_missing=0.1)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.bgplvm_test_model(optimize=False, verbose=1, plot=False, output_dim=200, nan=False)[source]
+

model for testing purposes. Samples from a GP with rbf kernel and learns +the samples with a new kernel. Normally not for optimization, just model cheking

+
+ +
+
+GPy.examples.dimensionality_reduction.brendan_faces(optimize=True, verbose=True, plot=True)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.cmu_mocap(subject='35', motion=['01'], in_place=True, optimize=True, verbose=True, plot=True)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.gplvm_oil_100(optimize=True, verbose=1, plot=True)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.mrd_simulation(optimize=True, verbose=True, plot=True, plot_sim=True, **kw)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.mrd_simulation_missing_data(optimize=True, verbose=True, plot=True, plot_sim=True, **kw)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.olivetti_faces(optimize=True, verbose=True, plot=True)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.robot_wireless(optimize=True, verbose=True, plot=True)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.sparse_gplvm_oil(optimize=True, verbose=0, plot=True, N=100, Q=6, num_inducing=15, max_iters=50)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.ssgplvm_oil(optimize=True, verbose=1, plot=True, N=200, Q=7, num_inducing=40, max_iters=1000, **k)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.ssgplvm_simulation(optimize=True, verbose=1, plot=True, plot_sim=False, max_iters=20000.0, useGPU=False)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.ssgplvm_simulation_linear()[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.stick(kernel=None, optimize=True, verbose=True, plot=True)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.stick_bgplvm(model=None, optimize=True, verbose=True, plot=True)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.stick_play(range=None, frame_rate=15, optimize=False, verbose=True, plot=True)[source]
+
+ +
+
+GPy.examples.dimensionality_reduction.swiss_roll(optimize=True, verbose=1, plot=True, N=1000, num_inducing=25, Q=4, sigma=0.2)[source]
+
+ +
+
+

GPy.examples.non_gaussian module

+
+
+GPy.examples.non_gaussian.boston_example(optimize=True, plot=True)[source]
+
+ +
+
+GPy.examples.non_gaussian.student_t_approx(optimize=True, plot=True)[source]
+

Example of regressing with a student t likelihood using Laplace

+
+ +
+
+

GPy.examples.regression module

+

Gaussian Processes regression examples

+
+
+GPy.examples.regression.coregionalization_sparse(optimize=True, plot=True)[source]
+

A simple demonstration of coregionalization on two sinusoidal functions using sparse approximations.

+
+ +
+
+GPy.examples.regression.coregionalization_toy(optimize=True, plot=True)[source]
+

A simple demonstration of coregionalization on two sinusoidal functions.

+
+ +
+
+GPy.examples.regression.epomeo_gpx(max_iters=200, optimize=True, plot=True)[source]
+

Perform Gaussian process regression on the latitude and longitude data +from the Mount Epomeo runs. Requires gpxpy to be installed on your system +to load in the data.

+
+ +
+
+GPy.examples.regression.multiple_optima(gene_number=937, resolution=80, model_restarts=10, seed=10000, max_iters=300, optimize=True, plot=True)[source]
+

Show an example of a multimodal error surface for Gaussian process +regression. Gene 939 has bimodal behaviour where the noisy mode is +higher.

+
+ +
+
+GPy.examples.regression.olympic_100m_men(optimize=True, plot=True)[source]
+

Run a standard Gaussian process regression on the Rogers and Girolami olympics data.

+
+ +
+
+GPy.examples.regression.olympic_marathon_men(optimize=True, plot=True)[source]
+

Run a standard Gaussian process regression on the Olympic marathon data.

+
+ +
+
+GPy.examples.regression.robot_wireless(max_iters=100, kernel=None, optimize=True, plot=True)[source]
+

Predict the location of a robot given wirelss signal strength readings.

+
+ +
+
+GPy.examples.regression.silhouette(max_iters=100, optimize=True, plot=True)[source]
+

Predict the pose of a figure given a silhouette. This is a task from Agarwal and Triggs 2004 ICML paper.

+
+ +
+
+GPy.examples.regression.sparse_GP_regression_1D(num_samples=400, num_inducing=5, max_iters=100, optimize=True, plot=True, checkgrad=False)[source]
+

Run a 1D example of a sparse GP regression.

+
+ +
+
+GPy.examples.regression.sparse_GP_regression_2D(num_samples=400, num_inducing=50, max_iters=100, optimize=True, plot=True, nan=False)[source]
+

Run a 2D example of a sparse GP regression.

+
+ +
+
+GPy.examples.regression.toy_ARD(max_iters=1000, kernel_type='linear', num_samples=300, D=4, optimize=True, plot=True)[source]
+
+ +
+
+GPy.examples.regression.toy_ARD_sparse(max_iters=1000, kernel_type='linear', num_samples=300, D=4, optimize=True, plot=True)[source]
+
+ +
+
+GPy.examples.regression.toy_poisson_rbf_1d_laplace(optimize=True, plot=True)[source]
+

Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance.

+
+ +
+
+GPy.examples.regression.toy_rbf_1d(optimize=True, plot=True)[source]
+

Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance.

+
+ +
+
+GPy.examples.regression.toy_rbf_1d_50(optimize=True, plot=True)[source]
+

Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance.

+
+ +
+
+GPy.examples.regression.uncertain_inputs_sparse_regression(max_iters=200, optimize=True, plot=True)[source]
+

Run a 1D example of a sparse GP regression with uncertain inputs.

+
+ +
+
+

GPy.examples.stochastic module

+
+
+

GPy.examples.tutorials module

+
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.html b/doc/_build/html/GPy.html new file mode 100644 index 00000000..461c452b --- /dev/null +++ b/doc/_build/html/GPy.html @@ -0,0 +1,439 @@ + + + + + + + + GPy package — GPy documentation + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy package

+
+

Subpackages

+
+ +
+
+
+

Module contents

+
+
+GPy.load(file_path)[source]
+

Load a previously pickled model, using `m.pickle(‘path/to/file.pickle)’

+ +++ + + + +
Parameters:file_name – path/to/file.pickle
+
+ +
+
+GPy.tests()[source]
+
+ +
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.inference.html b/doc/_build/html/GPy.inference.html new file mode 100644 index 00000000..31725358 --- /dev/null +++ b/doc/_build/html/GPy.inference.html @@ -0,0 +1,174 @@ + + + + + + + + GPy.inference package — GPy documentation + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.inference.latent_function_inference.html b/doc/_build/html/GPy.inference.latent_function_inference.html new file mode 100644 index 00000000..f57ab578 --- /dev/null +++ b/doc/_build/html/GPy.inference.latent_function_inference.html @@ -0,0 +1,651 @@ + + + + + + + + GPy.inference.latent_function_inference package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.inference.latent_function_inference package

+
+

Submodules

+
+
+

GPy.inference.latent_function_inference.dtc module

+
+
+class GPy.inference.latent_function_inference.dtc.DTC[source]
+

Bases: GPy.inference.latent_function_inference.LatentFunctionInference

+

An object for inference when the likelihood is Gaussian, but we want to do sparse inference.

+

The function self.inference returns a Posterior object, which summarizes +the posterior.

+

NB. It’s not recommended to use this function! It’s here for historical purposes.

+
+
+inference(kern, X, Z, likelihood, Y, Y_metadata=None)[source]
+
+ +
+ +
+
+class GPy.inference.latent_function_inference.dtc.vDTC[source]
+

Bases: object

+
+
+inference(kern, X, X_variance, Z, likelihood, Y, Y_metadata)[source]
+
+ +
+ +
+
+

GPy.inference.latent_function_inference.exact_gaussian_inference module

+
+
+class GPy.inference.latent_function_inference.exact_gaussian_inference.ExactGaussianInference[source]
+

Bases: GPy.inference.latent_function_inference.LatentFunctionInference

+

An object for inference when the likelihood is Gaussian.

+

The function self.inference returns a Posterior object, which summarizes +the posterior.

+

For efficiency, we sometimes work with the cholesky of Y*Y.T. To save repeatedly recomputing this, we cache it.

+
+
+get_YYTfactor(Y)[source]
+

find a matrix L which satisfies LL^T = YY^T.

+

Note that L may have fewer columns than Y, else L=Y.

+
+ +
+
+inference(kern, X, likelihood, Y, Y_metadata=None)[source]
+

Returns a Posterior class containing essential quantities of the posterior

+
+ +
+ +
+
+

GPy.inference.latent_function_inference.expectation_propagation module

+
+
+class GPy.inference.latent_function_inference.expectation_propagation.EP(epsilon=1e-06, eta=1.0, delta=1.0)[source]
+

Bases: GPy.inference.latent_function_inference.LatentFunctionInference

+
+
+expectation_propagation(K, Y, likelihood, Y_metadata)[source]
+
+ +
+
+inference(kern, X, likelihood, Y, Y_metadata=None, Z=None)[source]
+
+ +
+
+on_optimization_end()[source]
+
+ +
+
+on_optimization_start()[source]
+
+ +
+
+reset()[source]
+
+ +
+ +
+
+

GPy.inference.latent_function_inference.expectation_propagation_dtc module

+
+
+class GPy.inference.latent_function_inference.expectation_propagation_dtc.EPDTC(epsilon=1e-06, eta=1.0, delta=1.0, limit=1)[source]
+

Bases: GPy.inference.latent_function_inference.LatentFunctionInference

+
+
+const_jitter = 1e-06
+
+ +
+
+expectation_propagation(Kmm, Kmn, Y, likelihood, Y_metadata)[source]
+
+ +
+
+get_VVTfactor(Y, prec)[source]
+
+ +
+
+inference(kern, X, Z, likelihood, Y, Y_metadata=None)[source]
+
+ +
+
+on_optimization_end()[source]
+
+ +
+
+on_optimization_start()[source]
+
+ +
+
+reset()[source]
+
+ +
+
+set_limit(limit)[source]
+
+ +
+ +
+
+

GPy.inference.latent_function_inference.fitc module

+
+
+class GPy.inference.latent_function_inference.fitc.FITC[source]
+

Bases: GPy.inference.latent_function_inference.LatentFunctionInference

+

An object for inference when the likelihood is Gaussian, but we want to do sparse inference.

+

The function self.inference returns a Posterior object, which summarizes +the posterior.

+
+
+const_jitter = 1e-06
+
+ +
+
+inference(kern, X, Z, likelihood, Y, Y_metadata=None)[source]
+
+ +
+ +
+
+

GPy.inference.latent_function_inference.inferenceX module

+
+
+class GPy.inference.latent_function_inference.inferenceX.InferenceX(model, Y, name='inferenceX', init='L2')[source]
+

Bases: GPy.core.model.Model

+

The class for inference of new X with given new Y. (do_test_latent)

+ +++ + + + +
Parameters:
    +
  • model (GPy.core.Model) – the GPy model used in inference
  • +
  • Y (numpy.ndarray) – the new observed data for inference
  • +
+
+
+
+compute_dL()[source]
+
+ +
+
+log_likelihood()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+ +
+
+GPy.inference.latent_function_inference.inferenceX.infer_newX(model, Y_new, optimize=True, init='L2')[source]
+

Infer the distribution of X for the new observed data Y_new.

+ +++ + + + + + + + +
Parameters:
    +
  • model (GPy.core.Model) – the GPy model used in inference
  • +
  • Y_new (numpy.ndarray) – the new observed data for inference
  • +
  • optimize (boolean) – whether to optimize the location of new X (True by default)
  • +
+
Returns:

a tuple containing the estimated posterior distribution of X and the model that optimize X

+
Return type:

(GPy.core.parameterization.variational.VariationalPosterior, GPy.core.Model)

+
+
+ +
+
+

GPy.inference.latent_function_inference.laplace module

+
+
+class GPy.inference.latent_function_inference.laplace.Laplace[source]
+

Bases: GPy.inference.latent_function_inference.LatentFunctionInference

+
+
+inference(kern, X, likelihood, Y, Y_metadata=None)[source]
+

Returns a Posterior class containing essential quantities of the posterior

+
+ +
+
+mode_computations(f_hat, Ki_f, K, Y, likelihood, kern, Y_metadata)[source]
+

At the mode, compute the hessian and effective covariance matrix.

+
+
returns: logZ : approximation to the marginal likelihood
+
woodbury_inv : variable required for calculating the approximation to the covariance matrix +dL_dthetaL : array of derivatives (1 x num_kernel_params) +dL_dthetaL : array of derivatives (1 x num_likelihood_params)
+
+
+ +
+
+rasm_mode(K, Y, likelihood, Ki_f_init, Y_metadata=None)[source]
+

Rasmussen’s numerically stable mode finding +For nomenclature see Rasmussen & Williams 2006 +Influenced by GPML (BSD) code, all errors are our own

+ +++ + + + + + + + +
Parameters:
    +
  • K (NxD matrix) – Covariance matrix evaluated at locations X
  • +
  • Y (np.ndarray) – The data
  • +
  • likelihood (a GPy.likelihood object) – the likelihood of the latent function value for the given data
  • +
  • Ki_f_init (np.ndarray) – the initial guess at the mode
  • +
  • Y_metadata (np.ndarray | None) – information about the data, e.g. which likelihood to take from a multi-likelihood object
  • +
+
Returns:

f_hat, mode on which to make laplace approxmiation

+
Return type:

np.ndarray

+
+
+ +
+ +
+
+GPy.inference.latent_function_inference.laplace.warning_on_one_line(message, category, filename, lineno, file=None, line=None)[source]
+
+ +
+
+

GPy.inference.latent_function_inference.posterior module

+
+
+class GPy.inference.latent_function_inference.posterior.Posterior(woodbury_chol=None, woodbury_vector=None, K=None, mean=None, cov=None, K_chol=None, woodbury_inv=None)[source]
+

Bases: object

+

An object to represent a Gaussian posterior over latent function values, p(f|D). +This may be computed exactly for Gaussian likelihoods, or approximated for +non-Gaussian likelihoods.

+

The purpose of this class is to serve as an interface between the inference +schemes and the model classes. the model class can make predictions for +the function at any new point x_* by integrating over this posterior.

+
+
+K_chol
+

Cholesky of the prior covariance K

+
+ +
+
+covariance
+

Posterior covariance +$$ +K_{xx} - K_{xx}W_{xx}^{-1}K_{xx} +W_{xx} := exttt{Woodbury inv} +$$

+
+ +
+
+mean
+

Posterior mean +$$ +K_{xx}v +v := exttt{Woodbury vector} +$$

+
+ +
+
+precision
+

Inverse of posterior covariance

+
+ +
+
+woodbury_chol
+

return $L_{W}$ where L is the lower triangular Cholesky decomposition of the Woodbury matrix +$$ +L_{W}L_{W}^{ op} = W^{-1} +W^{-1} := exttt{Woodbury inv} +$$

+
+ +
+
+woodbury_inv
+

The inverse of the woodbury matrix, in the gaussian likelihood case it is defined as +$$ +(K_{xx} + Sigma_{xx})^{-1} +Sigma_{xx} := exttt{Likelihood.variance / Approximate likelihood covariance} +$$

+
+ +
+
+woodbury_vector
+

Woodbury vector in the gaussian likelihood case only is defined as +$$ +(K_{xx} + Sigma)^{-1}Y +Sigma := exttt{Likelihood.variance / Approximate likelihood covariance} +$$

+
+ +
+ +
+
+

GPy.inference.latent_function_inference.var_dtc module

+
+
+class GPy.inference.latent_function_inference.var_dtc.VarDTC(limit=1)[source]
+

Bases: GPy.inference.latent_function_inference.LatentFunctionInference

+

An object for inference when the likelihood is Gaussian, but we want to do sparse inference.

+

The function self.inference returns a Posterior object, which summarizes +the posterior.

+

For efficiency, we sometimes work with the cholesky of Y*Y.T. To save repeatedly recomputing this, we cache it.

+
+
+const_jitter = 1e-06
+
+ +
+
+get_VVTfactor(Y, prec)[source]
+
+ +
+
+inference(kern, X, Z, likelihood, Y, Y_metadata=None, Lm=None, dL_dKmm=None)[source]
+
+ +
+
+set_limit(limit)[source]
+
+ +
+ +
+
+

GPy.inference.latent_function_inference.var_dtc_gpu module

+
+
+

GPy.inference.latent_function_inference.var_dtc_parallel module

+
+
+class GPy.inference.latent_function_inference.var_dtc_parallel.VarDTC_minibatch(batchsize=None, limit=1, mpi_comm=None)[source]
+

Bases: GPy.inference.latent_function_inference.LatentFunctionInference

+

An object for inference when the likelihood is Gaussian, but we want to do sparse inference.

+

The function self.inference returns a Posterior object, which summarizes +the posterior.

+

For efficiency, we sometimes work with the cholesky of Y*Y.T. To save repeatedly recomputing this, we cache it.

+
+
+const_jitter = 1e-06
+
+ +
+
+gatherPsiStat(kern, X, Z, Y, beta, uncertain_inputs)[source]
+
+ +
+
+inference_likelihood(kern, X, Z, likelihood, Y)[source]
+

The first phase of inference: +Compute: log-likelihood, dL_dKmm

+

Cached intermediate results: Kmm, KmmInv,

+
+ +
+
+inference_minibatch(kern, X, Z, likelihood, Y)[source]
+

The second phase of inference: Computing the derivatives over a minibatch of Y +Compute: dL_dpsi0, dL_dpsi1, dL_dpsi2, dL_dthetaL +return a flag showing whether it reached the end of Y (isEnd)

+
+ +
+
+set_limit(limit)[source]
+
+ +
+ +
+
+GPy.inference.latent_function_inference.var_dtc_parallel.update_gradients(model, mpi_comm=None)[source]
+
+ +
+
+GPy.inference.latent_function_inference.var_dtc_parallel.update_gradients_sparsegp(model, mpi_comm=None)[source]
+
+ +
+
+

Module contents

+

Inference over Gaussian process latent functions

+

In all our GP models, the consistency propery means that we have a Gaussian +prior over a finite set of points f. This prior is

+
+
math:: N(f | 0, K)
+

where K is the kernel matrix.

+

We also have a likelihood (see GPy.likelihoods) which defines how the data are +related to the latent function: p(y | f). If the likelihood is also a Gaussian, +the inference over f is tractable (see exact_gaussian_inference.py).

+

If the likelihood object is something other than Gaussian, then exact inference +is not tractable. We then resort to a Laplace approximation (laplace.py) or +expectation propagation (ep.py).

+

The inference methods return a +Posterior +instance, which is a simple +structure which contains a summary of the posterior. The model classes can then +use this posterior object for making predictions, optimizing hyper-parameters, +etc.

+
+
+class GPy.inference.latent_function_inference.InferenceMethodList[source]
+

Bases: GPy.inference.latent_function_inference.LatentFunctionInference, list

+
+
+on_optimization_end()[source]
+
+ +
+
+on_optimization_start()[source]
+
+ +
+ +
+
+class GPy.inference.latent_function_inference.LatentFunctionInference[source]
+

Bases: object

+
+
+on_optimization_end()[source]
+

This function gets called, just after the optimization loop ended.

+
+ +
+
+on_optimization_start()[source]
+

This function gets called, just before the optimization loop to start.

+
+ +
+ +
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.inference.mcmc.html b/doc/_build/html/GPy.inference.mcmc.html new file mode 100644 index 00000000..d3c4fc00 --- /dev/null +++ b/doc/_build/html/GPy.inference.mcmc.html @@ -0,0 +1,221 @@ + + + + + + + + GPy.inference.mcmc package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.inference.mcmc package

+
+

Submodules

+
+
+

GPy.inference.mcmc.hmc module

+
+
+class GPy.inference.mcmc.hmc.HMC(model, M=None, stepsize=0.1)[source]
+

An implementation of Hybrid Monte Carlo (HMC) for GPy models

+

Initialize an object for HMC sampling. Note that the status of the model (model parameters) will be changed during sampling.

+ +++ + + + +
Parameters:
    +
  • model (GPy.core.Model) – the GPy model that will be sampled
  • +
  • M (numpy.ndarray) – the mass matrix (an identity matrix by default)
  • +
  • stepsize (float) – the step size for HMC sampling
  • +
+
+
+
+sample(num_samples=1000, hmc_iters=20)[source]
+

Sample the (unfixed) model parameters.

+ +++ + + + + + + + +
Parameters:
    +
  • num_samples (int) – the number of samples to draw (1000 by default)
  • +
  • hmc_iters (int) – the number of leap-frog iterations (20 by default)
  • +
+
Returns:

the list of parameters samples with the size N x P (N - the number of samples, P - the number of parameters to sample)

+
Return type:

numpy.ndarray

+
+
+ +
+ +
+
+class GPy.inference.mcmc.hmc.HMC_shortcut(model, M=None, stepsize_range=[1e-06, 0.1], groupsize=5, Hstd_th=[1e-05, 3.0])[source]
+
+
+sample(m_iters=1000, hmc_iters=20)[source]
+
+ +
+ +
+
+

GPy.inference.mcmc.samplers module

+
+
+class GPy.inference.mcmc.samplers.Metropolis_Hastings(model, cov=None)[source]
+
+
+new_chain(start=None)[source]
+
+ +
+
+predict(function, args)[source]
+

Make a prediction for the function, to which we will pass the additional arguments

+
+ +
+
+sample(Ntotal, Nburn, Nthin, tune=True, tune_throughout=False, tune_interval=400)[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.inference.optimization.html b/doc/_build/html/GPy.inference.optimization.html new file mode 100644 index 00000000..7e8e951e --- /dev/null +++ b/doc/_build/html/GPy.inference.optimization.html @@ -0,0 +1,456 @@ + + + + + + + + GPy.inference.optimization package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.inference.optimization package

+
+

Submodules

+
+
+

GPy.inference.optimization.conjugate_gradient_descent module

+
+
+class GPy.inference.optimization.conjugate_gradient_descent.Async_Optimize[source]
+

Bases: object

+
+
+SENTINEL = 'SENTINEL'
+
+ +
+
+async_callback_collect(q)[source]
+
+ +
+
+callback(*x)
+
+ +
+
+opt(f, df, x0, callback=None, update_rule=<class GPy.inference.optimization.gradient_descent_update_rules.FletcherReeves>, messages=0, maxiter=5000.0, max_f_eval=15000.0, gtol=1e-06, report_every=10, *args, **kwargs)[source]
+
+ +
+
+opt_async(f, df, x0, callback, update_rule=<class GPy.inference.optimization.gradient_descent_update_rules.PolakRibiere>, messages=0, maxiter=5000.0, max_f_eval=15000.0, gtol=1e-06, report_every=10, *args, **kwargs)[source]
+
+ +
+
+runsignal = <multiprocessing.synchronize.Event object>
+
+ +
+ +
+
+class GPy.inference.optimization.conjugate_gradient_descent.CGD[source]
+

Bases: GPy.inference.optimization.conjugate_gradient_descent.Async_Optimize

+

Conjugate gradient descent algorithm to minimize +function f with gradients df, starting at x0 +with update rule update_rule

+

if df returns tuple (grad, natgrad) it will optimize according +to natural gradient rules

+
+
+opt(*a, **kw)[source]
+
+
opt(self, f, df, x0, callback=None, update_rule=FletcherReeves,
+
messages=0, maxiter=5e3, max_f_eval=15e3, gtol=1e-6, +report_every=10, *args, **kwargs)
+
+

Minimize f, calling callback every report_every iterations with following syntax:

+
+
callback(xi, fi, gi, iteration, function_calls, gradient_calls, status_message)
+

if df returns tuple (grad, natgrad) it will optimize according +to natural gradient rules

+

f, and df will be called with

+
+
f(xi, *args, **kwargs) +df(xi, *args, **kwargs)
+

returns

+
+
x_opt, f_opt, g_opt, iteration, function_calls, gradient_calls, status_message
+

at end of optimization

+
+ +
+
+opt_async(*a, **kw)[source]
+
+
opt_async(self, f, df, x0, callback, update_rule=FletcherReeves,
+
messages=0, maxiter=5e3, max_f_eval=15e3, gtol=1e-6, +report_every=10, *args, **kwargs)
+
+

callback gets called every report_every iterations

+
+
callback(xi, fi, gi, iteration, function_calls, gradient_calls, status_message)
+

if df returns tuple (grad, natgrad) it will optimize according +to natural gradient rules

+

f, and df will be called with

+
+
f(xi, *args, **kwargs) +df(xi, *args, **kwargs)
+

Returns:

+
+
Started Process object, optimizing asynchronously
+

Calls:

+
+
callback(x_opt, f_opt, g_opt, iteration, function_calls, gradient_calls, status_message)
+

at end of optimization!

+
+ +
+
+opt_name = 'Conjugate Gradient Descent'
+
+ +
+ +
+
+

GPy.inference.optimization.gradient_descent_update_rules module

+
+
+class GPy.inference.optimization.gradient_descent_update_rules.FletcherReeves(initgrad, initgradnat=None)[source]
+

Bases: GPy.inference.optimization.gradient_descent_update_rules.GDUpdateRule

+

Fletcher Reeves update rule for gamma

+
+ +
+
+class GPy.inference.optimization.gradient_descent_update_rules.GDUpdateRule(initgrad, initgradnat=None)[source]
+
+ +
+
+class GPy.inference.optimization.gradient_descent_update_rules.PolakRibiere(initgrad, initgradnat=None)[source]
+

Bases: GPy.inference.optimization.gradient_descent_update_rules.GDUpdateRule

+

Fletcher Reeves update rule for gamma

+
+ +
+
+

GPy.inference.optimization.optimization module

+
+
+class GPy.inference.optimization.optimization.Optimizer(x_init, messages=False, model=None, max_f_eval=10000.0, max_iters=1000.0, ftol=None, gtol=None, xtol=None, bfgs_factor=None)[source]
+

Superclass for all the optimizers.

+ +++ + + + + + +
Parameters:
    +
  • x_init – initial set of parameters
  • +
  • f_fp – function that returns the function AND the gradients at the same time
  • +
  • f – function to optimize
  • +
  • fp – gradients
  • +
  • messages ((True | False)) – print messages from the optimizer?
  • +
  • max_f_eval – maximum number of function evaluations
  • +
+
Return type:

optimizer object.

+
+
+
+opt(f_fp=None, f=None, fp=None)[source]
+
+ +
+
+plot()[source]
+

See GPy.plotting.matplot_dep.inference_plots

+
+ +
+
+run(**kwargs)[source]
+
+ +
+ +
+
+GPy.inference.optimization.optimization.get_optimizer(f_min)[source]
+
+ +
+
+class GPy.inference.optimization.optimization.opt_SCG(*args, **kwargs)[source]
+

Bases: GPy.inference.optimization.optimization.Optimizer

+
+
+opt(f_fp=None, f=None, fp=None)[source]
+
+ +
+ +
+
+class GPy.inference.optimization.optimization.opt_lbfgsb(*args, **kwargs)[source]
+

Bases: GPy.inference.optimization.optimization.Optimizer

+
+
+opt(f_fp=None, f=None, fp=None)[source]
+

Run the optimizer

+
+ +
+ +
+
+class GPy.inference.optimization.optimization.opt_rasm(*args, **kwargs)[source]
+

Bases: GPy.inference.optimization.optimization.Optimizer

+
+
+opt(f_fp=None, f=None, fp=None)[source]
+

Run Rasmussen’s Conjugate Gradient optimizer

+
+ +
+ +
+
+class GPy.inference.optimization.optimization.opt_simplex(*args, **kwargs)[source]
+

Bases: GPy.inference.optimization.optimization.Optimizer

+
+
+opt(f_fp=None, f=None, fp=None)[source]
+

The simplex optimizer does not require gradients.

+
+ +
+ +
+
+class GPy.inference.optimization.optimization.opt_tnc(*args, **kwargs)[source]
+

Bases: GPy.inference.optimization.optimization.Optimizer

+
+
+opt(f_fp=None, f=None, fp=None)[source]
+

Run the TNC optimizer

+
+ +
+ +
+
+

GPy.inference.optimization.scg module

+
+
+GPy.inference.optimization.scg.SCG(f, gradf, x, optargs=(), maxiters=500, max_f_eval=inf, display=True, xtol=None, ftol=None, gtol=None)[source]
+

Optimisation through Scaled Conjugate Gradients (SCG)

+

f: the objective function +gradf : the gradient function (should return a 1D np.ndarray) +x : the initial condition

+

Returns +x the optimal value for x +flog : a list of all the objective values +function_eval number of fn evaluations +status: string describing convergence status

+
+ +
+
+GPy.inference.optimization.scg.exponents(fnow, current_grad)[source]
+
+ +
+
+GPy.inference.optimization.scg.print_out(len_maxiters, fnow, current_grad, beta, iteration)[source]
+
+ +
+
+

GPy.inference.optimization.sgd module

+
+
+

GPy.inference.optimization.stochastics module

+
+
+class GPy.inference.optimization.stochastics.SparseGPMissing(model, batchsize=1)[source]
+

Bases: GPy.inference.optimization.stochastics.StochasticStorage

+
+ +
+
+class GPy.inference.optimization.stochastics.SparseGPStochastics(model, batchsize=1)[source]
+

Bases: GPy.inference.optimization.stochastics.StochasticStorage

+

For the sparse gp we need to store the dimension we are in, +and the indices corresponding to those

+
+
+do_stochastics()[source]
+
+ +
+
+reset()[source]
+
+ +
+ +
+
+class GPy.inference.optimization.stochastics.StochasticStorage(model)[source]
+

Bases: object

+

This is a container for holding the stochastic parameters, +such as subset indices or step length and so on.

+
+
+do_stochastics()[source]
+

Update the internal state to the next batch of the stochastic +descent algorithm.

+
+ +
+
+reset()[source]
+

Reset the state of this stochastics generator.

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.kern._src.html b/doc/_build/html/GPy.kern._src.html new file mode 100644 index 00000000..677b85f1 --- /dev/null +++ b/doc/_build/html/GPy.kern._src.html @@ -0,0 +1,2052 @@ + + + + + + + + GPy.kern._src package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.kern._src package

+ +
+

Submodules

+
+
+

GPy.kern._src.ODE_UY module

+
+
+class GPy.kern._src.ODE_UY.ODE_UY(input_dim, variance_U=3.0, variance_Y=1.0, lengthscale_U=1.0, lengthscale_Y=1.0, active_dims=None, name='ode_uy')[source]
+

Bases: GPy.kern._src.kern.Kern

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+

Compute the diagonal of the covariance matrix associated to X.

+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+

derivative of the covariance matrix with respect to the parameters.

+
+ +
+ +
+
+

GPy.kern._src.ODE_UYC module

+
+
+class GPy.kern._src.ODE_UYC.ODE_UYC(input_dim, variance_U=3.0, variance_Y=1.0, lengthscale_U=1.0, lengthscale_Y=1.0, ubias=1.0, active_dims=None, name='ode_uyc')[source]
+

Bases: GPy.kern._src.kern.Kern

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+

Compute the diagonal of the covariance matrix associated to X.

+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+

derivative of the covariance matrix with respect to the parameters.

+
+ +
+ +
+
+

GPy.kern._src.ODE_st module

+
+
+class GPy.kern._src.ODE_st.ODE_st(input_dim, a=1.0, b=1.0, c=1.0, variance_Yx=3.0, variance_Yt=1.5, lengthscale_Yx=1.5, lengthscale_Yt=1.5, active_dims=None, name='ode_st')[source]
+

Bases: GPy.kern._src.kern.Kern

+

kernel resultiong from a first order ODE with OU driving GP

+ +++ + + + + + +
Parameters:
    +
  • input_dim (int) – the number of input dimension, has to be equal to one
  • +
  • varianceU (float) – variance of the driving GP
  • +
  • lengthscaleU (float) – lengthscale of the driving GP (sqrt(3)/lengthscaleU)
  • +
  • varianceY (float) – ‘variance’ of the transfer function
  • +
  • lengthscaleY (float) – ‘lengthscale’ of the transfer function (1/lengthscaleY)
  • +
+
Return type:

kernel object

+
+
+
+K(X, X2=None, *a, **kw)[source]
+

Compute the covariance matrix between X and X2.

+
+ +
+
+Kdiag(X, *a, **kw)[source]
+

Compute the diagonal of the covariance matrix associated to X.

+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+

derivative of the covariance matrix with respect to the parameters.

+
+ +
+ +
+
+

GPy.kern._src.ODE_t module

+
+
+class GPy.kern._src.ODE_t.ODE_t(input_dim, a=1.0, c=1.0, variance_Yt=3.0, lengthscale_Yt=1.5, ubias=1.0, active_dims=None, name='ode_st')[source]
+

Bases: GPy.kern._src.kern.Kern

+
+
+K(X, X2=None, *a, **kw)[source]
+

Compute the covariance matrix between X and X2.

+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+

derivative of the covariance matrix with respect to the parameters.

+
+ +
+ +
+
+

GPy.kern._src.add module

+
+
+class GPy.kern._src.add.Add(subkerns, name='add')[source]
+

Bases: GPy.kern._src.kern.CombinationKernel

+

Add given list of kernels together. +propagates gradients through.

+

This kernel will take over the active dims of it’s subkernels passed in.

+
+
+K(X, X2=None, *a, **kw)[source]
+

Add all kernels together. +If a list of parts (of this kernel!) which_parts is given, only +the parts of the list are taken to compute the covariance.

+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+add(other)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+

Compute the gradient of the objective function with respect to X.

+ +++ + + + +
Parameters:
    +
  • dL_dK (np.ndarray (num_samples x num_inducing)) – An array of gradients of the objective function with respect to the covariance function.
  • +
  • X (np.ndarray (num_samples x input_dim)) – Observed data inputs
  • +
  • X2 (np.ndarray (num_inducing x input_dim)) – Observed data inputs (optional, defaults to X)
  • +
+
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+gradients_Z_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+gradients_qX_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+input_sensitivity(summarize=True)[source]
+
+ +
+
+psi0(Z, variational_posterior)[source]
+
+ +
+
+psi1(Z, variational_posterior)[source]
+
+ +
+
+psi2(Z, variational_posterior)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+

GPy.kern._src.brownian module

+
+
+class GPy.kern._src.brownian.Brownian(input_dim=1, variance=1.0, active_dims=None, name='Brownian')[source]
+

Bases: GPy.kern._src.kern.Kern

+

Brownian motion in 1D only.

+

Negative times are treated as a separate (backwards!) Brownian motion.

+ +++ + + + +
Parameters:
    +
  • input_dim (int) – the number of input dimensions
  • +
  • variance (float) –
  • +
+
+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+

GPy.kern._src.coregionalize module

+
+
+class GPy.kern._src.coregionalize.Coregionalize(input_dim, output_dim, rank=1, W=None, kappa=None, active_dims=None, name='coregion')[source]
+

Bases: GPy.kern._src.kern.Kern

+

Covariance function for intrinsic/linear coregionalization models

+

This covariance has the form: +.. math:

+
\mathbf{B} = \mathbf{W}\mathbf{W}^       op +    ext{diag}(kappa)
+
+
+

An intrinsic/linear coregionalization covariance function of the form: +.. math:

+
k_2(x, y)=\mathbf{B} k(x, y)
+
+
+

it is obtained as the tensor product between a covariance function +k(x, y) and B.

+ +++ + + + +
Parameters:
    +
  • output_dim (int) – number of outputs to coregionalize
  • +
  • rank (int) – number of columns of the W matrix (this parameter is ignored if parameter W is not None)
  • +
  • W (numpy array of dimensionality (num_outpus, W_columns)) – a low rank matrix that determines the correlations between the different outputs, together with kappa it forms the coregionalization matrix B
  • +
  • kappa (numpy array of dimensionality (output_dim, )) – a vector which allows the outputs to behave independently
  • +
+
+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+

GPy.kern._src.hierarchical module

+
+
+

GPy.kern._src.independent_outputs module

+
+
+class GPy.kern._src.independent_outputs.Hierarchical(kernels, name='hierarchy')[source]
+

Bases: GPy.kern._src.kern.CombinationKernel

+

A kernel which can represent a simple hierarchical model.

+

See Hensman et al 2013, “Hierarchical Bayesian modelling of gene expression time +series across irregularly sampled replicates and clusters” +http://www.biomedcentral.com/1471-2105/14/252

+

To construct this kernel, you must pass a list of kernels. the first kernel +will be assumed to be the ‘base’ kernel, and will be computed everywhere. +For every additional kernel, we assume another layer in the hierachy, with +a corresponding column of the input matrix which indexes which function the +data are in at that level.

+

For more, see the ipython notebook documentation on Hierarchical +covariances.

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+class GPy.kern._src.independent_outputs.IndependentOutputs(kernels, index_dim=-1, name='independ')[source]
+

Bases: GPy.kern._src.kern.CombinationKernel

+

A kernel which can represent several independent functions. this kernel +‘switches off’ parts of the matrix where the output indexes are different.

+

The index of the functions is given by the last column in the input X the +rest of the columns of X are passed to the underlying kernel for +computation (in blocks).

+ +++ + + + +
Parameters:kernels – either a kernel, or list of kernels to work with. If it is
+

a list of kernels the indices in the index_dim, index the kernels you gave!

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+GPy.kern._src.independent_outputs.index_to_slices(index)[source]
+

take a numpy array of integers (index) and return a nested list of slices such that the slices describe the start, stop points for each integer in the index.

+

e.g. +>>> index = np.asarray([0,0,0,1,1,1,2,2,2]) +returns +>>> [[slice(0,3,None)],[slice(3,6,None)],[slice(6,9,None)]]

+

or, a more complicated example +>>> index = np.asarray([0,0,1,1,0,2,2,2,1,1]) +returns +>>> [[slice(0,2,None),slice(4,5,None)],[slice(2,4,None),slice(8,10,None)],[slice(5,8,None)]]

+
+ +
+
+

GPy.kern._src.kern module

+
+
+class GPy.kern._src.kern.CombinationKernel(kernels, name, extra_dims=[])[source]
+

Bases: GPy.kern._src.kern.Kern

+

Abstract super class for combination kernels. +A combination kernel combines (a list of) kernels and works on those. +Examples are the HierarchicalKernel or Add and Prod kernels.

+
+
+get_input_dim_active_dims(kernels, extra_dims=None)[source]
+
+ +
+
+input_sensitivity(summarize=True)[source]
+

If summize is true, we want to get the summerized view of the sensitivities, +otherwise put everything into an array with shape (#kernels, input_dim) +in the order of appearance of the kernels in the parameterized object.

+
+ +
+
+parts
+
+ +
+ +
+
+class GPy.kern._src.kern.Kern(input_dim, active_dims, name, useGPU=False, *a, **kw)[source]
+

Bases: GPy.core.parameterization.parameterized.Parameterized

+
+
+K(X, X2=None, *a, **kw)[source]
+

Compute the kernel function.

+ +++ + + + +
Parameters:
    +
  • X – the first set of inputs to the kernel
  • +
  • X2 – (optional) the second set of arguments to the kernel. If X2 +is None, this is passed throgh to the ‘part’ object, which +handLes this as X2 == X.
  • +
+
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+add(other, name='add')[source]
+

Add another kernel to this one.

+ +++ + + + +
Parameters:other (GPy.kern) – the other kernel to be added
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+gradients_Z_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+

Returns the derivative of the objective wrt Z, using the chain rule +through the expectation variables.

+
+ +
+
+gradients_qX_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+

Compute the gradients wrt the parameters of the variational +distruibution q(X), chain-ruling via the expectations of the kernel

+
+ +
+
+input_sensitivity(summarize=True)[source]
+

Returns the sensitivity for each dimension of this kernel.

+
+ +
+
+plot(x=None, fignum=None, ax=None, title=None, plot_limits=None, resolution=None, **mpl_kwargs)[source]
+

plot this kernel. +:param x: the value to use for the other kernel argument (kernels are a function of two variables!) +:param fignum: figure number of the plot +:param ax: matplotlib axis to plot on +:param title: the matplotlib title +:param plot_limits: the range over which to plot the kernel +:resolution: the resolution of the lines used in plotting +:mpl_kwargs avalid keyword arguments to pass through to matplotlib (e.g. lw=7)

+
+ +
+
+plot_ARD(*args, **kw)[source]
+

See kernel_plots

+
+ +
+
+prod(other, name='mul')[source]
+

Multiply two kernels (either on the same space, or on the tensor +product of the input space).

+ +++ + + + +
Parameters:
    +
  • other (GPy.kern) – the other kernel to be added
  • +
  • tensor (bool) – whether or not to use the tensor space (default is false).
  • +
+
+
+ +
+
+psi0(Z, variational_posterior)[source]
+
+ +
+
+psi1(Z, variational_posterior)[source]
+
+ +
+
+psi2(Z, variational_posterior)[source]
+
+ +
+
+return_psi2_n
+

Flag whether to pass back psi2 as NxMxM or MxM, by summing out N.

+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+

update the gradients of all parameters when using only the diagonal elements of the covariance matrix

+
+ +
+
+update_gradients_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+

Set the gradients of all parameters when doing inference with +uncertain inputs, using expectations of the kernel.

+

The esential maths is

+
+
dL_d{theta_i} = dL_dpsi0 * dpsi0_d{theta_i} +
+
dL_dpsi1 * dpsi1_d{theta_i} + +dL_dpsi2 * dpsi2_d{theta_i}
+
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+

Set the gradients of all parameters when doing full (N) inference.

+
+ +
+ +
+
+

GPy.kern._src.kernel_slice_operations module

+

Created on 11 Mar 2014

+

@author: maxz

+
+
+class GPy.kern._src.kernel_slice_operations.KernCallsViaSlicerMeta[source]
+

Bases: GPy.core.parameterization.parameterized.ParametersChangedMeta

+
+ +
+
+GPy.kern._src.kernel_slice_operations.put_clean(dct, name, func)[source]
+
+ +
+
+

GPy.kern._src.linear module

+
+
+class GPy.kern._src.linear.Linear(input_dim, variances=None, ARD=False, active_dims=None, name='linear')[source]
+

Bases: GPy.kern._src.kern.Kern

+

Linear kernel

+
+

k(x,y) = \sum_{i=1}^input_dim \sigma^2_i x_iy_i

+
+++ + + + + + +
Parameters:
    +
  • input_dim (int) – the number of input dimensions
  • +
  • variances (array or list of the appropriate size (or float if there +is only one variance parameter)) – the vector of variances \sigma^2_i
  • +
  • ARD (Boolean) – Auto Relevance Determination. If False, the kernel has only one +variance parameter sigma^2, otherwise there is one variance +parameter per dimension.
  • +
+
Return type:

kernel object

+
+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+gradients_Z_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+gradients_qX_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+input_sensitivity(summarize=True)[source]
+
+ +
+
+psi0(Z, variational_posterior)[source]
+
+ +
+
+psi1(Z, variational_posterior)[source]
+
+ +
+
+psi2(Z, variational_posterior)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+class GPy.kern._src.linear.LinearFull(input_dim, rank, W=None, kappa=None, active_dims=None, name='linear_full')[source]
+

Bases: GPy.kern._src.kern.Kern

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+

GPy.kern._src.mlp module

+
+
+class GPy.kern._src.mlp.MLP(input_dim, variance=1.0, weight_variance=1.0, bias_variance=100.0, active_dims=None, name='mlp')[source]
+

Bases: GPy.kern._src.kern.Kern

+

Multi layer perceptron kernel (also known as arc sine kernel or neural network kernel)

+
+

k(x,y) = \sigma^{2}\frac{2}{\pi }  \text{asin} \left ( \frac{ \sigma_w^2 x^\top y+\sigma_b^2}{\sqrt{\sigma_w^2x^\top x + \sigma_b^2 + 1}\sqrt{\sigma_w^2 y^\top y \sigma_b^2 +1}} \right )

+
+++ + + + + + +
Parameters:
    +
  • input_dim (int) – the number of input dimensions
  • +
  • variance (float) – the variance \sigma^2
  • +
  • weight_variance (array or list of the appropriate size (or float if there is only one weight variance parameter)) – the vector of the variances of the prior over input weights in the neural network \sigma^2_w
  • +
  • bias_variance – the variance of the prior over bias parameters \sigma^2_b
  • +
  • ARD (Boolean) – Auto Relevance Determination. If equal to “False”, the kernel is isotropic (ie. one weight variance parameter sigma^2_w), otherwise there is one weight variance parameter per dimension.
  • +
+
Return type:

Kernpart object

+
+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+

Compute the diagonal of the covariance matrix for X.

+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+

Derivative of the covariance matrix with respect to X

+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+

Gradient of diagonal of covariance with respect to X

+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+

Derivative of the covariance with respect to the parameters.

+
+ +
+ +
+
+

GPy.kern._src.periodic module

+
+
+class GPy.kern._src.periodic.Periodic(input_dim, variance, lengthscale, period, n_freq, lower, upper, active_dims, name)[source]
+

Bases: GPy.kern._src.kern.Kern

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+ +
+
+class GPy.kern._src.periodic.PeriodicExponential(input_dim=1, variance=1.0, lengthscale=1.0, period=6.283185307179586, n_freq=10, lower=0.0, upper=12.566370614359172, active_dims=None, name='periodic_exponential')[source]
+

Bases: GPy.kern._src.periodic.Periodic

+

Kernel of the periodic subspace (up to a given frequency) of a exponential +(Matern 1/2) RKHS.

+

Only defined for input_dim=1.

+
+
+Gram_matrix()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+

derivative of the covariance matrix with respect to the parameters (shape is N x num_inducing x num_params)

+
+ +
+ +
+
+class GPy.kern._src.periodic.PeriodicMatern32(input_dim=1, variance=1.0, lengthscale=1.0, period=6.283185307179586, n_freq=10, lower=0.0, upper=12.566370614359172, active_dims=None, name='periodic_Matern32')[source]
+

Bases: GPy.kern._src.periodic.Periodic

+

Kernel of the periodic subspace (up to a given frequency) of a Matern 3/2 RKHS. Only defined for input_dim=1.

+ +++ + + + + + +
Parameters:
    +
  • input_dim (int) – the number of input dimensions
  • +
  • variance (float) – the variance of the Matern kernel
  • +
  • lengthscale (np.ndarray of size (input_dim,)) – the lengthscale of the Matern kernel
  • +
  • period (float) – the period
  • +
  • n_freq (int) – the number of frequencies considered for the periodic subspace
  • +
+
Return type:

kernel object

+
+
+
+Gram_matrix()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+

derivative of the covariance matrix with respect to the parameters (shape is num_data x num_inducing x num_params)

+
+ +
+ +
+
+class GPy.kern._src.periodic.PeriodicMatern52(input_dim=1, variance=1.0, lengthscale=1.0, period=6.283185307179586, n_freq=10, lower=0.0, upper=12.566370614359172, active_dims=None, name='periodic_Matern52')[source]
+

Bases: GPy.kern._src.periodic.Periodic

+

Kernel of the periodic subspace (up to a given frequency) of a Matern 5/2 RKHS. Only defined for input_dim=1.

+ +++ + + + + + +
Parameters:
    +
  • input_dim (int) – the number of input dimensions
  • +
  • variance (float) – the variance of the Matern kernel
  • +
  • lengthscale (np.ndarray of size (input_dim,)) – the lengthscale of the Matern kernel
  • +
  • period (float) – the period
  • +
  • n_freq (int) – the number of frequencies considered for the periodic subspace
  • +
+
Return type:

kernel object

+
+
+
+Gram_matrix()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+

GPy.kern._src.poly module

+
+
+class GPy.kern._src.poly.Poly(input_dim, variance=1.0, order=3.0, active_dims=None, name='poly')[source]
+

Bases: GPy.kern._src.kern.Kern

+

Polynomial kernel

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+

GPy.kern._src.prod module

+
+
+class GPy.kern._src.prod.Prod(kernels, name='mul')[source]
+

Bases: GPy.kern._src.kern.CombinationKernel

+

Computes the product of 2 kernels

+ +++ + + + + + +
Parameters:
    +
  • k2 (k1,) – the kernels to multiply
  • +
  • tensor (Boolean) – The kernels are either multiply as functions defined on the same input space (default) or on the product of the input spaces
  • +
+
Return type:

kernel object

+
+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+

GPy.kern._src.rbf module

+
+
+class GPy.kern._src.rbf.RBF(input_dim, variance=1.0, lengthscale=None, ARD=False, active_dims=None, name='rbf', useGPU=False)[source]
+

Bases: GPy.kern._src.stationary.Stationary

+

Radial Basis Function kernel, aka squared-exponential, exponentiated quadratic or Gaussian kernel:

+
+

k(r) = \sigma^2 \exp \bigg(- \frac{1}{2} r^2 \bigg)

+
+
+K_of_r(r)[source]
+
+ +
+
+dK_dr(r)[source]
+
+ +
+
+gradients_Z_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+gradients_qX_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+psi0(Z, variational_posterior)[source]
+
+ +
+
+psi1(Z, variational_posterior)[source]
+
+ +
+
+psi2(Z, variational_posterior)[source]
+
+ +
+
+spectrum(omega)[source]
+
+ +
+
+update_gradients_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+ +
+
+

GPy.kern._src.splitKern module

+

A new kernel

+
+
+class GPy.kern._src.splitKern.DiffGenomeKern(kernel, idx_p, Xp, index_dim=-1, name='DiffGenomeKern')[source]
+

Bases: GPy.kern._src.kern.Kern

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+class GPy.kern._src.splitKern.SplitKern(kernel, Xp, index_dim=-1, name='SplitKern')[source]
+

Bases: GPy.kern._src.kern.CombinationKernel

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+class GPy.kern._src.splitKern.SplitKern_cross(kernel, Xp, name='SplitKern_cross')[source]
+

Bases: GPy.kern._src.kern.Kern

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+

GPy.kern._src.static module

+
+
+class GPy.kern._src.static.Bias(input_dim, variance=1.0, active_dims=None, name='bias')[source]
+

Bases: GPy.kern._src.static.Static

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+psi2(Z, variational_posterior)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+class GPy.kern._src.static.Fixed(input_dim, covariance_matrix, variance=1.0, active_dims=None, name='fixed')[source]
+

Bases: GPy.kern._src.static.Static

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+psi2(Z, variational_posterior)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+class GPy.kern._src.static.Static(input_dim, variance, active_dims, name)[source]
+

Bases: GPy.kern._src.kern.Kern

+
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+gradients_Z_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+gradients_qX_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+input_sensitivity(summarize=True)[source]
+
+ +
+
+psi0(Z, variational_posterior)[source]
+
+ +
+
+psi1(Z, variational_posterior)[source]
+
+ +
+
+psi2(Z, variational_posterior)[source]
+
+ +
+ +
+
+class GPy.kern._src.static.White(input_dim, variance=1.0, active_dims=None, name='white')[source]
+

Bases: GPy.kern._src.static.Static

+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+psi2(Z, variational_posterior)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+

GPy.kern._src.stationary module

+
+
+class GPy.kern._src.stationary.Cosine(input_dim, variance=1.0, lengthscale=None, ARD=False, active_dims=None, name='Cosine')[source]
+

Bases: GPy.kern._src.stationary.Stationary

+
+
+K_of_r(r)[source]
+
+ +
+
+dK_dr(r)[source]
+
+ +
+ +
+
+class GPy.kern._src.stationary.ExpQuad(input_dim, variance=1.0, lengthscale=None, ARD=False, active_dims=None, name='ExpQuad')[source]
+

Bases: GPy.kern._src.stationary.Stationary

+

The Exponentiated quadratic covariance function.

+
+

k(r) = \sigma^2 (1 + \sqrt{5} r + \frac53 r^2) \exp(- \sqrt{5} r)

+
+
notes::
+
    +
  • Yes, this is exactly the same as the RBF covariance function, but the +RBF implementation also has some features for doing variational kernels +(the psi-statistics).
  • +
+
+
+
+
+K_of_r(r)[source]
+
+ +
+
+dK_dr(r)[source]
+
+ +
+ +
+
+class GPy.kern._src.stationary.Exponential(input_dim, variance=1.0, lengthscale=None, ARD=False, active_dims=None, name='Exponential')[source]
+

Bases: GPy.kern._src.stationary.Stationary

+
+
+K_of_r(r)[source]
+
+ +
+
+dK_dr(r)[source]
+
+ +
+ +
+
+class GPy.kern._src.stationary.Matern32(input_dim, variance=1.0, lengthscale=None, ARD=False, active_dims=None, name='Mat32')[source]
+

Bases: GPy.kern._src.stationary.Stationary

+

Matern 3/2 kernel:

+
+

k(r) = \sigma^2 (1 + \sqrt{3} r) \exp(- \sqrt{3} r) \ \ \ \  \text{ where  } r = \sqrt{\sum_{i=1}^input_dim \frac{(x_i-y_i)^2}{\ell_i^2} }

+
+
+Gram_matrix(F, F1, F2, lower, upper)[source]
+

Return the Gram matrix of the vector of functions F with respect to the +RKHS norm. The use of this function is limited to input_dim=1.

+ +++ + + + +
Parameters:
    +
  • F (np.array) – vector of functions
  • +
  • F1 (np.array) – vector of derivatives of F
  • +
  • F2 (np.array) – vector of second derivatives of F
  • +
  • lower,upper (floats) – boundaries of the input domain
  • +
+
+
+ +
+
+K_of_r(r)[source]
+
+ +
+
+dK_dr(r)[source]
+
+ +
+ +
+
+class GPy.kern._src.stationary.Matern52(input_dim, variance=1.0, lengthscale=None, ARD=False, active_dims=None, name='Mat52')[source]
+

Bases: GPy.kern._src.stationary.Stationary

+

Matern 5/2 kernel:

+
+

k(r) = \sigma^2 (1 + \sqrt{5} r + \frac53 r^2) \exp(- \sqrt{5} r)

+
+
+Gram_matrix(F, F1, F2, F3, lower, upper)[source]
+

Return the Gram matrix of the vector of functions F with respect to the RKHS norm. The use of this function is limited to input_dim=1.

+ +++ + + + +
Parameters:
    +
  • F (np.array) – vector of functions
  • +
  • F1 (np.array) – vector of derivatives of F
  • +
  • F2 (np.array) – vector of second derivatives of F
  • +
  • F3 (np.array) – vector of third derivatives of F
  • +
  • lower,upper (floats) – boundaries of the input domain
  • +
+
+
+ +
+
+K_of_r(r)[source]
+
+ +
+
+dK_dr(r)[source]
+
+ +
+ +
+
+class GPy.kern._src.stationary.OU(input_dim, variance=1.0, lengthscale=None, ARD=False, active_dims=None, name='OU')[source]
+

Bases: GPy.kern._src.stationary.Stationary

+

OU kernel:

+
+

k(r) = \sigma^2 \exp(- r) \ \ \ \  \text{ where  } r = \sqrt{\sum_{i=1}^input_dim \frac{(x_i-y_i)^2}{\ell_i^2} }

+
+
+K_of_r(r)[source]
+
+ +
+
+dK_dr(r)[source]
+
+ +
+ +
+
+class GPy.kern._src.stationary.RatQuad(input_dim, variance=1.0, lengthscale=None, power=2.0, ARD=False, active_dims=None, name='RatQuad')[source]
+

Bases: GPy.kern._src.stationary.Stationary

+

Rational Quadratic Kernel

+
+

k(r) = \sigma^2 \bigg( 1 + \frac{r^2}{2} \bigg)^{- \alpha}

+
+
+K_of_r(r)[source]
+
+ +
+
+dK_dr(r)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+class GPy.kern._src.stationary.Stationary(input_dim, variance, lengthscale, ARD, active_dims, name, useGPU=False)[source]
+

Bases: GPy.kern._src.kern.Kern

+
+

Stationary kernels (covariance functions).

+

Stationary covariance fucntion depend only on r, where r is defined as

+
+
r = sqrt{ sum_{q=1}^Q (x_q - x’_q)^2 }
+

The covariance function k(x, x’ can then be written k(r).

+

In this implementation, r is scaled by the lengthscales parameter(s):

+
+
r = sqrt{ sum_{q=1}^Q
+
+

rac{(x_q - x’_q)^2}{ell_q^2} }.

+
+

By default, there’s only one lengthscale: seaprate lengthscales for each +dimension can be enables by setting ARD=True.

+

To implement a stationary covariance function using this class, one need +only define the covariance function k(r), and it derivative.

+
+

... +def K_of_r(self, r):

+
+
return foo
+
+
def dK_dr(self, r):
+
return bar
+
+
+

The lengthscale(s) and variance parameters are added to the structure automatically.

+
+
+
+K(X, X2=None, *a, **kw)[source]
+

Kernel function applied on inputs X and X2. +In the stationary case there is an inner function depending on the +distances from X to X2, called r.

+

K(X, X2) = K_of_r((X-X2)**2)

+
+ +
+
+K_of_r(r)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+dK_dr(r)[source]
+
+ +
+
+dK_dr_via_X = <functools.partial object>
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+

Given the derivative of the objective wrt K (dL_dK), compute the derivative wrt X

+
+ +
+
+gradients_X_(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+gradients_X_weave(dL_dK, X, X2=None)[source]
+
+ +
+
+input_sensitivity(summarize=True)[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+

Given the derivative of the objective with respect to the diagonal of +the covariance matrix, compute the derivative wrt the parameters of +this kernel and stor in the <parameter>.gradient field.

+

See also update_gradients_full

+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+

Given the derivative of the objective wrt the covariance matrix +(dL_dK), compute the gradient wrt the parameters of this kernel, +and store in the parameters object as e.g. self.variance.gradient

+
+ +
+
+weave_lengthscale_grads(tmp, X, X2)[source]
+

Use scipy.weave to compute derivatives wrt the lengthscales

+
+ +
+ +
+
+

GPy.kern._src.symbolic module

+
+
+

GPy.kern._src.trunclinear module

+
+
+class GPy.kern._src.trunclinear.TruncLinear(input_dim, variances=None, delta=None, ARD=False, active_dims=None, name='linear')[source]
+

Bases: GPy.kern._src.kern.Kern

+

Truncated Linear kernel

+
+

System Message: WARNING/2 (k(x,y) = \sum_{i=1}^input_dim \sigma^2_i \max(0, x_iy_i - \simga_q))

+latex exited with error +[stdout] +This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014/Debian) (preloaded format=latex) + restricted \write18 enabled. +entering extended mode +(./math.tex +LaTeX2e <2014/05/01> +Babel <3.9k> and hyphenation patterns for 79 languages loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2007/10/19 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size12.clo)) +(/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty +(/usr/share/texlive/texmf-dist/tex/latex/ucs/utf8x.def)) +(/usr/share/texlive/texmf-dist/tex/latex/ucs/ucs.sty +(/usr/share/texlive/texmf-dist/tex/latex/ucs/data/uni-global.def)) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +For additional information on amsmath, use the `?’ option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty)) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty)) +(/usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty) +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty)) +(/usr/share/texlive/texmf-dist/tex/latex/tools/bm.sty) +No file math.aux. +(/usr/share/texlive/texmf-dist/tex/latex/ucs/ucsencs.def) +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd) +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd) +! Undefined control sequence. +<argument> ...sigma ^2_i \max (0, x_iy_i - \simga + _q)\end {split}\notag +l.14 \end{gather} + +! Undefined control sequence. +<argument> ...sigma ^2_i \max (0, x_iy_i - \simga + _q)\end {split}\notag +l.14 \end{gather} + +[1] (./math.aux) ) +(see the transcript file for additional information) +Output written on math.dvi (1 page, 616 bytes). +Transcript written on math.log. +
+ +++ + + + + + +
Parameters:
    +
  • input_dim (int) – the number of input dimensions
  • +
  • variances (array or list of the appropriate size (or float if there +is only one variance parameter)) – the vector of variances \sigma^2_i
  • +
  • ARD (Boolean) – Auto Relevance Determination. If False, the kernel has only one +variance parameter sigma^2, otherwise there is one variance +parameter per dimension.
  • +
+
Return type:

kernel object

+
+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+input_sensitivity()[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+class GPy.kern._src.trunclinear.TruncLinear_inf(input_dim, interval, variances=None, ARD=False, active_dims=None, name='linear')[source]
+

Bases: GPy.kern._src.kern.Kern

+

Truncated Linear kernel

+
+

System Message: WARNING/2 (k(x,y) = \sum_{i=1}^input_dim \sigma^2_i \max(0, x_iy_i - \simga_q))

+latex exited with error +[stdout] +This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014/Debian) (preloaded format=latex) + restricted \write18 enabled. +entering extended mode +(./math.tex +LaTeX2e <2014/05/01> +Babel <3.9k> and hyphenation patterns for 79 languages loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2007/10/19 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size12.clo)) +(/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty +(/usr/share/texlive/texmf-dist/tex/latex/ucs/utf8x.def)) +(/usr/share/texlive/texmf-dist/tex/latex/ucs/ucs.sty +(/usr/share/texlive/texmf-dist/tex/latex/ucs/data/uni-global.def)) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty +For additional information on amsmath, use the `?’ option. +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty)) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty) +(/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty)) +(/usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty) +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty)) +(/usr/share/texlive/texmf-dist/tex/latex/tools/bm.sty) (./math.aux) +(/usr/share/texlive/texmf-dist/tex/latex/ucs/ucsencs.def) +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd) +(/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd) +! Undefined control sequence. +<argument> ...sigma ^2_i \max (0, x_iy_i - \simga + _q)\end {split}\notag +l.14 \end{gather} + +! Undefined control sequence. +<argument> ...sigma ^2_i \max (0, x_iy_i - \simga + _q)\end {split}\notag +l.14 \end{gather} + +[1] (./math.aux) ) +(see the transcript file for additional information) +Output written on math.dvi (1 page, 616 bytes). +Transcript written on math.log. +
+ +++ + + + + + +
Parameters:
    +
  • input_dim (int) – the number of input dimensions
  • +
  • variances (array or list of the appropriate size (or float if there +is only one variance parameter)) – the vector of variances \sigma^2_i
  • +
  • ARD (Boolean) – Auto Relevance Determination. If False, the kernel has only one +variance parameter sigma^2, otherwise there is one variance +parameter per dimension.
  • +
+
Return type:

kernel object

+
+
+
+K(X, X2=None, *a, **kw)[source]
+
+ +
+
+Kdiag(X, *a, **kw)[source]
+
+ +
+
+gradients_X(dL_dK, X, X2=None)[source]
+
+ +
+
+gradients_X_diag(dL_dKdiag, X)[source]
+
+ +
+
+input_sensitivity()[source]
+
+ +
+
+update_gradients_diag(dL_dKdiag, X)[source]
+
+ +
+
+update_gradients_full(dL_dK, X, X2=None)[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.kern._src.psi_comp.html b/doc/_build/html/GPy.kern._src.psi_comp.html new file mode 100644 index 00000000..eb47cbec --- /dev/null +++ b/doc/_build/html/GPy.kern._src.psi_comp.html @@ -0,0 +1,305 @@ + + + + + + + + GPy.kern._src.psi_comp package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.kern._src.psi_comp package

+
+

Submodules

+
+
+

GPy.kern._src.psi_comp.linear_psi_comp module

+

The package for the Psi statistics computation of the linear kernel for Bayesian GPLVM

+
+
+GPy.kern._src.psi_comp.linear_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior)[source]
+
+ +
+
+GPy.kern._src.psi_comp.linear_psi_comp.psicomputations(variance, Z, variational_posterior)[source]
+

Compute psi-statistics for ss-linear kernel

+
+ +
+
+

GPy.kern._src.psi_comp.rbf_psi_comp module

+

The module for psi-statistics for RBF kernel

+
+
+GPy.kern._src.psi_comp.rbf_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior)[source]
+
+ +
+
+GPy.kern._src.psi_comp.rbf_psi_comp.psicomputations(variance, lengthscale, Z, variational_posterior)[source]
+

Z - MxQ +mu - NxQ +S - NxQ +gamma - NxQ

+
+ +
+
+

GPy.kern._src.psi_comp.rbf_psi_gpucomp module

+

The module for psi-statistics for RBF kernel

+
+
+class GPy.kern._src.psi_comp.rbf_psi_gpucomp.PSICOMP_RBF_GPU(threadnum=128, blocknum=15, GPU_direct=False)[source]
+

Bases: GPy.kern._src.psi_comp.PSICOMP_RBF

+
+
+get_dimensions(Z, variational_posterior)[source]
+
+ +
+
+psiDerivativecomputations = <functools.partial object>
+
+ +
+
+psicomputations = <functools.partial object>
+
+ +
+
+reset_derivative()[source]
+
+ +
+
+sync_params(lengthscale, Z, mu, S)[source]
+
+ +
+ +
+
+

GPy.kern._src.psi_comp.sslinear_psi_comp module

+

The package for the Psi statistics computation of the linear kernel for SSGPLVM

+
+
+GPy.kern._src.psi_comp.sslinear_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior)[source]
+
+ +
+
+GPy.kern._src.psi_comp.sslinear_psi_comp.psicomputations(variance, Z, variational_posterior)[source]
+

Compute psi-statistics for ss-linear kernel

+
+ +
+
+

GPy.kern._src.psi_comp.ssrbf_psi_comp module

+

The package for the psi statistics computation

+
+
+GPy.kern._src.psi_comp.ssrbf_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior)[source]
+
+ +
+
+

GPy.kern._src.psi_comp.ssrbf_psi_gpucomp module

+

The module for psi-statistics for RBF kernel for Spike-and-Slab GPLVM

+
+
+class GPy.kern._src.psi_comp.ssrbf_psi_gpucomp.PSICOMP_SSRBF_GPU(threadnum=128, blocknum=15, GPU_direct=False)[source]
+

Bases: GPy.kern._src.psi_comp.PSICOMP_RBF

+
+
+get_dimensions(Z, variational_posterior)[source]
+
+ +
+
+psiDerivativecomputations = <functools.partial object>
+
+ +
+
+psicomputations = <functools.partial object>
+
+ +
+
+reset_derivative()[source]
+
+ +
+
+sync_params(lengthscale, Z, mu, S, gamma)[source]
+
+ +
+ +
+
+

Module contents

+
+
+class GPy.kern._src.psi_comp.PSICOMP_Linear(*a, **kw)[source]
+

Bases: GPy.core.parameterization.parameter_core.Pickleable

+
+
+psiDerivativecomputations = <functools.partial object>
+
+ +
+
+psicomputations = <functools.partial object>
+
+ +
+ +
+
+class GPy.kern._src.psi_comp.PSICOMP_RBF(*a, **kw)[source]
+

Bases: GPy.core.parameterization.parameter_core.Pickleable

+
+
+psiDerivativecomputations = <functools.partial object>
+
+ +
+
+psicomputations = <functools.partial object>
+
+ +
+ +
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.kern.html b/doc/_build/html/GPy.kern.html new file mode 100644 index 00000000..195b8708 --- /dev/null +++ b/doc/_build/html/GPy.kern.html @@ -0,0 +1,181 @@ + + + + + + + + GPy.kern package — GPy documentation + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.likelihoods.html b/doc/_build/html/GPy.likelihoods.html new file mode 100644 index 00000000..8b92b4ed --- /dev/null +++ b/doc/_build/html/GPy.likelihoods.html @@ -0,0 +1,2134 @@ + + + + + + + + GPy.likelihoods package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.likelihoods package

+
+

Submodules

+
+
+

GPy.likelihoods.bernoulli module

+
+
+class GPy.likelihoods.bernoulli.Bernoulli(gp_link=None)[source]
+

Bases: GPy.likelihoods.likelihood.Likelihood

+

Bernoulli likelihood

+
+

p(y_{i}|\lambda(f_{i})) = \lambda(f_{i})^{y_{i}}(1-f_{i})^{1-y_{i}}

+
+

Note

+

Y takes values in either {-1, 1} or {0, 1}. +link function should have the domain [0, 1], e.g. probit (default) or Heaviside

+
+
+
+d2logpdf_dlink2(inv_link_f, y, Y_metadata=None)[source]
+

Hessian at y, given inv_link_f, w.r.t inv_link_f the hessian will be 0 unless i == j +i.e. second derivative logpdf at y given inverse link of f_i and inverse link of f_j w.r.t inverse link of f_i and inverse link of f_j.

+
+

\frac{d^{2}\ln p(y_{i}|\lambda(f_{i}))}{d\lambda(f)^{2}} = \frac{-y_{i}}{\lambda(f)^{2}} - \frac{(1-y_{i})}{(1-\lambda(f))^{2}}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables inverse link of f.
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in bernoulli
  • +
+
Returns:

Diagonal of log hessian matrix (second derivative of log likelihood evaluated at points inverse link of f.

+
Return type:

Nx1 array

+
+
+

Note

+

Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases +(the distribution for y_i depends only on inverse link of f_i not on inverse link of f_(j!=i)

+
+
+ +
+
+d3logpdf_dlink3(inv_link_f, y, Y_metadata=None)[source]
+

Third order derivative log-likelihood function at y given inverse link of f w.r.t inverse link of f

+
+

\frac{d^{3} \ln p(y_{i}|\lambda(f_{i}))}{d^{3}\lambda(f)} = \frac{2y_{i}}{\lambda(f)^{3}} - \frac{2(1-y_{i}}{(1-\lambda(f))^{3}}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables passed through inverse link of f.
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in bernoulli
  • +
+
Returns:

third derivative of log likelihood evaluated at points inverse_link(f)

+
Return type:

Nx1 array

+
+
+ +
+ +

Gradient of the pdf at y, given inverse link of f w.r.t inverse link of f.

+
+

\frac{d\ln p(y_{i}|\lambda(f_{i}))}{d\lambda(f)} = \frac{y_{i}}{\lambda(f_{i})} - \frac{(1 - y_{i})}{(1 - \lambda(f_{i}))}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables inverse link of f.
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in bernoulli
  • +
+
Returns:

gradient of log likelihood evaluated at points inverse link of f.

+
Return type:

Nx1 array

+
+
+ +
+
+exact_inference_gradients(dL_dKdiag, Y_metadata=None)[source]
+
+ +
+ +

Log Likelihood function given inverse link of f.

+
+

\ln p(y_{i}|\lambda(f_{i})) = y_{i}\log\lambda(f_{i}) + (1-y_{i})\log (1-f_{i})

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables inverse link of f.
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in bernoulli
  • +
+
Returns:

log likelihood evaluated at points inverse link of f.

+
Return type:

float

+
+
+ +
+
+moments_match_ep(Y_i, tau_i, v_i)[source]
+

Moments match of the marginal approximation in EP algorithm

+ +++ + + + +
Parameters:
    +
  • i – number of observation (int)
  • +
  • tau_i – precision of the cavity distribution (float)
  • +
  • v_i – mean/variance of the cavity distribution (float)
  • +
+
+
+ +
+ +

Likelihood function given inverse link of f.

+
+

p(y_{i}|\lambda(f_{i})) = \lambda(f_{i})^{y_{i}}(1-f_{i})^{1-y_{i}}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables inverse link of f.
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in bernoulli
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+
+predictive_mean(mu, variance, Y_metadata=None)[source]
+
+ +
+
+predictive_variance(mu, variance, pred_mean, Y_metadata=None)[source]
+
+ +
+
+samples(gp, Y_metadata=None)[source]
+

Returns a set of samples of observations based on a given value of the latent variable.

+ +++ + + + +
Parameters:gp – latent variable
+
+ +
+ +
+
+

GPy.likelihoods.exponential module

+
+
+class GPy.likelihoods.exponential.Exponential(gp_link=None)[source]
+

Bases: GPy.likelihoods.likelihood.Likelihood

+

Expoential likelihood +Y is expected to take values in {0,1,2,...} +—– +$$ +L(x) = exp(lambda) * lambda**Y_i / Y_i! +$$

+
+
+d2logpdf_dlink2(link_f, y, Y_metadata=None)[source]
+

Hessian at y, given link(f), w.r.t link(f) +i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j) +The hessian will be 0 unless i == j

+
+

\frac{d^{2} \ln p(y_{i}|\lambda(f_{i}))}{d^{2}\lambda(f)} = -\frac{1}{\lambda(f_{i})^{2}}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in exponential distribution
  • +
+
Returns:

Diagonal of hessian matrix (second derivative of likelihood evaluated at points f)

+
Return type:

Nx1 array

+
+
+

Note

+

Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases +(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))

+
+
+ +
+
+d3logpdf_dlink3(link_f, y, Y_metadata=None)[source]
+

Third order derivative log-likelihood function at y given link(f) w.r.t link(f)

+
+

\frac{d^{3} \ln p(y_{i}|\lambda(f_{i}))}{d^{3}\lambda(f)} = \frac{2}{\lambda(f_{i})^{3}}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in exponential distribution
  • +
+
Returns:

third derivative of likelihood evaluated at points f

+
Return type:

Nx1 array

+
+
+ +
+ +

Gradient of the log likelihood function at y, given link(f) w.r.t link(f)

+
+

\frac{d \ln p(y_{i}|\lambda(f_{i}))}{d\lambda(f)} = \frac{1}{\lambda(f)} - y_{i}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables (f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in exponential distribution
  • +
+
Returns:

gradient of likelihood evaluated at points

+
Return type:

Nx1 array

+
+
+ +
+ +

Log Likelihood Function given link(f)

+
+

\ln p(y_{i}|\lambda(f_{i})) = \ln \lambda(f_{i}) - y_{i}\lambda(f_{i})

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables (link(f))
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in exponential distribution
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+ +

Likelihood function given link(f)

+
+

p(y_{i}|\lambda(f_{i})) = \lambda(f_{i})\exp (-y\lambda(f_{i}))

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in exponential distribution
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+
+samples(gp)[source]
+

Returns a set of samples of observations based on a given value of the latent variable.

+ +++ + + + +
Parameters:gp – latent variable
+
+ +
+ +
+
+

GPy.likelihoods.gamma module

+
+
+class GPy.likelihoods.gamma.Gamma(gp_link=None, beta=1.0)[source]
+

Bases: GPy.likelihoods.likelihood.Likelihood

+

Gamma likelihood

+
+

p(y_{i}|\lambda(f_{i})) = \frac{\beta^{\alpha_{i}}}{\Gamma(\alpha_{i})}y_{i}^{\alpha_{i}-1}e^{-\beta y_{i}}\\
+\alpha_{i} = \beta y_{i}

+
+
+d2logpdf_dlink2(link_f, y, Y_metadata=None)[source]
+

Hessian at y, given link(f), w.r.t link(f) +i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j) +The hessian will be 0 unless i == j

+
+

\frac{d^{2} \ln p(y_{i}|\lambda(f_{i}))}{d^{2}\lambda(f)} = -\beta^{2}\frac{d\Psi(\alpha_{i})}{d\alpha_{i}}\\
+\alpha_{i} = \beta y_{i}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in gamma distribution
  • +
+
Returns:

Diagonal of hessian matrix (second derivative of likelihood evaluated at points f)

+
Return type:

Nx1 array

+
+
+

Note

+

Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases +(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))

+
+
+ +
+
+d3logpdf_dlink3(link_f, y, Y_metadata=None)[source]
+

Third order derivative log-likelihood function at y given link(f) w.r.t link(f)

+
+

\frac{d^{3} \ln p(y_{i}|\lambda(f_{i}))}{d^{3}\lambda(f)} = -\beta^{3}\frac{d^{2}\Psi(\alpha_{i})}{d\alpha_{i}}\\
+\alpha_{i} = \beta y_{i}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in gamma distribution
  • +
+
Returns:

third derivative of likelihood evaluated at points f

+
Return type:

Nx1 array

+
+
+ +
+ +

Gradient of the log likelihood function at y, given link(f) w.r.t link(f)

+
+

\frac{d \ln p(y_{i}|\lambda(f_{i}))}{d\lambda(f)} = \beta (\log \beta y_{i}) - \Psi(\alpha_{i})\beta\\
+\alpha_{i} = \beta y_{i}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables (f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in gamma distribution
  • +
+
Returns:

gradient of likelihood evaluated at points

+
Return type:

Nx1 array

+
+
+ +
+ +

Log Likelihood Function given link(f)

+
+

\ln p(y_{i}|\lambda(f_{i})) = \alpha_{i}\log \beta - \log \Gamma(\alpha_{i}) + (\alpha_{i} - 1)\log y_{i} - \beta y_{i}\\
+\alpha_{i} = \beta y_{i}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables (link(f))
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in poisson distribution
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+ +

Likelihood function given link(f)

+
+

p(y_{i}|\lambda(f_{i})) = \frac{\beta^{\alpha_{i}}}{\Gamma(\alpha_{i})}y_{i}^{\alpha_{i}-1}e^{-\beta y_{i}}\\
+\alpha_{i} = \beta y_{i}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in poisson distribution
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+ +
+
+

GPy.likelihoods.gaussian module

+

A lot of this code assumes that the link function is the identity.

+

I think laplace code is okay, but I’m quite sure that the EP moments will only work if the link is identity.

+

Furthermore, exact Guassian inference can only be done for the identity link, so we should be asserting so for all calls which relate to that.

+

James 11/12/13

+
+
+class GPy.likelihoods.gaussian.Gaussian(gp_link=None, variance=1.0, name='Gaussian_noise')[source]
+

Bases: GPy.likelihoods.likelihood.Likelihood

+

Gaussian likelihood

+
+

\ln p(y_{i}|\lambda(f_{i})) = -\frac{N \ln 2\pi}{2} - \frac{\ln |K|}{2} - \frac{(y_{i} - \lambda(f_{i}))^{T}\sigma^{-2}(y_{i} - \lambda(f_{i}))}{2}

+
+++ + + + +
Parameters:
    +
  • variance – variance value of the Gaussian distribution
  • +
  • N (int) – Number of data points
  • +
+
+
+
+betaY(Y, Y_metadata=None)[source]
+
+ +
+
+d2logpdf_dlink2(link_f, y, Y_metadata=None)[source]
+

Hessian at y, given link_f, w.r.t link_f. +i.e. second derivative logpdf at y given link(f_i) link(f_j) w.r.t link(f_i) and link(f_j)

+

The hessian will be 0 unless i == j

+
+

\frac{d^{2} \ln p(y_{i}|\lambda(f_{i}))}{d^{2}f} = -\frac{1}{\sigma^{2}}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in gaussian
  • +
+
Returns:

Diagonal of log hessian matrix (second derivative of log likelihood evaluated at points link(f))

+
Return type:

Nx1 array

+
+
+

Note

+

Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases +(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))

+
+
+ +
+
+d2logpdf_dlink2_dtheta(f, y, Y_metadata=None)[source]
+
+ +
+
+d2logpdf_dlink2_dvar(link_f, y, Y_metadata=None)[source]
+

Gradient of the hessian (d2logpdf_dlink2) w.r.t variance parameter (noise_variance)

+
+

\frac{d}{d\sigma^{2}}(\frac{d^{2} \ln p(y_{i}|\lambda(f_{i}))}{d^{2}\lambda(f)}) = \frac{1}{\sigma^{4}}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in gaussian
  • +
+
Returns:

derivative of log hessian evaluated at points link(f_i) and link(f_j) w.r.t variance parameter

+
Return type:

Nx1 array

+
+
+ +
+
+d3logpdf_dlink3(link_f, y, Y_metadata=None)[source]
+

Third order derivative log-likelihood function at y given link(f) w.r.t link(f)

+
+

\frac{d^{3} \ln p(y_{i}|\lambda(f_{i}))}{d^{3}\lambda(f)} = 0

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in gaussian
  • +
+
Returns:

third derivative of log likelihood evaluated at points link(f)

+
Return type:

Nx1 array

+
+
+ +
+ +

Gradient of the pdf at y, given link(f) w.r.t link(f)

+
+

\frac{d \ln p(y_{i}|\lambda(f_{i}))}{d\lambda(f)} = \frac{1}{\sigma^{2}}(y_{i} - \lambda(f_{i}))

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in gaussian
  • +
+
Returns:

gradient of log likelihood evaluated at points link(f)

+
Return type:

Nx1 array

+
+
+ +
+ +
+ +
+ +

Derivative of the dlogpdf_dlink w.r.t variance parameter (noise_variance)

+
+

\frac{d}{d\sigma^{2}}(\frac{d \ln p(y_{i}|\lambda(f_{i}))}{d\lambda(f)}) = \frac{1}{\sigma^{4}}(-y_{i} + \lambda(f_{i}))

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in gaussian
  • +
+
Returns:

derivative of log likelihood evaluated at points link(f) w.r.t variance parameter

+
Return type:

Nx1 array

+
+
+ +
+ +
+ +
+ +

Gradient of the log-likelihood function at y given link(f), w.r.t variance parameter (noise_variance)

+
+

\frac{d \ln p(y_{i}|\lambda(f_{i}))}{d\sigma^{2}} = -\frac{N}{2\sigma^{2}} + \frac{(y_{i} - \lambda(f_{i}))^{2}}{2\sigma^{4}}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in gaussian
  • +
+
Returns:

derivative of log likelihood evaluated at points link(f) w.r.t variance parameter

+
Return type:

float

+
+
+ +
+
+exact_inference_gradients(dL_dKdiag, Y_metadata=None)[source]
+
+ +
+
+gaussian_variance(Y_metadata=None)[source]
+
+ +
+
+log_predictive_density(y_test, mu_star, var_star)[source]
+

assumes independence

+
+ +
+ +

Log likelihood function given link(f)

+
+

\ln p(y_{i}|\lambda(f_{i})) = -\frac{N \ln 2\pi}{2} - \frac{\ln |K|}{2} - \frac{(y_{i} - \lambda(f_{i}))^{T}\sigma^{-2}(y_{i} - \lambda(f_{i}))}{2}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in gaussian
  • +
+
Returns:

log likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+ +

Likelihood function given link(f)

+
+

\ln p(y_{i}|\lambda(f_{i})) = -\frac{N \ln 2\pi}{2} - \frac{\ln |K|}{2} - \frac{(y_{i} - \lambda(f_{i}))^{T}\sigma^{-2}(y_{i} - \lambda(f_{i}))}{2}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata not used in gaussian
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+
+predictive_mean(mu, sigma)[source]
+
+ +
+
+predictive_quantiles(mu, var, quantiles, Y_metadata=None)[source]
+
+ +
+
+predictive_values(mu, var, full_cov=False, Y_metadata=None)[source]
+
+ +
+
+predictive_variance(mu, sigma, predictive_mean=None)[source]
+
+ +
+
+samples(gp, Y_metadata=None)[source]
+

Returns a set of samples of observations based on a given value of the latent variable.

+ +++ + + + +
Parameters:gp – latent variable
+
+ +
+
+update_gradients(grad)[source]
+
+ +
+ +
+
+

GPy.likelihoods.likelihood module

+
+
+class GPy.likelihoods.likelihood.Likelihood(gp_link, name)[source]
+

Bases: GPy.core.parameterization.parameterized.Parameterized

+

Likelihood base class, used to defing p(y|f).

+

All instances use _inverse_ link functions, which can be swapped out. It is +expected that inheriting classes define a default inverse link function

+

To use this class, inherit and define missing functionality.

+
+
Inheriting classes must implement:
+
pdf_link : a bound method which turns the output of the link function into the pdf +logpdf_link : the logarithm of the above
+
To enable use with EP, inheriting classes must define:
+
TODO: a suitable derivative function for any parameters of the class
+
It is also desirable to define:
+
moments_match_ep : a function to compute the EP moments If this isn’t defined, the moments will be computed using 1D quadrature.
+
To enable use with Laplace approximation, inheriting classes must define:
+
Some derivative functions AS TODO
+
+

For exact Gaussian inference, define JH TODO

+
+
+conditional_mean(gp)[source]
+

The mean of the random variable conditioned on one value of the GP

+
+ +
+
+conditional_variance(gp)[source]
+

The variance of the random variable conditioned on one value of the GP

+
+ +
+
+d2logpdf_df2(f, y, Y_metadata=None)[source]
+

Evaluates the link function link(f) then computes the second derivative of log likelihood using it +Uses the Faa di Bruno’s formula for the chain rule

+
+

\frac{d^{2}\log p(y|\lambda(f))}{df^{2}} = \frac{d^{2}\log p(y|\lambda(f))}{d^{2}\lambda(f)}\left(\frac{d\lambda(f)}{df}\right)^{2} + \frac{d\log p(y|\lambda(f))}{d\lambda(f)}\frac{d^{2}\lambda(f)}{df^{2}}

+
+++ + + + + + + + +
Parameters:
    +
  • f (Nx1 array) – latent variables f
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution - not used
  • +
+
Returns:

second derivative of log likelihood evaluated for this point (diagonal only)

+
Return type:

1xN array

+
+
+ +
+
+d2logpdf_df2_dtheta(f, y, Y_metadata=None)[source]
+

TODO: Doc strings

+
+ +
+
+d2logpdf_dlink2(inv_link_f, y, Y_metadata=None)[source]
+
+ +
+
+d2logpdf_dlink2_dtheta(inv_link_f, y, Y_metadata=None)[source]
+
+ +
+
+d3logpdf_df3(f, y, Y_metadata=None)[source]
+

Evaluates the link function link(f) then computes the third derivative of log likelihood using it +Uses the Faa di Bruno’s formula for the chain rule

+
+

\frac{d^{3}\log p(y|\lambda(f))}{df^{3}} = \frac{d^{3}\log p(y|\lambda(f)}{d\lambda(f)^{3}}\left(\frac{d\lambda(f)}{df}\right)^{3} + 3\frac{d^{2}\log p(y|\lambda(f)}{d\lambda(f)^{2}}\frac{d\lambda(f)}{df}\frac{d^{2}\lambda(f)}{df^{2}} + \frac{d\log p(y|\lambda(f)}{d\lambda(f)}\frac{d^{3}\lambda(f)}{df^{3}}

+
+++ + + + + + + + +
Parameters:
    +
  • f (Nx1 array) – latent variables f
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution - not used
  • +
+
Returns:

third derivative of log likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+
+d3logpdf_dlink3(inv_link_f, y, Y_metadata=None)[source]
+
+ +
+
+dlogpdf_df(f, y, Y_metadata=None)[source]
+

Evaluates the link function link(f) then computes the derivative of log likelihood using it +Uses the Faa di Bruno’s formula for the chain rule

+
+

\frac{d\log p(y|\lambda(f))}{df} = \frac{d\log p(y|\lambda(f))}{d\lambda(f)}\frac{d\lambda(f)}{df}

+
+++ + + + + + + + +
Parameters:
    +
  • f (Nx1 array) – latent variables f
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution - not used
  • +
+
Returns:

derivative of log likelihood evaluated for this point

+
Return type:

1xN array

+
+
+ +
+
+dlogpdf_df_dtheta(f, y, Y_metadata=None)[source]
+

TODO: Doc strings

+
+ +
+ +
+ +
+ +
+ +
+
+dlogpdf_dtheta(f, y, Y_metadata=None)[source]
+

TODO: Doc strings

+
+ +
+ +
+ +
+
+log_predictive_density(y_test, mu_star, var_star)[source]
+

Calculation of the log predictive density

+ +++ + + + +
Parameters:
    +
  • y_test ((Nx1) array) – test observations (y_{*})
  • +
  • mu_star ((Nx1) array) – predictive mean of gaussian p(f_{*}|mu_{*}, var_{*})
  • +
  • var_star ((Nx1) array) – predictive variance of gaussian p(f_{*}|mu_{*}, var_{*})
  • +
+
+
+ +
+
+logpdf(f, y, Y_metadata=None)[source]
+

Evaluates the link function link(f) then computes the log likelihood (log pdf) using it

+ +++ + + + + + + + +
Parameters:
    +
  • f (Nx1 array) – latent variables f
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution - not used
  • +
+
Returns:

log likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+ +
+ +
+
+pdf(f, y, Y_metadata=None)[source]
+

Evaluates the link function link(f) then computes the likelihood (pdf) using it

+ +++ + + + + + + + +
Parameters:
    +
  • f (Nx1 array) – latent variables f
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution - not used
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+ +
+ +
+
+predictive_mean(mu, variance, Y_metadata=None)[source]
+

Quadrature calculation of the predictive mean: E(Y_star|Y) = E( E(Y_star|f_star, Y) )

+ +++ + + + +
Parameters:
    +
  • mu – mean of posterior
  • +
  • sigma – standard deviation of posterior
  • +
+
+
+ +
+
+predictive_quantiles(mu, var, quantiles, Y_metadata=None)[source]
+
+ +
+
+predictive_values(mu, var, full_cov=False, Y_metadata=None)[source]
+

Compute mean, variance of the predictive distibution.

+ +++ + + + +
Parameters:
    +
  • mu – mean of the latent variable, f, of posterior
  • +
  • var – variance of the latent variable, f, of posterior
  • +
  • full_cov (Boolean) – whether to use the full covariance or just the diagonal
  • +
+
+
+ +
+
+predictive_variance(mu, variance, predictive_mean=None, Y_metadata=None)[source]
+

Approximation to the predictive variance: V(Y_star)

+

The following variance decomposition is used: +V(Y_star) = E( V(Y_star|f_star) ) + V( E(Y_star|f_star) )

+ +++ + + + + + + +
Parameters:
    +
  • mu – mean of posterior
  • +
  • sigma – standard deviation of posterior
  • +
+
Predictive_mean:
 

output’s predictive mean, if None _predictive_mean function will be called.

+
+
+ +
+
+samples(gp, Y_metadata=None)[source]
+

Returns a set of samples of observations based on a given value of the latent variable.

+ +++ + + + +
Parameters:gp – latent variable
+
+ +
+
+update_gradients(partial)[source]
+
+ +
+
+variational_expectations(Y, m, v, gh_points=None)[source]
+

Use Gauss-Hermite Quadrature to compute

+
+
E_p(f) [ log p(y|f) ] +d/dm E_p(f) [ log p(y|f) ] +d/dv E_p(f) [ log p(y|f) ]
+

where p(f) is a Gaussian with mean m and variance v. The shapes of Y, m and v should match.

+

if no gh_points are passed, we construct them using defualt options

+
+ +
+ +
+ +
+

GPy.likelihoods.mixed_noise module

+
+
+class GPy.likelihoods.mixed_noise.MixedNoise(likelihoods_list, name='mixed_noise')[source]
+

Bases: GPy.likelihoods.likelihood.Likelihood

+
+
+betaY(Y, Y_metadata)[source]
+
+ +
+
+exact_inference_gradients(dL_dKdiag, Y_metadata)[source]
+
+ +
+
+gaussian_variance(Y_metadata)[source]
+
+ +
+
+predictive_quantiles(mu, var, quantiles, Y_metadata)[source]
+
+ +
+
+predictive_values(mu, var, full_cov=False, Y_metadata=None)[source]
+
+ +
+
+predictive_variance(mu, sigma, Y_metadata)[source]
+
+ +
+
+samples(gp, Y_metadata)[source]
+

Returns a set of samples of observations based on a given value of the latent variable.

+ +++ + + + +
Parameters:gp – latent variable
+
+ +
+
+update_gradients(gradients)[source]
+
+ +
+ +
+
+

GPy.likelihoods.poisson module

+
+
+class GPy.likelihoods.poisson.Poisson(gp_link=None)[source]
+

Bases: GPy.likelihoods.likelihood.Likelihood

+

Poisson likelihood

+
+

p(y_{i}|\lambda(f_{i})) = \frac{\lambda(f_{i})^{y_{i}}}{y_{i}!}e^{-\lambda(f_{i})}

+
+

Note

+

Y is expected to take values in {0,1,2,...}

+
+
+
+conditional_mean(gp)[source]
+

The mean of the random variable conditioned on one value of the GP

+
+ +
+
+conditional_variance(gp)[source]
+

The variance of the random variable conditioned on one value of the GP

+
+ +
+
+d2logpdf_dlink2(link_f, y, Y_metadata=None)[source]
+

Hessian at y, given link(f), w.r.t link(f) +i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j) +The hessian will be 0 unless i == j

+
+

\frac{d^{2} \ln p(y_{i}|\lambda(f_{i}))}{d^{2}\lambda(f)} = \frac{-y_{i}}{\lambda(f_{i})^{2}}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in poisson distribution
  • +
+
Returns:

Diagonal of hessian matrix (second derivative of likelihood evaluated at points f)

+
Return type:

Nx1 array

+
+
+

Note

+

Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases +(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))

+
+
+ +
+
+d3logpdf_dlink3(link_f, y, Y_metadata=None)[source]
+

Third order derivative log-likelihood function at y given link(f) w.r.t link(f)

+
+

\frac{d^{3} \ln p(y_{i}|\lambda(f_{i}))}{d^{3}\lambda(f)} = \frac{2y_{i}}{\lambda(f_{i})^{3}}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in poisson distribution
  • +
+
Returns:

third derivative of likelihood evaluated at points f

+
Return type:

Nx1 array

+
+
+ +
+ +

Gradient of the log likelihood function at y, given link(f) w.r.t link(f)

+
+

\frac{d \ln p(y_{i}|\lambda(f_{i}))}{d\lambda(f)} = \frac{y_{i}}{\lambda(f_{i})} - 1

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables (f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in poisson distribution
  • +
+
Returns:

gradient of likelihood evaluated at points

+
Return type:

Nx1 array

+
+
+ +
+ +

Log Likelihood Function given link(f)

+
+

\ln p(y_{i}|\lambda(f_{i})) = -\lambda(f_{i}) + y_{i}\log \lambda(f_{i}) - \log y_{i}!

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables (link(f))
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in poisson distribution
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+ +

Likelihood function given link(f)

+
+

p(y_{i}|\lambda(f_{i})) = \frac{\lambda(f_{i})^{y_{i}}}{y_{i}!}e^{-\lambda(f_{i})}

+
+++ + + + + + + + +
Parameters:
    +
  • link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in poisson distribution
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+
+samples(gp, Y_metadata=None)[source]
+

Returns a set of samples of observations based on a given value of the latent variable.

+ +++ + + + +
Parameters:gp – latent variable
+
+ +
+ +
+
+

GPy.likelihoods.student_t module

+
+
+class GPy.likelihoods.student_t.StudentT(gp_link=None, deg_free=5, sigma2=2)[source]
+

Bases: GPy.likelihoods.likelihood.Likelihood

+

Student T likelihood

+

For nomanclature see Bayesian Data Analysis 2003 p576

+
+

p(y_{i}|\lambda(f_{i})) = \frac{\Gamma\left(\frac{v+1}{2}\right)}{\Gamma\left(\frac{v}{2}\right)\sqrt{v\pi\sigma^{2}}}\left(1 + \frac{1}{v}\left(\frac{(y_{i} - f_{i})^{2}}{\sigma^{2}}\right)\right)^{\frac{-v+1}{2}}

+
+
+conditional_mean(gp)[source]
+
+ +
+
+conditional_variance(gp)[source]
+
+ +
+
+d2logpdf_dlink2(inv_link_f, y, Y_metadata=None)[source]
+

Hessian at y, given link(f), w.r.t link(f) +i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j) +The hessian will be 0 unless i == j

+
+

\frac{d^{2} \ln p(y_{i}|\lambda(f_{i}))}{d^{2}\lambda(f)} = \frac{(v+1)((y_{i}-\lambda(f_{i}))^{2} - \sigma^{2}v)}{((y_{i}-\lambda(f_{i}))^{2} + \sigma^{2}v)^{2}}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables inv_link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution
  • +
+
Returns:

Diagonal of hessian matrix (second derivative of likelihood evaluated at points f)

+
Return type:

Nx1 array

+
+
+

Note

+

Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases +(the distribution for y_i depends only on link(f_i) not on link(f_(j!=i))

+
+
+ +
+
+d2logpdf_dlink2_dtheta(f, y, Y_metadata=None)[source]
+
+ +
+
+d2logpdf_dlink2_dvar(inv_link_f, y, Y_metadata=None)[source]
+

Gradient of the hessian (d2logpdf_dlink2) w.r.t variance parameter (t_noise)

+
+

\frac{d}{d\sigma^{2}}(\frac{d^{2} \ln p(y_{i}|\lambda(f_{i}))}{d^{2}f}) = \frac{v(v+1)(\sigma^{2}v - 3(y_{i} - \lambda(f_{i}))^{2})}{(\sigma^{2}v + (y_{i} - \lambda(f_{i}))^{2})^{3}}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution
  • +
+
Returns:

derivative of hessian evaluated at points f and f_j w.r.t variance parameter

+
Return type:

Nx1 array

+
+
+ +
+
+d3logpdf_dlink3(inv_link_f, y, Y_metadata=None)[source]
+

Third order derivative log-likelihood function at y given link(f) w.r.t link(f)

+
+

\frac{d^{3} \ln p(y_{i}|\lambda(f_{i}))}{d^{3}\lambda(f)} = \frac{-2(v+1)((y_{i} - \lambda(f_{i}))^3 - 3(y_{i} - \lambda(f_{i})) \sigma^{2} v))}{((y_{i} - \lambda(f_{i})) + \sigma^{2} v)^3}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution
  • +
+
Returns:

third derivative of likelihood evaluated at points f

+
Return type:

Nx1 array

+
+
+ +
+ +

Gradient of the log likelihood function at y, given link(f) w.r.t link(f)

+
+

\frac{d \ln p(y_{i}|\lambda(f_{i}))}{d\lambda(f)} = \frac{(v+1)(y_{i}-\lambda(f_{i}))}{(y_{i}-\lambda(f_{i}))^{2} + \sigma^{2}v}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables (f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution
  • +
+
Returns:

gradient of likelihood evaluated at points

+
Return type:

Nx1 array

+
+
+ +
+ +
+ +
+ +

Derivative of the dlogpdf_dlink w.r.t variance parameter (t_noise)

+
+

\frac{d}{d\sigma^{2}}(\frac{d \ln p(y_{i}|\lambda(f_{i}))}{df}) = \frac{-2\sigma v(v + 1)(y_{i}-\lambda(f_{i}))}{(y_{i}-\lambda(f_{i}))^2 + \sigma^2 v)^2}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables inv_link_f
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution
  • +
+
Returns:

derivative of likelihood evaluated at points f w.r.t variance parameter

+
Return type:

Nx1 array

+
+
+ +
+ +
+ +
+ +

Gradient of the log-likelihood function at y given f, w.r.t variance parameter (t_noise)

+
+

\frac{d \ln p(y_{i}|\lambda(f_{i}))}{d\sigma^{2}} = \frac{v((y_{i} - \lambda(f_{i}))^{2} - \sigma^{2})}{2\sigma^{2}(\sigma^{2}v + (y_{i} - \lambda(f_{i}))^{2})}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution
  • +
+
Returns:

derivative of likelihood evaluated at points f w.r.t variance parameter

+
Return type:

float

+
+
+ +
+ +

Log Likelihood Function given link(f)

+
+

\ln p(y_{i}|\lambda(f_{i})) = \ln \Gamma\left(\frac{v+1}{2}\right) - \ln \Gamma\left(\frac{v}{2}\right) - \ln \sqrt{v \pi\sigma^{2}} - \frac{v+1}{2}\ln \left(1 + \frac{1}{v}\left(\frac{(y_{i} - \lambda(f_{i}))^{2}}{\sigma^{2}}\right)\right)

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables (link(f))
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+
+parameters_changed()[source]
+
+ +
+ +

Likelihood function given link(f)

+
+

p(y_{i}|\lambda(f_{i})) = \frac{\Gamma\left(\frac{v+1}{2}\right)}{\Gamma\left(\frac{v}{2}\right)\sqrt{v\pi\sigma^{2}}}\left(1 + \frac{1}{v}\left(\frac{(y_{i} - \lambda(f_{i}))^{2}}{\sigma^{2}}\right)\right)^{\frac{-v+1}{2}}

+
+++ + + + + + + + +
Parameters:
    +
  • inv_link_f (Nx1 array) – latent variables link(f)
  • +
  • y (Nx1 array) – data
  • +
  • Y_metadata – Y_metadata which is not used in student t distribution
  • +
+
Returns:

likelihood evaluated for this point

+
Return type:

float

+
+
+ +
+
+predictive_mean(mu, sigma, Y_metadata=None)[source]
+
+ +
+
+predictive_variance(mu, variance, predictive_mean=None, Y_metadata=None)[source]
+
+ +
+
+samples(gp, Y_metadata=None)[source]
+

Returns a set of samples of observations based on a given value of the latent variable.

+ +++ + + + +
Parameters:gp – latent variable
+
+ +
+
+update_gradients(grads)[source]
+

Pull out the gradients, be careful as the order must match the order +in which the parameters are added

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.mappings.html b/doc/_build/html/GPy.mappings.html new file mode 100644 index 00000000..a0775a92 --- /dev/null +++ b/doc/_build/html/GPy.mappings.html @@ -0,0 +1,323 @@ + + + + + + + + GPy.mappings package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.mappings package

+
+

Submodules

+
+
+

GPy.mappings.additive module

+
+
+class GPy.mappings.additive.Additive(mapping1, mapping2, tensor=False)[source]
+

Bases: GPy.core.mapping.Mapping

+

Mapping based on adding two existing mappings together.

+
+

f(\mathbf{x}*) = f_1(\mathbf{x}*) + f_2(\mathbf(x)*)

+
+++ + + + +
Parameters:
    +
  • mapping1 (GPy.mappings.Mapping) – first mapping to add together.
  • +
  • mapping2 (GPy.mappings.Mapping) – second mapping to add together.
  • +
  • tensor (bool) – whether or not to use the tensor product of input spaces
  • +
+
+
+
+df_dX(dL_df, X)[source]
+
+ +
+
+df_dtheta(dL_df, X)[source]
+
+ +
+
+f(X)[source]
+
+ +
+
+randomize()[source]
+
+ +
+ +
+
+

GPy.mappings.kernel module

+
+
+class GPy.mappings.kernel.Kernel(X, output_dim=1, kernel=None)[source]
+

Bases: GPy.core.mapping.Mapping

+

Mapping based on a kernel/covariance function.

+
+

f(\mathbf{x}*) = \mathbf{A}\mathbf{k}(\mathbf{X}, \mathbf{x}^*) + \mathbf{b}

+
+++ + + + +
Parameters:
    +
  • X (ndarray) – input observations containing \mathbf{X}
  • +
  • output_dim (int) – dimension of output.
  • +
  • kernel (GPy.kern.kern) – a GPy kernel, defaults to GPy.kern.RBF
  • +
+
+
+
+df_dX(dL_df, X)[source]
+
+ +
+
+df_dtheta(dL_df, X)[source]
+
+ +
+
+f(X)[source]
+
+ +
+
+randomize()[source]
+
+ +
+ +
+
+

GPy.mappings.linear module

+
+
+class GPy.mappings.linear.Linear(input_dim=1, output_dim=1, name='linear')[source]
+

Bases: GPy.core.mapping.Bijective_mapping

+

Mapping based on a linear model.

+
+

f(\mathbf{x}*) = \mathbf{W}\mathbf{x}^* + \mathbf{b}

+
+++ + + + +
Parameters:
    +
  • X (ndarray) – input observations
  • +
  • output_dim (int) – dimension of output.
  • +
+
+
+
+dL_dX(partial, X)[source]
+

The gradient of L with respect to the inputs to the mapping, where L is a function that is dependent on the output of the mapping, f.

+
+ +
+
+df_dtheta(dL_df, X)[source]
+
+ +
+
+f(X)[source]
+
+ +
+
+g(f)[source]
+
+ +
+ +
+
+

GPy.mappings.mlp module

+
+
+class GPy.mappings.mlp.MLP(input_dim=1, output_dim=1, hidden_dim=3)[source]
+

Bases: GPy.core.mapping.Mapping

+

Mapping based on a multi-layer perceptron neural network model.

+
+

f(\mathbf{x}*) = \mathbf{W}^0\boldsymbol{\phi}(\mathbf{W}^1\mathbf{x}+\mathbf{b}^1)^* + \mathbf{b}^0

+

where

+
+

\phi(\cdot) = \text{tanh}(\cdot)

+
+++ + + + +
Parameters:
    +
  • X (ndarray) – input observations
  • +
  • output_dim (int) – dimension of output.
  • +
  • hidden_dim (int or list of ints.) – dimension of hidden layer. If it is an int, there is one hidden layer of the given dimension. If it is a list of ints there are as manny hidden layers as the length of the list, each with the given number of hidden nodes in it.
  • +
+
+
+
+df_dX(dL_df, X)[source]
+
+ +
+
+df_dtheta(dL_df, X)[source]
+
+ +
+
+f(X)[source]
+
+ +
+
+randomize()[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.models.html b/doc/_build/html/GPy.models.html new file mode 100644 index 00000000..5a6596b9 --- /dev/null +++ b/doc/_build/html/GPy.models.html @@ -0,0 +1,1048 @@ + + + + + + + + GPy.models package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.models package

+
+

Submodules

+
+
+

GPy.models.bayesian_gplvm module

+
+
+class GPy.models.bayesian_gplvm.BayesianGPLVM(Y, input_dim, X=None, X_variance=None, init='PCA', num_inducing=10, Z=None, kernel=None, inference_method=None, likelihood=None, name='bayesian gplvm', mpi_comm=None, normalizer=None, missing_data=False, stochastic=False, batchsize=1)[source]
+

Bases: GPy.core.sparse_gp_mpi.SparseGP_MPI

+

Bayesian Gaussian Process Latent Variable Model

+ +++ + + + +
Parameters:
    +
  • Y (np.ndarray| GPy.likelihood instance) – observed data (np.ndarray) or GPy.likelihood
  • +
  • input_dim (int) – latent dimensionality
  • +
  • init (‘PCA’|’random’) – initialisation method for the latent space
  • +
+
+
+
+dmu_dX(Xnew)[source]
+

Calculate the gradient of the prediction at Xnew w.r.t Xnew.

+
+ +
+
+dmu_dXnew(Xnew)[source]
+

Individual gradient of prediction at Xnew w.r.t. each sample in Xnew

+
+ +
+
+do_test_latents(Y)[source]
+

Compute the latent representation for a set of new points Y

+

Notes: +This will only work with a univariate Gaussian likelihood (for now)

+
+ +
+
+get_X_gradients(X)[source]
+

Get the gradients of the posterior distribution of X in its specific form.

+
+ +
+
+parameters_changed()[source]
+
+ +
+
+plot_latent(labels=None, which_indices=None, resolution=50, ax=None, marker='o', s=40, fignum=None, plot_inducing=True, legend=True, plot_limits=None, aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={})[source]
+
+ +
+
+plot_steepest_gradient_map(*args, **kwargs)[source]
+

See GPy.plotting.matplot_dep.dim_reduction_plots.plot_steepest_gradient_map

+
+ +
+
+set_X_gradients(X, X_grad)[source]
+

Set the gradients of the posterior distribution of X in its specific form.

+
+ +
+ +
+
+GPy.models.bayesian_gplvm.latent_cost_and_grad(mu_S, input_dim, kern, Z, dL_dpsi0, dL_dpsi1, dL_dpsi2)[source]
+

objective function for fitting the latent variables for test points +(negative log-likelihood: should be minimised!)

+
+ +
+
+

GPy.models.bayesian_gplvm_minibatch module

+
+
+class GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch(Y, input_dim, X=None, X_variance=None, init='PCA', num_inducing=10, Z=None, kernel=None, inference_method=None, likelihood=None, name='bayesian gplvm', normalizer=None, missing_data=False, stochastic=False, batchsize=1)[source]
+

Bases: GPy.models.sparse_gp_minibatch.SparseGPMiniBatch

+

Bayesian Gaussian Process Latent Variable Model

+ +++ + + + +
Parameters:
    +
  • Y (np.ndarray| GPy.likelihood instance) – observed data (np.ndarray) or GPy.likelihood
  • +
  • input_dim (int) – latent dimensionality
  • +
  • init (‘PCA’|’random’) – initialisation method for the latent space
  • +
+
+
+
+dmu_dX(Xnew)[source]
+

Calculate the gradient of the prediction at Xnew w.r.t Xnew.

+
+ +
+
+dmu_dXnew(Xnew)[source]
+

Individual gradient of prediction at Xnew w.r.t. each sample in Xnew

+
+ +
+
+do_test_latents(Y)[source]
+

Compute the latent representation for a set of new points Y

+

Notes: +This will only work with a univariate Gaussian likelihood (for now)

+
+ +
+
+get_X_gradients(X)[source]
+

Get the gradients of the posterior distribution of X in its specific form.

+
+ +
+
+parameters_changed()[source]
+
+ +
+
+plot_latent(labels=None, which_indices=None, resolution=50, ax=None, marker='o', s=40, fignum=None, plot_inducing=True, legend=True, plot_limits=None, aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={})[source]
+
+ +
+
+plot_steepest_gradient_map(*args, **kwargs)[source]
+

See GPy.plotting.matplot_dep.dim_reduction_plots.plot_steepest_gradient_map

+
+ +
+
+set_X_gradients(X, X_grad)[source]
+

Set the gradients of the posterior distribution of X in its specific form.

+
+ +
+ +
+
+GPy.models.bayesian_gplvm_minibatch.latent_cost_and_grad(mu_S, input_dim, kern, Z, dL_dpsi0, dL_dpsi1, dL_dpsi2)[source]
+

objective function for fitting the latent variables for test points +(negative log-likelihood: should be minimised!)

+
+ +
+
+

GPy.models.bcgplvm module

+
+
+class GPy.models.bcgplvm.BCGPLVM(Y, input_dim, init='PCA', X=None, kernel=None, normalize_Y=False, mapping=None)[source]
+

Bases: GPy.models.gplvm.GPLVM

+

Back constrained Gaussian Process Latent Variable Model

+ +++ + + + +
Parameters:
    +
  • Y (np.ndarray) – observed data
  • +
  • input_dim (int) – latent dimensionality
  • +
  • init (‘PCA’|’random’) – initialisation method for the latent space
  • +
  • mapping (GPy.core.Mapping object) – mapping for back constraint
  • +
+
+
+ +
+
+

GPy.models.gp_classification module

+
+
+class GPy.models.gp_classification.GPClassification(X, Y, kernel=None, Y_metadata=None)[source]
+

Bases: GPy.core.gp.GP

+

Gaussian Process classification

+

This is a thin wrapper around the models.GP class, with a set of sensible defaults

+ +++ + + + +
Parameters:
    +
  • X – input observations
  • +
  • Y – observed values, can be None if likelihood is not None
  • +
  • kernel – a GPy kernel, defaults to rbf
  • +
+
+
+

Note

+

Multiple independent outputs are allowed using columns of Y

+
+
+ +
+
+

GPy.models.gp_coregionalized_regression module

+
+
+class GPy.models.gp_coregionalized_regression.GPCoregionalizedRegression(X_list, Y_list, kernel=None, likelihoods_list=None, name='GPCR', W_rank=1, kernel_name='coreg')[source]
+

Bases: GPy.core.gp.GP

+

Gaussian Process model for heteroscedastic multioutput regression

+

This is a thin wrapper around the models.GP class, with a set of sensible defaults

+ +++ + + + + + + +
Parameters:
    +
  • X_list (list of numpy arrays) – list of input observations corresponding to each output
  • +
  • Y_list (list of numpy arrays) – list of observed values related to the different noise models
  • +
  • kernel (None | GPy.kernel defaults) – a GPy kernel, defaults to RBF ** Coregionalized
  • +
  • name (string) – model name
  • +
  • W_rank (integer) – number tuples of the corregionalization parameters ‘W’ (see coregionalize kernel documentation)
  • +
  • kernel_name (string) – name of the kernel
  • +
+
Likelihoods_list:
 

a list of likelihoods, defaults to list of Gaussian likelihoods

+
+
+ +
+
+

GPy.models.gp_heteroscedastic_regression module

+
+
+class GPy.models.gp_heteroscedastic_regression.GPHeteroscedasticRegression(X, Y, kernel=None, Y_metadata=None)[source]
+

Bases: GPy.core.gp.GP

+

Gaussian Process model for heteroscedastic regression

+

This is a thin wrapper around the models.GP class, with a set of sensible defaults

+ +++ + + + +
Parameters:
    +
  • X – input observations
  • +
  • Y – observed values
  • +
  • kernel – a GPy kernel, defaults to rbf
  • +
+
+
+
+plot(*args)[source]
+
+ +
+ +
+
+

GPy.models.gp_kronecker_gaussian_regression module

+
+
+class GPy.models.gp_kronecker_gaussian_regression.GPKroneckerGaussianRegression(X1, X2, Y, kern1, kern2, noise_var=1.0, name='KGPR')[source]
+

Bases: GPy.core.model.Model

+

Kronecker GP regression

+

Take two kernels computed on separate spaces K1(X1), K2(X2), and a data +matrix Y which is f size (N1, N2).

+

The effective covaraince is np.kron(K2, K1) +The effective data is vec(Y) = Y.flatten(order=’F’)

+

The noise must be iid Gaussian.

+

See Stegle et al. +@inproceedings{stegle2011efficient,

+
+
title={Efficient inference in matrix-variate gaussian models with $backslash$ iid observation noise}, +author={Stegle, Oliver and Lippert, Christoph and Mooij, Joris M and Lawrence, Neil D and Borgwardt, Karsten M}, +booktitle={Advances in Neural Information Processing Systems}, +pages={630–638}, +year={2011}
+

}

+
+
+log_likelihood()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+
+predict(X1new, X2new)[source]
+

Return the predictive mean and variance at a series of new points X1new, X2new +Only returns the diagonal of the predictive variance, for now.

+ +++ + + + +
Parameters:
    +
  • X1new (np.ndarray, Nnew x self.input_dim1) – The points at which to make a prediction
  • +
  • X2new (np.ndarray, Nnew x self.input_dim2) – The points at which to make a prediction
  • +
+
+
+ +
+ +
+
+

GPy.models.gp_multioutput_regression module

+
+
+

GPy.models.gp_regression module

+
+
+class GPy.models.gp_regression.GPRegression(X, Y, kernel=None, Y_metadata=None, normalizer=None)[source]
+

Bases: GPy.core.gp.GP

+

Gaussian Process model for regression

+

This is a thin wrapper around the models.GP class, with a set of sensible defaults

+ +++ + + + +
Parameters:
    +
  • X – input observations
  • +
  • Y – observed values
  • +
  • kernel – a GPy kernel, defaults to rbf
  • +
  • normalizer (Norm) –

    [False]

    +

    Normalize Y with the norm given. +If normalizer is False, no normalization will be done +If it is None, we use GaussianNorm(alization)

    +
  • +
+
+
+

Note

+

Multiple independent outputs are allowed using columns of Y

+
+
+ +
+
+

GPy.models.gp_var_gauss module

+
+
+class GPy.models.gp_var_gauss.GPVariationalGaussianApproximation(X, Y, kernel=None)[source]
+

Bases: GPy.core.model.Model

+

The Variational Gaussian Approximation revisited implementation for regression

+
+
@article{Opper:2009,
+
title = {The Variational Gaussian Approximation Revisited}, +author = {Opper, Manfred and Archambeau, C{‘e}dric}, +journal = {Neural Comput.}, +year = {2009}, +pages = {786–792},
+
+

}

+
+
+likelihood_quadrature(m, v)[source]
+

Perform Gauss-Hermite quadrature over the log of the likelihood, with a fixed weight

+
+ +
+
+log_likelihood()[source]
+

Marginal log likelihood evaluation

+
+ +
+
+parameters_changed()[source]
+
+ +
+
+predict(Xnew)[source]
+

Predict the function(s) at the new point(s) Xnew.

+ +++ + + + +
Parameters:Xnew (np.ndarray, Nnew x self.input_dim) – The points at which to make a prediction
+
+ +
+ +
+
+

GPy.models.gplvm module

+
+
+class GPy.models.gplvm.GPLVM(Y, input_dim, init='PCA', X=None, kernel=None, name='gplvm')[source]
+

Bases: GPy.core.gp.GP

+

Gaussian Process Latent Variable Model

+
+
+jacobian(X)[source]
+
+ +
+
+magnification(X)[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+
+plot()[source]
+
+ +
+
+plot_latent(labels=None, which_indices=None, resolution=50, ax=None, marker='o', s=40, fignum=None, legend=True, plot_limits=None, aspect='auto', updates=False, **kwargs)[source]
+
+ +
+
+plot_magnification(*args, **kwargs)[source]
+
+ +
+ +
+
+

GPy.models.gradient_checker module

+
+
+class GPy.models.gradient_checker.GradientChecker(f, df, x0, names=None, *args, **kwargs)[source]
+

Bases: GPy.core.model.Model

+
+
+log_likelihood()[source]
+
+ +
+ +
+
+GPy.models.gradient_checker.at_least_one_element(x)[source]
+
+ +
+
+GPy.models.gradient_checker.flatten_if_needed(x)[source]
+
+ +
+
+GPy.models.gradient_checker.get_shape(x)[source]
+
+ +
+
+

GPy.models.mrd module

+
+
+class GPy.models.mrd.MRD(Ylist, input_dim, X=None, X_variance=None, initx='PCA', initz='permute', num_inducing=10, Z=None, kernel=None, inference_method=None, likelihoods=None, name='mrd', Ynames=None, normalizer=False, stochastic=False, batchsize=10)[source]
+

Bases: GPy.models.bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch

+

!WARNING: This is bleeding edge code and still in development. +Functionality may change fundamentally during development!

+

Apply MRD to all given datasets Y in Ylist.

+

Y_i in [n x p_i]

+

If Ylist is a dictionary, the keys of the dictionary are the names, and the +values are the different datasets to compare.

+

The samples n in the datasets need +to match up, whereas the dimensionality p_d can differ.

+ +++ + + + +
Parameters:
    +
  • Ylist ([array-like]) – List of datasets to apply MRD on
  • +
  • input_dim (int) – latent dimensionality
  • +
  • X (array-like) – mean of starting latent space q in [n x q]
  • +
  • X_variance (array-like) – variance of starting latent space q in [n x q]
  • +
  • initx ([‘concat’|’single’|’random’]) –

    initialisation method for the latent space :

    +
      +
    • ‘concat’ - PCA on concatenation of all datasets
    • +
    • ‘single’ - Concatenation of PCA on datasets, respectively
    • +
    • ‘random’ - Random draw from a Normal(0,1)
    • +
    +
  • +
  • initz (‘permute’|’random’) – initialisation method for inducing inputs
  • +
  • num_inducing – number of inducing inputs to use
  • +
  • Z – initial inducing inputs
  • +
  • kernel ([GPy.kernels.kernels] | GPy.kernels.kernels | None (default)) – list of kernels or kernel to copy for each output
  • +
+
+
+
:param :class:`~GPy.inference.latent_function_inference inference_method:
+
InferenceMethodList of inferences, or one inference method for all
+
+

:param likelihoods likelihoods: the likelihoods to use +:param str name: the name of this model +:param [str] Ynames: the names for the datasets given, must be of equal length as Ylist or None +:param bool|Norm normalizer: How to normalize the data? +:param bool stochastic: Should this model be using stochastic gradient descent over the dimensions? +:param bool|[bool] batchsize: either one batchsize for all, or one batchsize per dataset.

+
+
+log_likelihood()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+
+plot_latent(labels=None, which_indices=None, resolution=50, ax=None, marker='o', s=40, fignum=None, plot_inducing=True, legend=True, plot_limits=None, aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={})[source]
+

see plotting.matplot_dep.dim_reduction_plots.plot_latent +if predict_kwargs is None, will plot latent spaces for 0th dataset (and kernel), otherwise give +predict_kwargs=dict(Yindex=’index’) for plotting only the latent space of dataset with ‘index’.

+
+ +
+
+plot_scales(fignum=None, ax=None, titles=None, sharex=False, sharey=True, *args, **kwargs)[source]
+

TODO: Explain other parameters

+ +++ + + + +
Parameters:titles – titles for axes of datasets
+
+ +
+
+predict(Xnew, full_cov=False, Y_metadata=None, kern=None, Yindex=0)[source]
+

Prediction for data set Yindex[default=0]. +This predicts the output mean and variance for the dataset given in Ylist[Yindex]

+
+ +
+ +
+
+

GPy.models.sparse_gp_classification module

+
+
+class GPy.models.sparse_gp_classification.SparseGPClassification(X, Y=None, likelihood=None, kernel=None, Z=None, num_inducing=10, Y_metadata=None)[source]
+

Bases: GPy.core.sparse_gp.SparseGP

+

sparse Gaussian Process model for classification

+

This is a thin wrapper around the sparse_GP class, with a set of sensible defaults

+ +++ + + + + + +
Parameters:
    +
  • X – input observations
  • +
  • Y – observed values
  • +
  • likelihood – a GPy likelihood, defaults to Binomial with probit link_function
  • +
  • kernel – a GPy kernel, defaults to rbf+white
  • +
  • normalize_X (False|True) – whether to normalize the input data before computing (predictions will be in original scales)
  • +
  • normalize_Y (False|True) – whether to normalize the input data before computing (predictions will be in original scales)
  • +
+
Return type:

model object

+
+
+ +
+
+

GPy.models.sparse_gp_coregionalized_regression module

+
+
+class GPy.models.sparse_gp_coregionalized_regression.SparseGPCoregionalizedRegression(X_list, Y_list, Z_list=[], kernel=None, likelihoods_list=None, num_inducing=10, X_variance=None, name='SGPCR', W_rank=1, kernel_name='coreg')[source]
+

Bases: GPy.core.sparse_gp.SparseGP

+

Sparse Gaussian Process model for heteroscedastic multioutput regression

+

This is a thin wrapper around the SparseGP class, with a set of sensible defaults

+ +++ + + + + + + +
Parameters:
    +
  • X_list (list of numpy arrays) – list of input observations corresponding to each output
  • +
  • Y_list (list of numpy arrays) – list of observed values related to the different noise models
  • +
  • Z_list (empty list | list of numpy arrays) – list of inducing inputs (optional)
  • +
  • kernel (None | GPy.kernel defaults) – a GPy kernel, defaults to RBF ** Coregionalized
  • +
  • num_inducing (integer | list of integers) – number of inducing inputs, defaults to 10 per output (ignored if Z_list is not empty)
  • +
  • name (string) – model name
  • +
  • W_rank (integer) – number tuples of the corregionalization parameters ‘W’ (see coregionalize kernel documentation)
  • +
  • kernel_name (string) – name of the kernel
  • +
+
Likelihoods_list:
 

a list of likelihoods, defaults to list of Gaussian likelihoods

+
+
+ +
+
+

GPy.models.sparse_gp_minibatch module

+
+
+class GPy.models.sparse_gp_minibatch.SparseGPMiniBatch(X, Y, Z, kernel, likelihood, inference_method=None, name='sparse gp', Y_metadata=None, normalizer=False, missing_data=False, stochastic=False, batchsize=1)[source]
+

Bases: GPy.core.gp.GP

+
+
A general purpose Sparse GP model
+

‘’’ +Created on 3 Nov 2014

+

@author: maxz +‘’‘

+
+

This model allows (approximate) inference using variational DTC or FITC +(Gaussian likelihoods) as well as non-conjugate sparse methods based on +these.

+ +++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
param X:inputs
type X:np.ndarray (num_data x input_dim)
param likelihood:
 a likelihood instance, containing the observed data
type likelihood:
 GPy.likelihood.(Gaussian | EP | Laplace)
param kernel:the kernel (covariance function). See link kernels
type kernel:a GPy.kern.kern instance
param X_variance:
 The uncertainty in the measurements of X (Gaussian variance)
type X_variance:
 np.ndarray (num_data x input_dim) | None
param Z:inducing inputs
type Z:np.ndarray (num_inducing x input_dim)
param num_inducing:
 Number of inducing points (optional, default 10. Ignored if Z is not None)
type num_inducing:
 int
+
+
+
+has_uncertain_inputs()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+ +
+
+

GPy.models.sparse_gp_multioutput_regression module

+
+
+

GPy.models.sparse_gp_regression module

+
+
+class GPy.models.sparse_gp_regression.SparseGPRegression(X, Y, kernel=None, Z=None, num_inducing=10, X_variance=None, normalizer=None, mpi_comm=None)[source]
+

Bases: GPy.core.sparse_gp_mpi.SparseGP_MPI

+

Gaussian Process model for regression

+

This is a thin wrapper around the SparseGP class, with a set of sensible defalts

+ +++ + + + + + +
Parameters:
    +
  • X – input observations
  • +
  • Y – observed values
  • +
  • kernel – a GPy kernel, defaults to rbf+white
  • +
  • Z (np.ndarray (num_inducing x input_dim) | None) – inducing inputs (optional, see note)
  • +
  • num_inducing (int) – number of inducing points (ignored if Z is passed, see note)
  • +
+
Return type:

model object

+
+
+

Note

+

If no Z array is passed, num_inducing (default 10) points are selected from the data. Other wise num_inducing is ignored

+
+
+

Note

+

Multiple independent outputs are allowed using columns of Y

+
+
+
+parameters_changed()[source]
+
+ +
+ +
+
+class GPy.models.sparse_gp_regression.SparseGPRegressionUncertainInput(X, X_variance, Y, kernel=None, Z=None, num_inducing=10, normalizer=None)[source]
+

Bases: GPy.core.sparse_gp.SparseGP

+

Gaussian Process model for regression with Gaussian variance on the inputs (X_variance)

+

This is a thin wrapper around the SparseGP class, with a set of sensible defalts

+
+ +
+
+

GPy.models.sparse_gplvm module

+
+
+class GPy.models.sparse_gplvm.SparseGPLVM(Y, input_dim, X=None, kernel=None, init='PCA', num_inducing=10)[source]
+

Bases: GPy.models.sparse_gp_regression.SparseGPRegression

+

Sparse Gaussian Process Latent Variable Model

+ +++ + + + +
Parameters:
    +
  • Y (np.ndarray) – observed data
  • +
  • input_dim (int) – latent dimensionality
  • +
  • init (‘PCA’|’random’) – initialisation method for the latent space
  • +
+
+
+
+parameters_changed()[source]
+
+ +
+
+plot_latent(labels=None, which_indices=None, resolution=50, ax=None, marker='o', s=40, fignum=None, plot_inducing=True, legend=True, plot_limits=None, aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={})[source]
+
+ +
+ +
+
+

GPy.models.ss_gplvm module

+
+
+class GPy.models.ss_gplvm.SSGPLVM(Y, input_dim, X=None, X_variance=None, Gamma=None, init='PCA', num_inducing=10, Z=None, kernel=None, inference_method=None, likelihood=None, name='Spike_and_Slab GPLVM', group_spike=False, mpi_comm=None, pi=None, learnPi=True, normalizer=False, **kwargs)[source]
+

Bases: GPy.core.sparse_gp_mpi.SparseGP_MPI

+

Spike-and-Slab Gaussian Process Latent Variable Model

+ +++ + + + +
Parameters:
    +
  • Y (np.ndarray| GPy.likelihood instance) – observed data (np.ndarray) or GPy.likelihood
  • +
  • input_dim (int) – latent dimensionality
  • +
  • init (‘PCA’|’random’) – initialisation method for the latent space
  • +
+
+
+
+get_X_gradients(X)[source]
+

Get the gradients of the posterior distribution of X in its specific form.

+
+ +
+
+input_sensitivity()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+
+plot_latent(plot_inducing=True, *args, **kwargs)[source]
+
+ +
+
+set_X_gradients(X, X_grad)[source]
+

Set the gradients of the posterior distribution of X in its specific form.

+
+ +
+ +
+
+

GPy.models.ss_mrd module

+

The Maniforld Relevance Determination model with the spike-and-slab prior

+
+
+class GPy.models.ss_mrd.SSMRD(Ylist, input_dim, X=None, X_variance=None, initx='PCA', initz='permute', num_inducing=10, Z=None, kernel=None, inference_method=None, likelihoods=None, name='ss_mrd', Ynames=None)[source]
+

Bases: GPy.core.model.Model

+
+
+log_likelihood()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+ +
+
+

GPy.models.svigp_regression module

+
+
+

GPy.models.warped_gp module

+
+
+class GPy.models.warped_gp.WarpedGP(X, Y, kernel=None, warping_function=None, warping_terms=3, normalize_X=False, normalize_Y=False)[source]
+

Bases: GPy.core.gp.GP

+
+
+log_likelihood()[source]
+
+ +
+
+plot_warping()[source]
+
+ +
+
+predict(Xnew, which_parts='all', full_cov=False, pred_init=None)[source]
+
+ +
+
+transform_data()[source]
+
+ +
+
+warping_function_gradients(Kiy)[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.plotting.html b/doc/_build/html/GPy.plotting.html new file mode 100644 index 00000000..d90f0b68 --- /dev/null +++ b/doc/_build/html/GPy.plotting.html @@ -0,0 +1,181 @@ + + + + + + + + GPy.plotting package — GPy documentation + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.plotting.matplot_dep.html b/doc/_build/html/GPy.plotting.matplot_dep.html new file mode 100644 index 00000000..cedd4e77 --- /dev/null +++ b/doc/_build/html/GPy.plotting.matplot_dep.html @@ -0,0 +1,1098 @@ + + + + + + + + GPy.plotting.matplot_dep package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.plotting.matplot_dep package

+ +
+

Submodules

+
+
+

GPy.plotting.matplot_dep.Tango module

+
+
+GPy.plotting.matplot_dep.Tango.currentDark()[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.currentLight()[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.currentMedium()[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.fewerXticks(ax=None, divideby=2)[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.hex2rgb(hexcolor)[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.nextDark()[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.nextLight()[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.nextMedium()[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.removeRightTicks(ax=None)[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.removeUpperTicks(ax=None)[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.reset()[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.setDarkFigures()[source]
+
+ +
+
+GPy.plotting.matplot_dep.Tango.setLightFigures()[source]
+
+ +
+
+

GPy.plotting.matplot_dep.base_plots module

+
+
+GPy.plotting.matplot_dep.base_plots.align_subplot_array(axes, xlim=None, ylim=None)[source]
+

Make all of the axes in the array hae the same limits, turn off unnecessary ticks +use pb.subplots() to get an array of axes

+
+ +
+
+GPy.plotting.matplot_dep.base_plots.align_subplots(N, M, xlim=None, ylim=None)[source]
+

make all of the subplots have the same limits, turn off unnecessary ticks

+
+ +
+
+GPy.plotting.matplot_dep.base_plots.ax_default(fignum, ax)[source]
+
+ +
+
+GPy.plotting.matplot_dep.base_plots.fewerXticks(ax=None, divideby=2)[source]
+
+ +
+
+GPy.plotting.matplot_dep.base_plots.gpplot(x, mu, lower, upper, edgecol='#204a87', fillcol='#729fcf', ax=None, fignum=None, **kwargs)[source]
+
+ +
+
+GPy.plotting.matplot_dep.base_plots.meanplot(x, mu, color='#204a87', ax=None, fignum=None, linewidth=2, **kw)[source]
+
+ +
+
+GPy.plotting.matplot_dep.base_plots.removeRightTicks(ax=None)[source]
+
+ +
+
+GPy.plotting.matplot_dep.base_plots.removeUpperTicks(ax=None)[source]
+
+ +
+
+GPy.plotting.matplot_dep.base_plots.x_frame1D(X, plot_limits=None, resolution=None)[source]
+

Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits

+
+ +
+
+GPy.plotting.matplot_dep.base_plots.x_frame2D(X, plot_limits=None, resolution=None)[source]
+

Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits

+
+ +
+
+

GPy.plotting.matplot_dep.dim_reduction_plots module

+
+
+GPy.plotting.matplot_dep.dim_reduction_plots.most_significant_input_dimensions(model, which_indices)[source]
+

Determine which dimensions should be plotted

+
+ +
+
+GPy.plotting.matplot_dep.dim_reduction_plots.plot_latent(model, labels=None, which_indices=None, resolution=50, ax=None, marker='o', s=40, fignum=None, plot_inducing=False, legend=True, plot_limits=None, aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={})[source]
+
+++ + + + +
Parameters:
    +
  • labels – a np.array of size model.num_data containing labels for the points (can be number, strings, etc)
  • +
  • resolution – the resolution of the grid on which to evaluate the predictive variance
  • +
+
+
+ +
+
+GPy.plotting.matplot_dep.dim_reduction_plots.plot_magnification(model, labels=None, which_indices=None, resolution=60, ax=None, marker='o', s=40, fignum=None, plot_inducing=False, legend=True, aspect='auto', updates=False)[source]
+
+++ + + + +
Parameters:
    +
  • labels – a np.array of size model.num_data containing labels for the points (can be number, strings, etc)
  • +
  • resolution – the resolution of the grid on which to evaluate the predictive variance
  • +
+
+
+ +
+
+GPy.plotting.matplot_dep.dim_reduction_plots.plot_steepest_gradient_map(model, fignum=None, ax=None, which_indices=None, labels=None, data_labels=None, data_marker='o', data_s=40, resolution=20, aspect='auto', updates=False, **kwargs)[source]
+
+ +
+
+

GPy.plotting.matplot_dep.img_plots module

+

The module contains the tools for ploting 2D image visualizations

+
+
+GPy.plotting.matplot_dep.img_plots.plot_2D_images(figure, arr, symmetric=False, pad=None, zoom=None, mode=None, interpolation='nearest')[source]
+
+ +
+
+

GPy.plotting.matplot_dep.inference_plots module

+
+
+GPy.plotting.matplot_dep.inference_plots.plot_optimizer(optimizer)[source]
+
+ +
+
+GPy.plotting.matplot_dep.inference_plots.plot_sgd_traces(optimizer)[source]
+
+ +
+
+

GPy.plotting.matplot_dep.kernel_plots module

+
+
+GPy.plotting.matplot_dep.kernel_plots.add_bar_labels(fig, ax, bars, bottom=0)[source]
+
+ +
+
+GPy.plotting.matplot_dep.kernel_plots.plot(kernel, x=None, fignum=None, ax=None, title=None, plot_limits=None, resolution=None, **mpl_kwargs)[source]
+

plot a kernel. +:param x: the value to use for the other kernel argument (kernels are a function of two variables!) +:param fignum: figure number of the plot +:param ax: matplotlib axis to plot on +:param title: the matplotlib title +:param plot_limits: the range over which to plot the kernel +:resolution: the resolution of the lines used in plotting +:mpl_kwargs avalid keyword arguments to pass through to matplotlib (e.g. lw=7)

+
+ +
+
+GPy.plotting.matplot_dep.kernel_plots.plot_ARD(kernel, fignum=None, ax=None, title='', legend=False, filtering=None)[source]
+

If an ARD kernel is present, plot a bar representation using matplotlib

+ +++ + + + +
Parameters:
    +
  • fignum – figure number of the plot
  • +
  • ax – matplotlib axis to plot on
  • +
  • title – title of the plot, +pass ‘’ to not print a title +pass None for a generic title
  • +
  • filtering (list of names to use for ARD plot) – list of names, which to use for plotting ARD parameters. +Only kernels which match names in the list of names in filtering +will be used for plotting.
  • +
+
+
+ +
+
+GPy.plotting.matplot_dep.kernel_plots.plot_bars(fig, ax, x, ard_params, color, name, bottom=0)[source]
+
+ +
+
+

GPy.plotting.matplot_dep.mapping_plots module

+
+
+GPy.plotting.matplot_dep.mapping_plots.plot_mapping(self, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, samples=0, fignum=None, ax=None, fixed_inputs=[], linecol='#204a87')[source]
+
+
Plots the mapping associated with the model.
+
    +
  • In one dimension, the function is plotted.
  • +
  • In two dimsensions, a contour-plot shows the function
  • +
  • In higher dimensions, we’ve not implemented this yet !TODO!
  • +
+
+
+

Can plot only part of the data and part of the posterior functions +using which_data and which_functions

+ +++ + + + +
Parameters:
    +
  • plot_limits (np.array) – The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
  • +
  • which_data (‘all’ or a slice object to slice self.X, self.Y) – which if the training data to plot (default all)
  • +
  • which_parts (‘all’, or list of bools) – which of the kernel functions to plot (additively)
  • +
  • resolution (int) – the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
  • +
  • levels (int) – number of levels to plot in a contour plot.
  • +
  • samples (int) – the number of a posteriori samples to plot
  • +
  • fignum (figure number) – figure to plot on.
  • +
  • ax (axes handle) – axes to plot on.
  • +
  • fixed_inputs (a list of tuples) – a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
  • +
  • linecol – color of line to plot.
  • +
  • levels – for 2D plotting, the number of contour levels to use is ax is None, create a new figure
  • +
+
+
+ +
+
+

GPy.plotting.matplot_dep.maps module

+
+
+GPy.plotting.matplot_dep.maps.apply_bbox(sf, ax)[source]
+

Use bbox as xlim and ylim in ax

+
+ +
+
+GPy.plotting.matplot_dep.maps.bbox_match(sf, bbox, inside_only=True)[source]
+

Return the geometry and attributes of a shapefile that lie within (or intersect) a bounding box

+ +++ + + + + + +
Parameters:
    +
  • sf (shapefile object) – shapefile
  • +
  • bbox (list of floats [x_min,y_min,x_max,y_max]) – bounding box
  • +
+
Inside_only:

True if the objects returned are those that lie within the bbox and False if the objects returned are any that intersect the bbox

+
+
+ +
+
+GPy.plotting.matplot_dep.maps.new_shape_string(sf, name, regex, field=2, type=None)[source]
+
+ +
+
+GPy.plotting.matplot_dep.maps.plot(shape_records, facecolor='w', edgecolor='k', linewidths=0.5, ax=None, xlims=None, ylims=None)[source]
+

Plot the geometry of a shapefile

+ +++ + + + +
Parameters:
    +
  • shape_records (ShapeRecord object (output of a shapeRecords() method)) – geometry and attributes list
  • +
  • facecolor – color to be used to fill in polygons
  • +
  • edgecolor – color to be used for lines
  • +
  • ax (axes handle) – axes to plot on.
  • +
+
+
+ +
+
+GPy.plotting.matplot_dep.maps.plot_bbox(sf, bbox, inside_only=True)[source]
+

Plot the geometry of a shapefile within a bbox

+ +++ + + + + + +
Parameters:
    +
  • sf (shapefile object) – shapefile
  • +
  • bbox (list of floats [x_min,y_min,x_max,y_max]) – bounding box
  • +
+
Inside_only:

True if the objects returned are those that lie within the bbox and False if the objects returned are any that intersect the bbox

+
+
+ +
+
+GPy.plotting.matplot_dep.maps.plot_string_match(sf, regex, field, **kwargs)[source]
+

Plot the geometry of a shapefile whose fields match a regular expression given

+ +++ + + + + + + + +
Parameters:sf (shapefile object) – shapefile
Regex:regular expression to match
Field:field number to be matched with the regex
+
+ +
+
+GPy.plotting.matplot_dep.maps.string_match(sf, regex, field=2)[source]
+

Return the geometry and attributes of a shapefile whose fields match a regular expression given

+ +++ + + + + + + + +
Parameters:sf (shapefile object) – shapefile
Regex:regular expression to match
Field:field number to be matched with the regex
+
+ +
+
+

GPy.plotting.matplot_dep.models_plots module

+
+
+GPy.plotting.matplot_dep.models_plots.plot_fit(model, plot_limits=None, which_data_rows='all', which_data_ycols='all', fixed_inputs=[], levels=20, samples=0, fignum=None, ax=None, resolution=None, plot_raw=False, linecol='#204a87', fillcol='#729fcf', Y_metadata=None, data_symbol='kx')[source]
+
+
Plot the posterior of the GP.
+
    +
  • In one dimension, the function is plotted with a shaded region identifying two standard deviations.
  • +
  • In two dimsensions, a contour-plot shows the mean predicted function
  • +
  • In higher dimensions, use fixed_inputs to plot the GP with some of the inputs fixed.
  • +
+
+
+

Can plot only part of the data and part of the posterior functions +using which_data_rowsm which_data_ycols.

+ +++ + + + +
Parameters:
    +
  • plot_limits (np.array) – The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
  • +
  • which_data_rows (‘all’ or a list of integers) – which of the training data to plot (default all)
  • +
  • which_data_ycols – when the data has several columns (independant outputs), only plot these
  • +
  • fixed_inputs (a list of tuples) – a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
  • +
  • resolution (int) – the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
  • +
  • levels (int) – number of levels to plot in a contour plot.
  • +
  • samples (int) – the number of a posteriori samples to plot
  • +
  • fignum (figure number) – figure to plot on.
  • +
  • ax (axes handle) – axes to plot on.
  • +
  • linecol – color of line to plot.
  • +
  • fillcol – color of fill
  • +
  • levels – for 2D plotting, the number of contour levels to use is ax is None, create a new figure
  • +
+
+
+ +
+
+GPy.plotting.matplot_dep.models_plots.plot_fit_f(model, *args, **kwargs)[source]
+

Plot the GP’s view of the world, where the data is normalized and before applying a likelihood.

+

All args and kwargs are passed on to models_plots.plot.

+
+ +
+
+

GPy.plotting.matplot_dep.netpbmfile module

+

Read and write image data from respectively to Netpbm files.

+

This implementation follows the Netpbm format specifications at +http://netpbm.sourceforge.net/doc/. No gamma correction is performed.

+

The following image formats are supported: PBM (bi-level), PGM (grayscale), +PPM (color), PAM (arbitrary), XV thumbnail (RGB332, read-only).

+ +++ + + + + + + + +
Author:Christoph Gohlke
Organization:Laboratory for Fluorescence Dynamics, University of California, Irvine
Version:2013.01.18
+
+

Requirements

+ +
+
+

Examples

+
>>> im1 = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16)
+>>> imsave('_tmp.pgm', im1)
+>>> im2 = imread('_tmp.pgm')
+>>> assert numpy.all(im1 == im2)
+
+
+
+
+GPy.plotting.matplot_dep.netpbmfile.imread(filename, *args, **kwargs)[source]
+

Return image data from Netpbm file as numpy array.

+

args and kwargs are arguments to NetpbmFile.asarray().

+
>>> image = imread('_tmp.pgm')
+
+
+
+ +
+
+GPy.plotting.matplot_dep.netpbmfile.imsave(filename, data, maxval=None, pam=False)[source]
+

Write image data to Netpbm file.

+
>>> image = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16)
+>>> imsave('_tmp.pgm', image)
+
+
+
+ +
+
+class GPy.plotting.matplot_dep.netpbmfile.NetpbmFile(arg=None, **kwargs)[source]
+

Bases: object

+

Read and write Netpbm PAM, PBM, PGM, PPM, files.

+
+
+asarray(copy=True, cache=False, **kwargs)[source]
+

Return image data from file as numpy array.

+
+ +
+
+close()[source]
+

Close open file. Future asarray calls might fail.

+
+ +
+
+write(arg, **kwargs)[source]
+

Write instance to file.

+
+ +
+ +
+
+
+

GPy.plotting.matplot_dep.priors_plots module

+
+
+GPy.plotting.matplot_dep.priors_plots.plot(prior)[source]
+
+ +
+
+GPy.plotting.matplot_dep.priors_plots.univariate_plot(prior)[source]
+
+ +
+
+

GPy.plotting.matplot_dep.ssgplvm module

+

The module plotting results for SSGPLVM

+
+
+class GPy.plotting.matplot_dep.ssgplvm.SSGPLVM_plot(model, imgsize)[source]
+

Bases: object

+
+
+plot_inducing()[source]
+
+ +
+ +
+
+

GPy.plotting.matplot_dep.svig_plots module

+
+
+GPy.plotting.matplot_dep.svig_plots.plot(model, ax=None, fignum=None, Z_height=None, **kwargs)[source]
+
+ +
+
+GPy.plotting.matplot_dep.svig_plots.plot_traces(model)[source]
+
+ +
+
+

GPy.plotting.matplot_dep.variational_plots module

+
+
+GPy.plotting.matplot_dep.variational_plots.plot(parameterized, fignum=None, ax=None, colors=None)[source]
+

Plot latent space X in 1D:

+
+
    +
  • if fig is given, create input_dim subplots in fig and plot in these
  • +
  • if ax is given plot input_dim 1D latent space plots of X into each axis
  • +
  • if neither fig nor ax is given create a figure with fignum and plot in there
  • +
+
+
+
colors:
+
colors of different latent space dimensions input_dim
+
+
+ +
+
+GPy.plotting.matplot_dep.variational_plots.plot_SpikeSlab(parameterized, fignum=None, ax=None, colors=None, side_by_side=True)[source]
+

Plot latent space X in 1D:

+
+
    +
  • if fig is given, create input_dim subplots in fig and plot in these
  • +
  • if ax is given plot input_dim 1D latent space plots of X into each axis
  • +
  • if neither fig nor ax is given create a figure with fignum and plot in there
  • +
+
+
+
colors:
+
colors of different latent space dimensions input_dim
+
+
+ +
+
+

GPy.plotting.matplot_dep.visualize module

+
+
+GPy.plotting.matplot_dep.visualize.data_play(Y, visualizer, frame_rate=30)[source]
+

Play a data set using the data_show object given.

+ +++ + + + + + +
Y:the data set to be visualized.
Parameters:visualizer (data_show) – the data show objectwhether to display during optimisation
+

Example usage:

+

This example loads in the CMU mocap database (http://mocap.cs.cmu.edu) subject number 35 motion number 01. It then plays it using the mocap_show visualize object.

+
data = GPy.util.datasets.cmu_mocap(subject='35', train_motions=['01'])
+Y = data['Y']
+Y[:, 0:3] = 0.   # Make figure walk in place
+visualize = GPy.util.visualize.skeleton_show(Y[0, :], data['skel'])
+GPy.util.visualize.data_play(Y, visualize)
+
+
+
+ +
+
+class GPy.plotting.matplot_dep.visualize.data_show(vals)[source]
+

The data_show class is a base class which describes how to visualize a +particular data set. For example, motion capture data can be plotted as a +stick figure, or images are shown using imshow. This class enables latent +to data visualizations for the GP-LVM.

+
+
+close()[source]
+
+ +
+
+modify(vals)[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.visualize.image_show(vals, axes=None, dimensions=(16, 16), transpose=False, order='C', invert=False, scale=False, palette=[], preset_mean=0.0, preset_std=1.0, select_image=0, cmap=None)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.matplotlib_show

+

Show a data vector as an image. This visualizer rehapes the output vector and displays it as an image.

+ +++ + + + +
Parameters:
    +
  • vals (axes handle) – the values of the output to display.
  • +
  • axes – the axes to show the output on.
  • +
  • dimensions (tuple) – the dimensions that the image needs to be transposed to for display.
  • +
  • transpose – whether to transpose the image before display.
  • +
  • order (string) – whether array is in Fortan ordering (‘F’) or Python ordering (‘C’). Default is python (‘C’).
  • +
  • invert (bool) – whether to invert the pixels or not (default False).
  • +
  • palette – a palette to use for the image.
  • +
  • preset_mean (double) – the preset mean of a scaled image.
  • +
  • preset_std (double) – the preset standard deviation of a scaled image.
  • +
  • cmap (matplotlib.cm) – the colormap for image visualization
  • +
+
+
+
+modify(vals)[source]
+
+ +
+
+set_image(vals)[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.visualize.lvm(vals, model, data_visualize, latent_axes=None, sense_axes=None, latent_index=[0, 1], disable_drag=False)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.matplotlib_show

+
+
+modify(vals)[source]
+

When latent values are modified update the latent representation and ulso update the output visualization.

+
+ +
+
+on_click(event)[source]
+
+ +
+
+on_enter(event)[source]
+
+ +
+
+on_leave(event)[source]
+
+ +
+
+on_move(event)[source]
+
+ +
+
+show_sensitivities()[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.visualize.lvm_dimselect(vals, model, data_visualize, latent_axes=None, sense_axes=None, latent_index=[0, 1], labels=None)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.lvm

+

A visualizer for latent variable models which allows selection of the latent dimensions to use by clicking on a bar chart of their length scales.

+

For an example of the visualizer’s use try:

+

GPy.examples.dimensionality_reduction.BGPVLM_oil()

+
+
+on_click(event)[source]
+
+ +
+
+on_leave(event)[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.visualize.lvm_subplots(vals, Model, data_visualize, latent_axes=None, sense_axes=None)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.lvm

+

latent_axes is a np array of dimension np.ceil(input_dim/2), +one for each pair of the latent dimensions.

+
+ +
+
+class GPy.plotting.matplot_dep.visualize.matplotlib_show(vals, axes=None)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.data_show

+

the matplotlib_show class is a base class for all visualization methods that use matplotlib. It is initialized with an axis. If the axis is set to None it creates a figure window.

+
+
+close()[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.visualize.mocap_data_show(vals, axes=None, connect=None)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.matplotlib_show

+

Base class for visualizing motion capture data.

+
+
+draw_edges()[source]
+
+ +
+
+draw_vertices()[source]
+
+ +
+
+finalize_axes()[source]
+
+ +
+
+finalize_axes_modify()[source]
+
+ +
+
+initialize_axes(boundary=0.05)[source]
+

Set up the axes with the right limits and scaling.

+
+ +
+
+initialize_axes_modify()[source]
+
+ +
+
+modify(vals)[source]
+
+ +
+
+process_values()[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.visualize.mocap_data_show_vpython(vals, scene=None, connect=None, radius=0.1)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.vpython_show

+

Base class for visualizing motion capture data using visual module.

+
+
+draw_edges()[source]
+
+ +
+
+draw_vertices()[source]
+
+ +
+
+modify(vals)[source]
+
+ +
+
+modify_edges()[source]
+
+ +
+
+modify_vertices()[source]
+
+ +
+
+pos_axis(i, j)[source]
+
+ +
+
+process_values()[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.visualize.skeleton_show(vals, skel, axes=None, padding=0)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.mocap_data_show

+

data_show class for visualizing motion capture data encoded as a skeleton with angles.

+
+
+process_values()[source]
+

Takes a set of angles and converts them to the x,y,z coordinates in the internal prepresentation of the class, ready for plotting.

+ +++ + + + +
Parameters:vals – the values that are being modelled.
+
+ +
+
+wrap_around(lim, connect)[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.visualize.stick_show(vals, connect=None, axes=None)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.mocap_data_show

+

Show a three dimensional point cloud as a figure. Connect elements of the figure together using the matrix connect.

+
+
+process_values()[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.visualize.vector_show(vals, axes=None)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.matplotlib_show

+

A base visualization class that just shows a data vector as a plot of +vector elements alongside their indices.

+
+
+modify(vals)[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.visualize.vpython_show(vals, scene=None)[source]
+

Bases: GPy.plotting.matplot_dep.visualize.data_show

+

the vpython_show class is a base class for all visualization methods that use vpython to display. It is initialized with a scene. If the scene is set to None it creates a scene window.

+
+
+close()[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.plotting.matplot_dep.latent_space_visualizations.controllers.html b/doc/_build/html/GPy.plotting.matplot_dep.latent_space_visualizations.controllers.html new file mode 100644 index 00000000..3e12c5a6 --- /dev/null +++ b/doc/_build/html/GPy.plotting.matplot_dep.latent_space_visualizations.controllers.html @@ -0,0 +1,260 @@ + + + + + + + + GPy.plotting.matplot_dep.latent_space_visualizations.controllers package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.plotting.matplot_dep.latent_space_visualizations.controllers package

+
+

Submodules

+
+
+

GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller module

+

Created on 24 Jul 2013

+

@author: maxz

+
+
+class GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller.AxisChangedController(ax, update_lim=None)[source]
+

Bases: GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller.AxisEventController

+

Buffered control of axis limit changes

+
+
+extent(lim)[source]
+
+ +
+
+lim_changed(axlim, savedlim)[source]
+
+ +
+
+update(ax)[source]
+
+ +
+
+xlim_changed(ax)[source]
+
+ +
+
+ylim_changed(ax)[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller.AxisEventController(ax)[source]
+

Bases: object

+
+
+activate()[source]
+
+ +
+
+deactivate()[source]
+
+ +
+
+xlim_changed(ax)[source]
+
+ +
+
+ylim_changed(ax)[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller.BufferedAxisChangedController(ax, plot_function, plot_limits, resolution=50, update_lim=None, **kwargs)[source]
+

Bases: GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller.AxisChangedController

+
+
+get_grid(buffered=True)[source]
+
+ +
+
+recompute_X(buffered=True)[source]
+
+ +
+
+update(ax)[source]
+
+ +
+
+update_view(view, X, xmin, xmax, ymin, ymax)[source]
+
+ +
+ +
+
+

GPy.plotting.matplot_dep.latent_space_visualizations.controllers.imshow_controller module

+

Created on 24 Jul 2013

+

@author: maxz

+
+
+class GPy.plotting.matplot_dep.latent_space_visualizations.controllers.imshow_controller.ImAnnotateController(ax, plot_function, plot_limits, resolution=20, update_lim=0.99, **kwargs)[source]
+

Bases: GPy.plotting.matplot_dep.latent_space_visualizations.controllers.imshow_controller.ImshowController

+
+
+update_view(view, X, xmin, xmax, ymin, ymax)[source]
+
+ +
+ +
+
+class GPy.plotting.matplot_dep.latent_space_visualizations.controllers.imshow_controller.ImshowController(ax, plot_function, plot_limits, resolution=50, update_lim=0.8, **kwargs)[source]
+

Bases: GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller.BufferedAxisChangedController

+
+
+update_view(view, X, xmin, xmax, ymin, ymax)[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.plotting.matplot_dep.latent_space_visualizations.html b/doc/_build/html/GPy.plotting.matplot_dep.latent_space_visualizations.html new file mode 100644 index 00000000..44909eaa --- /dev/null +++ b/doc/_build/html/GPy.plotting.matplot_dep.latent_space_visualizations.html @@ -0,0 +1,151 @@ + + + + + + + + GPy.plotting.matplot_dep.latent_space_visualizations package — GPy documentation + + + + + + + + + + + + + + + + +
+
+ +
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.testing.html b/doc/_build/html/GPy.testing.html new file mode 100644 index 00000000..286b4ddb --- /dev/null +++ b/doc/_build/html/GPy.testing.html @@ -0,0 +1,1282 @@ + + + + + + + + GPy.testing package — GPy documentation + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.testing package

+
+

Submodules

+
+
+

GPy.testing.examples_tests module

+
+
+class GPy.testing.examples_tests.ExamplesTests(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+ +
+
+GPy.testing.examples_tests.flatten_nested(lst)[source]
+
+ +
+
+GPy.testing.examples_tests.model_checkgrads(model)[source]
+
+ +
+
+GPy.testing.examples_tests.model_instance(model)[source]
+
+ +
+
+GPy.testing.examples_tests.test_models()[source]
+
+ +
+
+

GPy.testing.fitc module

+
+
+class GPy.testing.fitc.FITCtest(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+setUp()[source]
+
+ +
+
+test_fitc_1d()[source]
+
+ +
+
+test_fitc_2d()[source]
+
+ +
+ +
+
+

GPy.testing.index_operations_tests module

+
+
+class GPy.testing.index_operations_tests.Test(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+setUp()[source]
+
+ +
+
+test_clear()[source]
+
+ +
+
+test_index_view()[source]
+
+ +
+
+test_indexview_remove()[source]
+
+ +
+
+test_misc()[source]
+
+ +
+
+test_print()[source]
+
+ +
+
+test_remove()[source]
+
+ +
+
+test_shift_left()[source]
+
+ +
+
+test_shift_right()[source]
+
+ +
+
+test_view_of_view()[source]
+
+ +
+ +
+
+

GPy.testing.inference_tests module

+

The test cases for various inference algorithms

+
+
+class GPy.testing.inference_tests.InferenceXTestCase(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+genData()[source]
+
+ +
+
+test_inferenceX_BGPLVM()[source]
+
+ +
+
+test_inferenceX_GPLVM()[source]
+
+ +
+ +
+
+

GPy.testing.kernel_tests module

+
+
+class GPy.testing.kernel_tests.Coregionalize_weave_test(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+

Make sure that the coregionalize kernel work with and without weave enabled

+
+
+setUp()[source]
+
+ +
+
+test_nonsym()[source]
+
+ +
+
+test_sym()[source]
+
+ +
+ +
+
+class GPy.testing.kernel_tests.Kern_check_dK_dX(kernel=None, dL_dK=None, X=None, X2=None)[source]
+

Bases: GPy.testing.kernel_tests.Kern_check_model

+

This class allows gradient checks for the gradient of a kernel with respect to X.

+
+
+parameters_changed()[source]
+
+ +
+ +
+
+class GPy.testing.kernel_tests.Kern_check_dK_dtheta(kernel=None, dL_dK=None, X=None, X2=None)[source]
+

Bases: GPy.testing.kernel_tests.Kern_check_model

+

This class allows gradient checks for the gradient of a kernel with +respect to parameters.

+
+
+parameters_changed()[source]
+
+ +
+ +
+
+class GPy.testing.kernel_tests.Kern_check_dKdiag_dX(kernel=None, dL_dK=None, X=None, X2=None)[source]
+

Bases: GPy.testing.kernel_tests.Kern_check_dK_dX

+

This class allows gradient checks for the gradient of a kernel diagonal with respect to X.

+
+
+log_likelihood()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+ +
+
+class GPy.testing.kernel_tests.Kern_check_dKdiag_dtheta(kernel=None, dL_dK=None, X=None)[source]
+

Bases: GPy.testing.kernel_tests.Kern_check_model

+

This class allows gradient checks of the gradient of the diagonal of a +kernel with respect to the parameters.

+
+
+log_likelihood()[source]
+
+ +
+
+parameters_changed()[source]
+
+ +
+ +
+
+class GPy.testing.kernel_tests.Kern_check_model(kernel=None, dL_dK=None, X=None, X2=None)[source]
+

Bases: GPy.core.model.Model

+

This is a dummy model class used as a base class for checking that the +gradients of a given kernel are implemented correctly. It enables +checkgrad() to be called independently on a kernel.

+
+
+is_positive_semi_definite()[source]
+
+ +
+
+log_likelihood()[source]
+
+ +
+ +
+
+class GPy.testing.kernel_tests.KernelGradientTestsContinuous(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+setUp()[source]
+
+ +
+
+test_Add()[source]
+
+ +
+
+test_Add_dims()[source]
+
+ +
+
+test_Linear()[source]
+
+ +
+
+test_LinearFull()[source]
+
+ +
+
+test_Matern32()[source]
+
+ +
+
+test_Matern52()[source]
+
+ +
+
+test_Prod()[source]
+
+ +
+
+test_Prod2()[source]
+
+ +
+
+test_Prod3()[source]
+
+ +
+
+test_RBF()[source]
+
+ +
+ +
+
+class GPy.testing.kernel_tests.KernelTestsMiscellaneous(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+setUp()[source]
+
+ +
+
+test_which_parts()[source]
+
+ +
+ +
+
+class GPy.testing.kernel_tests.KernelTestsNonContinuous(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+setUp()[source]
+
+ +
+
+test_Hierarchical()[source]
+
+ +
+
+test_IndependentOutputs()[source]
+
+ +
+
+test_ODE_UY()[source]
+
+ +
+ +
+
+GPy.testing.kernel_tests.check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verbose=False, fixed_X_dims=None)[source]
+

This function runs on kernels to check the correctness of their +implementation. It checks that the covariance function is positive definite +for a randomly generated data set.

+ +++ + + + +
Parameters:
    +
  • kern (GPy.kern.Kernpart) – the kernel to be tested.
  • +
  • X (ndarray) – X input values to test the covariance function.
  • +
  • X2 (ndarray) – X2 input values to test the covariance function.
  • +
+
+
+ +
+
+

GPy.testing.likelihood_tests module

+
+
+class GPy.testing.likelihood_tests.LaplaceTests(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+

Specific likelihood tests, not general enough for the above tests

+
+
+setUp()[source]
+
+ +
+
+tearDown()[source]
+
+ +
+
+test_gaussian_d2logpdf_df2_2()[source]
+
+ +
+
+test_laplace_log_likelihood()[source]
+
+ +
+ +
+
+class GPy.testing.likelihood_tests.TestNoiseModels[source]
+

Bases: object

+

Generic model checker

+
+
+setUp()[source]
+
+ +
+
+t_d2logpdf2_df2_dparams(model, Y, f, params, params_names, param_constraints)[source]
+
+ +
+
+t_d2logpdf2_dlink2_dparams(model, Y, f, params, param_names, param_constraints)[source]
+
+ +
+
+t_d2logpdf_df2(model, Y, f)[source]
+
+ +
+
+t_d2logpdf_dlink2(model, Y, f, link_f_constraints)[source]
+
+ +
+
+t_d3logpdf_df3(model, Y, f)[source]
+
+ +
+
+t_d3logpdf_dlink3(model, Y, f, link_f_constraints)[source]
+
+ +
+
+t_dlogpdf_df(model, Y, f)[source]
+
+ +
+
+t_dlogpdf_df_dparams(model, Y, f, params, params_names, param_constraints)[source]
+
+ +
+ +
+ +
+ +
+ +
+
+t_dlogpdf_dparams(model, Y, f, params, params_names, param_constraints)[source]
+
+ +
+ +
+ +
+
+t_ep_fit_rbf_white(model, X, Y, f, step, param_vals, param_names, constraints)[source]
+
+ +
+
+t_laplace_fit_rbf_white(model, X, Y, f, step, param_vals, param_names, constraints)[source]
+
+ +
+
+t_logpdf(model, Y, f)[source]
+
+ +
+
+tearDown()[source]
+
+ +
+
+test_scale2_models()[source]
+
+ +
+ +
+
+GPy.testing.likelihood_tests.dparam_checkgrad(func, dfunc, params, params_names, args, constraints=None, randomize=False, verbose=False)[source]
+

checkgrad expects a f: R^N -> R^1 and df: R^N -> R^N +However if we are holding other parameters fixed and moving something else +We need to check the gradient of each of the fixed parameters +(f and y for example) seperately, whilst moving another parameter. +Otherwise f: gives back R^N and

+
+
df: gives back R^NxM where M is
+

The number of parameters and N is the number of data +Need to take a slice out from f and a slice out of df

+
+ +
+
+GPy.testing.likelihood_tests.dparam_partial(inst_func, *args)[source]
+

If we have a instance method that needs to be called but that doesn’t +take the parameter we wish to change to checkgrad, then this function +will change the variable using set params.

+
+
inst_func: should be a instance function of an object that we would like
+
to change
+
+

param: the param that will be given to set_params +args: anything else that needs to be given to the function (for example

+
+
the f or Y that are being used in the function whilst we tweak the +param
+
+ +
+
+

GPy.testing.model_tests module

+
+
+class GPy.testing.model_tests.GradientTests(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+check_model(kern, model_type='GPRegression', dimension=1, uncertain_inputs=False)[source]
+
+ +
+
+setUp()[source]
+
+ +
+
+test_GPLVM_rbf_bias_white_kern_2D()[source]
+

Testing GPLVM with rbf + bias kernel

+
+ +
+
+test_GPLVM_rbf_linear_white_kern_2D()[source]
+

Testing GPLVM with rbf + bias kernel

+
+ +
+
+test_GPRegression_bias_kern_1D()[source]
+

Testing the GP regression with bias kernel on 1d data

+
+ +
+
+test_GPRegression_bias_kern_2D()[source]
+

Testing the GP regression with bias kernel on 2d data

+
+ +
+
+test_GPRegression_exponential_1D()[source]
+

Testing the GP regression with exponential kernel on 1d data

+
+ +
+
+test_GPRegression_exponential_2D()[source]
+

Testing the GP regression with exponential kernel on 2d data

+
+ +
+
+test_GPRegression_exponential_ARD_2D()[source]
+

Testing the GP regression with exponential kernel on 2d data

+
+ +
+
+test_GPRegression_linear_kern_1D()[source]
+

Testing the GP regression with linear kernel on 1d data

+
+ +
+
+test_GPRegression_linear_kern_1D_ARD()[source]
+

Testing the GP regression with linear kernel on 1d data

+
+ +
+
+test_GPRegression_linear_kern_2D()[source]
+

Testing the GP regression with linear kernel on 2d data

+
+ +
+
+test_GPRegression_linear_kern_2D_ARD()[source]
+

Testing the GP regression with linear kernel on 2d data

+
+ +
+
+test_GPRegression_matern32_1D()[source]
+

Testing the GP regression with matern32 kernel on 1d data

+
+ +
+
+test_GPRegression_matern32_2D()[source]
+

Testing the GP regression with matern32 kernel on 2d data

+
+ +
+
+test_GPRegression_matern32_ARD_2D()[source]
+

Testing the GP regression with matern32 kernel on 2d data

+
+ +
+
+test_GPRegression_matern52_1D()[source]
+

Testing the GP regression with matern52 kernel on 1d data

+
+ +
+
+test_GPRegression_matern52_2D()[source]
+

Testing the GP regression with matern52 kernel on 2d data

+
+ +
+
+test_GPRegression_matern52_ARD_2D()[source]
+

Testing the GP regression with matern52 kernel on 2d data

+
+ +
+
+test_GPRegression_mlp_1d()[source]
+

Testing the GP regression with mlp kernel with white kernel on 1d data

+
+ +
+
+test_GPRegression_rbf_1d()[source]
+

Testing the GP regression with rbf kernel with white kernel on 1d data

+
+ +
+
+test_GPRegression_rbf_2D()[source]
+

Testing the GP regression with rbf kernel on 2d data

+
+ +
+
+test_GPRegression_rbf_ARD_2D()[source]
+

Testing the GP regression with rbf kernel on 2d data

+
+ +
+
+test_GP_EP_probit()[source]
+
+ +
+
+test_SparseGPRegression_rbf_linear_white_kern_1D()[source]
+

Testing the sparse GP regression with rbf kernel on 2d data

+
+ +
+
+test_SparseGPRegression_rbf_linear_white_kern_1D_uncertain_inputs()[source]
+

Testing the sparse GP regression with rbf, linear kernel on 1d data with uncertain inputs

+
+ +
+
+test_SparseGPRegression_rbf_linear_white_kern_2D()[source]
+

Testing the sparse GP regression with rbf kernel on 2d data

+
+ +
+
+test_SparseGPRegression_rbf_linear_white_kern_2D_uncertain_inputs()[source]
+

Testing the sparse GP regression with rbf, linear kernel on 2d data with uncertain inputs

+
+ +
+
+test_SparseGPRegression_rbf_white_kern_1d()[source]
+

Testing the sparse GP regression with rbf kernel with white kernel on 1d data

+
+ +
+
+test_SparseGPRegression_rbf_white_kern_2D()[source]
+

Testing the sparse GP regression with rbf kernel on 2d data

+
+ +
+
+test_generalized_FITC(*args, **kwargs)[source]
+
+ +
+
+test_gp_VGPC()[source]
+
+ +
+
+test_gp_heteroscedastic_regression()[source]
+
+ +
+
+test_gp_kronecker_gaussian()[source]
+
+ +
+
+test_multioutput_regression_1D(*args, **kwargs)[source]
+
+ +
+
+test_multioutput_sparse_regression_1D(*args, **kwargs)[source]
+
+ +
+
+test_sparse_EP_DTC_probit()[source]
+
+ +
+
+test_sparse_gp_heteroscedastic_regression()[source]
+
+ +
+ +
+
+class GPy.testing.model_tests.MiscTests(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+setUp()[source]
+
+ +
+
+test_big_model()[source]
+
+ +
+
+test_likelihood_replicate()[source]
+
+ +
+
+test_likelihood_replicate_kern()[source]
+
+ +
+
+test_likelihood_set()[source]
+
+ +
+
+test_missing_data()[source]
+
+ +
+
+test_model_optimize()[source]
+
+ +
+
+test_model_set_params()[source]
+
+ +
+
+test_raw_predict()[source]
+
+ +
+
+test_sparse_raw_predict()[source]
+
+ +
+ +
+
+

GPy.testing.observable_tests module

+
+
+class GPy.testing.observable_tests.ParamTestParent(name=None, parameters=[], *a, **kw)[source]
+

Bases: GPy.core.parameterization.parameterized.Parameterized

+
+
+parameters_changed()[source]
+
+ +
+
+parent_changed_count = -1
+
+ +
+ +
+
+class GPy.testing.observable_tests.ParameterizedTest(name=None, parameters=[], *a, **kw)[source]
+

Bases: GPy.core.parameterization.parameterized.Parameterized

+
+
+parameters_changed()[source]
+
+ +
+
+params_changed_count = -1
+
+ +
+ +
+
+class GPy.testing.observable_tests.Test(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+setUp()[source]
+
+ +
+
+test_observable()[source]
+
+ +
+
+test_priority()[source]
+
+ +
+
+test_priority_notify()[source]
+
+ +
+
+test_set_params()[source]
+
+ +
+ +
+
+

GPy.testing.parameterized_tests module

+

Created on Feb 13, 2014

+

@author: maxzwiessele

+
+
+class GPy.testing.parameterized_tests.ArrayCoreTest(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+setUp()[source]
+
+ +
+
+test_init()[source]
+
+ +
+
+test_slice()[source]
+
+ +
+ +
+
+class GPy.testing.parameterized_tests.ParameterizedTest(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+setUp()[source]
+
+ +
+
+test_add_parameter()[source]
+
+ +
+
+test_add_parameter_already_in_hirarchy()[source]
+
+ +
+
+test_add_parameter_in_hierarchy()[source]
+
+ +
+
+test_constraints()[source]
+
+ +
+
+test_constraints_in_init()[source]
+
+ +
+ +
+ +
+
+test_constraints_views()[source]
+
+ +
+
+test_default_constraints()[source]
+
+ +
+
+test_fix_unfix()[source]
+
+ +
+
+test_fixes()[source]
+
+ +
+
+test_fixing_optimize()[source]
+
+ +
+
+test_fixing_randomize()[source]
+
+ +
+
+test_fixing_randomize_parameter_handling()[source]
+
+ +
+
+test_parameter_modify_in_init()[source]
+
+ +
+
+test_printing()[source]
+
+ +
+
+test_randomize()[source]
+
+ +
+
+test_regular_expression_misc()[source]
+
+ +
+
+test_remove_parameter()[source]
+
+ +
+
+test_remove_parameter_param_array_grad_array()[source]
+
+ +
+
+test_updates()[source]
+
+ +
+ +
+
+

GPy.testing.pickle_tests module

+

Created on 13 Mar 2014

+

@author: maxz

+
+
+class GPy.testing.pickle_tests.ListDictTestCase(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+assertArrayListEquals(l1, l2)[source]
+
+ +
+
+assertListDictEquals(d1, d2, msg=None)[source]
+
+ +
+ +
+
+class GPy.testing.pickle_tests.Test(methodName='runTest')[source]
+

Bases: GPy.testing.pickle_tests.ListDictTestCase

+
+
+test_add_observer(test_item)
+
+ +
+
+test_model()[source]
+
+ +
+
+test_model_concat()[source]
+
+ +
+
+test_modelrecreation()[source]
+
+ +
+
+test_observable_array()[source]
+
+ +
+
+test_param()[source]
+
+ +
+
+test_parameter_index_operations()[source]
+
+ +
+
+test_parameterized()[source]
+
+ +
+
+test_posterior()[source]
+
+ +
+ +
+
+GPy.testing.pickle_tests.toy_model()[source]
+
+ +
+
+

GPy.testing.prior_tests module

+
+
+class GPy.testing.prior_tests.PriorTests(methodName='runTest')[source]
+

Bases: unittest.case.TestCase

+
+
+test_Gamma()[source]
+
+ +
+
+test_fixed_domain_check()[source]
+
+ +
+
+test_fixed_domain_check1()[source]
+
+ +
+
+test_incompatibility()[source]
+
+ +
+
+test_lognormal()[source]
+
+ +
+
+test_set_gaussian_for_reals()[source]
+
+ +
+
+test_set_prior()[source]
+
+ +
+ +
+
+

Module contents

+

MaxZ

+
+
+GPy.testing.deepTest(reason)[source]
+
+ +
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/GPy.util.html b/doc/_build/html/GPy.util.html new file mode 100644 index 00000000..d057ac00 --- /dev/null +++ b/doc/_build/html/GPy.util.html @@ -0,0 +1,2085 @@ + + + + + + + + GPy.util package — GPy documentation + + + + + + + + + + + + + + + +
+
+
+
+ +
+

GPy.util package

+
+

Submodules

+
+
+

GPy.util.block_matrices module

+
+
+GPy.util.block_matrices.get_blocks(A, blocksizes)[source]
+
+ +
+
+

GPy.util.caching module

+
+
+class GPy.util.caching.Cache_this(limit=5, ignore_args=(), force_kwargs=())[source]
+

Bases: object

+

A decorator which can be applied to bound methods in order to cache them

+
+ +
+
+class GPy.util.caching.Cacher(operation, limit=5, ignore_args=(), force_kwargs=())[source]
+

Bases: object

+
+
+add_to_cache(cache_id, inputs, output)[source]
+

This adds cache_id to the cache, with inputs and output

+
+ +
+
+combine_inputs(args, kw, ignore_args)[source]
+

Combines the args and kw in a unique way, such that ordering of kwargs does not lead to recompute

+
+ +
+
+ensure_cache_length(cache_id)[source]
+

Ensures the cache is within its limits and has one place free

+
+ +
+
+id(obj)[source]
+

returns the self.id of an object, to be used in caching individual self.ids

+
+ +
+
+on_cache_changed(direct, which=None)[source]
+

A callback funtion, which sets local flags when the elements of some cached inputs change

+

this function gets ‘hooked up’ to the inputs when we cache them, and upon their elements being changed we update here.

+
+ +
+
+prepare_cache_id(combined_args_kw)[source]
+

get the cacheid (conc. string of argument self.ids in order)

+
+ +
+
+reset()[source]
+

Totally reset the cache

+
+ +
+ +
+
+class GPy.util.caching.Cacher_wrap(f, limit, ignore_args, force_kwargs)[source]
+

Bases: object

+
+ +
+
+

GPy.util.classification module

+
+
+GPy.util.classification.conf_matrix(p, labels, names=['1', '0'], threshold=0.5, show=True)[source]
+

Returns error rate and true/false positives in a binary classification problem +- Actual classes are displayed by column. +- Predicted classes are displayed by row.

+ +++ + + + +
Parameters:
    +
  • p – array of class ‘1’ probabilities.
  • +
  • labels – array of actual classes.
  • +
  • names – list of class names, defaults to [‘1’,‘0’].
  • +
  • threshold – probability value used to decide the class.
  • +
  • show (False|True) – whether the matrix should be shown or not
  • +
+
+
+ +
+
+

GPy.util.config module

+
+
+

GPy.util.datasets module

+
+
+GPy.util.datasets.authorize_download(dataset_name=None)[source]
+

Check with the user that the are happy with terms and conditions for the data set.

+
+ +
+
+GPy.util.datasets.boston_housing(data_set='boston_housing')[source]
+
+ +
+
+GPy.util.datasets.boxjenkins_airline(data_set='boxjenkins_airline', num_train=96)[source]
+
+ +
+
+GPy.util.datasets.brendan_faces(data_set='brendan_faces')[source]
+
+ +
+
+GPy.util.datasets.cifar10_patches(data_set='cifar-10')[source]
+

The Candian Institute for Advanced Research 10 image data set. Code for loading in this data is taken from this Boris Babenko’s blog post, original code available here: http://bbabenko.tumblr.com/post/86756017649/learning-low-level-vision-feautres-in-10-lines-of-code

+
+ +
+
+GPy.util.datasets.cmu_mocap(subject, train_motions, test_motions=[], sample_every=4, data_set='cmu_mocap')[source]
+

Load a given subject’s training and test motions from the CMU motion capture data.

+
+ +
+
+GPy.util.datasets.cmu_mocap_35_walk_jog(data_set='cmu_mocap')[source]
+

Load CMU subject 35’s walking and jogging motions, the same data that was used by Taylor, Roweis and Hinton at NIPS 2007. but without their preprocessing. Also used by Lawrence at AISTATS 2007.

+
+ +
+
+GPy.util.datasets.cmu_mocap_49_balance(data_set='cmu_mocap')[source]
+

Load CMU subject 49’s one legged balancing motion that was used by Alvarez, Luengo and Lawrence at AISTATS 2009.

+
+ +
+
+GPy.util.datasets.cmu_urls_files(subj_motions, messages=True)[source]
+

Find which resources are missing on the local disk for the requested CMU motion capture motions.

+
+ +
+
+GPy.util.datasets.creep_data(data_set='creep_rupture')[source]
+

Brun and Yoshida’s metal creep rupture data.

+
+ +
+
+GPy.util.datasets.crescent_data(num_data=200, seed=10000)[source]
+

Data set formed from a mixture of four Gaussians. In each class two of the Gaussians are elongated at right angles to each other and offset to form an approximation to the crescent data that is popular in semi-supervised learning as a toy problem.

+
+
+++ + + + + + + + + + + +
param num_data_part:
 number of data to be sampled (default is 200).
type num_data:int
param seed:random seed to be used for data generation.
type seed:int
+
+
+ +
+
+GPy.util.datasets.data_available(dataset_name=None)[source]
+

Check if the data set is available on the local machine already.

+
+ +
+
+GPy.util.datasets.data_details_return(data, data_set)[source]
+

Update the data component of the data dictionary with details drawn from the data_resources.

+
+ +
+
+GPy.util.datasets.decampos_digits(data_set='decampos_characters', which_digits=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])[source]
+
+ +
+
+GPy.util.datasets.della_gatta_TRP63_gene_expression(data_set='della_gatta', gene_number=None)[source]
+
+ +
+
+GPy.util.datasets.download_data(dataset_name=None)[source]
+

Check with the user that the are happy with terms and conditions for the data set, then download it.

+
+ +
+
+GPy.util.datasets.download_rogers_girolami_data(data_set='rogers_girolami_data')[source]
+
+ +
+
+GPy.util.datasets.download_url(url, store_directory, save_name=None, messages=True, suffix='')[source]
+

Download a file from a url and save it to disk.

+
+ +
+
+GPy.util.datasets.drosophila_knirps(data_set='drosophila_protein')[source]
+
+ +
+
+GPy.util.datasets.drosophila_protein(data_set='drosophila_protein')[source]
+
+ +
+
+GPy.util.datasets.football_data(season='1314', data_set='football_data')[source]
+

Football data from English games since 1993. This downloads data from football-data.co.uk for the given season.

+
+ +
+
+GPy.util.datasets.fruitfly_tomancak(data_set='fruitfly_tomancak', gene_number=None)[source]
+
+ +
+
+GPy.util.datasets.global_average_temperature(data_set='global_temperature', num_train=1000, refresh_data=False)[source]
+
+ +
+ +

Data downloaded from Google trends for given query terms. Warning, if you use this function multiple times in a row you get blocked due to terms of service violations. The function will cache the result of your query, if you wish to refresh an old query set refresh_data to True. The function is inspired by this notebook: http://nbviewer.ipython.org/github/sahuguet/notebooks/blob/master/GoogleTrends%20meet%20Notebook.ipynb

+
+ +
+
+GPy.util.datasets.hapmap3(data_set='hapmap3')[source]
+

The HapMap phase three SNP dataset - 1184 samples out of 11 populations.

+

SNP_matrix (A) encoding [see Paschou et all. 2007 (PCA-Correlated SNPs...)]: +Let (B1,B2) be the alphabetically sorted bases, which occur in the j-th SNP, then

+
+
/ 1, iff SNPij==(B1,B1)
+
+
Aij = | 0, iff SNPij==(B1,B2)
+
-1, iff SNPij==(B2,B2)
+
+

The SNP data and the meta information (such as iid, sex and phenotype) are +stored in the dataframe datadf, index is the Individual ID, +with following columns for metainfo:

+
+
    +
  • family_id -> Family ID
  • +
  • paternal_id -> Paternal ID
  • +
  • maternal_id -> Maternal ID
  • +
  • sex -> Sex (1=male; 2=female; other=unknown)
  • +
  • phenotype -> Phenotype (-9, or 0 for unknown)
  • +
  • population -> Population string (e.g. ‘ASW’ - ‘YRI’)
  • +
  • rest are SNP rs (ids)
  • +
+
+

More information is given in infodf:

+
+
    +
  • +
    Chromosome:
    +
      +
    • autosomal chromosemes -> 1-22
    • +
    • X X chromosome -> 23
    • +
    • Y Y chromosome -> 24
    • +
    • XY Pseudo-autosomal region of X -> 25
    • +
    • MT Mitochondrial -> 26
    • +
    +
    +
    +
  • +
  • Relative Positon (to Chromosome) [base pairs]

    +
  • +
+
+
+ +
+
+GPy.util.datasets.isomap_faces(num_samples=698, data_set='isomap_face_data')[source]
+
+ +
+
+GPy.util.datasets.lee_yeast_ChIP(data_set='lee_yeast_ChIP')[source]
+
+ +
+
+GPy.util.datasets.mauna_loa(data_set='mauna_loa', num_train=545, refresh_data=False)[source]
+
+ +
+
+GPy.util.datasets.oil(data_set='three_phase_oil_flow')[source]
+

The three phase oil data from Bishop and James (1993).

+
+ +
+
+GPy.util.datasets.oil_100(seed=10000, data_set='three_phase_oil_flow')[source]
+
+ +
+
+GPy.util.datasets.olivetti_faces(data_set='olivetti_faces')[source]
+
+ +
+
+GPy.util.datasets.olivetti_glasses(data_set='olivetti_glasses', num_training=200, seed=10000)[source]
+
+ +
+
+GPy.util.datasets.olympic_100m_men(data_set='rogers_girolami_data')[source]
+
+ +
+
+GPy.util.datasets.olympic_100m_women(data_set='rogers_girolami_data')[source]
+
+ +
+
+GPy.util.datasets.olympic_200m_men(data_set='rogers_girolami_data')[source]
+
+ +
+
+GPy.util.datasets.olympic_200m_women(data_set='rogers_girolami_data')[source]
+
+ +
+
+GPy.util.datasets.olympic_400m_men(data_set='rogers_girolami_data')[source]
+
+ +
+
+GPy.util.datasets.olympic_400m_women(data_set='rogers_girolami_data')[source]
+
+ +
+
+GPy.util.datasets.olympic_marathon_men(data_set='olympic_marathon_men')[source]
+
+ +
+
+GPy.util.datasets.olympic_sprints(data_set='rogers_girolami_data')[source]
+

All olympics sprint winning times for multiple output prediction.

+
+ +
+
+GPy.util.datasets.osu_run1(data_set='osu_run1', sample_every=4)[source]
+
+ +
+
+GPy.util.datasets.prompt_user(prompt)[source]
+

Ask user for agreeing to data set licenses.

+
+ +
+
+GPy.util.datasets.pumadyn(seed=10000, data_set='pumadyn-32nm')[source]
+
+ +
+
+GPy.util.datasets.reporthook(a, b, c)[source]
+
+ +
+
+GPy.util.datasets.ripley_synth(data_set='ripley_prnn_data')[source]
+
+ +
+
+GPy.util.datasets.robot_wireless(data_set='robot_wireless')[source]
+
+ +
+
+GPy.util.datasets.sample_class(f)[source]
+
+ +
+
+GPy.util.datasets.silhouette(data_set='ankur_pose_data')[source]
+
+ +
+
+GPy.util.datasets.simulation_BGPLVM()[source]
+
+ +
+
+GPy.util.datasets.singlecell(data_set='singlecell')[source]
+
+ +
+
+GPy.util.datasets.singlecell_rna_seq_deng(dataset='singlecell_deng')[source]
+
+ +
+
+GPy.util.datasets.singlecell_rna_seq_islam(dataset='singlecell_islam')[source]
+
+ +
+
+GPy.util.datasets.sod1_mouse(data_set='sod1_mouse')[source]
+
+ +
+
+GPy.util.datasets.spellman_yeast(data_set='spellman_yeast')[source]
+
+ +
+
+GPy.util.datasets.spellman_yeast_cdc15(data_set='spellman_yeast')[source]
+
+ +
+
+GPy.util.datasets.swiss_roll(num_samples=3000, data_set='swiss_roll')[source]
+
+ +
+
+GPy.util.datasets.swiss_roll_1000()[source]
+
+ +
+
+GPy.util.datasets.swiss_roll_generated(num_samples=1000, sigma=0.0)[source]
+
+ +
+
+GPy.util.datasets.toy_linear_1d_classification(seed=10000)[source]
+
+ +
+
+GPy.util.datasets.toy_rbf_1d(seed=10000, num_samples=500)[source]
+

Samples values of a function from an RBF covariance with very small noise for inputs uniformly distributed between -1 and 1.

+ +++ + + + +
Parameters:
    +
  • seed (int) – seed to use for random sampling.
  • +
  • num_samples (int) – number of samples to sample in the function (default 500).
  • +
+
+
+ +
+
+GPy.util.datasets.toy_rbf_1d_50(seed=10000)[source]
+
+ +
+
+GPy.util.datasets.xw_pen(data_set='xw_pen')[source]
+
+ +
+
+

GPy.util.debug module

+

The module for some general debug tools

+
+
+GPy.util.debug.checkFinite(arr, name=None)[source]
+
+ +
+
+GPy.util.debug.checkFullRank(m, tol=1e-10, name=None, force_check=False)[source]
+
+ +
+
+

GPy.util.decorators module

+
+
+GPy.util.decorators.silence_errors(f)[source]
+

This wraps a function and it silences numpy errors that +happen during the execution. After the function has exited, it restores +the previous state of the warnings.

+
+ +
+
+

GPy.util.diag module

+
+
+GPy.util.diag.add(A, b, offset=0)[source]
+

Add b to the view of A in place (!). +Returns modified A. +Broadcasting is allowed, thus b can be scalar.

+

if offset is not zero, make sure b is of right shape!

+ +++ + + + + + +
Parameters:
    +
  • A (ndarray) – 2 dimensional array
  • +
  • b (ndarray-like) – either one dimensional or scalar
  • +
  • offset (int) – same as in view.
  • +
+
Return type:

view of A, which is adjusted inplace

+
+
+ +
+
+GPy.util.diag.divide(A, b, offset=0)[source]
+

Divide the view of A by b in place (!). +Returns modified A +Broadcasting is allowed, thus b can be scalar.

+

if offset is not zero, make sure b is of right shape!

+ +++ + + + + + +
Parameters:
    +
  • A (ndarray) – 2 dimensional array
  • +
  • b (ndarray-like) – either one dimensional or scalar
  • +
  • offset (int) – same as in view.
  • +
+
Return type:

view of A, which is adjusted inplace

+
+
+ +
+
+GPy.util.diag.multiply(A, b, offset=0)
+

Times the view of A with b in place (!). +Returns modified A +Broadcasting is allowed, thus b can be scalar.

+

if offset is not zero, make sure b is of right shape!

+ +++ + + + + + +
Parameters:
    +
  • A (ndarray) – 2 dimensional array
  • +
  • b (ndarray-like) – either one dimensional or scalar
  • +
  • offset (int) – same as in view.
  • +
+
Return type:

view of A, which is adjusted inplace

+
+
+ +
+
+GPy.util.diag.offdiag_view(A, offset=0)[source]
+
+ +
+
+GPy.util.diag.subtract(A, b, offset=0)[source]
+

Subtract b from the view of A in place (!). +Returns modified A. +Broadcasting is allowed, thus b can be scalar.

+

if offset is not zero, make sure b is of right shape!

+ +++ + + + + + +
Parameters:
    +
  • A (ndarray) – 2 dimensional array
  • +
  • b (ndarray-like) – either one dimensional or scalar
  • +
  • offset (int) – same as in view.
  • +
+
Return type:

view of A, which is adjusted inplace

+
+
+ +
+
+GPy.util.diag.times(A, b, offset=0)[source]
+

Times the view of A with b in place (!). +Returns modified A +Broadcasting is allowed, thus b can be scalar.

+

if offset is not zero, make sure b is of right shape!

+ +++ + + + + + +
Parameters:
    +
  • A (ndarray) – 2 dimensional array
  • +
  • b (ndarray-like) – either one dimensional or scalar
  • +
  • offset (int) – same as in view.
  • +
+
Return type:

view of A, which is adjusted inplace

+
+
+ +
+
+GPy.util.diag.view(A, offset=0)[source]
+

Get a view on the diagonal elements of a 2D array.

+

This is actually a view (!) on the diagonal of the array, so you can +in-place adjust the view.

+

:param ndarray A: 2 dimensional numpy array +:param int offset: view offset to give back (negative entries allowed) +:rtype: ndarray view of diag(A)

+
>>> import numpy as np
+>>> X = np.arange(9).reshape(3,3)
+>>> view(X)
+array([0, 4, 8])
+>>> d = view(X)
+>>> d += 2
+>>> view(X)
+array([ 2,  6, 10])
+>>> view(X, offset=-1)
+array([3, 7])
+>>> subtract(X, 3, offset=-1)
+array([[ 2,  1,  2],
+       [ 0,  6,  5],
+       [ 6,  4, 10]])
+
+
+
+ +
+
+

GPy.util.erfcx module

+
+
+GPy.util.erfcx.erfcx(arg)[source]
+
+ +
+
+

GPy.util.functions module

+
+
+GPy.util.functions.clip_exp(x)[source]
+
+ +
+
+GPy.util.functions.differfln(x0, x1)[source]
+
+ +
+
+GPy.util.functions.logistic(x)[source]
+
+ +
+
+GPy.util.functions.logisticln(x)[source]
+
+ +
+
+GPy.util.functions.normcdf(x)[source]
+
+ +
+
+GPy.util.functions.normcdfln(x)[source]
+
+ +
+
+

GPy.util.gpu_init module

+

The package for scikits.cuda initialization

+

Global variables: initSuccess +providing CUBLAS handle: cublas_handle

+
+
+GPy.util.gpu_init.closeGPU()[source]
+
+ +
+
+

GPy.util.initialization module

+

Created on 24 Feb 2014

+

@author: maxz

+
+
+GPy.util.initialization.initialize_latent(init, input_dim, Y)[source]
+
+ +
+
+

GPy.util.linalg module

+
+
+GPy.util.linalg.DSYR(*args, **kwargs)[source]
+
+ +
+
+GPy.util.linalg.DSYR_blas(A, x, alpha=1.0)[source]
+

Performs a symmetric rank-1 update operation: +A <- A + alpha * np.dot(x,x.T)

+ +++ + + + +
Parameters:
    +
  • A – Symmetric NxN np.array
  • +
  • x – Nx1 np.array
  • +
  • alpha – scalar
  • +
+
+
+ +
+
+GPy.util.linalg.DSYR_numpy(A, x, alpha=1.0)[source]
+

Performs a symmetric rank-1 update operation: +A <- A + alpha * np.dot(x,x.T)

+ +++ + + + +
Parameters:
    +
  • A – Symmetric NxN np.array
  • +
  • x – Nx1 np.array
  • +
  • alpha – scalar
  • +
+
+
+ +
+
+GPy.util.linalg.backsub_both_sides(L, X, transpose='left')[source]
+

Return L^-T * X * L^-1, assumuing X is symmetrical and L is lower cholesky

+
+ +
+
+GPy.util.linalg.cholupdate(L, x)[source]
+

update the LOWER cholesky factor of a pd matrix IN PLACE

+

if L is the lower chol. of K, then this function computes L_ +where L_ is the lower chol of K + x*x^T

+
+ +
+
+GPy.util.linalg.dpotri(A, lower=1)[source]
+

Wrapper for lapack dpotri function

+
+
DPOTRI - compute the inverse of a real symmetric positive
+
definite matrix A using the Cholesky factorization A = +U**T*U or A = L*L**T computed by DPOTRF
+
+ +++ + + + + + +
Parameters:
    +
  • A – Matrix A
  • +
  • lower – is matrix lower (true) or upper (false)
  • +
+
Returns:

A inverse

+
+
+ +
+
+GPy.util.linalg.dpotrs(A, B, lower=1)[source]
+

Wrapper for lapack dpotrs function +:param A: Matrix A +:param B: Matrix B +:param lower: is matrix lower (true) or upper (false) +:returns:

+
+ +
+
+GPy.util.linalg.dtrtri(L)[source]
+

Inverts a Cholesky lower triangular matrix

+ +++ + + + + + +
Parameters:L – lower triangular matrix
Return type:inverse of L
+
+ +
+
+GPy.util.linalg.dtrtrs(A, B, lower=1, trans=0, unitdiag=0)[source]
+

Wrapper for lapack dtrtrs function

+

DTRTRS solves a triangular system of the form

+
+
A * X = B or A**T * X = B,
+

where A is a triangular matrix of order N, and B is an N-by-NRHS +matrix. A check is made to verify that A is nonsingular.

+ +++ + + + + + +
Parameters:
    +
  • A – Matrix A(triangular)
  • +
  • B – Matrix B
  • +
  • lower – is matrix lower (true) or upper (false)
  • +
+
Returns:

Solution to A * X = B or A**T * X = B

+
+
+ +
+
+GPy.util.linalg.force_F_ordered(A)[source]
+

return a F ordered version of A, assuming A is triangular

+
+ +
+
+GPy.util.linalg.force_F_ordered_symmetric(A)[source]
+

return a F ordered version of A, assuming A is symmetric

+
+ +
+
+GPy.util.linalg.jitchol(A, maxtries=5)[source]
+
+ +
+
+GPy.util.linalg.mdot(*args)[source]
+

Multiply all the arguments using matrix product rules. +The output is equivalent to multiplying the arguments one by one +from left to right using dot(). +Precedence can be controlled by creating tuples of arguments, +for instance mdot(a,((b,c),d)) multiplies a (a*((b*c)*d)). +Note that this means the output of dot(a,b) and mdot(a,b) will differ if +a or b is a pure tuple of numbers.

+
+ +
+
+GPy.util.linalg.multiple_pdinv(A)[source]
+
+++ + + + + + + + + + + + +
Parameters:A – A DxDxN numpy array (each A[:,:,i] is pd)
Rval invs:the inverses of A
Rtype invs:np.ndarray
Rval hld:0.5* the log of the determinants of A
Rtype hld:np.array
+
+ +
+
+GPy.util.linalg.pca(Y, input_dim)[source]
+

Principal component analysis: maximum likelihood solution by SVD

+ +++ + + + + + + + +
Parameters:
    +
  • Y – NxD np.array of data
  • +
  • input_dim – int, dimension of projection
  • +
+
Rval X:
    +
  • Nxinput_dim np.array of dimensionality reduced data
  • +
+
Rval W:
    +
  • input_dimxD mapping from X to Y
  • +
+
+
+ +
+
+GPy.util.linalg.pddet(A)[source]
+

Determinant of a positive definite matrix, only symmetric matricies though

+
+ +
+
+GPy.util.linalg.pdinv(A, *args)[source]
+
+++ + + + + + + + + + + + + + + + + + + + +
Parameters:A – A DxD pd numpy array
Rval Ai:the inverse of A
Rtype Ai:np.ndarray
Rval L:the Cholesky decomposition of A
Rtype L:np.ndarray
Rval Li:the Cholesky decomposition of Ai
Rtype Li:np.ndarray
Rval logdet:the log of the determinant of A
Rtype logdet:float64
+
+ +
+
+GPy.util.linalg.ppca(Y, Q, iterations=100)[source]
+

EM implementation for probabilistic pca.

+ +++ + + + +
Parameters:
    +
  • Y (array-like) – Observed Data
  • +
  • Q (int) – Dimensionality for reduced array
  • +
  • iterations (int) – number of iterations for EM
  • +
+
+
+ +
+
+GPy.util.linalg.symmetrify(A, upper=False)[source]
+

Take the square matrix A and make it symmetrical by copting elements from the lower half to the upper

+

works IN PLACE.

+

note: tries to use weave, falls back to a slower numpy version

+
+ +
+
+GPy.util.linalg.symmetrify_numpy(A, upper=False)[source]
+

Force a matrix to be symmetric

+
+ +
+
+GPy.util.linalg.symmetrify_weave(A, upper=False)[source]
+

Take the square matrix A and make it symmetrical by copting elements from the lower half to the upper

+

works IN PLACE.

+
+ +
+
+GPy.util.linalg.tdot(*args, **kwargs)[source]
+
+ +
+
+GPy.util.linalg.tdot_blas(mat, out=None)[source]
+

returns np.dot(mat, mat.T), but faster for large 2D arrays of doubles.

+
+ +
+
+GPy.util.linalg.tdot_numpy(mat, out=None)[source]
+
+ +
+
+GPy.util.linalg.trace_dot(a, b)[source]
+

Efficiently compute the trace of the matrix product of a and b

+
+ +
+
+

GPy.util.linalg_gpu module

+
+
+

GPy.util.ln_diff_erfs module

+
+
+GPy.util.ln_diff_erfs.ln_diff_erfs(x1, x2, return_sign=False)[source]
+

Function for stably computing the log of difference of two erfs in a numerically stable manner. +:param x1 : argument of the positive erf +:type x1: ndarray +:param x2 : argument of the negative erf +:type x2: ndarray +:return: tuple containing (log(abs(erf(x1) - erf(x2))), sign(erf(x1) - erf(x2)))

+

Based on MATLAB code that was written by Antti Honkela and modified by David Luengo and originally derived from code by Neil Lawrence.

+
+ +
+
+

GPy.util.misc module

+
+
+GPy.util.misc.chain_1(df_dg, dg_dx)[source]
+

Generic chaining function for first derivative

+
+

\frac{d(f . g)}{dx} = \frac{df}{dg} \frac{dg}{dx}

+
+ +
+
+GPy.util.misc.chain_2(d2f_dg2, dg_dx, df_dg, d2g_dx2)[source]
+

Generic chaining function for second derivative

+
+

\frac{d^{2}(f . g)}{dx^{2}} = \frac{d^{2}f}{dg^{2}}(\frac{dg}{dx})^{2} + \frac{df}{dg}\frac{d^{2}g}{dx^{2}}

+
+ +
+
+GPy.util.misc.chain_3(d3f_dg3, dg_dx, d2f_dg2, d2g_dx2, df_dg, d3g_dx3)[source]
+

Generic chaining function for third derivative

+
+

\frac{d^{3}(f . g)}{dx^{3}} = \frac{d^{3}f}{dg^{3}}(\frac{dg}{dx})^{3} + 3\frac{d^{2}f}{dg^{2}}\frac{dg}{dx}\frac{d^{2}g}{dx^{2}} + \frac{df}{dg}\frac{d^{3}g}{dx^{3}}

+
+ +
+
+GPy.util.misc.kmm_init(X, m=10)[source]
+

This is the same initialization algorithm that is used +in Kmeans++. It’s quite simple and very useful to initialize +the locations of the inducing points in sparse GPs.

+ +++ + + + +
Parameters:
    +
  • X – data
  • +
  • m – number of inducing points
  • +
+
+
+ +
+
+GPy.util.misc.linear_grid(D, n=100, min_max=(-100, 100))[source]
+

Creates a D-dimensional grid of n linearly spaced points

+ +++ + + + +
Parameters:
    +
  • D – dimension of the grid
  • +
  • n – number of points
  • +
  • min_max – (min, max) list
  • +
+
+
+ +
+
+GPy.util.misc.opt_wrapper(m, **kwargs)[source]
+

This function just wraps the optimization procedure of a GPy +object so that optimize() pickleable (necessary for multiprocessing).

+
+ +
+
+GPy.util.misc.param_to_array(*param)[source]
+

Convert an arbitrary number of parameters to :class:ndarray class objects. This is for +converting parameter objects to numpy arrays, when using scipy.weave.inline routine. +In scipy.weave.blitz there is no automatic array detection (even when the array inherits +from :class:ndarray)

+
+ +
+
+

GPy.util.mocap module

+
+
+class GPy.util.mocap.acclaim_skeleton(file_name=None)[source]
+

Bases: GPy.util.mocap.skeleton

+
+
+get_child_xyz(ind, channels)[source]
+
+ +
+
+load_channels(file_name)[source]
+
+ +
+
+load_skel(file_name)[source]
+

Loads an ASF file into a skeleton structure.

+ +++ + + + +
Parameters:file_name – The file name to load in.
+
+ +
+
+read_bonedata(fid)[source]
+

Read bone data from an acclaim skeleton file stream.

+
+ +
+
+read_channels(fid)[source]
+

Read channels from an acclaim file.

+
+ +
+
+read_documentation(fid)[source]
+

Read documentation from an acclaim skeleton file stream.

+
+ +
+
+read_hierarchy(fid)[source]
+

Read hierarchy information from acclaim skeleton file stream.

+
+ +
+
+read_line(fid)[source]
+

Read a line from a file string and check it isn’t either empty or commented before returning.

+
+ +
+
+read_root(fid)[source]
+

Read the root node from an acclaim skeleton file stream.

+
+ +
+
+read_skel(fid)[source]
+

Loads an acclaim skeleton format from a file stream.

+
+ +
+
+read_units(fid)[source]
+

Read units from an acclaim skeleton file stream.

+
+ +
+
+resolve_indices(index, start_val)[source]
+

Get indices for the skeleton from the channels when loading in channel data.

+
+ +
+
+set_rotation_matrices()[source]
+

Set the meta information at each vertex to contain the correct matrices C and Cinv as prescribed by the rotations and rotation orders.

+
+ +
+
+to_xyz(channels)[source]
+
+ +
+ +
+
+GPy.util.mocap.load_text_data(dataset, directory, centre=True)[source]
+

Load in a data set of marker points from the Ohio State University C3D motion capture files (http://accad.osu.edu/research/mocap/mocap_data.htm).

+
+ +
+
+GPy.util.mocap.parse_text(file_name)[source]
+

Parse data from Ohio State University text mocap files (http://accad.osu.edu/research/mocap/mocap_data.htm).

+
+ +
+
+GPy.util.mocap.read_connections(file_name, point_names)[source]
+

Read a file detailing which markers should be connected to which for motion capture data.

+
+ +
+
+GPy.util.mocap.rotation_matrix(xangle, yangle, zangle, order='zxy', degrees=False)[source]
+

Compute the rotation matrix for an angle in each direction. +This is a helper function for computing the rotation matrix for a given set of angles in a given order.

+ +++ + + + +
Parameters:
    +
  • xangle – rotation for x-axis.
  • +
  • yangle – rotation for y-axis.
  • +
  • zangle – rotation for z-axis.
  • +
  • order – the order for the rotations.
  • +
+
+
+ +
+
+class GPy.util.mocap.skeleton[source]
+

Bases: GPy.util.mocap.tree

+
+
+connection_matrix()[source]
+
+ +
+
+finalize()[source]
+

After loading in a skeleton ensure parents are correct, vertex orders are correct and rotation matrices are correct.

+
+ +
+
+smooth_angle_channels(channels)[source]
+

Remove discontinuities in angle channels so that they don’t cause artifacts in algorithms that rely on the smoothness of the functions.

+
+ +
+
+to_xyz(channels)[source]
+
+ +
+ +
+
+class GPy.util.mocap.tree[source]
+
+
+branch_str(index, indent='')[source]
+
+ +
+
+find_children()[source]
+

Take a tree and set the children according to the parents.

+

Takes a tree structure which lists the parents of each vertex +and computes the children for each vertex and places them in.

+
+ +
+
+find_parents()[source]
+

Take a tree and set the parents according to the children

+

Takes a tree structure which lists the children of each vertex +and computes the parents for each vertex and places them in.

+
+ +
+
+find_root()[source]
+

Finds the index of the root node of the tree.

+
+ +
+
+get_index_by_id(id)[source]
+

Give the index associated with a given vertex id.

+
+ +
+
+get_index_by_name(name)[source]
+

Give the index associated with a given vertex name.

+
+ +
+
+order_vertices()[source]
+

Order vertices in the graph such that parents always have a lower index than children.

+
+ +
+
+swap_vertices(i, j)[source]
+

Swap two vertices in the tree structure array. +swap_vertex swaps the location of two vertices in a tree structure array.

+ +++ + + + + + +
Parameters:
    +
  • tree – the tree for which two vertices are to be swapped.
  • +
  • i – the index of the first vertex to be swapped.
  • +
  • j – the index of the second vertex to be swapped.
  • +
+
Rval tree:

the tree structure with the two vertex locations swapped.

+
+
+ +
+ +
+
+class GPy.util.mocap.vertex(name, id, parents=[], children=[], meta={})[source]
+
+ +
+
+

GPy.util.mpi module

+
+
+

GPy.util.multioutput module

+
+
+GPy.util.multioutput.ICM(input_dim, num_outputs, kernel, W_rank=1, W=None, kappa=None, name='ICM')[source]
+

Builds a kernel for an Intrinsic Coregionalization Model

+ +++ + + + + + + + +
Input_dim:

Input dimensionality (does not include dimension of indices)

+
Num_outputs:

Number of outputs

+
Parameters:
    +
  • kernel (a GPy kernel) – kernel that will be multiplied by the coregionalize kernel (matrix B).
  • +
  • W_rank (integer) – number tuples of the corregionalization parameters ‘W’
  • +
+
+
+ +
+
+GPy.util.multioutput.LCM(input_dim, num_outputs, kernels_list, W_rank=1, name='ICM')[source]
+

Builds a kernel for an Linear Coregionalization Model

+ +++ + + + + + + + +
Input_dim:

Input dimensionality (does not include dimension of indices)

+
Num_outputs:

Number of outputs

+
Parameters:
    +
  • kernel (a GPy kernel) – kernel that will be multiplied by the coregionalize kernel (matrix B).
  • +
  • W_rank (integer) – number tuples of the corregionalization parameters ‘W’
  • +
+
+
+ +
+
+GPy.util.multioutput.Private(input_dim, num_outputs, kernel, output, kappa=None, name='X')[source]
+

Builds a kernel for an Intrinsic Coregionalization Model

+ +++ + + + + + + + +
Input_dim:

Input dimensionality

+
Num_outputs:

Number of outputs

+
Parameters:
    +
  • kernel (a GPy kernel) – kernel that will be multiplied by the coregionalize kernel (matrix B).
  • +
  • W_rank (integer) – number tuples of the corregionalization parameters ‘W’
  • +
+
+
+ +
+
+GPy.util.multioutput.build_XY(input_list, output_list=None, index=None)[source]
+
+ +
+
+GPy.util.multioutput.build_likelihood(Y_list, noise_index, likelihoods_list=None)[source]
+
+ +
+
+GPy.util.multioutput.get_slices(input_list)[source]
+
+ +
+
+

GPy.util.netpbmfile module

+

Read and write image data from respectively to Netpbm files.

+

This implementation follows the Netpbm format specifications at +http://netpbm.sourceforge.net/doc/. No gamma correction is performed.

+

The following image formats are supported: PBM (bi-level), PGM (grayscale), +PPM (color), PAM (arbitrary), XV thumbnail (RGB332, read-only).

+ +++ + + + + + + + +
Author:Christoph Gohlke
Organization:Laboratory for Fluorescence Dynamics, University of California, Irvine
Version:2013.01.18
+
+

Requirements

+ +
+
+

Examples

+
>>> im1 = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16)
+>>> imsave('_tmp.pgm', im1)
+>>> im2 = imread('_tmp.pgm')
+>>> assert numpy.all(im1 == im2)
+
+
+
+
+GPy.util.netpbmfile.imread(filename, *args, **kwargs)[source]
+

Return image data from Netpbm file as numpy array.

+

args and kwargs are arguments to NetpbmFile.asarray().

+
>>> image = imread('_tmp.pgm')
+
+
+
+ +
+
+GPy.util.netpbmfile.imsave(filename, data, maxval=None, pam=False)[source]
+

Write image data to Netpbm file.

+
>>> image = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16)
+>>> imsave('_tmp.pgm', image)
+
+
+
+ +
+
+class GPy.util.netpbmfile.NetpbmFile(arg=None, **kwargs)[source]
+

Bases: object

+

Read and write Netpbm PAM, PBM, PGM, PPM, files.

+
+
+asarray(copy=True, cache=False, **kwargs)[source]
+

Return image data from file as numpy array.

+
+ +
+
+close()[source]
+

Close open file. Future asarray calls might fail.

+
+ +
+
+write(arg, **kwargs)[source]
+

Write instance to file.

+
+ +
+ +
+
+
+

GPy.util.normalizer module

+

Created on Aug 27, 2014

+

@author: t-mazwie

+
+
+class GPy.util.normalizer.MeanNorm[source]
+

Bases: GPy.util.normalizer.Norm

+
+
+inverse_mean(X)[source]
+
+ +
+
+normalize(Y)[source]
+
+ +
+
+scale_by(Y)[source]
+
+ +
+
+scaled()[source]
+
+ +
+ +
+
+class GPy.util.normalizer.Norm[source]
+

Bases: object

+
+
+inverse_mean(X)[source]
+

Project the normalized object X into space of Y

+
+ +
+
+inverse_variance(var)[source]
+
+ +
+
+normalize(Y)[source]
+

Project Y into normalized space

+
+ +
+
+scale_by(Y)[source]
+

Use data matrix Y as normalization space to work in.

+
+ +
+
+scaled()[source]
+

Whether this Norm object has been initialized.

+
+ +
+ +
+
+

GPy.util.parallel module

+

The module of tools for parallelization (MPI)

+
+
+GPy.util.parallel.divide_data(datanum, rank, size)[source]
+
+ +
+
+

GPy.util.pca module

+

Created on 10 Sep 2012

+

@author: Max Zwiessele +@copyright: Max Zwiessele 2012

+
+
+class GPy.util.pca.PCA(X)[source]
+

Bases: object

+

PCA module with automatic primal/dual determination.

+
+
+center(X)[source]
+

Center X in PCA space.

+
+ +
+
+plot_2d(X, labels=None, s=20, marker='o', dimensions=(0, 1), ax=None, colors=None, fignum=None, cmap=None, **kwargs)[source]
+

Plot dimensions dimensions with given labels against each other in +PC space. Labels can be any sequence of labels of dimensions X.shape[0]. +Labels can be drawn with a subsequent call to legend()

+
+ +
+
+plot_fracs(Q=None, ax=None, fignum=None)[source]
+

Plot fractions of Eigenvalues sorted in descending order.

+
+ +
+
+project(X, Q=None)[source]
+

Project X into PCA space, defined by the Q highest eigenvalues. +Y = X dot V

+
+ +
+ +
+
+

GPy.util.squashers module

+
+
+GPy.util.squashers.sigmoid(x)[source]
+
+ +
+
+GPy.util.squashers.single_softmax(x)[source]
+
+ +
+
+GPy.util.squashers.softmax(x)[source]
+
+ +
+
+

GPy.util.subarray_and_sorting module

+
+
+GPy.util.subarray_and_sorting.common_subarrays(X, axis=0)[source]
+

Find common subarrays of 2 dimensional X, where axis is the axis to apply the search over. +Common subarrays are returned as a dictionary of <subarray, [index]> pairs, where +the subarray is a tuple representing the subarray and the index is the index +for the subarray in X, where index is the index to the remaining axis.

+

:param np.ndarray X: 2d array to check for common subarrays in +:param int axis: axis to apply subarray detection over.

+
+
When the index is 0, compare rows – columns, otherwise.
+

In a 2d array: +>>> import numpy as np +>>> X = np.zeros((3,6), dtype=bool) +>>> X[[1,1,1],[0,4,5]] = 1; X[1:,[2,3]] = 1 +>>> X +array([[False, False, False, False, False, False],

+
+
[ True, False, True, True, True, True], +[False, False, True, True, False, False]], dtype=bool)
+
>>> d = common_subarrays(X,axis=1)
+>>> len(d)
+3
+>>> X[:, d[tuple(X[:,0])]]
+array([[False, False, False],
+       [ True,  True,  True],
+       [False, False, False]], dtype=bool)
+>>> d[tuple(X[:,4])] == d[tuple(X[:,0])] == [0, 4, 5]
+True
+>>> d[tuple(X[:,1])]
+[1]
+
+
+
+ +
+
+

GPy.util.univariate_Gaussian module

+
+
+GPy.util.univariate_Gaussian.inv_std_norm_cdf(x)[source]
+

Inverse cumulative standard Gaussian distribution +Based on Winitzki, S. (2008)

+
+ +
+
+GPy.util.univariate_Gaussian.std_norm_cdf(x)[source]
+

Cumulative standard Gaussian distribution +Based on Abramowitz, M. and Stegun, I. (1970)

+
+ +
+
+GPy.util.univariate_Gaussian.std_norm_cdf_weave(x)[source]
+

Cumulative standard Gaussian distribution +Based on Abramowitz, M. and Stegun, I. (1970)

+

A weave implementation of std_norm_cdf, which is faster. this is unused, +because of the difficulties of a weave dependency. (see github issue #94)

+
+ +
+
+GPy.util.univariate_Gaussian.std_norm_pdf(x)[source]
+

Standard Gaussian density function

+
+ +
+
+

GPy.util.warping_functions module

+
+
+class GPy.util.warping_functions.TanhWarpingFunction(n_terms=3)[source]
+

Bases: GPy.util.warping_functions.WarpingFunction

+
+
+f(y, psi)[source]
+

transform y with f using parameter vector psi +psi = [[a,b,c]] +::math::f = sum_{terms} a * tanh(b*(y+c))

+
+ +
+
+f_inv(y, psi, iterations=10)[source]
+

calculate the numerical inverse of f

+ +++ + + + +
Parameters:iterations – number of N.R. iterations
+
+ +
+
+fgrad_y(y, psi, return_precalc=False)[source]
+

gradient of f w.r.t to y ([N x 1]) +returns: Nx1 vector of derivatives, unless return_precalc is true, +then it also returns the precomputed stuff

+
+ +
+
+fgrad_y_psi(y, psi, return_covar_chain=False)[source]
+

gradient of f w.r.t to y and psi

+

returns: NxIx3 tensor of partial derivatives

+
+ +
+ +
+
+class GPy.util.warping_functions.TanhWarpingFunction_d(n_terms=3)[source]
+

Bases: GPy.util.warping_functions.WarpingFunction

+
+
+f(y, psi)[source]
+

Transform y with f using parameter vector psi +psi = [[a,b,c]]

+

f = \sum_{terms} a * tanh(b*(y+c))

+
+ +
+
+f_inv(z, psi, max_iterations=1000, y=None)[source]
+

calculate the numerical inverse of f

+ +++ + + + +
Parameters:max_iterations – maximum number of N.R. iterations
+
+ +
+
+fgrad_y(y, psi, return_precalc=False)[source]
+

gradient of f w.r.t to y ([N x 1])

+ +++ + + + +
Returns:Nx1 vector of derivatives, unless return_precalc is true, then it also returns the precomputed stuff
+
+ +
+
+fgrad_y_psi(y, psi, return_covar_chain=False)[source]
+

gradient of f w.r.t to y and psi

+ +++ + + + +
Returns:NxIx4 tensor of partial derivatives
+
+ +
+ +
+
+class GPy.util.warping_functions.WarpingFunction[source]
+

Bases: object

+

abstract function for warping +z = f(y)

+
+
+f(y, psi)[source]
+

function transformation +y is a list of values (GP training data) of shpape [N,1]

+
+ +
+
+f_inv(z, psi)[source]
+

inverse function transformation

+
+ +
+
+fgrad_y(y, psi)[source]
+

gradient of f w.r.t to y

+
+ +
+
+fgrad_y_psi(y, psi)[source]
+

gradient of f w.r.t to y

+
+ +
+
+plot(psi, xmin, xmax)[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_images/math/07aad80690e06cd5a29e87d6e696222f9b3a2f39.png b/doc/_build/html/_images/math/07aad80690e06cd5a29e87d6e696222f9b3a2f39.png new file mode 100644 index 00000000..6eb978b5 Binary files /dev/null and b/doc/_build/html/_images/math/07aad80690e06cd5a29e87d6e696222f9b3a2f39.png differ diff --git a/doc/_build/html/_images/math/0b03b7b9ecad878eac8336d77abfce94453f7943.png b/doc/_build/html/_images/math/0b03b7b9ecad878eac8336d77abfce94453f7943.png new file mode 100644 index 00000000..6a6bd41f Binary files /dev/null and b/doc/_build/html/_images/math/0b03b7b9ecad878eac8336d77abfce94453f7943.png differ diff --git a/doc/_build/html/_images/math/0ee9a0a290af1db274c2ea2ef1cae298bc701ce4.png b/doc/_build/html/_images/math/0ee9a0a290af1db274c2ea2ef1cae298bc701ce4.png new file mode 100644 index 00000000..d8027a10 Binary files /dev/null and b/doc/_build/html/_images/math/0ee9a0a290af1db274c2ea2ef1cae298bc701ce4.png differ diff --git a/doc/_build/html/_images/math/112c6d94605f31bddb3f52529408cf14d2a03456.png b/doc/_build/html/_images/math/112c6d94605f31bddb3f52529408cf14d2a03456.png new file mode 100644 index 00000000..0ea5b7ae Binary files /dev/null and b/doc/_build/html/_images/math/112c6d94605f31bddb3f52529408cf14d2a03456.png differ diff --git a/doc/_build/html/_images/math/143f49a801c035369b4e0e7ca765346063e4686d.png b/doc/_build/html/_images/math/143f49a801c035369b4e0e7ca765346063e4686d.png new file mode 100644 index 00000000..f9bcb182 Binary files /dev/null and b/doc/_build/html/_images/math/143f49a801c035369b4e0e7ca765346063e4686d.png differ diff --git a/doc/_build/html/_images/math/153e15220d6bec90ed9f8e0c870c3c808eae75aa.png b/doc/_build/html/_images/math/153e15220d6bec90ed9f8e0c870c3c808eae75aa.png new file mode 100644 index 00000000..976b19a7 Binary files /dev/null and b/doc/_build/html/_images/math/153e15220d6bec90ed9f8e0c870c3c808eae75aa.png differ diff --git a/doc/_build/html/_images/math/1e2b408025f9da95787112c13a2e7401032a0063.png b/doc/_build/html/_images/math/1e2b408025f9da95787112c13a2e7401032a0063.png new file mode 100644 index 00000000..177aebf8 Binary files /dev/null and b/doc/_build/html/_images/math/1e2b408025f9da95787112c13a2e7401032a0063.png differ diff --git a/doc/_build/html/_images/math/1ee9c98e88e9896c1f62c6486c77b6a83231ccbc.png b/doc/_build/html/_images/math/1ee9c98e88e9896c1f62c6486c77b6a83231ccbc.png new file mode 100644 index 00000000..975f3e9e Binary files /dev/null and b/doc/_build/html/_images/math/1ee9c98e88e9896c1f62c6486c77b6a83231ccbc.png differ diff --git a/doc/_build/html/_images/math/21bfcdadd1abee6b044daaa51d5a195606ee453c.png b/doc/_build/html/_images/math/21bfcdadd1abee6b044daaa51d5a195606ee453c.png new file mode 100644 index 00000000..6f44a7e0 Binary files /dev/null and b/doc/_build/html/_images/math/21bfcdadd1abee6b044daaa51d5a195606ee453c.png differ diff --git a/doc/_build/html/_images/math/2520c5bbd4ca1928f464fd3873b10a9b0bde8c18.png b/doc/_build/html/_images/math/2520c5bbd4ca1928f464fd3873b10a9b0bde8c18.png new file mode 100644 index 00000000..2c01240a Binary files /dev/null and b/doc/_build/html/_images/math/2520c5bbd4ca1928f464fd3873b10a9b0bde8c18.png differ diff --git a/doc/_build/html/_images/math/26038e5468fa3f743e11b649cd49e30d4bf2d9aa.png b/doc/_build/html/_images/math/26038e5468fa3f743e11b649cd49e30d4bf2d9aa.png new file mode 100644 index 00000000..60fd6d13 Binary files /dev/null and b/doc/_build/html/_images/math/26038e5468fa3f743e11b649cd49e30d4bf2d9aa.png differ diff --git a/doc/_build/html/_images/math/26d17fb3a403d131bb3eef5cfb5c32587282b0d5.png b/doc/_build/html/_images/math/26d17fb3a403d131bb3eef5cfb5c32587282b0d5.png new file mode 100644 index 00000000..262e5952 Binary files /dev/null and b/doc/_build/html/_images/math/26d17fb3a403d131bb3eef5cfb5c32587282b0d5.png differ diff --git a/doc/_build/html/_images/math/2984fd9b4b48bc7212f5b97e2ffabbc4060cb544.png b/doc/_build/html/_images/math/2984fd9b4b48bc7212f5b97e2ffabbc4060cb544.png new file mode 100644 index 00000000..fa2ff21c Binary files /dev/null and b/doc/_build/html/_images/math/2984fd9b4b48bc7212f5b97e2ffabbc4060cb544.png differ diff --git a/doc/_build/html/_images/math/30b07cfe9d64b0e6d96edc415ebaaf936b5820ca.png b/doc/_build/html/_images/math/30b07cfe9d64b0e6d96edc415ebaaf936b5820ca.png new file mode 100644 index 00000000..8a36e2a2 Binary files /dev/null and b/doc/_build/html/_images/math/30b07cfe9d64b0e6d96edc415ebaaf936b5820ca.png differ diff --git a/doc/_build/html/_images/math/36ad6994800a13c9387535b07ae468a4784b120d.png b/doc/_build/html/_images/math/36ad6994800a13c9387535b07ae468a4784b120d.png new file mode 100644 index 00000000..de055027 Binary files /dev/null and b/doc/_build/html/_images/math/36ad6994800a13c9387535b07ae468a4784b120d.png differ diff --git a/doc/_build/html/_images/math/3a68be8ed48ce0799d2da0027b48dfc94dade8d3.png b/doc/_build/html/_images/math/3a68be8ed48ce0799d2da0027b48dfc94dade8d3.png new file mode 100644 index 00000000..e392d187 Binary files /dev/null and b/doc/_build/html/_images/math/3a68be8ed48ce0799d2da0027b48dfc94dade8d3.png differ diff --git a/doc/_build/html/_images/math/3c943d4fc1aea61edc8246a049f058483725f902.png b/doc/_build/html/_images/math/3c943d4fc1aea61edc8246a049f058483725f902.png new file mode 100644 index 00000000..d6b9a89b Binary files /dev/null and b/doc/_build/html/_images/math/3c943d4fc1aea61edc8246a049f058483725f902.png differ diff --git a/doc/_build/html/_images/math/3eccf5d08b634e400733f5568da0e3d0c64383ac.png b/doc/_build/html/_images/math/3eccf5d08b634e400733f5568da0e3d0c64383ac.png new file mode 100644 index 00000000..9ee5f1d9 Binary files /dev/null and b/doc/_build/html/_images/math/3eccf5d08b634e400733f5568da0e3d0c64383ac.png differ diff --git a/doc/_build/html/_images/math/4069809108e9e054f33c34a3a488f6f65caf7c59.png b/doc/_build/html/_images/math/4069809108e9e054f33c34a3a488f6f65caf7c59.png new file mode 100644 index 00000000..d893b62c Binary files /dev/null and b/doc/_build/html/_images/math/4069809108e9e054f33c34a3a488f6f65caf7c59.png differ diff --git a/doc/_build/html/_images/math/42ecdfc10af100dfbbc3ec3b19efda0433ba1580.png b/doc/_build/html/_images/math/42ecdfc10af100dfbbc3ec3b19efda0433ba1580.png new file mode 100644 index 00000000..b865ad86 Binary files /dev/null and b/doc/_build/html/_images/math/42ecdfc10af100dfbbc3ec3b19efda0433ba1580.png differ diff --git a/doc/_build/html/_images/math/4323a5c5edaef294453f24e767d1772c0bc233ca.png b/doc/_build/html/_images/math/4323a5c5edaef294453f24e767d1772c0bc233ca.png new file mode 100644 index 00000000..f8a3b011 Binary files /dev/null and b/doc/_build/html/_images/math/4323a5c5edaef294453f24e767d1772c0bc233ca.png differ diff --git a/doc/_build/html/_images/math/437f2299194c0bf019dd646a9e9c76092e57d919.png b/doc/_build/html/_images/math/437f2299194c0bf019dd646a9e9c76092e57d919.png new file mode 100644 index 00000000..6a8d0220 Binary files /dev/null and b/doc/_build/html/_images/math/437f2299194c0bf019dd646a9e9c76092e57d919.png differ diff --git a/doc/_build/html/_images/math/4533f6b5623760a1facf22800afd4214b73538b0.png b/doc/_build/html/_images/math/4533f6b5623760a1facf22800afd4214b73538b0.png new file mode 100644 index 00000000..ae3f45a4 Binary files /dev/null and b/doc/_build/html/_images/math/4533f6b5623760a1facf22800afd4214b73538b0.png differ diff --git a/doc/_build/html/_images/math/4b19c5c53c58678e9292c8e646b72103694e99f2.png b/doc/_build/html/_images/math/4b19c5c53c58678e9292c8e646b72103694e99f2.png new file mode 100644 index 00000000..b1343c71 Binary files /dev/null and b/doc/_build/html/_images/math/4b19c5c53c58678e9292c8e646b72103694e99f2.png differ diff --git a/doc/_build/html/_images/math/4c7d40be0b140d6249e2761f424632441eb1f475.png b/doc/_build/html/_images/math/4c7d40be0b140d6249e2761f424632441eb1f475.png new file mode 100644 index 00000000..254c158f Binary files /dev/null and b/doc/_build/html/_images/math/4c7d40be0b140d6249e2761f424632441eb1f475.png differ diff --git a/doc/_build/html/_images/math/4cd3f22296f0a10cf5a10a200669957cf04dc550.png b/doc/_build/html/_images/math/4cd3f22296f0a10cf5a10a200669957cf04dc550.png new file mode 100644 index 00000000..b82c1f25 Binary files /dev/null and b/doc/_build/html/_images/math/4cd3f22296f0a10cf5a10a200669957cf04dc550.png differ diff --git a/doc/_build/html/_images/math/4f8a60521b12d9341a7d63d315e8c4d6d4944769.png b/doc/_build/html/_images/math/4f8a60521b12d9341a7d63d315e8c4d6d4944769.png new file mode 100644 index 00000000..3c4baf72 Binary files /dev/null and b/doc/_build/html/_images/math/4f8a60521b12d9341a7d63d315e8c4d6d4944769.png differ diff --git a/doc/_build/html/_images/math/4fbab675639838c2c3f11f9ad372ec258a842318.png b/doc/_build/html/_images/math/4fbab675639838c2c3f11f9ad372ec258a842318.png new file mode 100644 index 00000000..169212a0 Binary files /dev/null and b/doc/_build/html/_images/math/4fbab675639838c2c3f11f9ad372ec258a842318.png differ diff --git a/doc/_build/html/_images/math/508c8b33737f7c90395256d7c1efbfc68f346ce8.png b/doc/_build/html/_images/math/508c8b33737f7c90395256d7c1efbfc68f346ce8.png new file mode 100644 index 00000000..8e747f7a Binary files /dev/null and b/doc/_build/html/_images/math/508c8b33737f7c90395256d7c1efbfc68f346ce8.png differ diff --git a/doc/_build/html/_images/math/57f8e051e69685f0bad7e87ab3d5a189b1c713b6.png b/doc/_build/html/_images/math/57f8e051e69685f0bad7e87ab3d5a189b1c713b6.png new file mode 100644 index 00000000..733d7bde Binary files /dev/null and b/doc/_build/html/_images/math/57f8e051e69685f0bad7e87ab3d5a189b1c713b6.png differ diff --git a/doc/_build/html/_images/math/5821f26082a79756b532348fdc05c458a1b4d96c.png b/doc/_build/html/_images/math/5821f26082a79756b532348fdc05c458a1b4d96c.png new file mode 100644 index 00000000..1529b4e1 Binary files /dev/null and b/doc/_build/html/_images/math/5821f26082a79756b532348fdc05c458a1b4d96c.png differ diff --git a/doc/_build/html/_images/math/5a17c31c81502afdd1553e394d07efd32af07f80.png b/doc/_build/html/_images/math/5a17c31c81502afdd1553e394d07efd32af07f80.png new file mode 100644 index 00000000..d5ed2958 Binary files /dev/null and b/doc/_build/html/_images/math/5a17c31c81502afdd1553e394d07efd32af07f80.png differ diff --git a/doc/_build/html/_images/math/5d7004dd45c58bd71e97c825ae1e74559b30bfbd.png b/doc/_build/html/_images/math/5d7004dd45c58bd71e97c825ae1e74559b30bfbd.png new file mode 100644 index 00000000..50a88a44 Binary files /dev/null and b/doc/_build/html/_images/math/5d7004dd45c58bd71e97c825ae1e74559b30bfbd.png differ diff --git a/doc/_build/html/_images/math/5fb1ead7a3ae880faf3e493e050ee55a0e435038.png b/doc/_build/html/_images/math/5fb1ead7a3ae880faf3e493e050ee55a0e435038.png new file mode 100644 index 00000000..e7738c1a Binary files /dev/null and b/doc/_build/html/_images/math/5fb1ead7a3ae880faf3e493e050ee55a0e435038.png differ diff --git a/doc/_build/html/_images/math/604066808935cbbebeeb48a5590ae334a9511f26.png b/doc/_build/html/_images/math/604066808935cbbebeeb48a5590ae334a9511f26.png new file mode 100644 index 00000000..ed4b9c26 Binary files /dev/null and b/doc/_build/html/_images/math/604066808935cbbebeeb48a5590ae334a9511f26.png differ diff --git a/doc/_build/html/_images/math/61987fe37668cce0640009518e7aa9451c370b03.png b/doc/_build/html/_images/math/61987fe37668cce0640009518e7aa9451c370b03.png new file mode 100644 index 00000000..c7e46557 Binary files /dev/null and b/doc/_build/html/_images/math/61987fe37668cce0640009518e7aa9451c370b03.png differ diff --git a/doc/_build/html/_images/math/62acd55b473d8ea01ea4c1533bb6b4d9b652423a.png b/doc/_build/html/_images/math/62acd55b473d8ea01ea4c1533bb6b4d9b652423a.png new file mode 100644 index 00000000..c89bfc78 Binary files /dev/null and b/doc/_build/html/_images/math/62acd55b473d8ea01ea4c1533bb6b4d9b652423a.png differ diff --git a/doc/_build/html/_images/math/66e9ec52652f5885327c00676d9a4a1c4d4f7f47.png b/doc/_build/html/_images/math/66e9ec52652f5885327c00676d9a4a1c4d4f7f47.png new file mode 100644 index 00000000..600852cc Binary files /dev/null and b/doc/_build/html/_images/math/66e9ec52652f5885327c00676d9a4a1c4d4f7f47.png differ diff --git a/doc/_build/html/_images/math/67a3ca8b772a75e4d54fe3e40f9e567f00b66f2f.png b/doc/_build/html/_images/math/67a3ca8b772a75e4d54fe3e40f9e567f00b66f2f.png new file mode 100644 index 00000000..76c88a5c Binary files /dev/null and b/doc/_build/html/_images/math/67a3ca8b772a75e4d54fe3e40f9e567f00b66f2f.png differ diff --git a/doc/_build/html/_images/math/68a2d79b5ad6f38311ea4b1bc63bdbc4b67df02b.png b/doc/_build/html/_images/math/68a2d79b5ad6f38311ea4b1bc63bdbc4b67df02b.png new file mode 100644 index 00000000..7361b46c Binary files /dev/null and b/doc/_build/html/_images/math/68a2d79b5ad6f38311ea4b1bc63bdbc4b67df02b.png differ diff --git a/doc/_build/html/_images/math/68a7f1a9ea162f83dbb18eb5eeada4da9ec1805d.png b/doc/_build/html/_images/math/68a7f1a9ea162f83dbb18eb5eeada4da9ec1805d.png new file mode 100644 index 00000000..c1024f8e Binary files /dev/null and b/doc/_build/html/_images/math/68a7f1a9ea162f83dbb18eb5eeada4da9ec1805d.png differ diff --git a/doc/_build/html/_images/math/6b92b5aded6d4eb0dd8b17739862bf1d347d3ea3.png b/doc/_build/html/_images/math/6b92b5aded6d4eb0dd8b17739862bf1d347d3ea3.png new file mode 100644 index 00000000..95dbff52 Binary files /dev/null and b/doc/_build/html/_images/math/6b92b5aded6d4eb0dd8b17739862bf1d347d3ea3.png differ diff --git a/doc/_build/html/_images/math/7073988fc18d98dd1fa609563743c060408c44d5.png b/doc/_build/html/_images/math/7073988fc18d98dd1fa609563743c060408c44d5.png new file mode 100644 index 00000000..e6cd8da1 Binary files /dev/null and b/doc/_build/html/_images/math/7073988fc18d98dd1fa609563743c060408c44d5.png differ diff --git a/doc/_build/html/_images/math/72c94abc177c437d0c0be762987594d986bcf711.png b/doc/_build/html/_images/math/72c94abc177c437d0c0be762987594d986bcf711.png new file mode 100644 index 00000000..c5d2b8ff Binary files /dev/null and b/doc/_build/html/_images/math/72c94abc177c437d0c0be762987594d986bcf711.png differ diff --git a/doc/_build/html/_images/math/72ccd2a09fe1d38b26319c571d7072d31e08bce3.png b/doc/_build/html/_images/math/72ccd2a09fe1d38b26319c571d7072d31e08bce3.png new file mode 100644 index 00000000..711b3c08 Binary files /dev/null and b/doc/_build/html/_images/math/72ccd2a09fe1d38b26319c571d7072d31e08bce3.png differ diff --git a/doc/_build/html/_images/math/775e11e817ec90bc434b37341dd7c56d71ae492e.png b/doc/_build/html/_images/math/775e11e817ec90bc434b37341dd7c56d71ae492e.png new file mode 100644 index 00000000..651440ec Binary files /dev/null and b/doc/_build/html/_images/math/775e11e817ec90bc434b37341dd7c56d71ae492e.png differ diff --git a/doc/_build/html/_images/math/78f08794d1aed52b66ce2b784d263d3e7376acf0.png b/doc/_build/html/_images/math/78f08794d1aed52b66ce2b784d263d3e7376acf0.png new file mode 100644 index 00000000..4e89df5d Binary files /dev/null and b/doc/_build/html/_images/math/78f08794d1aed52b66ce2b784d263d3e7376acf0.png differ diff --git a/doc/_build/html/_images/math/7a9b78bdb36f2fbd5ca087212e58fc74dde40e86.png b/doc/_build/html/_images/math/7a9b78bdb36f2fbd5ca087212e58fc74dde40e86.png new file mode 100644 index 00000000..899ffb83 Binary files /dev/null and b/doc/_build/html/_images/math/7a9b78bdb36f2fbd5ca087212e58fc74dde40e86.png differ diff --git a/doc/_build/html/_images/math/7af82c540112d04a12bed95744925acfebcedf6e.png b/doc/_build/html/_images/math/7af82c540112d04a12bed95744925acfebcedf6e.png new file mode 100644 index 00000000..4543a0b2 Binary files /dev/null and b/doc/_build/html/_images/math/7af82c540112d04a12bed95744925acfebcedf6e.png differ diff --git a/doc/_build/html/_images/math/812f92da6db61fb4e16c0060582e4cab04c5cb60.png b/doc/_build/html/_images/math/812f92da6db61fb4e16c0060582e4cab04c5cb60.png new file mode 100644 index 00000000..2717dd62 Binary files /dev/null and b/doc/_build/html/_images/math/812f92da6db61fb4e16c0060582e4cab04c5cb60.png differ diff --git a/doc/_build/html/_images/math/836d46125c08b336c780001fd9b6cfa2ecd6f6d6.png b/doc/_build/html/_images/math/836d46125c08b336c780001fd9b6cfa2ecd6f6d6.png new file mode 100644 index 00000000..1fc99aa0 Binary files /dev/null and b/doc/_build/html/_images/math/836d46125c08b336c780001fd9b6cfa2ecd6f6d6.png differ diff --git a/doc/_build/html/_images/math/8fb292d863fb6fc858ea26b35516ef78fc853543.png b/doc/_build/html/_images/math/8fb292d863fb6fc858ea26b35516ef78fc853543.png new file mode 100644 index 00000000..fc9ac0de Binary files /dev/null and b/doc/_build/html/_images/math/8fb292d863fb6fc858ea26b35516ef78fc853543.png differ diff --git a/doc/_build/html/_images/math/908550a4d7fbf593ce9180499b72adbf17b50d99.png b/doc/_build/html/_images/math/908550a4d7fbf593ce9180499b72adbf17b50d99.png new file mode 100644 index 00000000..904dbf21 Binary files /dev/null and b/doc/_build/html/_images/math/908550a4d7fbf593ce9180499b72adbf17b50d99.png differ diff --git a/doc/_build/html/_images/math/90e371af90a73ea4ad53551cb110df130bfd0990.png b/doc/_build/html/_images/math/90e371af90a73ea4ad53551cb110df130bfd0990.png new file mode 100644 index 00000000..e227c9ba Binary files /dev/null and b/doc/_build/html/_images/math/90e371af90a73ea4ad53551cb110df130bfd0990.png differ diff --git a/doc/_build/html/_images/math/93c29bfedc993de115781b4fbb7e3a8b9e8d6b51.png b/doc/_build/html/_images/math/93c29bfedc993de115781b4fbb7e3a8b9e8d6b51.png new file mode 100644 index 00000000..1b3b9557 Binary files /dev/null and b/doc/_build/html/_images/math/93c29bfedc993de115781b4fbb7e3a8b9e8d6b51.png differ diff --git a/doc/_build/html/_images/math/93d57b731d01eff6d0e66b973f5d2768e5347a4a.png b/doc/_build/html/_images/math/93d57b731d01eff6d0e66b973f5d2768e5347a4a.png new file mode 100644 index 00000000..f0e0345f Binary files /dev/null and b/doc/_build/html/_images/math/93d57b731d01eff6d0e66b973f5d2768e5347a4a.png differ diff --git a/doc/_build/html/_images/math/988e0e11a8d6647b1763eb35ad4aa6c01478b0a9.png b/doc/_build/html/_images/math/988e0e11a8d6647b1763eb35ad4aa6c01478b0a9.png new file mode 100644 index 00000000..dbe937a2 Binary files /dev/null and b/doc/_build/html/_images/math/988e0e11a8d6647b1763eb35ad4aa6c01478b0a9.png differ diff --git a/doc/_build/html/_images/math/98a5b90f5f53332b472e7f022af254db7c92c86c.png b/doc/_build/html/_images/math/98a5b90f5f53332b472e7f022af254db7c92c86c.png new file mode 100644 index 00000000..2112213f Binary files /dev/null and b/doc/_build/html/_images/math/98a5b90f5f53332b472e7f022af254db7c92c86c.png differ diff --git a/doc/_build/html/_images/math/9af67d8f787d95df1e400b2a998bc16206095c72.png b/doc/_build/html/_images/math/9af67d8f787d95df1e400b2a998bc16206095c72.png new file mode 100644 index 00000000..704faf5d Binary files /dev/null and b/doc/_build/html/_images/math/9af67d8f787d95df1e400b2a998bc16206095c72.png differ diff --git a/doc/_build/html/_images/math/a51d2cde832e2fe0f2df87be7c62ffc60a456418.png b/doc/_build/html/_images/math/a51d2cde832e2fe0f2df87be7c62ffc60a456418.png new file mode 100644 index 00000000..8043556e Binary files /dev/null and b/doc/_build/html/_images/math/a51d2cde832e2fe0f2df87be7c62ffc60a456418.png differ diff --git a/doc/_build/html/_images/math/a59a66c531afd1167c497e377131e38dba8e0dfd.png b/doc/_build/html/_images/math/a59a66c531afd1167c497e377131e38dba8e0dfd.png new file mode 100644 index 00000000..06b30f0e Binary files /dev/null and b/doc/_build/html/_images/math/a59a66c531afd1167c497e377131e38dba8e0dfd.png differ diff --git a/doc/_build/html/_images/math/a8ab03f1f7e4f60328e1b8d96389e2d5a31e6e24.png b/doc/_build/html/_images/math/a8ab03f1f7e4f60328e1b8d96389e2d5a31e6e24.png new file mode 100644 index 00000000..2ab8289b Binary files /dev/null and b/doc/_build/html/_images/math/a8ab03f1f7e4f60328e1b8d96389e2d5a31e6e24.png differ diff --git a/doc/_build/html/_images/math/ae3bd00b8434112f53b49d89e8e598ca33f5cc34.png b/doc/_build/html/_images/math/ae3bd00b8434112f53b49d89e8e598ca33f5cc34.png new file mode 100644 index 00000000..ee2de9ed Binary files /dev/null and b/doc/_build/html/_images/math/ae3bd00b8434112f53b49d89e8e598ca33f5cc34.png differ diff --git a/doc/_build/html/_images/math/ae9f0580cb8ea29c74c8e96c3d9d7d4d77ba3e46.png b/doc/_build/html/_images/math/ae9f0580cb8ea29c74c8e96c3d9d7d4d77ba3e46.png new file mode 100644 index 00000000..0fba1af9 Binary files /dev/null and b/doc/_build/html/_images/math/ae9f0580cb8ea29c74c8e96c3d9d7d4d77ba3e46.png differ diff --git a/doc/_build/html/_images/math/afb7f8aa812a6bafd2d1c4423555e766bce85146.png b/doc/_build/html/_images/math/afb7f8aa812a6bafd2d1c4423555e766bce85146.png new file mode 100644 index 00000000..d1932792 Binary files /dev/null and b/doc/_build/html/_images/math/afb7f8aa812a6bafd2d1c4423555e766bce85146.png differ diff --git a/doc/_build/html/_images/math/afe71d9f26a15da7a8f28a7b3a66fd7f477b5df7.png b/doc/_build/html/_images/math/afe71d9f26a15da7a8f28a7b3a66fd7f477b5df7.png new file mode 100644 index 00000000..e4485ff7 Binary files /dev/null and b/doc/_build/html/_images/math/afe71d9f26a15da7a8f28a7b3a66fd7f477b5df7.png differ diff --git a/doc/_build/html/_images/math/b0f3fa8d6aec4217077dd92bd58d218dcc0dc663.png b/doc/_build/html/_images/math/b0f3fa8d6aec4217077dd92bd58d218dcc0dc663.png new file mode 100644 index 00000000..acfc583a Binary files /dev/null and b/doc/_build/html/_images/math/b0f3fa8d6aec4217077dd92bd58d218dcc0dc663.png differ diff --git a/doc/_build/html/_images/math/b606edea521a130e1064a48a5147e4930dc8b55c.png b/doc/_build/html/_images/math/b606edea521a130e1064a48a5147e4930dc8b55c.png new file mode 100644 index 00000000..1fc99aa0 Binary files /dev/null and b/doc/_build/html/_images/math/b606edea521a130e1064a48a5147e4930dc8b55c.png differ diff --git a/doc/_build/html/_images/math/b671e3f640198fb9b743e2e405aad0dfcd645984.png b/doc/_build/html/_images/math/b671e3f640198fb9b743e2e405aad0dfcd645984.png new file mode 100644 index 00000000..b587574e Binary files /dev/null and b/doc/_build/html/_images/math/b671e3f640198fb9b743e2e405aad0dfcd645984.png differ diff --git a/doc/_build/html/_images/math/b75a7991cbb1a7fc99730d8856ca842ee8171eae.png b/doc/_build/html/_images/math/b75a7991cbb1a7fc99730d8856ca842ee8171eae.png new file mode 100644 index 00000000..737f010a Binary files /dev/null and b/doc/_build/html/_images/math/b75a7991cbb1a7fc99730d8856ca842ee8171eae.png differ diff --git a/doc/_build/html/_images/math/b9164be40b826a2f164f45571034ed55764d3b7e.png b/doc/_build/html/_images/math/b9164be40b826a2f164f45571034ed55764d3b7e.png new file mode 100644 index 00000000..e3ed2287 Binary files /dev/null and b/doc/_build/html/_images/math/b9164be40b826a2f164f45571034ed55764d3b7e.png differ diff --git a/doc/_build/html/_images/math/c44a71659d7a772231846371a575382ab5ecb4dc.png b/doc/_build/html/_images/math/c44a71659d7a772231846371a575382ab5ecb4dc.png new file mode 100644 index 00000000..9441b6fb Binary files /dev/null and b/doc/_build/html/_images/math/c44a71659d7a772231846371a575382ab5ecb4dc.png differ diff --git a/doc/_build/html/_images/math/c582b5b606a2c3060394219159d4b17ff4611044.png b/doc/_build/html/_images/math/c582b5b606a2c3060394219159d4b17ff4611044.png new file mode 100644 index 00000000..5b0d92bd Binary files /dev/null and b/doc/_build/html/_images/math/c582b5b606a2c3060394219159d4b17ff4611044.png differ diff --git a/doc/_build/html/_images/math/c6550fb5636af16f487a8b9739f9abe82dbf07b8.png b/doc/_build/html/_images/math/c6550fb5636af16f487a8b9739f9abe82dbf07b8.png new file mode 100644 index 00000000..96a9c9b7 Binary files /dev/null and b/doc/_build/html/_images/math/c6550fb5636af16f487a8b9739f9abe82dbf07b8.png differ diff --git a/doc/_build/html/_images/math/cea5452e08d6d9f15b2b63894d4554bfeb9d951d.png b/doc/_build/html/_images/math/cea5452e08d6d9f15b2b63894d4554bfeb9d951d.png new file mode 100644 index 00000000..ade6c6a9 Binary files /dev/null and b/doc/_build/html/_images/math/cea5452e08d6d9f15b2b63894d4554bfeb9d951d.png differ diff --git a/doc/_build/html/_images/math/d46f1c279ce0c199db52748ba5f2feb62a46363b.png b/doc/_build/html/_images/math/d46f1c279ce0c199db52748ba5f2feb62a46363b.png new file mode 100644 index 00000000..8dea4ee3 Binary files /dev/null and b/doc/_build/html/_images/math/d46f1c279ce0c199db52748ba5f2feb62a46363b.png differ diff --git a/doc/_build/html/_images/math/d65e31c763326e79ede203940e047624c0428f2c.png b/doc/_build/html/_images/math/d65e31c763326e79ede203940e047624c0428f2c.png new file mode 100644 index 00000000..87784ee9 Binary files /dev/null and b/doc/_build/html/_images/math/d65e31c763326e79ede203940e047624c0428f2c.png differ diff --git a/doc/_build/html/_images/math/d891af7e39e0ff3708b97ef66c7e246a93aee52e.png b/doc/_build/html/_images/math/d891af7e39e0ff3708b97ef66c7e246a93aee52e.png new file mode 100644 index 00000000..4a8cebce Binary files /dev/null and b/doc/_build/html/_images/math/d891af7e39e0ff3708b97ef66c7e246a93aee52e.png differ diff --git a/doc/_build/html/_images/math/d91c19e81a73403c46fc57af8f02014851713dbe.png b/doc/_build/html/_images/math/d91c19e81a73403c46fc57af8f02014851713dbe.png new file mode 100644 index 00000000..6afe16f3 Binary files /dev/null and b/doc/_build/html/_images/math/d91c19e81a73403c46fc57af8f02014851713dbe.png differ diff --git a/doc/_build/html/_images/math/dd6e77999bb2b0a71f5089b6a48aabd729045633.png b/doc/_build/html/_images/math/dd6e77999bb2b0a71f5089b6a48aabd729045633.png new file mode 100644 index 00000000..28264014 Binary files /dev/null and b/doc/_build/html/_images/math/dd6e77999bb2b0a71f5089b6a48aabd729045633.png differ diff --git a/doc/_build/html/_images/math/e67edbe203d60c70e432522604959c63318ca2c4.png b/doc/_build/html/_images/math/e67edbe203d60c70e432522604959c63318ca2c4.png new file mode 100644 index 00000000..938ae3ea Binary files /dev/null and b/doc/_build/html/_images/math/e67edbe203d60c70e432522604959c63318ca2c4.png differ diff --git a/doc/_build/html/_images/math/e70d5f1b33598371cd2960cbd61cdc79f720732f.png b/doc/_build/html/_images/math/e70d5f1b33598371cd2960cbd61cdc79f720732f.png new file mode 100644 index 00000000..0c5dd577 Binary files /dev/null and b/doc/_build/html/_images/math/e70d5f1b33598371cd2960cbd61cdc79f720732f.png differ diff --git a/doc/_build/html/_images/math/ec9f908da0039cda866af0e06264a6fad9dbed48.png b/doc/_build/html/_images/math/ec9f908da0039cda866af0e06264a6fad9dbed48.png new file mode 100644 index 00000000..2db91fa8 Binary files /dev/null and b/doc/_build/html/_images/math/ec9f908da0039cda866af0e06264a6fad9dbed48.png differ diff --git a/doc/_build/html/_images/math/f66e06331b1ae3c96e126c035b09ee277f6fc50d.png b/doc/_build/html/_images/math/f66e06331b1ae3c96e126c035b09ee277f6fc50d.png new file mode 100644 index 00000000..27952878 Binary files /dev/null and b/doc/_build/html/_images/math/f66e06331b1ae3c96e126c035b09ee277f6fc50d.png differ diff --git a/doc/_build/html/_images/math/f8a932e370ada3f336aca285ab12d4b239473624.png b/doc/_build/html/_images/math/f8a932e370ada3f336aca285ab12d4b239473624.png new file mode 100644 index 00000000..cf38aea9 Binary files /dev/null and b/doc/_build/html/_images/math/f8a932e370ada3f336aca285ab12d4b239473624.png differ diff --git a/doc/_build/html/_images/math/f9939fafeac3df2cd993cd6d46762f5c9e184253.png b/doc/_build/html/_images/math/f9939fafeac3df2cd993cd6d46762f5c9e184253.png new file mode 100644 index 00000000..6e16b74a Binary files /dev/null and b/doc/_build/html/_images/math/f9939fafeac3df2cd993cd6d46762f5c9e184253.png differ diff --git a/doc/_build/html/_images/tick.png b/doc/_build/html/_images/tick.png new file mode 100644 index 00000000..1175c802 Binary files /dev/null and b/doc/_build/html/_images/tick.png differ diff --git a/doc/_build/html/_images/tuto_GP_regression_m1.png b/doc/_build/html/_images/tuto_GP_regression_m1.png new file mode 100644 index 00000000..e1a11fb1 Binary files /dev/null and b/doc/_build/html/_images/tuto_GP_regression_m1.png differ diff --git a/doc/_build/html/_images/tuto_GP_regression_m2.png b/doc/_build/html/_images/tuto_GP_regression_m2.png new file mode 100644 index 00000000..7e54e919 Binary files /dev/null and b/doc/_build/html/_images/tuto_GP_regression_m2.png differ diff --git a/doc/_build/html/_images/tuto_GP_regression_m3.png b/doc/_build/html/_images/tuto_GP_regression_m3.png new file mode 100644 index 00000000..5b2b227c Binary files /dev/null and b/doc/_build/html/_images/tuto_GP_regression_m3.png differ diff --git a/doc/_build/html/_images/tuto_kern_overview_allkern.png b/doc/_build/html/_images/tuto_kern_overview_allkern.png new file mode 100644 index 00000000..f3406b07 Binary files /dev/null and b/doc/_build/html/_images/tuto_kern_overview_allkern.png differ diff --git a/doc/_build/html/_images/tuto_kern_overview_basicplot.png b/doc/_build/html/_images/tuto_kern_overview_basicplot.png new file mode 100644 index 00000000..bad43b09 Binary files /dev/null and b/doc/_build/html/_images/tuto_kern_overview_basicplot.png differ diff --git a/doc/_build/html/_images/tuto_kern_overview_mANOVA.png b/doc/_build/html/_images/tuto_kern_overview_mANOVA.png new file mode 100644 index 00000000..255a3a80 Binary files /dev/null and b/doc/_build/html/_images/tuto_kern_overview_mANOVA.png differ diff --git a/doc/_build/html/_images/tuto_kern_overview_mANOVAdec.png b/doc/_build/html/_images/tuto_kern_overview_mANOVAdec.png new file mode 100644 index 00000000..45b7ae2a Binary files /dev/null and b/doc/_build/html/_images/tuto_kern_overview_mANOVAdec.png differ diff --git a/doc/_build/html/_images/tuto_kern_overview_multadd.png b/doc/_build/html/_images/tuto_kern_overview_multadd.png new file mode 100644 index 00000000..72b6797b Binary files /dev/null and b/doc/_build/html/_images/tuto_kern_overview_multadd.png differ diff --git a/doc/_build/html/_images/tuto_kern_overview_multperdecay.png b/doc/_build/html/_images/tuto_kern_overview_multperdecay.png new file mode 100644 index 00000000..3970d342 Binary files /dev/null and b/doc/_build/html/_images/tuto_kern_overview_multperdecay.png differ diff --git a/doc/_build/html/_modules/GPy.html b/doc/_build/html/_modules/GPy.html new file mode 100644 index 00000000..6d341e50 --- /dev/null +++ b/doc/_build/html/_modules/GPy.html @@ -0,0 +1,141 @@ + + + + + + + + GPy — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+import warnings
+warnings.filterwarnings("ignore", category=DeprecationWarning)
+
+import core
+from core.parameterization import transformations, priors
+constraints = transformations
+import models
+import mappings
+import inference
+import util
+import examples
+import likelihoods
+import testing
+from numpy.testing import Tester
+import kern
+import plotting
+
+# Direct imports for convenience:
+from core import Model
+from core.parameterization import Param, Parameterized, ObsAr
+
+#@nottest
+try:
+    #Get rid of nose dependency by only ignoring if you have nose installed
+    from nose.tools import nottest
+    @nottest
+    def tests():
+        Tester(testing).test(verbose=10)
+except:
+
[docs] def tests(): + Tester(testing).test(verbose=10) +
+
[docs]def load(file_path): + """ + Load a previously pickled model, using `m.pickle('path/to/file.pickle)' + + :param file_name: path/to/file.pickle + """ + import cPickle as pickle + try: + with open(file_path, 'rb') as f: + m = pickle.load(f) + except: + import pickle as pickle + with open(file_path, 'rb') as f: + m = pickle.load(f) + return m
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/gp.html b/doc/_build/html/_modules/GPy/core/gp.html new file mode 100644 index 00000000..f57e862e --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/gp.html @@ -0,0 +1,553 @@ + + + + + + + + GPy.core.gp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.gp

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+import sys
+from .. import kern
+from model import Model
+from parameterization import ObsAr
+from .. import likelihoods
+from ..inference.latent_function_inference import exact_gaussian_inference, expectation_propagation
+from parameterization.variational import VariationalPosterior
+
+import logging
+from GPy.util.normalizer import MeanNorm
+logger = logging.getLogger("GP")
+
+
[docs]class GP(Model): + """ + General purpose Gaussian process model + + :param X: input observations + :param Y: output observations + :param kernel: a GPy kernel, defaults to rbf+white + :param likelihood: a GPy likelihood + :param inference_method: The :class:`~GPy.inference.latent_function_inference.LatentFunctionInference` inference method to use for this GP + :rtype: model object + :param Norm normalizer: + normalize the outputs Y. + Prediction will be un-normalized using this normalizer. + If normalizer is None, we will normalize using MeanNorm. + If normalizer is False, no normalization will be done. + + .. Note:: Multiple independent outputs are allowed using columns of Y + + + """ + def __init__(self, X, Y, kernel, likelihood, inference_method=None, name='gp', Y_metadata=None, normalizer=False): + super(GP, self).__init__(name) + + assert X.ndim == 2 + if isinstance(X, (ObsAr, VariationalPosterior)): + self.X = X.copy() + else: self.X = ObsAr(X) + + self.num_data, self.input_dim = self.X.shape + + assert Y.ndim == 2 + logger.info("initializing Y") + + if normalizer is True: + self.normalizer = MeanNorm() + elif normalizer is False: + self.normalizer = None + else: + self.normalizer = normalizer + + if self.normalizer is not None: + self.normalizer.scale_by(Y) + self.Y_normalized = ObsAr(self.normalizer.normalize(Y)) + self.Y = Y + else: + self.Y = ObsAr(Y) + self.Y_normalized = self.Y + + assert Y.shape[0] == self.num_data + _, self.output_dim = self.Y.shape + + #TODO: check the type of this is okay? + self.Y_metadata = Y_metadata + + assert isinstance(kernel, kern.Kern) + #assert self.input_dim == kernel.input_dim + self.kern = kernel + + assert isinstance(likelihood, likelihoods.Likelihood) + self.likelihood = likelihood + + #find a sensible inference method + logger.info("initializing inference method") + if inference_method is None: + if isinstance(likelihood, likelihoods.Gaussian) or isinstance(likelihood, likelihoods.MixedNoise): + inference_method = exact_gaussian_inference.ExactGaussianInference() + else: + inference_method = expectation_propagation.EP() + print "defaulting to ", inference_method, "for latent function inference" + self.inference_method = inference_method + + logger.info("adding kernel and likelihood as parameters") + self.link_parameter(self.kern) + self.link_parameter(self.likelihood) + +
[docs] def set_XY(self, X=None, Y=None): + """ + Set the input / output data of the model + This is useful if we wish to change our existing data but maintain the same model + + :param X: input observations + :type X: np.ndarray + :param Y: output observations + :type Y: np.ndarray + """ + self.update_model(False) + if Y is not None: + if self.normalizer is not None: + self.normalizer.scale_by(Y) + self.Y_normalized = ObsAr(self.normalizer.normalize(Y)) + self.Y = Y + else: + self.Y = ObsAr(Y) + self.Y_normalized = self.Y + if X is not None: + if self.X in self.parameters: + # LVM models + if isinstance(self.X, VariationalPosterior): + assert isinstance(X, type(self.X)), "The given X must have the same type as the X in the model!" + self.unlink_parameter(self.X) + self.X = X + self.link_parameters(self.X) + else: + self.unlink_parameter(self.X) + from ..core import Param + self.X = Param('latent mean',X) + self.link_parameters(self.X) + else: + self.X = ObsAr(X) + self.update_model(True) +
+
[docs] def set_X(self,X): + """ + Set the input data of the model + + :param X: input observations + :type X: np.ndarray + """ + self.set_XY(X=X) +
+
[docs] def set_Y(self,Y): + """ + Set the output data of the model + + :param X: output observations + :type X: np.ndarray + """ + self.set_XY(Y=Y) +
+
[docs] def parameters_changed(self): + """ + Method that is called upon any changes to :class:`~GPy.core.parameterization.param.Param` variables within the model. + In particular in the GP class this method reperforms inference, recalculating the posterior and log marginal likelihood and gradients of the model + + .. warning:: + This method is not designed to be called manually, the framework is set up to automatically call this method upon changes to parameters, if you call + this method yourself, there may be unexpected consequences. + """ + self.posterior, self._log_marginal_likelihood, self.grad_dict = self.inference_method.inference(self.kern, self.X, self.likelihood, self.Y_normalized, self.Y_metadata) + self.likelihood.update_gradients(self.grad_dict['dL_dthetaL']) + self.kern.update_gradients_full(self.grad_dict['dL_dK'], self.X) +
+
[docs] def log_likelihood(self): + """ + The log marginal likelihood of the model, :math:`p(\mathbf{y})`, this is the objective function of the model being optimised + """ + return self._log_marginal_likelihood +
+ def _raw_predict(self, _Xnew, full_cov=False, kern=None): + """ + For making predictions, does not account for normalization or likelihood + + full_cov is a boolean which defines whether the full covariance matrix + of the prediction is computed. If full_cov is False (default), only the + diagonal of the covariance is returned. + + .. math:: + p(f*|X*, X, Y) = \int^{\inf}_{\inf} p(f*|f,X*)p(f|X,Y) df + = N(f*| K_{x*x}(K_{xx} + \Sigma)^{-1}Y, K_{x*x*} - K_{xx*}(K_{xx} + \Sigma)^{-1}K_{xx*} + \Sigma := \texttt{Likelihood.variance / Approximate likelihood covariance} + """ + if kern is None: + kern = self.kern + + Kx = kern.K(_Xnew, self.X).T + WiKx = np.dot(self.posterior.woodbury_inv, Kx) + mu = np.dot(Kx.T, self.posterior.woodbury_vector) + if full_cov: + Kxx = kern.K(_Xnew) + var = Kxx - np.dot(Kx.T, WiKx) + else: + Kxx = kern.Kdiag(_Xnew) + var = Kxx - np.sum(WiKx*Kx, 0) + var = var.reshape(-1, 1) + + #force mu to be a column vector + if len(mu.shape)==1: mu = mu[:,None] + return mu, var + +
[docs] def predict(self, Xnew, full_cov=False, Y_metadata=None, kern=None): + """ + Predict the function(s) at the new point(s) Xnew. + + :param Xnew: The points at which to make a prediction + :type Xnew: np.ndarray (Nnew x self.input_dim) + :param full_cov: whether to return the full covariance matrix, or just + the diagonal + :type full_cov: bool + :param Y_metadata: metadata about the predicting point to pass to the likelihood + :param kern: The kernel to use for prediction (defaults to the model + kern). this is useful for examining e.g. subprocesses. + :returns: (mean, var, lower_upper): + mean: posterior mean, a Numpy array, Nnew x self.input_dim + var: posterior variance, a Numpy array, Nnew x 1 if full_cov=False, Nnew x Nnew otherwise + lower_upper: lower and upper boundaries of the 95% confidence intervals, Numpy arrays, Nnew x self.input_dim + + If full_cov and self.input_dim > 1, the return shape of var is Nnew x Nnew x self.input_dim. If self.input_dim == 1, the return shape is Nnew x Nnew. + This is to allow for different normalizations of the output dimensions. + """ + #predict the latent function values + mu, var = self._raw_predict(Xnew, full_cov=full_cov, kern=kern) + if self.normalizer is not None: + mu, var = self.normalizer.inverse_mean(mu), self.normalizer.inverse_variance(var) + + # now push through likelihood + mean, var = self.likelihood.predictive_values(mu, var, full_cov, Y_metadata) + return mean, var +
+
[docs] def predict_quantiles(self, X, quantiles=(2.5, 97.5), Y_metadata=None): + """ + Get the predictive quantiles around the prediction at X + + :param X: The points at which to make a prediction + :type X: np.ndarray (Xnew x self.input_dim) + :param quantiles: tuple of quantiles, default is (2.5, 97.5) which is the 95% interval + :type quantiles: tuple + :returns: list of quantiles for each X and predictive quantiles for interval combination + :rtype: [np.ndarray (Xnew x self.input_dim), np.ndarray (Xnew x self.input_dim)] + """ + m, v = self._raw_predict(X, full_cov=False) + if self.normalizer is not None: + m, v = self.normalizer.inverse_mean(m), self.normalizer.inverse_variance(v) + return self.likelihood.predictive_quantiles(m, v, quantiles, Y_metadata) +
+
[docs] def predictive_gradients(self, Xnew): + """ + Compute the derivatives of the latent function with respect to X* + + Given a set of points at which to predict X* (size [N*,Q]), compute the + derivatives of the mean and variance. Resulting arrays are sized: + dmu_dX* -- [N*, Q ,D], where D is the number of output in this GP (usually one). + + dv_dX* -- [N*, Q], (since all outputs have the same variance) + :param X: The points at which to get the predictive gradients + :type X: np.ndarray (Xnew x self.input_dim) + :returns: dmu_dX, dv_dX + :rtype: [np.ndarray (N*, Q ,D), np.ndarray (N*,Q) ] + + """ + dmu_dX = np.empty((Xnew.shape[0],Xnew.shape[1],self.output_dim)) + for i in range(self.output_dim): + dmu_dX[:,:,i] = self.kern.gradients_X(self.posterior.woodbury_vector[:,i:i+1].T, Xnew, self.X) + + # gradients wrt the diagonal part k_{xx} + dv_dX = self.kern.gradients_X(np.eye(Xnew.shape[0]), Xnew) + #grads wrt 'Schur' part K_{xf}K_{ff}^{-1}K_{fx} + alpha = -2.*np.dot(self.kern.K(Xnew, self.X),self.posterior.woodbury_inv) + dv_dX += self.kern.gradients_X(alpha, Xnew, self.X) + return dmu_dX, dv_dX + +
+
[docs] def posterior_samples_f(self,X,size=10, full_cov=True): + """ + Samples the posterior GP at the points X. + + :param X: The points at which to take the samples. + :type X: np.ndarray (Nnew x self.input_dim) + :param size: the number of a posteriori samples. + :type size: int. + :param full_cov: whether to return the full covariance matrix, or just the diagonal. + :type full_cov: bool. + :returns: Ysim: set of simulations + :rtype: np.ndarray (N x samples) + """ + m, v = self._raw_predict(X, full_cov=full_cov) + if self.normalizer is not None: + m, v = self.normalizer.inverse_mean(m), self.normalizer.inverse_variance(v) + v = v.reshape(m.size,-1) if len(v.shape)==3 else v + if not full_cov: + Ysim = np.random.multivariate_normal(m.flatten(), np.diag(v.flatten()), size).T + else: + Ysim = np.random.multivariate_normal(m.flatten(), v, size).T + + return Ysim +
+
[docs] def posterior_samples(self, X, size=10, full_cov=False, Y_metadata=None): + """ + Samples the posterior GP at the points X. + + :param X: the points at which to take the samples. + :type X: np.ndarray (Nnew x self.input_dim.) + :param size: the number of a posteriori samples. + :type size: int. + :param full_cov: whether to return the full covariance matrix, or just the diagonal. + :type full_cov: bool. + :param noise_model: for mixed noise likelihood, the noise model to use in the samples. + :type noise_model: integer. + :returns: Ysim: set of simulations, a Numpy array (N x samples). + """ + Ysim = self.posterior_samples_f(X, size, full_cov=full_cov) + Ysim = self.likelihood.samples(Ysim, Y_metadata) + + return Ysim +
+
[docs] def plot_f(self, plot_limits=None, which_data_rows='all', + which_data_ycols='all', fixed_inputs=[], + levels=20, samples=0, fignum=None, ax=None, resolution=None, + plot_raw=True, + linecol=None,fillcol=None, Y_metadata=None, data_symbol='kx'): + """ + Plot the GP's view of the world, where the data is normalized and before applying a likelihood. + This is a call to plot with plot_raw=True. + Data will not be plotted in this, as the GP's view of the world + may live in another space, or units then the data. + + Can plot only part of the data and part of the posterior functions + using which_data_rowsm which_data_ycols. + + :param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits + :type plot_limits: np.array + :param which_data_rows: which of the training data to plot (default all) + :type which_data_rows: 'all' or a slice object to slice model.X, model.Y + :param which_data_ycols: when the data has several columns (independant outputs), only plot these + :type which_data_ycols: 'all' or a list of integers + :param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v. + :type fixed_inputs: a list of tuples + :param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D + :type resolution: int + :param levels: number of levels to plot in a contour plot. + :param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure + :type levels: int + :param samples: the number of a posteriori samples to plot + :type samples: int + :param fignum: figure to plot on. + :type fignum: figure number + :param ax: axes to plot on. + :type ax: axes handle + :param linecol: color of line to plot [Tango.colorsHex['darkBlue']] + :type linecol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib + :param fillcol: color of fill [Tango.colorsHex['lightBlue']] + :type fillcol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib + :param Y_metadata: additional data associated with Y which may be needed + :type Y_metadata: dict + :param data_symbol: symbol as used matplotlib, by default this is a black cross ('kx') + :type data_symbol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) alongside marker type, as is standard in matplotlib. + """ + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import models_plots + kw = {} + if linecol is not None: + kw['linecol'] = linecol + if fillcol is not None: + kw['fillcol'] = fillcol + return models_plots.plot_fit(self, plot_limits, which_data_rows, + which_data_ycols, fixed_inputs, + levels, samples, fignum, ax, resolution, + plot_raw=plot_raw, Y_metadata=Y_metadata, + data_symbol=data_symbol, **kw) +
+
[docs] def plot(self, plot_limits=None, which_data_rows='all', + which_data_ycols='all', fixed_inputs=[], + levels=20, samples=0, fignum=None, ax=None, resolution=None, + plot_raw=False, + linecol=None,fillcol=None, Y_metadata=None, data_symbol='kx'): + """ + Plot the posterior of the GP. + - In one dimension, the function is plotted with a shaded region identifying two standard deviations. + - In two dimsensions, a contour-plot shows the mean predicted function + - In higher dimensions, use fixed_inputs to plot the GP with some of the inputs fixed. + + Can plot only part of the data and part of the posterior functions + using which_data_rowsm which_data_ycols. + + :param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits + :type plot_limits: np.array + :param which_data_rows: which of the training data to plot (default all) + :type which_data_rows: 'all' or a slice object to slice model.X, model.Y + :param which_data_ycols: when the data has several columns (independant outputs), only plot these + :type which_data_ycols: 'all' or a list of integers + :param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v. + :type fixed_inputs: a list of tuples + :param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D + :type resolution: int + :param levels: number of levels to plot in a contour plot. + :param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure + :type levels: int + :param samples: the number of a posteriori samples to plot + :type samples: int + :param fignum: figure to plot on. + :type fignum: figure number + :param ax: axes to plot on. + :type ax: axes handle + :param linecol: color of line to plot [Tango.colorsHex['darkBlue']] + :type linecol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib + :param fillcol: color of fill [Tango.colorsHex['lightBlue']] + :type fillcol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib + :param Y_metadata: additional data associated with Y which may be needed + :type Y_metadata: dict + :param data_symbol: symbol as used matplotlib, by default this is a black cross ('kx') + :type data_symbol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) alongside marker type, as is standard in matplotlib. + """ + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import models_plots + kw = {} + if linecol is not None: + kw['linecol'] = linecol + if fillcol is not None: + kw['fillcol'] = fillcol + return models_plots.plot_fit(self, plot_limits, which_data_rows, + which_data_ycols, fixed_inputs, + levels, samples, fignum, ax, resolution, + plot_raw=plot_raw, Y_metadata=Y_metadata, + data_symbol=data_symbol, **kw) +
+
[docs] def input_sensitivity(self, summarize=True): + """ + Returns the sensitivity for each dimension of this model + """ + return self.kern.input_sensitivity(summarize=summarize) +
+
[docs] def optimize(self, optimizer=None, start=None, **kwargs): + """ + Optimize the model using self.log_likelihood and self.log_likelihood_gradient, as well as self.priors. + kwargs are passed to the optimizer. They can be: + + :param max_f_eval: maximum number of function evaluations + :type max_f_eval: int + :messages: whether to display during optimisation + :type messages: bool + :param optimizer: which optimizer to use (defaults to self.preferred optimizer), a range of optimisers can be found in :module:`~GPy.inference.optimization`, they include 'scg', 'lbfgs', 'tnc'. + :type optimizer: string + """ + self.inference_method.on_optimization_start() + try: + super(GP, self).optimize(optimizer, start, **kwargs) + except KeyboardInterrupt: + print "KeyboardInterrupt caught, calling on_optimization_end() to round things up" + self.inference_method.on_optimization_end() + raise +
+
[docs] def infer_newX(self, Y_new, optimize=True, ): + """ + Infer the distribution of X for the new observed data *Y_new*. + + :param Y_new: the new observed data for inference + :type Y_new: numpy.ndarray + :param optimize: whether to optimize the location of new X (True by default) + :type optimize: boolean + :return: a tuple containing the posterior estimation of X and the model that optimize X + :rtype: (:class:`~GPy.core.parameterization.variational.VariationalPosterior` or numpy.ndarray, :class:`~GPy.core.model.Model`) + """ + from ..inference.latent_function_inference.inferenceX import infer_newX + return infer_newX(self, Y_new, optimize=optimize)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/mapping.html b/doc/_build/html/_modules/GPy/core/mapping.html new file mode 100644 index 00000000..5d787fe0 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/mapping.html @@ -0,0 +1,238 @@ + + + + + + + + GPy.core.mapping — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.mapping

+# Copyright (c) 2013,2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import sys
+from parameterization import Parameterized
+import numpy as np
+
+
[docs]class Mapping(Parameterized): + """ + Base model for shared behavior between models that can act like a mapping. + """ + + def __init__(self, input_dim, output_dim, name='mapping'): + self.input_dim = input_dim + self.output_dim = output_dim + super(Mapping, self).__init__(name=name) + +
[docs] def f(self, X): + raise NotImplementedError +
+
[docs] def df_dX(self, dL_df, X): + """Evaluate derivatives of mapping outputs with respect to inputs. + + :param dL_df: gradient of the objective with respect to the function. + :type dL_df: ndarray (num_data x output_dim) + :param X: the input locations where derivatives are to be evaluated. + :type X: ndarray (num_data x input_dim) + :returns: matrix containing gradients of the function with respect to the inputs. + """ + raise NotImplementedError +
+
[docs] def df_dtheta(self, dL_df, X): + """The gradient of the outputs of the mapping with respect to each of the parameters. + + :param dL_df: gradient of the objective with respect to the function. + :type dL_df: ndarray (num_data x output_dim) + :param X: input locations where the function is evaluated. + :type X: ndarray (num_data x input_dim) + :returns: Matrix containing gradients with respect to parameters of each output for each input data. + :rtype: ndarray (num_params length) + """ + + raise NotImplementedError +
+
[docs] def plot(self, *args): + """ + Plots the mapping associated with the model. + - In one dimension, the function is plotted. + - In two dimensions, a contour-plot shows the function + - In higher dimensions, we've not implemented this yet !TODO! + + Can plot only part of the data and part of the posterior functions + using which_data and which_functions + + This is a convenience function: arguments are passed to + GPy.plotting.matplot_dep.models_plots.plot_mapping + """ + + if "matplotlib" in sys.modules: + from ..plotting.matplot_dep import models_plots + mapping_plots.plot_mapping(self,*args) + else: + raise NameError, "matplotlib package has not been imported." +
+
[docs]class Bijective_mapping(Mapping): + """ + This is a mapping that is bijective, i.e. you can go from X to f and + also back from f to X. The inverse mapping is called g(). + """ + def __init__(self, input_dim, output_dim, name='bijective_mapping'): + super(Bijective_apping, self).__init__(name=name) + +
[docs] def g(self, f): + """Inverse mapping from output domain of the function to the inputs.""" + raise NotImplementedError +
+from model import Model + +
[docs]class Mapping_check_model(Model): + """ + This is a dummy model class used as a base class for checking that the + gradients of a given mapping are implemented correctly. It enables + checkgradient() to be called independently on each mapping. + """ + def __init__(self, mapping=None, dL_df=None, X=None): + num_samples = 20 + if mapping==None: + mapping = GPy.mapping.linear(1, 1) + if X==None: + X = np.random.randn(num_samples, mapping.input_dim) + if dL_df==None: + dL_df = np.ones((num_samples, mapping.output_dim)) + + self.mapping=mapping + self.X = X + self.dL_df = dL_df + self.num_params = self.mapping.num_params + Model.__init__(self) + + + def _get_params(self): + return self.mapping._get_params() + + def _get_param_names(self): + return self.mapping._get_param_names() + + def _set_params(self, x): + self.mapping._set_params(x) + +
[docs] def log_likelihood(self): + return (self.dL_df*self.mapping.f(self.X)).sum() +
+ def _log_likelihood_gradients(self): + raise NotImplementedError, "This needs to be implemented to use the Mapping_check_model class." +
+
[docs]class Mapping_check_df_dtheta(Mapping_check_model): + """This class allows gradient checks for the gradient of a mapping with respect to parameters. """ + def __init__(self, mapping=None, dL_df=None, X=None): + Mapping_check_model.__init__(self,mapping=mapping,dL_df=dL_df, X=X) + + def _log_likelihood_gradients(self): + return self.mapping.df_dtheta(self.dL_df, self.X) + +
+
[docs]class Mapping_check_df_dX(Mapping_check_model): + """This class allows gradient checks for the gradient of a mapping with respect to X. """ + def __init__(self, mapping=None, dL_df=None, X=None): + Mapping_check_model.__init__(self,mapping=mapping,dL_df=dL_df, X=X) + + if dL_df==None: + dL_df = np.ones((self.X.shape[0],self.mapping.output_dim)) + self.num_params = self.X.shape[0]*self.mapping.input_dim + + def _log_likelihood_gradients(self): + return self.mapping.df_dX(self.dL_df, self.X).flatten() + + def _get_param_names(self): + return ['X_' +str(i) + ','+str(j) for j in range(self.X.shape[1]) for i in range(self.X.shape[0])] + + def _get_params(self): + return self.X.flatten() + + def _set_params(self, x): + self.X=x.reshape(self.X.shape) +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/model.html b/doc/_build/html/_modules/GPy/core/model.html new file mode 100644 index 00000000..d53e34e7 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/model.html @@ -0,0 +1,509 @@ + + + + + + + + GPy.core.model — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.model

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+from .. import likelihoods
+from ..inference import optimization
+from ..util.misc import opt_wrapper
+from parameterization import Parameterized
+import multiprocessing as mp
+import numpy as np
+from numpy.linalg.linalg import LinAlgError
+import itertools
+# import numdifftools as ndt
+
+
[docs]class Model(Parameterized): + _fail_count = 0 # Count of failed optimization steps (see objective) + _allowed_failures = 10 # number of allowed failures + + def __init__(self, name): + super(Model, self).__init__(name) # Parameterized.__init__(self) + self.optimization_runs = [] + self.sampling_runs = [] + self.preferred_optimizer = 'bfgs' + from .parameterization.ties_and_remappings import Tie + self.tie = Tie() + self.link_parameter(self.tie, -1) + self.add_observer(self.tie, self.tie._parameters_changed_notification, priority=-500) + +
[docs] def log_likelihood(self): + raise NotImplementedError, "this needs to be implemented to use the model class"
+ def _log_likelihood_gradients(self): + return self.gradient + +
[docs] def optimize_restarts(self, num_restarts=10, robust=False, verbose=True, parallel=False, num_processes=None, **kwargs): + """ + Perform random restarts of the model, and set the model to the best + seen solution. + + If the robust flag is set, exceptions raised during optimizations will + be handled silently. If _all_ runs fail, the model is reset to the + existing parameter values. + + **Notes** + + :param num_restarts: number of restarts to use (default 10) + :type num_restarts: int + :param robust: whether to handle exceptions silently or not (default False) + :type robust: bool + :param parallel: whether to run each restart as a separate process. It relies on the multiprocessing module. + :type parallel: bool + :param num_processes: number of workers in the multiprocessing pool + :type numprocesses: int + + \*\*kwargs are passed to the optimizer. They can be: + + :param max_f_eval: maximum number of function evaluations + :type max_f_eval: int + :param max_iters: maximum number of iterations + :type max_iters: int + :param messages: whether to display during optimisation + :type messages: bool + + .. note:: If num_processes is None, the number of workes in the + multiprocessing pool is automatically set to the number of processors + on the current machine. + + """ + initial_parameters = self.optimizer_array.copy() + + if parallel: + try: + jobs = [] + pool = mp.Pool(processes=num_processes) + for i in range(num_restarts): + self.randomize() + job = pool.apply_async(opt_wrapper, args=(self,), kwds=kwargs) + jobs.append(job) + + pool.close() # signal that no more data coming in + pool.join() # wait for all the tasks to complete + except KeyboardInterrupt: + print "Ctrl+c received, terminating and joining pool." + pool.terminate() + pool.join() + + for i in range(num_restarts): + try: + if not parallel: + self.randomize() + self.optimize(**kwargs) + else: + self.optimization_runs.append(jobs[i].get()) + + if verbose: + print("Optimization restart {0}/{1}, f = {2}".format(i + 1, num_restarts, self.optimization_runs[-1].f_opt)) + except Exception as e: + if robust: + print("Warning - optimization restart {0}/{1} failed".format(i + 1, num_restarts)) + else: + raise e + + if len(self.optimization_runs): + i = np.argmin([o.f_opt for o in self.optimization_runs]) + self.optimizer_array = self.optimization_runs[i].x_opt + else: + self.optimizer_array = initial_parameters +
+
[docs] def ensure_default_constraints(self, warning=True): + """ + Ensure that any variables which should clearly be positive + have been constrained somehow. The method performs a regular + expression search on parameter names looking for the terms + 'variance', 'lengthscale', 'precision' and 'kappa'. If any of + these terms are present in the name the parameter is + constrained positive. + + DEPRECATED. + """ + raise DeprecationWarning, 'parameters now have default constraints' +
+
[docs] def objective_function(self): + """ + The objective function for the given algorithm. + + This function is the true objective, which wants to be minimized. + Note that all parameters are already set and in place, so you just need + to return the objective function here. + + For probabilistic models this is the negative log_likelihood + (including the MAP prior), so we return it here. If your model is not + probabilistic, just return your objective to minimize here! + """ + return -float(self.log_likelihood()) - self.log_prior() +
+
[docs] def objective_function_gradients(self): + """ + The gradients for the objective function for the given algorithm. + The gradients are w.r.t. the *negative* objective function, as + this framework works with *negative* log-likelihoods as a default. + + You can find the gradient for the parameters in self.gradient at all times. + This is the place, where gradients get stored for parameters. + + This function is the true objective, which wants to be minimized. + Note that all parameters are already set and in place, so you just need + to return the gradient here. + + For probabilistic models this is the gradient of the negative log_likelihood + (including the MAP prior), so we return it here. If your model is not + probabilistic, just return your *negative* gradient here! + """ + return -(self._log_likelihood_gradients() + self._log_prior_gradients()) +
+ def _grads(self, x): + """ + Gets the gradients from the likelihood and the priors. + + Failures are handled robustly. The algorithm will try several times to + return the gradients, and will raise the original exception if + the objective cannot be computed. + + :param x: the parameters of the model. + :type x: np.array + """ + try: + # self._set_params_transformed(x) + self.optimizer_array = x + obj_grads = self._transform_gradients(self.objective_function_gradients()) + self._fail_count = 0 + except (LinAlgError, ZeroDivisionError, ValueError): + if self._fail_count >= self._allowed_failures: + raise + self._fail_count += 1 + obj_grads = np.clip(self._transform_gradients(self.objective_function_gradients()), -1e100, 1e100) + return obj_grads + + def _objective(self, x): + """ + The objective function passed to the optimizer. It combines + the likelihood and the priors. + + Failures are handled robustly. The algorithm will try several times to + return the objective, and will raise the original exception if + the objective cannot be computed. + + :param x: the parameters of the model. + :parameter type: np.array + """ + try: + self.optimizer_array = x + obj = self.objective_function() + self._fail_count = 0 + except (LinAlgError, ZeroDivisionError, ValueError): + if self._fail_count >= self._allowed_failures: + raise + self._fail_count += 1 + return np.inf + return obj + + def _objective_grads(self, x): + try: + self.optimizer_array = x + obj_f, obj_grads = self.objective_function(), self._transform_gradients(self.objective_function_gradients()) + self._fail_count = 0 + except (LinAlgError, ZeroDivisionError, ValueError): + if self._fail_count >= self._allowed_failures: + raise + self._fail_count += 1 + obj_f = np.inf + obj_grads = np.clip(self._transform_gradients(self.objective_function_gradients()), -1e100, 1e100) + return obj_f, obj_grads + +
[docs] def optimize(self, optimizer=None, start=None, **kwargs): + """ + Optimize the model using self.log_likelihood and self.log_likelihood_gradient, as well as self.priors. + + kwargs are passed to the optimizer. They can be: + + :param max_f_eval: maximum number of function evaluations + :type max_f_eval: int + :messages: whether to display during optimisation + :type messages: bool + :param optimizer: which optimizer to use (defaults to self.preferred optimizer) + :type optimizer: string + + Valid optimizers are: + - 'scg': scaled conjugate gradient method, recommended for stability. + See also GPy.inference.optimization.scg + - 'fmin_tnc': truncated Newton method (see scipy.optimize.fmin_tnc) + - 'simplex': the Nelder-Mead simplex method (see scipy.optimize.fmin), + - 'lbfgsb': the l-bfgs-b method (see scipy.optimize.fmin_l_bfgs_b), + - 'sgd': stochastic gradient decsent (see scipy.optimize.sgd). For experts only! + + + """ + if self.is_fixed: + print 'nothing to optimize' + if self.size == 0: + print 'nothing to optimize' + + if not self.update_model(): + print "setting updates on again" + self.update_model(True) + + if start == None: + start = self.optimizer_array + + if optimizer is None: + optimizer = self.preferred_optimizer + + if isinstance(optimizer, optimization.Optimizer): + opt = optimizer + opt.model = self + else: + optimizer = optimization.get_optimizer(optimizer) + opt = optimizer(start, model=self, **kwargs) + + opt.run(f_fp=self._objective_grads, f=self._objective, fp=self._grads) + + self.optimization_runs.append(opt) + + self.optimizer_array = opt.x_opt +
+
[docs] def optimize_SGD(self, momentum=0.1, learning_rate=0.01, iterations=20, **kwargs): + # assert self.Y.shape[1] > 1, "SGD only works with D > 1" + sgd = SGD.StochasticGD(self, iterations, learning_rate, momentum, **kwargs) # @UndefinedVariable + sgd.run() + self.optimization_runs.append(sgd) +
+ def _checkgrad(self, target_param=None, verbose=False, step=1e-6, tolerance=1e-3, df_tolerance=1e-12): + """ + Check the gradient of the ,odel by comparing to a numerical + estimate. If the verbose flag is passed, individual + components are tested (and printed) + + :param verbose: If True, print a "full" checking of each parameter + :type verbose: bool + :param step: The size of the step around which to linearise the objective + :type step: float (default 1e-6) + :param tolerance: the tolerance allowed (see note) + :type tolerance: float (default 1e-3) + + Note:- + The gradient is considered correct if the ratio of the analytical + and numerical gradients is within <tolerance> of unity. + + The *dF_ratio* indicates the limit of numerical accuracy of numerical gradients. + If it is too small, e.g., smaller than 1e-12, the numerical gradients are usually + not accurate enough for the tests (shown with blue). + """ + x = self.optimizer_array.copy() + + if not verbose: + # make sure only to test the selected parameters + if target_param is None: + transformed_index = range(len(x)) + else: + transformed_index = self._raveled_index_for(target_param) + if self._has_fixes(): + indices = np.r_[:self.size] + which = (transformed_index[:, None] == indices[self._fixes_][None, :]).nonzero() + transformed_index = (indices - (~self._fixes_).cumsum())[transformed_index[which[0]]] + + if transformed_index.size == 0: + print "No free parameters to check" + return + + # just check the global ratio + dx = np.zeros(x.shape) + dx[transformed_index] = step * (np.sign(np.random.uniform(-1, 1, transformed_index.size)) if transformed_index.size != 2 else 1.) + + # evaulate around the point x + f1 = self._objective(x + dx) + f2 = self._objective(x - dx) + gradient = self._grads(x) + + dx = dx[transformed_index] + gradient = gradient[transformed_index] + + denominator = (2 * np.dot(dx, gradient)) + global_ratio = (f1 - f2) / np.where(denominator == 0., 1e-32, denominator) + global_diff = np.abs(f1 - f2) < tolerance and np.allclose(gradient, 0, atol=tolerance) + if global_ratio is np.nan: + global_ratio = 0 + return np.abs(1. - global_ratio) < tolerance or global_diff + else: + # check the gradient of each parameter individually, and do some pretty printing + try: + names = self._get_param_names() + except NotImplementedError: + names = ['Variable %i' % i for i in range(len(x))] + # Prepare for pretty-printing + header = ['Name', 'Ratio', 'Difference', 'Analytical', 'Numerical', 'dF_ratio'] + max_names = max([len(names[i]) for i in range(len(names))] + [len(header[0])]) + float_len = 10 + cols = [max_names] + cols.extend([max(float_len, len(header[i])) for i in range(1, len(header))]) + cols = np.array(cols) + 5 + header_string = ["{h:^{col}}".format(h=header[i], col=cols[i]) for i in range(len(cols))] + header_string = map(lambda x: '|'.join(x), [header_string]) + separator = '-' * len(header_string[0]) + print '\n'.join([header_string[0], separator]) + if target_param is None: + param_index = range(len(x)) + transformed_index = param_index + else: + param_index = self._raveled_index_for(target_param) + if self._has_fixes(): + indices = np.r_[:self.size] + which = (param_index[:, None] == indices[self._fixes_][None, :]).nonzero() + param_index = param_index[which[0]] + transformed_index = (indices - (~self._fixes_).cumsum())[param_index] + # print param_index, transformed_index + else: + transformed_index = param_index + + if param_index.size == 0: + print "No free parameters to check" + return + + gradient = self._grads(x).copy() + np.where(gradient == 0, 1e-312, gradient) + ret = True + for nind, xind in itertools.izip(param_index, transformed_index): + xx = x.copy() + xx[xind] += step + f1 = self._objective(xx) + xx[xind] -= 2.*step + f2 = self._objective(xx) + df_ratio = np.abs((f1-f2)/min(f1,f2)) + df_unstable = df_ratio<df_tolerance + numerical_gradient = (f1 - f2) / (2 * step) + if np.all(gradient[xind] == 0): ratio = (f1 - f2) == gradient[xind] + else: ratio = (f1 - f2) / (2 * step * gradient[xind]) + difference = np.abs(numerical_gradient - gradient[xind]) + + if (np.abs(1. - ratio) < tolerance) or np.abs(difference) < tolerance: + formatted_name = "\033[92m {0} \033[0m".format(names[nind]) + ret &= True + else: + formatted_name = "\033[91m {0} \033[0m".format(names[nind]) + ret &= False + if df_unstable: + formatted_name = "\033[94m {0} \033[0m".format(names[nind]) + + r = '%.6f' % float(ratio) + d = '%.6f' % float(difference) + g = '%.6f' % gradient[xind] + ng = '%.6f' % float(numerical_gradient) + df = '%1.e' % float(df_ratio) + grad_string = "{0:<{c0}}|{1:^{c1}}|{2:^{c2}}|{3:^{c3}}|{4:^{c4}}|{5:^{c5}}".format(formatted_name, r, d, g, ng, df, c0=cols[0] + 9, c1=cols[1], c2=cols[2], c3=cols[3], c4=cols[4], c5=cols[5]) + print grad_string + + self.optimizer_array = x + return ret + + def _repr_html_(self): + """Representation of the model in html for notebook display.""" + model_details = [['<b>Model</b>', self.name + '<br>'], + ['<b>Log-likelihood</b>', '{}<br>'.format(float(self.log_likelihood()))], + ["<b>Number of Parameters</b>", '{}<br>'.format(self.size)]] + from operator import itemgetter + to_print = [""] + ["{}: {}".format(name, detail) for name, detail in model_details] + ["<br><b>Parameters</b>:"] + to_print.append(super(Model, self)._repr_html_()) + return "\n".join(to_print) + + def __str__(self): + model_details = [['Name', self.name], + ['Log-likelihood', '{}'.format(float(self.log_likelihood()))], + ["Number of Parameters", '{}'.format(self.size)]] + from operator import itemgetter + max_len = reduce(lambda a, b: max(len(b[0]), a), model_details, 0) + to_print = [""] + ["{0:{l}} : {1}".format(name, detail, l=max_len) for name, detail in model_details] + ["Parameters:"] + to_print.append(super(Model, self).__str__()) + return "\n".join(to_print) +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/parameterization/index_operations.html b/doc/_build/html/_modules/GPy/core/parameterization/index_operations.html new file mode 100644 index 00000000..53b17f41 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/parameterization/index_operations.html @@ -0,0 +1,395 @@ + + + + + + + + GPy.core.parameterization.index_operations — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.parameterization.index_operations

+# Copyright (c) 2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy
+from numpy.lib.function_base import vectorize
+from lists_and_dicts import IntArrayDict
+
+
[docs]def extract_properties_to_index(index, props): + prop_index = dict() + for i, cl in enumerate(props): + for c in cl: + ind = prop_index.get(c, list()) + ind.append(index[i]) + prop_index[c] = ind + + for c, i in prop_index.items(): + prop_index[c] = numpy.array(i, dtype=int) + + return prop_index + +
+
[docs]class ParameterIndexOperations(object): + """ + This object wraps a dictionary, whos keys are _operations_ that we'd like + to apply to a parameter array, and whose values are np integer arrays which + index the parameter array appropriately. + + A model instance will contain one instance of this class for each thing + that needs indexing (i.e. constraints, ties and priors). Parameters within + the model constain instances of the ParameterIndexOperationsView class, + which can map from a 'local' index (starting 0) to this global index. + + Here's an illustration: + + #======================================================================= + model : 0 1 2 3 4 5 6 7 8 9 + key1: 4 5 + key2: 7 8 + + param1: 0 1 2 3 4 5 + key1: 2 3 + key2: 5 + + param2: 0 1 2 3 4 + key1: 0 + key2: 2 3 + #======================================================================= + + The views of this global index have a subset of the keys in this global + (model) index. + + Adding a new key (e.g. a constraint) to a view will cause the view to pass + the new key to the global index, along with the local index and an offset. + This global index then stores the key and the appropriate global index + (which can be seen by the view). + + See also: + ParameterIndexOperationsView + + """ + _offset = 0 + def __init__(self, constraints=None): + self._properties = IntArrayDict() + if constraints is not None: + for t, i in constraints.iteritems(): + self.add(t, i) + +
[docs] def iteritems(self): + return self._properties.iteritems() +
+
[docs] def items(self): + return self._properties.items() +
+
[docs] def properties(self): + return self._properties.keys() +
+
[docs] def iterproperties(self): + return self._properties.iterkeys() +
+
[docs] def shift_right(self, start, size): + for ind in self.iterindices(): + toshift = ind>=start + ind[toshift] += size +
+
[docs] def shift_left(self, start, size): + for v, ind in self.items(): + todelete = (ind>=start) * (ind<start+size) + if todelete.size != 0: + ind = ind[~todelete] + toshift = ind>=start + if toshift.size != 0: + ind[toshift] -= size + if ind.size != 0: self._properties[v] = ind + else: del self._properties[v] +
+
[docs] def clear(self): + self._properties.clear() +
+ @property + def size(self): + return reduce(lambda a,b: a+b.size, self.iterindices(), 0) + +
[docs] def iterindices(self): + return self._properties.itervalues() +
+
[docs] def indices(self): + return self._properties.values() +
+
[docs] def properties_for(self, index): + """ + Returns a list of properties, such that each entry in the list corresponds + to the element of the index given. + + Example: + let properties: 'one':[1,2,3,4], 'two':[3,5,6] + + >>> properties_for([2,3,5]) + [['one'], ['one', 'two'], ['two']] + """ + return vectorize(lambda i: [prop for prop in self.iterproperties() if i in self[prop]], otypes=[list])(index) +
+
[docs] def properties_to_index_dict(self, index): + """ + Return a dictionary, containing properties as keys and indices as index + Thus, the indices for each constraint, which is contained will be collected as + one dictionary + + Example: + let properties: 'one':[1,2,3,4], 'two':[3,5,6] + + >>> properties_to_index_dict([2,3,5]) + {'one':[2,3], 'two':[3,5]} + """ + props = self.properties_for(index) + prop_index = extract_properties_to_index(index, props) + return prop_index +
+
[docs] def add(self, prop, indices): + self._properties[prop] = combine_indices(self._properties[prop], indices) +
+
[docs] def remove(self, prop, indices): + if prop in self._properties: + diff = remove_indices(self[prop], indices) + removed = numpy.intersect1d(self[prop], indices, True) + if not index_empty(diff): + self._properties[prop] = diff + else: + del self._properties[prop] + return removed.astype(int) + return numpy.array([]).astype(int) +
+
[docs] def update(self, parameter_index_view, offset=0): + for i, v in parameter_index_view.iteritems(): + self.add(i, v+offset) +
+
[docs] def copy(self): + return self.__deepcopy__(None) +
+ def __deepcopy__(self, memo): + return ParameterIndexOperations(dict(self.iteritems())) + + def __getitem__(self, prop): + return self._properties[prop] + + def __delitem__(self, prop): + del self._properties[prop] + + def __str__(self, *args, **kwargs): + import pprint + return pprint.pformat(dict(self._properties)) +
+
[docs]def combine_indices(arr1, arr2): + return numpy.union1d(arr1, arr2) +
+
[docs]def remove_indices(arr, to_remove): + return numpy.setdiff1d(arr, to_remove, True) +
+
[docs]def index_empty(index): + return numpy.size(index) == 0 +
+
[docs]class ParameterIndexOperationsView(object): + def __init__(self, param_index_operations, offset, size): + self._param_index_ops = param_index_operations + self._offset = offset + self._size = size + + def __getstate__(self): + return [self._param_index_ops, self._offset, self._size] + + def __setstate__(self, state): + self._param_index_ops = state[0] + self._offset = state[1] + self._size = state[2] + + def _filter_index(self, ind): + return ind[(ind >= self._offset) * (ind < (self._offset + self._size))] - self._offset + + +
[docs] def iteritems(self): + for i, ind in self._param_index_ops.iteritems(): + ind2 = self._filter_index(ind) + if ind2.size > 0: + yield i, ind2 +
+
[docs] def items(self): + return [[i,v] for i,v in self.iteritems()] +
+
[docs] def properties(self): + return [i for i in self.iterproperties()] + +
+
[docs] def iterproperties(self): + for i, _ in self.iteritems(): + yield i + +
+
[docs] def shift_right(self, start, size): + self._param_index_ops.shift_right(start+self._offset, size) +
+
[docs] def shift_left(self, start, size): + self._param_index_ops.shift_left(start+self._offset, size) +
+
[docs] def clear(self): + for i, ind in self.items(): + self._param_index_ops.remove(i, ind+self._offset) +
+ @property + def size(self): + return reduce(lambda a,b: a+b.size, self.iterindices(), 0) + + +
[docs] def iterindices(self): + for _, ind in self.iteritems(): + yield ind + +
+
[docs] def indices(self): + return [ind for ind in self.iterindices()] + +
+
[docs] def properties_for(self, index): + """ + Returns a list of properties, such that each entry in the list corresponds + to the element of the index given. + + Example: + let properties: 'one':[1,2,3,4], 'two':[3,5,6] + + >>> properties_for([2,3,5]) + [['one'], ['one', 'two'], ['two']] + """ + return vectorize(lambda i: [prop for prop in self.iterproperties() if i in self[prop]], otypes=[list])(index) +
+
[docs] def properties_to_index_dict(self, index): + """ + Return a dictionary, containing properties as keys and indices as index + Thus, the indices for each constraint, which is contained will be collected as + one dictionary + + Example: + let properties: 'one':[1,2,3,4], 'two':[3,5,6] + + >>> properties_to_index_dict([2,3,5]) + {'one':[2,3], 'two':[3,5]} + """ + return extract_properties_to_index(index, self.properties_for(index)) + +
+
[docs] def add(self, prop, indices): + self._param_index_ops.add(prop, indices+self._offset) + +
+
[docs] def remove(self, prop, indices): + removed = self._param_index_ops.remove(prop, numpy.array(indices)+self._offset) + if removed.size > 0: + return removed-self._offset + return removed + +
+ def __getitem__(self, prop): + ind = self._filter_index(self._param_index_ops[prop]) + return ind + + def __delitem__(self, prop): + self.remove(prop, self[prop]) + + def __str__(self, *args, **kwargs): + import pprint + return pprint.pformat(dict(self.iteritems())) + +
[docs] def update(self, parameter_index_view, offset=0): + for i, v in parameter_index_view.iteritems(): + self.add(i, v+offset) + +
+
[docs] def copy(self): + return self.__deepcopy__(None) +
+ def __deepcopy__(self, memo): + return ParameterIndexOperations(dict(self.iteritems())) + pass +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/parameterization/lists_and_dicts.html b/doc/_build/html/_modules/GPy/core/parameterization/lists_and_dicts.html new file mode 100644 index 00000000..74cdf4f5 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/parameterization/lists_and_dicts.html @@ -0,0 +1,233 @@ + + + + + + + + GPy.core.parameterization.lists_and_dicts — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.parameterization.lists_and_dicts

+# Copyright (c) 2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from collections import defaultdict
+import weakref
+
+
[docs]def intarray_default_factory(): + import numpy as np + return np.int_([]) +
+
[docs]class IntArrayDict(defaultdict): + def __init__(self, default_factory=None): + """ + Default will be self._default, if not set otherwise + """ + defaultdict.__init__(self, intarray_default_factory) +
+
[docs]class ArrayList(list): + """ + List to store ndarray-likes in. + It will look for 'is' instead of calling __eq__ on each element. + """ + def __contains__(self, other): + for el in self: + if el is other: + return True + return False + +
[docs] def index(self, item): + index = 0 + for el in self: + if el is item: + return index + index += 1 + raise ValueError, "{} is not in list".format(item)
+ pass +
+
[docs]class ObserverList(object): + """ + A list which containts the observables. + It only holds weak references to observers, such that unbound + observers dont dangle in memory. + """ + def __init__(self): + self._poc = [] + + def __getitem__(self, ind): + p,o,c = self._poc[ind] + return p, o(), c + +
[docs] def remove(self, priority, observer, callble): + """ + Remove one observer, which had priority and callble. + """ + self.flush() + for i in range(len(self) - 1, -1, -1): + p,o,c = self[i] + if priority==p and observer==o and callble==c: + del self._poc[i] +
+ def __repr__(self): + return self._poc.__repr__() + +
[docs] def add(self, priority, observer, callble): + """ + Add an observer with priority and callble + """ + if observer is not None: + ins = 0 + for pr, _, _ in self: + if priority > pr: + break + ins += 1 + self._poc.insert(ins, (priority, weakref.ref(observer), callble)) +
+ def __str__(self): + from . import ObsAr, Param + from parameter_core import Parameterizable + ret = [] + curr_p = None + + def frmt(o): + if isinstance(o, ObsAr): + return 'ObsArr <{}>'.format(hex(id(o))) + elif isinstance(o, (Param,Parameterizable)): + return '{}'.format(o.hierarchy_name()) + else: + return repr(o) + for p, o, c in self: + curr = '' + if curr_p != p: + pre = "{!s}: ".format(p) + curr_pre = pre + else: curr_pre = " "*len(pre) + curr_p = p + curr += curr_pre + + ret.append(curr + ", ".join([frmt(o), str(c)])) + return '\n'.join(ret) + +
[docs] def flush(self): + """ + Make sure all weak references, which point to nothing are flushed (deleted) + """ + self._poc = [(p,o,c) for p,o,c in self._poc if o() is not None] +
+ def __iter__(self): + self.flush() + for p, o, c in self._poc: + yield p, o(), c + + def __len__(self): + self.flush() + return self._poc.__len__() + + def __deepcopy__(self, memo): + s = ObserverList() + for p,o,c in self: + import copy + s.add(p, copy.deepcopy(o, memo), copy.deepcopy(c, memo)) + s.flush() + return s + + def __getstate__(self): + self.flush() + from ...util.caching import Cacher + obs = [] + for p, o, c in self: + if (getattr(o, c.__name__, None) is not None + and not isinstance(o, Cacher)): + obs.append((p,o,c.__name__)) + return obs + + def __setstate__(self, state): + self._poc = [] + for p, o, c in state: + self.add(p,o,getattr(o, c)) + + pass
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/parameterization/observable_array.html b/doc/_build/html/_modules/GPy/core/parameterization/observable_array.html new file mode 100644 index 00000000..06ce7878 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/parameterization/observable_array.html @@ -0,0 +1,241 @@ + + + + + + + + GPy.core.parameterization.observable_array — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.parameterization.observable_array

+# Copyright (c) 2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from parameter_core import Pickleable
+from observable import Observable
+
+
[docs]class ObsAr(np.ndarray, Pickleable, Observable): + """ + An ndarray which reports changes to its observers. + The observers can add themselves with a callable, which + will be called every time this array changes. The callable + takes exactly one argument, which is this array itself. + """ + __array_priority__ = -1 # Never give back ObsAr + def __new__(cls, input_array, *a, **kw): + # allways make a copy of input paramters, as we need it to be in C order: + if not isinstance(input_array, ObsAr): + obj = np.atleast_1d(np.require(input_array, dtype=np.float64, requirements=['W', 'C'])).view(cls) + else: obj = input_array + super(ObsAr, obj).__init__(*a, **kw) + return obj + + def __array_finalize__(self, obj): + # see InfoArray.__array_finalize__ for comments + if obj is None: return + self.observers = getattr(obj, 'observers', None) + + def __array_wrap__(self, out_arr, context=None): + return out_arr.view(np.ndarray) + + def _setup_observers(self): + # do not setup anything, as observable arrays do not have default observers + pass + + @property + def values(self): + return self.view(np.ndarray) + +
[docs] def copy(self): + from lists_and_dicts import ObserverList + memo = {} + memo[id(self)] = self + memo[id(self.observers)] = ObserverList() + return self.__deepcopy__(memo) +
+ def __deepcopy__(self, memo): + s = self.__new__(self.__class__, input_array=self.view(np.ndarray).copy()) + memo[id(self)] = s + import copy + Pickleable.__setstate__(s, copy.deepcopy(self.__getstate__(), memo)) + return s + + def __reduce__(self): + func, args, state = super(ObsAr, self).__reduce__() + return func, args, (state, Pickleable.__getstate__(self)) + + def __setstate__(self, state): + np.ndarray.__setstate__(self, state[0]) + Pickleable.__setstate__(self, state[1]) + + def __setitem__(self, s, val): + super(ObsAr, self).__setitem__(s, val) + self.notify_observers() + + def __getslice__(self, start, stop): + return self.__getitem__(slice(start, stop)) + + def __setslice__(self, start, stop, val): + return self.__setitem__(slice(start, stop), val) + + def __ilshift__(self, *args, **kwargs): + r = np.ndarray.__ilshift__(self, *args, **kwargs) + self.notify_observers() + return r + + def __irshift__(self, *args, **kwargs): + r = np.ndarray.__irshift__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __ixor__(self, *args, **kwargs): + r = np.ndarray.__ixor__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __ipow__(self, *args, **kwargs): + r = np.ndarray.__ipow__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __ifloordiv__(self, *args, **kwargs): + r = np.ndarray.__ifloordiv__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __isub__(self, *args, **kwargs): + r = np.ndarray.__isub__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __ior__(self, *args, **kwargs): + r = np.ndarray.__ior__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __itruediv__(self, *args, **kwargs): + r = np.ndarray.__itruediv__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __idiv__(self, *args, **kwargs): + r = np.ndarray.__idiv__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __iand__(self, *args, **kwargs): + r = np.ndarray.__iand__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __imod__(self, *args, **kwargs): + r = np.ndarray.__imod__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __iadd__(self, *args, **kwargs): + r = np.ndarray.__iadd__(self, *args, **kwargs) + self.notify_observers() + return r + + + def __imul__(self, *args, **kwargs): + r = np.ndarray.__imul__(self, *args, **kwargs) + self.notify_observers() + return r
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/parameterization/param.html b/doc/_build/html/_modules/GPy/core/parameterization/param.html new file mode 100644 index 00000000..59068bac --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/parameterization/param.html @@ -0,0 +1,570 @@ + + + + + + + + GPy.core.parameterization.param — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.parameterization.param

+# Copyright (c) 2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import itertools
+import numpy
+np = numpy
+from parameter_core import Parameterizable, adjust_name_for_printing, Pickleable
+from observable_array import ObsAr
+
+###### printing
+__constraints_name__ = "Constraint"
+__index_name__ = "Index"
+__tie_name__ = "Tied to"
+__priors_name__ = "Prior"
+__precision__ = numpy.get_printoptions()['precision'] # numpy printing precision used, sublassing numpy ndarray after all
+__print_threshold__ = 5
+######
+
+
[docs]class Param(Parameterizable, ObsAr): + """ + Parameter object for GPy models. + + :param str name: name of the parameter to be printed + :param input_array: array which this parameter handles + :type input_array: numpy.ndarray + :param default_constraint: The default constraint for this parameter + :type default_constraint: + + You can add/remove constraints by calling constrain on the parameter itself, e.g: + + - self[:,1].constrain_positive() + - self[0].tie_to(other) + - self.untie() + - self[:3,:].unconstrain() + - self[1].fix() + + Fixing parameters will fix them to the value they are right now. If you change + the fixed value, it will be fixed to the new value! + + See :py:class:`GPy.core.parameterized.Parameterized` for more details on constraining etc. + + """ + __array_priority__ = -1 # Never give back Param + _fixes_ = None + parameters = [] + def __new__(cls, name, input_array, default_constraint=None): + obj = numpy.atleast_1d(super(Param, cls).__new__(cls, input_array=input_array)) + obj._current_slice_ = (slice(obj.shape[0]),) + obj._realshape_ = obj.shape + obj._realsize_ = obj.size + obj._realndim_ = obj.ndim + obj._original_ = obj + return obj + + def __init__(self, name, input_array, default_constraint=None, *a, **kw): + self._in_init_ = True + super(Param, self).__init__(name=name, default_constraint=default_constraint, *a, **kw) + self._in_init_ = False + +
[docs] def build_pydot(self,G): + import pydot + node = pydot.Node(id(self), shape='trapezium', label=self.name)#, fontcolor='white', color='white') + G.add_node(node) + for _, o, _ in self.observers: + label = o.name if hasattr(o, 'name') else str(o) + observed_node = pydot.Node(id(o), label=label) + G.add_node(observed_node) + edge = pydot.Edge(str(id(self)), str(id(o)), color='darkorange2', arrowhead='vee') + G.add_edge(edge) + + return node +
+ def __array_finalize__(self, obj): + # see InfoArray.__array_finalize__ for comments + if obj is None: return + super(Param, self).__array_finalize__(obj) + self._parent_ = getattr(obj, '_parent_', None) + self._parent_index_ = getattr(obj, '_parent_index_', None) + self._default_constraint_ = getattr(obj, '_default_constraint_', None) + self._current_slice_ = getattr(obj, '_current_slice_', None) + self._realshape_ = getattr(obj, '_realshape_', None) + self._realsize_ = getattr(obj, '_realsize_', None) + self._realndim_ = getattr(obj, '_realndim_', None) + self._original_ = getattr(obj, '_original_', None) + self._name = getattr(obj, '_name', None) + self._gradient_array_ = getattr(obj, '_gradient_array_', None) + self.constraints = getattr(obj, 'constraints', None) + self.priors = getattr(obj, 'priors', None) + + @property + def param_array(self): + """ + As we are a leaf, this just returns self + """ + return self + + @property + def values(self): + """ + Return self as numpy array view + """ + return self.view(np.ndarray) + + @property + def gradient(self): + """ + Return a view on the gradient, which is in the same shape as this parameter is. + Note: this is not the real gradient array, it is just a view on it. + + To work on the real gradient array use: self.full_gradient + """ + if getattr(self, '_gradient_array_', None) is None: + self._gradient_array_ = numpy.empty(self._realshape_, dtype=numpy.float64) + return self._gradient_array_#[self._current_slice_] + + @gradient.setter + def gradient(self, val): + self._gradient_array_[:] = val + + #=========================================================================== + # Array operations -> done + #=========================================================================== + def __getitem__(self, s, *args, **kwargs): + if not isinstance(s, tuple): + s = (s,) + #if not reduce(lambda a, b: a or numpy.any(b is Ellipsis), s, False) and len(s) <= self.ndim: + # s += (Ellipsis,) + new_arr = super(Param, self).__getitem__(s, *args, **kwargs) + try: + new_arr._current_slice_ = s + new_arr._gradient_array_ = self.gradient[s] + new_arr._original_ = self._original_ + except AttributeError: pass # returning 0d array or float, double etc + return new_arr + + def _raveled_index(self, slice_index=None): + # return an index array on the raveled array, which is formed by the current_slice + # of this object + extended_realshape = numpy.cumprod((1,) + self._realshape_[:0:-1])[::-1] + ind = self._indices(slice_index) + if ind.ndim < 2: ind = ind[:, None] + return numpy.asarray(numpy.apply_along_axis(lambda x: numpy.sum(extended_realshape * x), 1, ind), dtype=int) + + def _raveled_index_for(self, obj): + return self._raveled_index() + + #=========================================================================== + # Constrainable + #=========================================================================== + def _ensure_fixes(self): + if not self._has_fixes(): self._fixes_ = numpy.ones(self._realsize_, dtype=bool) + + #=========================================================================== + # Convenience + #=========================================================================== + @property + def is_fixed(self): + from transformations import __fixed__ + return self.constraints[__fixed__].size == self.size + + def _get_original(self, param): + return self._original_ + + #=========================================================================== + # Pickling and copying + #=========================================================================== +
[docs] def copy(self): + return Parameterizable.copy(self, which=self) +
+ def __deepcopy__(self, memo): + s = self.__new__(self.__class__, name=self.name, input_array=self.view(numpy.ndarray).copy()) + memo[id(self)] = s + import copy + Pickleable.__setstate__(s, copy.deepcopy(self.__getstate__(), memo)) + return s + def _setup_observers(self): + """ + Setup the default observers + + 1: pass through to parent, if present + """ + if self.has_parent(): + self.add_observer(self._parent_, self._parent_._pass_through_notify_observers, -np.inf) + + #=========================================================================== + # Printing -> done + #=========================================================================== + @property + def _description_str(self): + if self.size <= 1: + return [str(self.view(numpy.ndarray)[0])] + else: return [str(self.shape)] +
[docs] def parameter_names(self, add_self=False, adjust_for_printing=False, recursive=True): + # this is just overwrighting the parameterized calls to parameter names, in order to maintain OOP + if adjust_for_printing: + return [adjust_name_for_printing(self.name)] + return [self.name]
+ @property + def flattened_parameters(self): + return [self] + @property + def parameter_shapes(self): + return [self.shape] + @property + def num_params(self): + return 0 + @property + def _constraints_str(self): + return [' '.join(map(lambda c: str(c[0]) if c[1].size == self._realsize_ else "{" + str(c[0]) + "}", self.constraints.iteritems()))] + @property + def _priors_str(self): + return [' '.join(map(lambda c: str(c[0]) if c[1].size == self._realsize_ else "{" + str(c[0]) + "}", self.priors.iteritems()))] + @property + def _ties_str(self): + return [''] + def _ties_for(self, ravi): + return [['N/A']]*ravi.size + def __repr__(self, *args, **kwargs): + name = "\033[1m{x:s}\033[0;0m:\n".format( + x=self.hierarchy_name()) + return name + super(Param, self).__repr__(*args, **kwargs) + def _indices(self, slice_index=None): + # get a int-array containing all indices in the first axis. + if slice_index is None: + slice_index = self._current_slice_ + try: + indices = np.indices(self._realshape_, dtype=int) + indices = indices[(slice(None),)+slice_index] + indices = np.rollaxis(indices, 0, indices.ndim).reshape(-1,self._realndim_) + #print indices_ + #if not np.all(indices==indices__): + # import ipdb; ipdb.set_trace() + except: + indices = np.indices(self._realshape_, dtype=int) + indices = indices[(slice(None),)+slice_index] + indices = np.rollaxis(indices, 0, indices.ndim) + return indices + def _max_len_names(self, gen, header): + gen = map(lambda x: " ".join(map(str, x)), gen) + return reduce(lambda a, b:max(a, len(b)), gen, len(header)) + def _max_len_values(self): + return reduce(lambda a, b:max(a, len("{x:=.{0}g}".format(__precision__, x=b))), self.flat, len(self.hierarchy_name())) + def _max_len_index(self, ind): + return reduce(lambda a, b:max(a, len(str(b))), ind, len(__index_name__)) + def _short(self): + # short string to print + name = self.hierarchy_name() + if self._realsize_ < 2: + return name + ind = self._indices() + if ind.size > 4: indstr = ','.join(map(str, ind[:2])) + "..." + ','.join(map(str, ind[-2:])) + else: indstr = ','.join(map(str, ind)) + return name + '[' + indstr + ']' + + def _repr_html_(self, constr_matrix=None, indices=None, prirs=None, ties=None): + """Representation of the parameter in html for notebook display.""" + filter_ = self._current_slice_ + vals = self.flat + if indices is None: indices = self._indices(filter_) + ravi = self._raveled_index(filter_) + if constr_matrix is None: constr_matrix = self.constraints.properties_for(ravi) + if prirs is None: prirs = self.priors.properties_for(ravi) + if ties is None: ties = self._ties_for(ravi) + ties = [' '.join(map(lambda x: x, t)) for t in ties] + header_format = """ +<tr> + <td><b>{i}</b></td> + <td><b>{x}</b></td> + <td><b>{c}</b></td> + <td><b>{p}</b></td> + <td><b>{t}</b></td> +</tr>""" + header = header_format.format(x=self.hierarchy_name(), c=__constraints_name__, i=__index_name__, t=__tie_name__, p=__priors_name__) # nice header for printing + if not ties: ties = itertools.cycle(['']) + return "\n".join(['<table>'] + [header] + ["<tr><td>{i}</td><td align=\"right\">{x}</td><td>{c}</td><td>{p}</td><td>{t}</td></tr>".format(x=x, c=" ".join(map(str, c)), p=" ".join(map(str, p)), t=(t or ''), i=i) for i, x, c, t, p in itertools.izip(indices, vals, constr_matrix, ties, prirs)] + ["</table>"]) + + def __str__(self, constr_matrix=None, indices=None, prirs=None, ties=None, lc=None, lx=None, li=None, lp=None, lt=None, only_name=False): + filter_ = self._current_slice_ + vals = self.flat + if indices is None: indices = self._indices(filter_) + ravi = self._raveled_index(filter_) + if constr_matrix is None: constr_matrix = self.constraints.properties_for(ravi) + if prirs is None: prirs = self.priors.properties_for(ravi) + if ties is None: ties = self._ties_for(ravi) + ties = [' '.join(map(lambda x: x, t)) for t in ties] + if lc is None: lc = self._max_len_names(constr_matrix, __constraints_name__) + if lx is None: lx = self._max_len_values() + if li is None: li = self._max_len_index(indices) + if lt is None: lt = self._max_len_names(ties, __tie_name__) + if lp is None: lp = self._max_len_names(prirs, __tie_name__) + sep = '-' + header_format = " {i:{5}^{2}s} | \033[1m{x:{5}^{1}s}\033[0;0m | {c:{5}^{0}s} | {p:{5}^{4}s} | {t:{5}^{3}s}" + if only_name: header = header_format.format(lc, lx, li, lt, lp, ' ', x=self.hierarchy_name(), c=sep*lc, i=sep*li, t=sep*lt, p=sep*lp) # nice header for printing + else: header = header_format.format(lc, lx, li, lt, lp, ' ', x=self.hierarchy_name(), c=__constraints_name__, i=__index_name__, t=__tie_name__, p=__priors_name__) # nice header for printing + if not ties: ties = itertools.cycle(['']) + return "\n".join([header] + [" {i!s:^{3}s} | {x: >{1}.{2}g} | {c:^{0}s} | {p:^{5}s} | {t:^{4}s} ".format(lc, lx, __precision__, li, lt, lp, x=x, c=" ".join(map(str, c)), p=" ".join(map(str, p)), t=(t or ''), i=i) for i, x, c, t, p in itertools.izip(indices, vals, constr_matrix, ties, prirs)]) # return all the constraints with right indices + # except: return super(Param, self).__str__() +
+
[docs]class ParamConcatenation(object): + def __init__(self, params): + """ + Parameter concatenation for convenience of printing regular expression matched arrays + you can index this concatenation as if it was the flattened concatenation + of all the parameters it contains, same for setting parameters (Broadcasting enabled). + + See :py:class:`GPy.core.parameter.Param` for more details on constraining. + """ + # self.params = params + from lists_and_dicts import ArrayList + self.params = ArrayList([]) + for p in params: + for p in p.flattened_parameters: + if p not in self.params: + self.params.append(p) + self._param_sizes = [p.size for p in self.params] + startstops = numpy.cumsum([0] + self._param_sizes) + self._param_slices_ = [slice(start, stop) for start,stop in zip(startstops, startstops[1:])] + + parents = dict() + for p in self.params: + if p.has_parent(): + parent = p._parent_ + level = 0 + while parent is not None: + if parent in parents: + parents[parent] = max(level, parents[parent]) + else: + parents[parent] = level + level += 1 + parent = parent._parent_ + import operator + self.parents = map(lambda x: x[0], sorted(parents.iteritems(), key=operator.itemgetter(1))) + #=========================================================================== + # Get/set items, enable broadcasting + #=========================================================================== + def __getitem__(self, s): + ind = numpy.zeros(sum(self._param_sizes), dtype=bool); ind[s] = True; + params = [p.param_array.flat[ind[ps]] for p,ps in zip(self.params, self._param_slices_) if numpy.any(p.param_array.flat[ind[ps]])] + if len(params)==1: return params[0] + return ParamConcatenation(params) + def __setitem__(self, s, val, update=True): + if isinstance(val, ParamConcatenation): + val = val.values() + ind = numpy.zeros(sum(self._param_sizes), dtype=bool); ind[s] = True; + vals = self.values(); vals[s] = val + for p, ps in zip(self.params, self._param_slices_): + p.flat[ind[ps]] = vals[ps] + if update: + self.update_all_params() +
[docs] def values(self): + return numpy.hstack([p.param_array.flat for p in self.params]) + #=========================================================================== + # parameter operations: + #===========================================================================
+
[docs] def update_all_params(self): + for par in self.parents: + par.notify_observers() +
+
[docs] def constrain(self, constraint, warning=True): + [param.constrain(constraint, trigger_parent=False) for param in self.params] + self.update_all_params()
+ constrain.__doc__ = Param.constrain.__doc__ + +
[docs] def constrain_positive(self, warning=True): + [param.constrain_positive(warning, trigger_parent=False) for param in self.params] + self.update_all_params()
+ constrain_positive.__doc__ = Param.constrain_positive.__doc__ + +
[docs] def constrain_fixed(self, value=None, warning=True, trigger_parent=True): + [param.constrain_fixed(value, warning, trigger_parent) for param in self.params]
+ constrain_fixed.__doc__ = Param.constrain_fixed.__doc__ + fix = constrain_fixed + +
[docs] def constrain_negative(self, warning=True): + [param.constrain_negative(warning, trigger_parent=False) for param in self.params] + self.update_all_params()
+ constrain_negative.__doc__ = Param.constrain_negative.__doc__ + +
[docs] def constrain_bounded(self, lower, upper, warning=True): + [param.constrain_bounded(lower, upper, warning, trigger_parent=False) for param in self.params] + self.update_all_params()
+ constrain_bounded.__doc__ = Param.constrain_bounded.__doc__ + +
[docs] def unconstrain(self, *constraints): + [param.unconstrain(*constraints) for param in self.params]
+ unconstrain.__doc__ = Param.unconstrain.__doc__ + +
[docs] def unconstrain_negative(self): + [param.unconstrain_negative() for param in self.params]
+ unconstrain_negative.__doc__ = Param.unconstrain_negative.__doc__ + +
[docs] def unconstrain_positive(self): + [param.unconstrain_positive() for param in self.params]
+ unconstrain_positive.__doc__ = Param.unconstrain_positive.__doc__ + +
[docs] def unconstrain_fixed(self): + [param.unconstrain_fixed() for param in self.params]
+ unconstrain_fixed.__doc__ = Param.unconstrain_fixed.__doc__ + unfix = unconstrain_fixed + +
[docs] def unconstrain_bounded(self, lower, upper): + [param.unconstrain_bounded(lower, upper) for param in self.params]
+ unconstrain_bounded.__doc__ = Param.unconstrain_bounded.__doc__ + +
[docs] def untie(self, *ties): + [param.untie(*ties) for param in self.params] +
+
[docs] def checkgrad(self, verbose=0, step=1e-6, tolerance=1e-3): + return self.params[0]._highest_parent_._checkgrad(self, verbose, step, tolerance) + #checkgrad.__doc__ = Gradcheckable.checkgrad.__doc__ +
+ __lt__ = lambda self, val: self.values() < val + __le__ = lambda self, val: self.values() <= val + __eq__ = lambda self, val: self.values() == val + __ne__ = lambda self, val: self.values() != val + __gt__ = lambda self, val: self.values() > val + __ge__ = lambda self, val: self.values() >= val + def __str__(self, *args, **kwargs): + def f(p): + ind = p._raveled_index() + return p.constraints.properties_for(ind), p._ties_for(ind), p.priors.properties_for(ind) + params = self.params + constr_matrices, ties_matrices, prior_matrices = zip(*map(f, params)) + indices = [p._indices() for p in params] + lc = max([p._max_len_names(cm, __constraints_name__) for p, cm in itertools.izip(params, constr_matrices)]) + lx = max([p._max_len_values() for p in params]) + li = max([p._max_len_index(i) for p, i in itertools.izip(params, indices)]) + lt = max([p._max_len_names(tm, __tie_name__) for p, tm in itertools.izip(params, ties_matrices)]) + lp = max([p._max_len_names(pm, __constraints_name__) for p, pm in itertools.izip(params, prior_matrices)]) + strings = [] + start = True + for p, cm, i, tm, pm in itertools.izip(params,constr_matrices,indices,ties_matrices,prior_matrices): + strings.append(p.__str__(constr_matrix=cm, indices=i, prirs=pm, ties=tm, lc=lc, lx=lx, li=li, lp=lp, lt=lt, only_name=(1-start))) + start = False + return "\n".join(strings) + def __repr__(self): + return "\n".join(map(repr,self.params)) + + def __ilshift__(self, *args, **kwargs): + self[:] = np.ndarray.__ilshift__(self.values(), *args, **kwargs) + + def __irshift__(self, *args, **kwargs): + self[:] = np.ndarray.__irshift__(self.values(), *args, **kwargs) + + def __ixor__(self, *args, **kwargs): + self[:] = np.ndarray.__ixor__(self.values(), *args, **kwargs) + + def __ipow__(self, *args, **kwargs): + self[:] = np.ndarray.__ipow__(self.values(), *args, **kwargs) + + def __ifloordiv__(self, *args, **kwargs): + self[:] = np.ndarray.__ifloordiv__(self.values(), *args, **kwargs) + + def __isub__(self, *args, **kwargs): + self[:] = np.ndarray.__isub__(self.values(), *args, **kwargs) + + def __ior__(self, *args, **kwargs): + self[:] = np.ndarray.__ior__(self.values(), *args, **kwargs) + + def __itruediv__(self, *args, **kwargs): + self[:] = np.ndarray.__itruediv__(self.values(), *args, **kwargs) + + def __idiv__(self, *args, **kwargs): + self[:] = np.ndarray.__idiv__(self.values(), *args, **kwargs) + + def __iand__(self, *args, **kwargs): + self[:] = np.ndarray.__iand__(self.values(), *args, **kwargs) + + def __imod__(self, *args, **kwargs): + self[:] = np.ndarray.__imod__(self.values(), *args, **kwargs) + + def __iadd__(self, *args, **kwargs): + self[:] = np.ndarray.__iadd__(self.values(), *args, **kwargs) + + def __imul__(self, *args, **kwargs): + self[:] = np.ndarray.__imul__(self.values(), *args, **kwargs)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/parameterization/parameter_core.html b/doc/_build/html/_modules/GPy/core/parameterization/parameter_core.html new file mode 100644 index 00000000..51f2c794 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/parameterization/parameter_core.html @@ -0,0 +1,1130 @@ + + + + + + + + GPy.core.parameterization.parameter_core — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.parameterization.parameter_core

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+"""
+Core module for parameterization.
+This module implements all parameterization techniques, split up in modular bits.
+
+HierarchyError:
+raised when an error with the hierarchy occurs (circles etc.)
+
+Observable:
+Observable Pattern for patameterization
+
+
+"""
+
+from transformations import Transformation,Logexp, NegativeLogexp, Logistic, __fixed__, FIXED, UNFIXED
+import numpy as np
+import re
+import logging
+from updateable import Updateable
+
+
[docs]class HierarchyError(Exception): + """ + Gets thrown when something is wrong with the parameter hierarchy. + """ +
+
[docs]def adjust_name_for_printing(name): + """ + Make sure a name can be printed, alongside used as a variable name. + """ + if name is not None: + name2 = name + name = name.replace(" ", "_").replace(".", "_").replace("-", "_m_") + name = name.replace("+", "_p_").replace("!", "_I_") + name = name.replace("**", "_xx_").replace("*", "_x_") + name = name.replace("/", "_l_").replace("@", '_at_') + name = name.replace("(", "_of_").replace(")", "") + if re.match(r'^[a-zA-Z_][a-zA-Z0-9-_]*$', name) is None: + raise NameError, "name {} converted to {} cannot be further converted to valid python variable name!".format(name2, name) + return name + return '' + + +
+
[docs]class Parentable(object): + """ + Enable an Object to have a parent. + + Additionally this adds the parent_index, which is the index for the parent + to look for in its parameter list. + """ + _parent_ = None + _parent_index_ = None + def __init__(self, *args, **kwargs): + super(Parentable, self).__init__() + +
[docs] def has_parent(self): + """ + Return whether this parentable object currently has a parent. + """ + return self._parent_ is not None +
+ def _parent_changed(self): + """ + Gets called, when the parent changed, so we can adjust our + inner attributes according to the new parent. + """ + raise NotImplementedError, "shouldnt happen, Parentable objects need to be able to change their parent" + + def _disconnect_parent(self, *args, **kw): + """ + Disconnect this object from its parent + """ + raise NotImplementedError, "Abstract superclass" + + @property + def _highest_parent_(self): + """ + Gets the highest parent by traversing up to the root node of the hierarchy. + """ + if self._parent_ is None: + return self + return self._parent_._highest_parent_ + + def _notify_parent_change(self): + """ + Dont do anything if in leaf node + """ + pass +
+
[docs]class Pickleable(object): + """ + Make an object pickleable (See python doc 'pickling'). + + This class allows for pickling support by Memento pattern. + _getstate returns a memento of the class, which gets pickled. + _setstate(<memento>) (re-)sets the state of the class to the memento + """ + def __init__(self, *a, **kw): + super(Pickleable, self).__init__() + + #=========================================================================== + # Pickling operations + #=========================================================================== +
[docs] def pickle(self, f, protocol=-1): + """ + :param f: either filename or open file object to write to. + if it is an open buffer, you have to make sure to close + it properly. + :param protocol: pickling protocol to use, python-pickle for details. + """ + import cPickle as pickle + if isinstance(f, str): + with open(f, 'wb') as f: + pickle.dump(self, f, protocol) + else: + pickle.dump(self, f, protocol) + + #=========================================================================== + # copy and pickling + #===========================================================================
+
[docs] def copy(self, memo=None, which=None): + """ + Returns a (deep) copy of the current parameter handle. + + All connections to parents of the copy will be cut. + + :param dict memo: memo for deepcopy + :param Parameterized which: parameterized object which started the copy process [default: self] + """ + #raise NotImplementedError, "Copy is not yet implemented, TODO: Observable hierarchy" + if memo is None: + memo = {} + import copy + # the next part makes sure that we do not include parents in any form: + parents = [] + if which is None: + which = self + which.traverse_parents(parents.append) # collect parents + for p in parents: + if not memo.has_key(id(p)):memo[id(p)] = None # set all parents to be None, so they will not be copied + if not memo.has_key(id(self.gradient)):memo[id(self.gradient)] = None # reset the gradient + if not memo.has_key(id(self._fixes_)):memo[id(self._fixes_)] = None # fixes have to be reset, as this is now highest parent + copy = copy.deepcopy(self, memo) # and start the copy + copy._parent_index_ = None + copy._trigger_params_changed() + return copy +
+ def __deepcopy__(self, memo): + s = self.__new__(self.__class__) # fresh instance + memo[id(self)] = s # be sure to break all cycles --> self is already done + import copy + s.__setstate__(copy.deepcopy(self.__getstate__(), memo)) # standard copy + return s + + def __getstate__(self): + ignore_list = ['_param_array_', # parameters get set from bottom to top + '_gradient_array_', # as well as gradients + '_optimizer_copy_', + 'logger', + 'observers', + '_fixes_', # and fixes + '_Cacher_wrap__cachers', # never pickle cachers + ] + dc = dict() + for k,v in self.__dict__.iteritems(): + if k not in ignore_list: + dc[k] = v + return dc + + def __setstate__(self, state): + self.__dict__.update(state) + from lists_and_dicts import ObserverList + self.observers = ObserverList() + self._setup_observers() + self._optimizer_copy_transformed = False + +
+
[docs]class Gradcheckable(Pickleable, Parentable): + """ + Adds the functionality for an object to be gradcheckable. + It is just a thin wrapper of a call to the highest parent for now. + TODO: Can be done better, by only changing parameters of the current parameter handle, + such that object hierarchy only has to change for those. + """ + def __init__(self, *a, **kw): + super(Gradcheckable, self).__init__(*a, **kw) + +
[docs] def checkgrad(self, verbose=0, step=1e-6, tolerance=1e-3, df_tolerance=1e-12): + """ + Check the gradient of this parameter with respect to the highest parent's + objective function. + This is a three point estimate of the gradient, wiggling at the parameters + with a stepsize step. + The check passes if either the ratio or the difference between numerical and + analytical gradient is smaller then tolerance. + + :param bool verbose: whether each parameter shall be checked individually. + :param float step: the stepsize for the numerical three point gradient estimate. + :param float tolerance: the tolerance for the gradient ratio or difference. + :param float df_tolerance: the tolerance for df_tolerance + + Note:- + The *dF_ratio* indicates the limit of accuracy of numerical gradients. + If it is too small, e.g., smaller than 1e-12, the numerical gradients + are usually not accurate enough for the tests (shown with blue). + """ + if self.has_parent(): + return self._highest_parent_._checkgrad(self, verbose=verbose, step=step, tolerance=tolerance, df_tolerance=df_tolerance) + return self._checkgrad(self, verbose=verbose, step=step, tolerance=tolerance, df_tolerance=df_tolerance) +
+ def _checkgrad(self, param, verbose=0, step=1e-6, tolerance=1e-3): + """ + Perform the checkgrad on the model. + TODO: this can be done more efficiently, when doing it inside here + """ + raise HierarchyError, "This parameter is not in a model with a likelihood, and, therefore, cannot be gradient checked!" +
+
[docs]class Nameable(Gradcheckable): + """ + Make an object nameable inside the hierarchy. + """ + def __init__(self, name, *a, **kw): + super(Nameable, self).__init__(*a, **kw) + self._name = name or self.__class__.__name__ + + @property + def name(self): + """ + The name of this object + """ + return self._name + @name.setter + def name(self, name): + """ + Set the name of this object. + Tell the parent if the name has changed. + """ + from_name = self.name + assert isinstance(name, str) + self._name = name + if self.has_parent(): + self._parent_._name_changed(self, from_name) +
[docs] def hierarchy_name(self, adjust_for_printing=True): + """ + return the name for this object with the parents names attached by dots. + + :param bool adjust_for_printing: whether to call :func:`~adjust_for_printing()` + on the names, recursively + """ + if adjust_for_printing: adjust = lambda x: adjust_name_for_printing(x) + else: adjust = lambda x: x + if self.has_parent(): + return self._parent_.hierarchy_name() + "." + adjust(self.name) + return adjust(self.name) + +
+
[docs]class Indexable(Nameable, Updateable): + """ + Make an object constrainable with Priors and Transformations. + TODO: Mappings!! + Adding a constraint to a Parameter means to tell the highest parent that + the constraint was added and making sure that all parameters covered + by this object are indeed conforming to the constraint. + + :func:`constrain()` and :func:`unconstrain()` are main methods here + """ + def __init__(self, name, default_constraint=None, *a, **kw): + super(Indexable, self).__init__(name=name, *a, **kw) + self._default_constraint_ = default_constraint + from index_operations import ParameterIndexOperations + self.constraints = ParameterIndexOperations() + self.priors = ParameterIndexOperations() + if self._default_constraint_ is not None: + self.constrain(self._default_constraint_) + + def _disconnect_parent(self, constr=None, *args, **kw): + """ + From Parentable: + disconnect the parent and set the new constraints to constr + """ + if constr is None: + constr = self.constraints.copy() + self.constraints.clear() + self.constraints = constr + self._parent_ = None + self._parent_index_ = None + self._connect_fixes() + self._notify_parent_change() + + #=========================================================================== + # Indexable + #=========================================================================== + def _offset_for(self, param): + """ + Return the offset of the param inside this parameterized object. + This does not need to account for shaped parameters, as it + basically just sums up the parameter sizes which come before param. + """ + if param.has_parent(): + p = param._parent_._get_original(param) + if p in self.parameters: + return reduce(lambda a,b: a + b.size, self.parameters[:p._parent_index_], 0) + return self._offset_for(param._parent_) + param._parent_._offset_for(param) + return 0 + + def _raveled_index_for(self, param): + """ + get the raveled index for a param + that is an int array, containing the indexes for the flattened + param inside this parameterized logic. + """ + from param import ParamConcatenation + if isinstance(param, ParamConcatenation): + return np.hstack((self._raveled_index_for(p) for p in param.params)) + return param._raveled_index() + self._offset_for(param) + + def _raveled_index(self): + """ + Flattened array of ints, specifying the index of this object. + This has to account for shaped parameters! + """ + return np.r_[:self.size] + + #=========================================================================== + # Fixing Parameters: + #=========================================================================== +
[docs] def constrain_fixed(self, value=None, warning=True, trigger_parent=True): + """ + Constrain this parameter to be fixed to the current value it carries. + + :param warning: print a warning for overwriting constraints. + """ + if value is not None: + self[:] = value + + index = self.unconstrain() + index = self._add_to_index_operations(self.constraints, index, __fixed__, warning) + self._highest_parent_._set_fixed(self, index) + self.notify_observers(self, None if trigger_parent else -np.inf) + return index
+ fix = constrain_fixed + +
[docs] def unconstrain_fixed(self): + """ + This parameter will no longer be fixed. + """ + unconstrained = self.unconstrain(__fixed__) + self._highest_parent_._set_unfixed(self, unconstrained) + return unconstrained
+ unfix = unconstrain_fixed + + def _ensure_fixes(self): + # Ensure that the fixes array is set: + # Parameterized: ones(self.size) + # Param: ones(self._realsize_ + if not self._has_fixes(): self._fixes_ = np.ones(self.size, dtype=bool) + + def _set_fixed(self, param, index): + self._ensure_fixes() + offset = self._offset_for(param) + self._fixes_[index+offset] = FIXED + if np.all(self._fixes_): self._fixes_ = None # ==UNFIXED + + def _set_unfixed(self, param, index): + self._ensure_fixes() + offset = self._offset_for(param) + self._fixes_[index+offset] = UNFIXED + if np.all(self._fixes_): self._fixes_ = None # ==UNFIXED + + def _connect_fixes(self): + fixed_indices = self.constraints[__fixed__] + if fixed_indices.size > 0: + self._ensure_fixes() + self._fixes_[fixed_indices] = FIXED + else: + self._fixes_ = None + del self.constraints[__fixed__] + + #=========================================================================== + # Convenience for fixed + #=========================================================================== + def _has_fixes(self): + return hasattr(self, "_fixes_") and self._fixes_ is not None and self._fixes_.size == self.size + + @property + def is_fixed(self): + for p in self.parameters: + if not p.is_fixed: return False + return True + + def _get_original(self, param): + # if advanced indexing is activated it happens that the array is a copy + # you can retrieve the original param through this method, by passing + # the copy here + return self.parameters[param._parent_index_] + + #=========================================================================== + # Prior Operations + #=========================================================================== +
[docs] def set_prior(self, prior, warning=True): + """ + Set the prior for this object to prior. + :param :class:`~GPy.priors.Prior` prior: a prior to set for this parameter + :param bool warning: whether to warn if another prior was set for this parameter + """ + repriorized = self.unset_priors() + self._add_to_index_operations(self.priors, repriorized, prior, warning) + + from domains import _REAL, _POSITIVE, _NEGATIVE + if prior.domain is _POSITIVE: + self.constrain_positive(warning) + elif prior.domain is _NEGATIVE: + self.constrain_negative(warning) + elif prior.domain is _REAL: + rav_i = self._raveled_index() + assert all(all(False if c is __fixed__ else c.domain is _REAL for c in con) for con in self.constraints.properties_for(rav_i)), 'Domain of prior and constraint have to match, please unconstrain if you REALLY wish to use this prior' +
+
[docs] def unset_priors(self, *priors): + """ + Un-set all priors given (in *priors) from this parameter handle. + """ + return self._remove_from_index_operations(self.priors, priors) +
+
[docs] def log_prior(self): + """evaluate the prior""" + if self.priors.size > 0: + x = self.param_array + return reduce(lambda a, b: a + b, (p.lnpdf(x[ind]).sum() for p, ind in self.priors.iteritems()), 0) + return 0. +
+ def _log_prior_gradients(self): + """evaluate the gradients of the priors""" + if self.priors.size > 0: + x = self.param_array + ret = np.zeros(x.size) + [np.put(ret, ind, p.lnpdf_grad(x[ind])) for p, ind in self.priors.iteritems()] + return ret + return 0. + + #=========================================================================== + # Tie parameters together + #=========================================================================== + + def _has_ties(self): + if self._highest_parent_.tie.tied_param is None: + return False + if self.has_parent(): + return self._highest_parent_.tie.label_buf[self._highest_parent_._raveled_index_for(self)].sum()>0 + return True + +
[docs] def tie_together(self): + self._highest_parent_.tie.add_tied_parameter(self) + self._highest_parent_._set_fixed(self,self._raveled_index()) + self._trigger_params_changed() + + #=========================================================================== + # Constrain operations -> done + #=========================================================================== +
+
[docs] def constrain(self, transform, warning=True, trigger_parent=True): + """ + :param transform: the :py:class:`GPy.core.transformations.Transformation` + to constrain the this parameter to. + :param warning: print a warning if re-constraining parameters. + + Constrain the parameter to the given + :py:class:`GPy.core.transformations.Transformation`. + """ + if isinstance(transform, Transformation): + self.param_array[...] = transform.initialize(self.param_array) + reconstrained = self.unconstrain() + added = self._add_to_index_operations(self.constraints, reconstrained, transform, warning) + self.notify_observers(self, None if trigger_parent else -np.inf) + return added +
+
[docs] def unconstrain(self, *transforms): + """ + :param transforms: The transformations to unconstrain from. + + remove all :py:class:`GPy.core.transformations.Transformation` + transformats of this parameter object. + """ + return self._remove_from_index_operations(self.constraints, transforms) +
+
[docs] def constrain_positive(self, warning=True, trigger_parent=True): + """ + :param warning: print a warning if re-constraining parameters. + + Constrain this parameter to the default positive constraint. + """ + self.constrain(Logexp(), warning=warning, trigger_parent=trigger_parent) +
+
[docs] def constrain_negative(self, warning=True, trigger_parent=True): + """ + :param warning: print a warning if re-constraining parameters. + + Constrain this parameter to the default negative constraint. + """ + self.constrain(NegativeLogexp(), warning=warning, trigger_parent=trigger_parent) +
+
[docs] def constrain_bounded(self, lower, upper, warning=True, trigger_parent=True): + """ + :param lower, upper: the limits to bound this parameter to + :param warning: print a warning if re-constraining parameters. + + Constrain this parameter to lie within the given range. + """ + self.constrain(Logistic(lower, upper), warning=warning, trigger_parent=trigger_parent) +
+
[docs] def unconstrain_positive(self): + """ + Remove positive constraint of this parameter. + """ + self.unconstrain(Logexp()) +
+
[docs] def unconstrain_negative(self): + """ + Remove negative constraint of this parameter. + """ + self.unconstrain(NegativeLogexp()) +
+
[docs] def unconstrain_bounded(self, lower, upper): + """ + :param lower, upper: the limits to unbound this parameter from + + Remove (lower, upper) bounded constrain from this parameter/ + """ + self.unconstrain(Logistic(lower, upper)) +
+ def _parent_changed(self, parent): + """ + From Parentable: + Called when the parent changed + + update the constraints and priors view, so that + constraining is automized for the parent. + """ + from index_operations import ParameterIndexOperationsView + #if getattr(self, "_in_init_"): + #import ipdb;ipdb.set_trace() + #self.constraints.update(param.constraints, start) + #self.priors.update(param.priors, start) + offset = parent._offset_for(self) + self.constraints = ParameterIndexOperationsView(parent.constraints, offset, self.size) + self.priors = ParameterIndexOperationsView(parent.priors, offset, self.size) + self._fixes_ = None + for p in self.parameters: + p._parent_changed(parent) + + def _add_to_index_operations(self, which, reconstrained, what, warning): + """ + Helper preventing copy code. + This adds the given what (transformation, prior etc) to parameter index operations which. + reconstrained are reconstrained indices. + warn when reconstraining parameters if warning is True. + TODO: find out which parameters have changed specifically + """ + if warning and reconstrained.size > 0: + # TODO: figure out which parameters have changed and only print those + print "WARNING: reconstraining parameters {}".format(self.hierarchy_name() or self.name) + index = self._raveled_index() + which.add(what, index) + return index + + def _remove_from_index_operations(self, which, transforms): + """ + Helper preventing copy code. + Remove given what (transform prior etc) from which param index ops. + """ + if len(transforms) == 0: + transforms = which.properties() + removed = np.empty((0,), dtype=int) + for t in transforms: + unconstrained = which.remove(t, self._raveled_index()) + removed = np.union1d(removed, unconstrained) + if t is __fixed__: + self._highest_parent_._set_unfixed(self, unconstrained) + + return removed +
+
[docs]class OptimizationHandlable(Indexable): + """ + This enables optimization handles on an Object as done in GPy 0.4. + + `..._optimizer_copy_transformed`: make sure the transformations and constraints etc are handled + """ + def __init__(self, name, default_constraint=None, *a, **kw): + super(OptimizationHandlable, self).__init__(name, default_constraint=default_constraint, *a, **kw) + self._optimizer_copy_ = None + self._optimizer_copy_transformed = False + + #=========================================================================== + # Optimizer copy + #=========================================================================== + @property + def optimizer_array(self): + """ + Array for the optimizer to work on. + This array always lives in the space for the optimizer. + Thus, it is untransformed, going from Transformations. + + Setting this array, will make sure the transformed parameters for this model + will be set accordingly. It has to be set with an array, retrieved from + this method, as e.g. fixing will resize the array. + + The optimizer should only interfere with this array, such that transformations + are secured. + """ + if self.__dict__.get('_optimizer_copy_', None) is None or self.size != self._optimizer_copy_.size: + self._optimizer_copy_ = np.empty(self.size) + + if not self._optimizer_copy_transformed: + self._optimizer_copy_.flat = self.param_array.flat + [np.put(self._optimizer_copy_, ind, c.finv(self.param_array[ind])) for c, ind in self.constraints.iteritems() if c != __fixed__] + if self.has_parent() and (self.constraints[__fixed__].size != 0 or self._has_ties()): + fixes = np.ones(self.size).astype(bool) + fixes[self.constraints[__fixed__]] = FIXED + return self._optimizer_copy_[np.logical_and(fixes, self._highest_parent_.tie.getTieFlag(self))] + elif self._has_fixes(): + return self._optimizer_copy_[self._fixes_] + + self._optimizer_copy_transformed = True + + return self._optimizer_copy_ + + @optimizer_array.setter + def optimizer_array(self, p): + """ + Make sure the optimizer copy does not get touched, thus, we only want to + set the values *inside* not the array itself. + + Also we want to update param_array in here. + """ + f = None + if self.has_parent() and self.constraints[__fixed__].size != 0: + f = np.ones(self.size).astype(bool) + f[self.constraints[__fixed__]] = FIXED + elif self._has_fixes(): + f = self._fixes_ + if f is None: + self.param_array.flat = p + [np.put(self.param_array, ind, c.f(self.param_array.flat[ind])) + for c, ind in self.constraints.iteritems() if c != __fixed__] + else: + self.param_array.flat[f] = p + [np.put(self.param_array, ind[f[ind]], c.f(self.param_array.flat[ind[f[ind]]])) + for c, ind in self.constraints.iteritems() if c != __fixed__] + #self._highest_parent_.tie.propagate_val() + + self._optimizer_copy_transformed = False + self.trigger_update() + + def _get_params_transformed(self): + raise DeprecationWarning, "_get|set_params{_optimizer_copy_transformed} is deprecated, use self.optimizer array insetad!" +# + def _set_params_transformed(self, p): + raise DeprecationWarning, "_get|set_params{_optimizer_copy_transformed} is deprecated, use self.optimizer array insetad!" + + def _trigger_params_changed(self, trigger_parent=True): + """ + First tell all children to update, + then update yourself. + + If trigger_parent is True, we will tell the parent, otherwise not. + """ + [p._trigger_params_changed(trigger_parent=False) for p in self.parameters if not p.is_fixed] + self.notify_observers(None, None if trigger_parent else -np.inf) + + def _size_transformed(self): + """ + As fixes are not passed to the optimiser, the size of the model for the optimiser + is the size of all parameters minus the size of the fixes. + """ + return self.size - self.constraints[__fixed__].size + + def _transform_gradients(self, g): + """ + Transform the gradients by multiplying the gradient factor for each + constraint to it. + """ + self._highest_parent_.tie.collate_gradient() + [np.put(g, i, c.gradfactor(self.param_array[i], g[i])) for c, i in self.constraints.iteritems() if c != __fixed__] + if self._has_fixes(): return g[self._fixes_] + return g + + @property + def num_params(self): + """ + Return the number of parameters of this parameter_handle. + Param objects will always return 0. + """ + raise NotImplemented, "Abstract, please implement in respective classes" + +
[docs] def parameter_names(self, add_self=False, adjust_for_printing=False, recursive=True): + """ + Get the names of all parameters of this model. + + :param bool add_self: whether to add the own name in front of names + :param bool adjust_for_printing: whether to call `adjust_name_for_printing` on names + :param bool recursive: whether to traverse through hierarchy and append leaf node names + """ + if adjust_for_printing: adjust = lambda x: adjust_name_for_printing(x) + else: adjust = lambda x: x + if recursive: names = [xi for x in self.parameters for xi in x.parameter_names(add_self=True, adjust_for_printing=adjust_for_printing)] + else: names = [adjust(x.name) for x in self.parameters] + if add_self: names = map(lambda x: adjust(self.name) + "." + x, names) + return names +
+ def _get_param_names(self): + n = np.array([p.hierarchy_name() + '[' + str(i) + ']' for p in self.flattened_parameters for i in p._indices()]) + return n + + def _get_param_names_transformed(self): + n = self._get_param_names() + if self._has_fixes(): + return n[self._fixes_] + return n + + #=========================================================================== + # Randomizeable + #=========================================================================== +
[docs] def randomize(self, rand_gen=None, *args, **kwargs): + """ + Randomize the model. + Make this draw from the prior if one exists, else draw from given random generator + + :param rand_gen: np random number generator which takes args and kwargs + :param flaot loc: loc parameter for random number generator + :param float scale: scale parameter for random number generator + :param args, kwargs: will be passed through to random number generator + """ + if rand_gen is None: + rand_gen = np.random.normal + # first take care of all parameters (from N(0,1)) + x = rand_gen(size=self._size_transformed(), *args, **kwargs) + updates = self.update_model() + self.update_model(False) # Switch off the updates + self.optimizer_array = x # makes sure all of the tied parameters get the same init (since there's only one prior object...) + # now draw from prior where possible + x = self.param_array.copy() + [np.put(x, ind, p.rvs(ind.size)) for p, ind in self.priors.iteritems() if not p is None] + unfixlist = np.ones((self.size,),dtype=np.bool) + unfixlist[self.constraints[__fixed__]] = False + self.param_array.flat[unfixlist] = x.view(np.ndarray).ravel()[unfixlist] + self.update_model(updates) + + #=========================================================================== + # For shared memory arrays. This does nothing in Param, but sets the memory + # for all parameterized objects + #===========================================================================
+ @property + def gradient_full(self): + """ + Note to users: + This does not return the gradient in the right shape! Use self.gradient + for the right gradient array. + + To work on the gradient array, use this as the gradient handle. + This method exists for in memory use of parameters. + When trying to access the true gradient array, use this. + """ + self.gradient # <<< ensure _gradient_array_ + return self._gradient_array_ + + def _propagate_param_grad(self, parray, garray): + """ + For propagating the param_array and gradient_array. + This ensures the in memory view of each subsequent array. + + 1.) connect param_array of children to self.param_array + 2.) tell all children to propagate further + """ + if self.param_array.size != self.size: + self._param_array_ = np.empty(self.size, dtype=np.float64) + if self.gradient.size != self.size: + self._gradient_array_ = np.empty(self.size, dtype=np.float64) + + pi_old_size = 0 + for pi in self.parameters: + pislice = slice(pi_old_size, pi_old_size + pi.size) + + self.param_array[pislice] = pi.param_array.flat # , requirements=['C', 'W']).flat + self.gradient_full[pislice] = pi.gradient_full.flat # , requirements=['C', 'W']).flat + + pi.param_array.data = parray[pislice].data + pi.gradient_full.data = garray[pislice].data + + pi._propagate_param_grad(parray[pislice], garray[pislice]) + pi_old_size += pi.size + + def _connect_parameters(self): + pass +
+_name_digit = re.compile("(?P<name>.*)_(?P<digit>\d+)$") +
[docs]class Parameterizable(OptimizationHandlable): + """ + A parameterisable class. + + This class provides the parameters list (ArrayList) and standard parameter handling, + such as {add|remove}_parameter(), traverse hierarchy and param_array, gradient_array + and the empty parameters_changed(). + + This class is abstract and should not be instantiated. + Use GPy.core.Parameterized() as node (or leaf) in the parameterized hierarchy. + Use GPy.core.Param() for a leaf in the parameterized hierarchy. + """ + def __init__(self, *args, **kwargs): + super(Parameterizable, self).__init__(*args, **kwargs) + from GPy.core.parameterization.lists_and_dicts import ArrayList + self.parameters = ArrayList() + self._param_array_ = None + self._added_names_ = set() + self.logger = logging.getLogger(self.__class__.__name__) + self.__visited = False # for traversing in reverse order we need to know if we were here already + + @property + def param_array(self): + """ + Array representing the parameters of this class. + There is only one copy of all parameters in memory, two during optimization. + + !WARNING!: setting the parameter array MUST always be done in memory: + m.param_array[:] = m_copy.param_array + """ + if (self.__dict__.get('_param_array_', None) is None) or (self._param_array_.size != self.size): + self._param_array_ = np.empty(self.size, dtype=np.float64) + return self._param_array_ + + @property + def unfixed_param_array(self): + """ + Array representing the parameters of this class. + There is only one copy of all parameters in memory, two during optimization. + + !WARNING!: setting the parameter array MUST always be done in memory: + m.param_array[:] = m_copy.param_array + """ + if self.__dict__.get('_param_array_', None) is None: + self._param_array_ = np.empty(self.size, dtype=np.float64) + + if self.constraints[__fixed__].size !=0: + fixes = np.ones(self.size).astype(bool) + fixes[self.constraints[__fixed__]] = FIXED + return self._param_array_[fixes] + else: + return self._param_array_ + + @param_array.setter + def param_array(self, arr): + self._param_array_ = arr + +
[docs] def traverse(self, visit, *args, **kwargs): + """ + Traverse the hierarchy performing visit(self, *args, **kwargs) + at every node passed by downwards. This function includes self! + + See "visitor pattern" in literature. This is implemented in pre-order fashion. + + Example: + Collect all children: + + children = [] + self.traverse(children.append) + print children + """ + if not self.__visited: + visit(self, *args, **kwargs) + self.__visited = True + for c in self.parameters: + c.traverse(visit, *args, **kwargs) + self.__visited = False +
+
[docs] def traverse_parents(self, visit, *args, **kwargs): + """ + Traverse the hierarchy upwards, visiting all parents and their children except self. + See "visitor pattern" in literature. This is implemented in pre-order fashion. + + Example: + + parents = [] + self.traverse_parents(parents.append) + print parents + """ + if self.has_parent(): + self.__visited = True + self._parent_._traverse_parents(visit, *args, **kwargs) + self.__visited = False +
+ def _traverse_parents(self, visit, *args, **kwargs): + if not self.__visited: + self.__visited = True + visit(self, *args, **kwargs) + if self.has_parent(): + self._parent_._traverse_parents(visit, *args, **kwargs) + self._parent_.traverse(visit, *args, **kwargs) + self.__visited = False + + #========================================================================= + # Gradient handling + #========================================================================= + @property + def gradient(self): + if (self.__dict__.get('_gradient_array_', None) is None) or self._gradient_array_.size != self.size: + self._gradient_array_ = np.empty(self.size, dtype=np.float64) + return self._gradient_array_ + + @gradient.setter + def gradient(self, val): + self._gradient_array_[:] = val + + @property + def num_params(self): + return len(self.parameters) + + def _add_parameter_name(self, param, ignore_added_names=False): + pname = adjust_name_for_printing(param.name) + if ignore_added_names: + self.__dict__[pname] = param + return + + def warn_and_retry(param, match=None): + #=================================================================== + # print """ + # WARNING: added a parameter with formatted name {}, + # which is already assigned to {}. + # Trying to change the parameter name to + # + # {}.{} + # """.format(pname, self.hierarchy_name(), self.hierarchy_name(), param.name + "_") + #=================================================================== + if match is None: + param.name += "_1" + else: + param.name = match.group('name') + "_" + str(int(match.group('digit'))+1) + self._add_parameter_name(param, ignore_added_names) + # and makes sure to not delete programmatically added parameters + for other in self.parameters[::-1]: + if other is not param and other.name.startswith(param.name): + warn_and_retry(param, _name_digit.match(other.name)) + return + if pname not in dir(self): + self.__dict__[pname] = param + self._added_names_.add(pname) + elif pname in self.__dict__: + if pname in self._added_names_: + other = self.__dict__[pname] + if not (param is other): + del self.__dict__[pname] + self._added_names_.remove(pname) + warn_and_retry(other) + warn_and_retry(param, _name_digit.match(other.name)) + return + + def _remove_parameter_name(self, param=None, pname=None): + assert param is None or pname is None, "can only delete either param by name, or the name of a param" + pname = adjust_name_for_printing(pname) or adjust_name_for_printing(param.name) + if pname in self._added_names_: + del self.__dict__[pname] + self._added_names_.remove(pname) + self._connect_parameters() + + def _name_changed(self, param, old_name): + self._remove_parameter_name(None, old_name) + self._add_parameter_name(param) + + def __setstate__(self, state): + super(Parameterizable, self).__setstate__(state) + self.logger = logging.getLogger(self.__class__.__name__) + return self + + #=========================================================================== + # notification system + #=========================================================================== + def _parameters_changed_notification(self, me, which=None): + """ + In parameterizable we just need to make sure, that the next call to optimizer_array + will update the optimizer_array to the latest parameters + """ + self._optimizer_copy_transformed = False # tells the optimizer array to update on next request + self.parameters_changed() + def _pass_through_notify_observers(self, me, which=None): + self.notify_observers(which=which) + def _setup_observers(self): + """ + Setup the default observers + + 1: parameters_changed_notify + 2: pass through to parent, if present + """ + self.add_observer(self, self._parameters_changed_notification, -100) + if self.has_parent(): + self.add_observer(self._parent_, self._parent_._pass_through_notify_observers, -np.inf) + #=========================================================================== + # From being parentable, we have to define the parent_change notification + #=========================================================================== + def _notify_parent_change(self): + """ + Notify all parameters that the parent has changed + """ + for p in self.parameters: + p._parent_changed(self) + +
[docs] def parameters_changed(self): + """ + This method gets called when parameters have changed. + Another way of listening to param changes is to + add self as a listener to the param, such that + updates get passed through. See :py:function:``GPy.core.param.Observable.add_observer`` + """ + pass +
+
[docs] def save(self, filename, ftype='HDF5'): + """ + Save all the model parameters into a file (HDF5 by default). + """ + from . import Param + from ...util.misc import param_to_array + def gather_params(self, plist): + if isinstance(self,Param): + plist.append(self) + plist = [] + self.traverse(gather_params, plist) + names = self.parameter_names(adjust_for_printing=True) + if ftype=='HDF5': + try: + import h5py + f = h5py.File(filename,'w') + for p,n in zip(plist,names): + n = n.replace('.','_') + p = param_to_array(p) + d = f.create_dataset(n,p.shape,dtype=p.dtype) + d[:] = p + f.close() + except: + raise 'Fails to write the parameters into a HDF5 file!' +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/parameterization/parameterized.html b/doc/_build/html/_modules/GPy/core/parameterization/parameterized.html new file mode 100644 index 00000000..2dc72f86 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/parameterization/parameterized.html @@ -0,0 +1,510 @@ + + + + + + + + GPy.core.parameterization.parameterized — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.parameterization.parameterized

+# Copyright (c) 2014, Max Zwiessele, James Hensman
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy; np = numpy
+import itertools
+from re import compile, _pattern_type
+from param import ParamConcatenation
+from parameter_core import HierarchyError, Parameterizable, adjust_name_for_printing
+
+import logging
+from GPy.core.parameterization.index_operations import ParameterIndexOperationsView
+logger = logging.getLogger("parameters changed meta")
+
+
[docs]class ParametersChangedMeta(type): + def __call__(self, *args, **kw): + self._in_init_ = True + #import ipdb;ipdb.set_trace() + self = super(ParametersChangedMeta, self).__call__(*args, **kw) + logger.debug("finished init") + self._in_init_ = False + logger.debug("connecting parameters") + self._highest_parent_._connect_parameters() + #self._highest_parent_._notify_parent_change() + self._highest_parent_._connect_fixes() + logger.debug("calling parameters changed") + self.parameters_changed() + return self +
+
[docs]class Parameterized(Parameterizable): + """ + Parameterized class + + Say m is a handle to a parameterized class. + + Printing parameters: + + - print m: prints a nice summary over all parameters + - print m.name: prints details for param with name 'name' + - print m[regexp]: prints details for all the parameters + which match (!) regexp + - print m['']: prints details for all parameters + + Fields: + + Name: The name of the param, can be renamed! + Value: Shape or value, if one-valued + Constrain: constraint of the param, curly "{c}" brackets indicate + some parameters are constrained by c. See detailed print + to get exact constraints. + Tied_to: which paramter it is tied to. + + Getting and setting parameters: + + Set all values in param to one: + + m.name.to.param = 1 + + Handling of constraining, fixing and tieing parameters: + + You can constrain parameters by calling the constrain on the param itself, e.g: + + - m.name[:,1].constrain_positive() + - m.name[0].tie_to(m.name[1]) + + Fixing parameters will fix them to the value they are right now. If you change + the parameters value, the param will be fixed to the new value! + + If you want to operate on all parameters use m[''] to wildcard select all paramters + and concatenate them. Printing m[''] will result in printing of all parameters in detail. + """ + #=========================================================================== + # Metaclass for parameters changed after init. + # This makes sure, that parameters changed will always be called after __init__ + # **Never** call parameters_changed() yourself + __metaclass__ = ParametersChangedMeta + #=========================================================================== + def __init__(self, name=None, parameters=[], *a, **kw): + super(Parameterized, self).__init__(name=name, *a, **kw) + self.size = sum(p.size for p in self.parameters) + self.add_observer(self, self._parameters_changed_notification, -100) + if not self._has_fixes(): + self._fixes_ = None + self._param_slices_ = [] + #self._connect_parameters() + self.link_parameters(*parameters) + +
[docs] def build_pydot(self, G=None): + import pydot # @UnresolvedImport + iamroot = False + if G is None: + G = pydot.Dot(graph_type='digraph', bgcolor=None) + iamroot=True + node = pydot.Node(id(self), shape='box', label=self.name)#, color='white') + G.add_node(node) + for child in self.parameters: + child_node = child.build_pydot(G) + G.add_edge(pydot.Edge(node, child_node))#, color='white')) + + for _, o, _ in self.observers: + label = o.name if hasattr(o, 'name') else str(o) + observed_node = pydot.Node(id(o), label=label) + G.add_node(observed_node) + edge = pydot.Edge(str(id(self)), str(id(o)), color='darkorange2', arrowhead='vee') + G.add_edge(edge) + + if iamroot: + return G + return node + + #=========================================================================== + # Add remove parameters: + #===========================================================================
+ + + +
[docs] def add_parameter(self, *args, **kwargs): + raise DeprecationWarning, "add_parameter was renamed to link_parameter to avoid confusion of setting variables"
+
[docs] def remove_parameter(self, *args, **kwargs): + raise DeprecationWarning, "remove_parameter was renamed to link_parameter to avoid confusion of setting variables" +
+ def _connect_parameters(self, ignore_added_names=False): + # connect parameterlist to this parameterized object + # This just sets up the right connection for the params objects + # to be used as parameters + # it also sets the constraints for each parameter to the constraints + # of their respective parents + if not hasattr(self, "parameters") or len(self.parameters) < 1: + # no parameters for this class + return + if self.param_array.size != self.size: + self._param_array_ = np.empty(self.size, dtype=np.float64) + if self.gradient.size != self.size: + self._gradient_array_ = np.empty(self.size, dtype=np.float64) + + old_size = 0 + self._param_slices_ = [] + for i, p in enumerate(self.parameters): + if not p.param_array.flags['C_CONTIGUOUS']: + raise ValueError, "This should not happen! Please write an email to the developers with the code, which reproduces this error. All parameter arrays must be C_CONTIGUOUS" + + p._parent_ = self + p._parent_index_ = i + + pslice = slice(old_size, old_size + p.size) + + # first connect all children + p._propagate_param_grad(self.param_array[pslice], self.gradient_full[pslice]) + + # then connect children to self + self.param_array[pslice] = p.param_array.flat # , requirements=['C', 'W']).ravel(order='C') + self.gradient_full[pslice] = p.gradient_full.flat # , requirements=['C', 'W']).ravel(order='C') + + p.param_array.data = self.param_array[pslice].data + p.gradient_full.data = self.gradient_full[pslice].data + + self._param_slices_.append(pslice) + + self._add_parameter_name(p, ignore_added_names=ignore_added_names) + old_size += p.size + + #=========================================================================== + # Get/set parameters: + #=========================================================================== +
[docs] def grep_param_names(self, regexp): + """ + create a list of parameters, matching regular expression regexp + """ + if not isinstance(regexp, _pattern_type): regexp = compile(regexp) + found_params = [] + for n, p in itertools.izip(self.parameter_names(False, False, True), self.flattened_parameters): + if regexp.match(n) is not None: + found_params.append(p) + return found_params +
+ def __getitem__(self, name, paramlist=None): + if isinstance(name, (int, slice, tuple, np.ndarray)): + return self.param_array[name] + else: + if paramlist is None: + paramlist = self.grep_param_names(name) + if len(paramlist) < 1: raise AttributeError, name + if len(paramlist) == 1: + if isinstance(paramlist[-1], Parameterized): + paramlist = paramlist[-1].flattened_parameters + if len(paramlist) != 1: + return ParamConcatenation(paramlist) + return paramlist[-1] + return ParamConcatenation(paramlist) + + def __setitem__(self, name, value, paramlist=None): + if value is None: + return # nothing to do here + if isinstance(name, (slice, tuple, np.ndarray)): + try: + self.param_array[name] = value + except: + raise ValueError, "Setting by slice or index only allowed with array-like" + self._trigger_params_changed() + else: + try: param = self.__getitem__(name, paramlist) + except: raise + param[:] = value + + def __setattr__(self, name, val): + # override the default behaviour, if setting a param, so broadcasting can by used + if hasattr(self, "parameters"): + try: + pnames = self.parameter_names(False, adjust_for_printing=True, recursive=False) + if name in pnames: + param = self.parameters[pnames.index(name)] + param[:] = val; return + except AttributeError: + pass + object.__setattr__(self, name, val); + + #=========================================================================== + # Pickling + #=========================================================================== + def __setstate__(self, state): + super(Parameterized, self).__setstate__(state) + try: + self._connect_parameters() + self._connect_fixes() + self._notify_parent_change() + self.parameters_changed() + except Exception as e: + print "WARNING: caught exception {!s}, trying to continue".format(e) + +
[docs] def copy(self, memo=None): + if memo is None: + memo = {} + memo[id(self.optimizer_array)] = None # and param_array + memo[id(self.param_array)] = None # and param_array + copy = super(Parameterized, self).copy(memo) + copy._connect_parameters() + copy._connect_fixes() + copy._notify_parent_change() + return copy + + #=========================================================================== + # Printing: + #===========================================================================
+ def _short(self): + return self.hierarchy_name() + @property + def flattened_parameters(self): + return [xi for x in self.parameters for xi in x.flattened_parameters] + @property + def _parameter_sizes_(self): + return [x.size for x in self.parameters] + @property + def parameter_shapes(self): + return [xi for x in self.parameters for xi in x.parameter_shapes] + @property + def _constraints_str(self): + return [cs for p in self.parameters for cs in p._constraints_str] + @property + def _priors_str(self): + return [cs for p in self.parameters for cs in p._priors_str] + @property + def _description_str(self): + return [xi for x in self.parameters for xi in x._description_str] + @property + def _ties_str(self): + return [','.join(x._ties_str) for x in self.flattened_parameters] + + def _repr_html_(self, header=True): + """Representation of the parameters in html for notebook display.""" + name = adjust_name_for_printing(self.name) + "." + constrs = self._constraints_str; + ts = self._ties_str + prirs = self._priors_str + desc = self._description_str; names = self.parameter_names() + nl = max([len(str(x)) for x in names + [name]]) + sl = max([len(str(x)) for x in desc + ["Value"]]) + cl = max([len(str(x)) if x else 0 for x in constrs + ["Constraint"]]) + tl = max([len(str(x)) if x else 0 for x in ts + ["Tied to"]]) + pl = max([len(str(x)) if x else 0 for x in prirs + ["Prior"]]) + format_spec = "<tr><td>{{name:<{0}s}}</td><td align=\"right\">{{desc:>{1}s}}</td><td>{{const:^{2}s}}</td><td>{{pri:^{3}s}}</td><td>{{t:^{4}s}}</td></tr>".format(nl, sl, cl, pl, tl) + to_print = [] + for n, d, c, t, p in itertools.izip(names, desc, constrs, ts, prirs): + to_print.append(format_spec.format(name=n, desc=d, const=c, t=t, pri=p)) + sep = '-' * (nl + sl + cl + + pl + tl + 8 * 2 + 3) + if header: + header = """ +<tr> + <td><b>{name}</b> + <td><b>Value</b></td> + <td><b>Constraint</b></td> + <td><b>Prior</b></td> + <td><b>Tied to</b></td>""".format(name=name) + to_print.insert(0, header) + return '<table>' + '\n'.format(sep).join(to_print) + '\n</table>' + + def __str__(self, header=True): + name = adjust_name_for_printing(self.name) + "." + constrs = self._constraints_str; + ts = self._ties_str + prirs = self._priors_str + desc = self._description_str; names = self.parameter_names() + nl = max([len(str(x)) for x in names + [name]]) + sl = max([len(str(x)) for x in desc + ["Value"]]) + cl = max([len(str(x)) if x else 0 for x in constrs + ["Constraint"]]) + tl = max([len(str(x)) if x else 0 for x in ts + ["Tied to"]]) + pl = max([len(str(x)) if x else 0 for x in prirs + ["Prior"]]) + format_spec = " \033[1m{{name:<{0}s}}\033[0;0m | {{desc:>{1}s}} | {{const:^{2}s}} | {{pri:^{3}s}} | {{t:^{4}s}}".format(nl, sl, cl, pl, tl) + to_print = [] + for n, d, c, t, p in itertools.izip(names, desc, constrs, ts, prirs): + to_print.append(format_spec.format(name=n, desc=d, const=c, t=t, pri=p)) + sep = '-' * (nl + sl + cl + + pl + tl + 8 * 2 + 3) + if header: + header = " {{0:<{0}s}} | {{1:^{1}s}} | {{2:^{2}s}} | {{3:^{3}s}} | {{4:^{4}s}}".format(nl, sl, cl, pl, tl).format(name, "Value", "Constraint", "Prior", "Tied to") + to_print.insert(0, header) + return '\n'.format(sep).join(to_print) + pass +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/parameterization/priors.html b/doc/_build/html/_modules/GPy/core/parameterization/priors.html new file mode 100644 index 00000000..9167e8a2 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/parameterization/priors.html @@ -0,0 +1,864 @@ + + + + + + + + GPy.core.parameterization.priors — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.parameterization.priors

+# Copyright (c) 2012 - 2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from scipy.special import gammaln, digamma
+from ...util.linalg import pdinv
+from domains import _REAL, _POSITIVE
+import warnings
+import weakref
+
+
+
[docs]class Prior(object): + domain = None + _instance = None + def __new__(cls, *args, **kwargs): + if not cls._instance or cls._instance.__class__ is not cls: + cls._instance = super(Prior, cls).__new__(cls, *args, **kwargs) + return cls._instance + +
[docs] def pdf(self, x): + return np.exp(self.lnpdf(x)) +
+
[docs] def plot(self): + import sys + + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ...plotting.matplot_dep import priors_plots + + priors_plots.univariate_plot(self) +
+ def __repr__(self, *args, **kwargs): + return self.__str__() + +
+
[docs]class Gaussian(Prior): + """ + Implementation of the univariate Gaussian probability function, coupled with random variables. + + :param mu: mean + :param sigma: standard deviation + + .. Note:: Bishop 2006 notation is used throughout the code + + """ + domain = _REAL + _instances = [] + + def __new__(cls, mu=0, sigma=1): # Singleton: + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if instance().mu == mu and instance().sigma == sigma: + return instance() + o = super(Prior, cls).__new__(cls, mu, sigma) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, mu, sigma): + self.mu = float(mu) + self.sigma = float(sigma) + self.sigma2 = np.square(self.sigma) + self.constant = -0.5 * np.log(2 * np.pi * self.sigma2) + + def __str__(self): + return "N({:.2g}, {:.2g})".format(self.mu, self.sigma) + +
[docs] def lnpdf(self, x): + return self.constant - 0.5 * np.square(x - self.mu) / self.sigma2 +
+
[docs] def lnpdf_grad(self, x): + return -(x - self.mu) / self.sigma2 +
+
[docs] def rvs(self, n): + return np.random.randn(n) * self.sigma + self.mu + +# def __getstate__(self): +# return self.mu, self.sigma +# +# def __setstate__(self, state): +# self.mu = state[0] +# self.sigma = state[1] +# self.sigma2 = np.square(self.sigma) +# self.constant = -0.5 * np.log(2 * np.pi * self.sigma2) +
+
[docs]class Uniform(Prior): + domain = _REAL + _instances = [] + + def __new__(cls, lower=0, upper=1): # Singleton: + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if instance().lower == lower and instance().upper == upper: + return instance() + o = super(Prior, cls).__new__(cls, lower, upper) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, lower, upper): + self.lower = float(lower) + self.upper = float(upper) + + def __str__(self): + return "[{:.2g}, {:.2g}]".format(self.lower, self.upper) + +
[docs] def lnpdf(self, x): + region = (x >= self.lower) * (x <= self.upper) + return region +
+
[docs] def lnpdf_grad(self, x): + return np.zeros(x.shape) +
+
[docs] def rvs(self, n): + return np.random.uniform(self.lower, self.upper, size=n) + +# def __getstate__(self): +# return self.lower, self.upper +# +# def __setstate__(self, state): +# self.lower = state[0] +# self.upper = state[1] +
+
[docs]class LogGaussian(Gaussian): + """ + Implementation of the univariate *log*-Gaussian probability function, coupled with random variables. + + :param mu: mean + :param sigma: standard deviation + + .. Note:: Bishop 2006 notation is used throughout the code + + """ + domain = _POSITIVE + _instances = [] + + def __new__(cls, mu=0, sigma=1): # Singleton: + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if instance().mu == mu and instance().sigma == sigma: + return instance() + o = super(Prior, cls).__new__(cls, mu, sigma) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, mu, sigma): + self.mu = float(mu) + self.sigma = float(sigma) + self.sigma2 = np.square(self.sigma) + self.constant = -0.5 * np.log(2 * np.pi * self.sigma2) + + def __str__(self): + return "lnN({:.2g}, {:.2g})".format(self.mu, self.sigma) + +
[docs] def lnpdf(self, x): + return self.constant - 0.5 * np.square(np.log(x) - self.mu) / self.sigma2 - np.log(x) +
+
[docs] def lnpdf_grad(self, x): + return -((np.log(x) - self.mu) / self.sigma2 + 1.) / x +
+
[docs] def rvs(self, n): + return np.exp(np.random.randn(n) * self.sigma + self.mu) + +
+
[docs]class MultivariateGaussian(Prior): + """ + Implementation of the multivariate Gaussian probability function, coupled with random variables. + + :param mu: mean (N-dimensional array) + :param var: covariance matrix (NxN) + + .. Note:: Bishop 2006 notation is used throughout the code + + """ + domain = _REAL + _instances = [] + + def __new__(cls, mu=0, var=1): # Singleton: + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if np.all(instance().mu == mu) and np.all(instance().var == var): + return instance() + o = super(Prior, cls).__new__(cls, mu, var) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, mu, var): + self.mu = np.array(mu).flatten() + self.var = np.array(var) + assert len(self.var.shape) == 2 + assert self.var.shape[0] == self.var.shape[1] + assert self.var.shape[0] == self.mu.size + self.input_dim = self.mu.size + self.inv, self.hld = pdinv(self.var) + self.constant = -0.5 * self.input_dim * np.log(2 * np.pi) - self.hld + +
[docs] def summary(self): + raise NotImplementedError +
+
[docs] def pdf(self, x): + return np.exp(self.lnpdf(x)) +
+
[docs] def lnpdf(self, x): + d = x - self.mu + return self.constant - 0.5 * np.sum(d * np.dot(d, self.inv), 1) +
+
[docs] def lnpdf_grad(self, x): + d = x - self.mu + return -np.dot(self.inv, d) +
+
[docs] def rvs(self, n): + return np.random.multivariate_normal(self.mu, self.var, n) +
+
[docs] def plot(self): + import sys + + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import priors_plots + + priors_plots.multivariate_plot(self) +
+ def __getstate__(self): + return self.mu, self.var + + def __setstate__(self, state): + self.mu = state[0] + self.var = state[1] + assert len(self.var.shape) == 2 + assert self.var.shape[0] == self.var.shape[1] + assert self.var.shape[0] == self.mu.size + self.input_dim = self.mu.size + self.inv, self.hld = pdinv(self.var) + self.constant = -0.5 * self.input_dim * np.log(2 * np.pi) - self.hld +
+
[docs]def gamma_from_EV(E, V): + warnings.warn("use Gamma.from_EV to create Gamma Prior", FutureWarning) + return Gamma.from_EV(E, V) + +
+
[docs]class Gamma(Prior): + """ + Implementation of the Gamma probability function, coupled with random variables. + + :param a: shape parameter + :param b: rate parameter (warning: it's the *inverse* of the scale) + + .. Note:: Bishop 2006 notation is used throughout the code + + """ + domain = _POSITIVE + _instances = [] + + def __new__(cls, a=1, b=.5): # Singleton: + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if instance().a == a and instance().b == b: + return instance() + o = super(Prior, cls).__new__(cls, a, b) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, a, b): + self.a = float(a) + self.b = float(b) + self.constant = -gammaln(self.a) + a * np.log(b) + + def __str__(self): + return "Ga({:.2g}, {:.2g})".format(self.a, self.b) + +
[docs] def summary(self): + ret = {"E[x]": self.a / self.b, \ + "E[ln x]": digamma(self.a) - np.log(self.b), \ + "var[x]": self.a / self.b / self.b, \ + "Entropy": gammaln(self.a) - (self.a - 1.) * digamma(self.a) - np.log(self.b) + self.a} + if self.a > 1: + ret['Mode'] = (self.a - 1.) / self.b + else: + ret['mode'] = np.nan + return ret +
+
[docs] def lnpdf(self, x): + return self.constant + (self.a - 1) * np.log(x) - self.b * x +
+
[docs] def lnpdf_grad(self, x): + return (self.a - 1.) / x - self.b +
+
[docs] def rvs(self, n): + return np.random.gamma(scale=1. / self.b, shape=self.a, size=n) +
+ @staticmethod +
[docs] def from_EV(E, V): + """ + Creates an instance of a Gamma Prior by specifying the Expected value(s) + and Variance(s) of the distribution. + + :param E: expected value + :param V: variance + """ + a = np.square(E) / V + b = E / V + return Gamma(a, b) +
+ def __getstate__(self): + return self.a, self.b + + def __setstate__(self, state): + self.a = state[0] + self.b = state[1] + self.constant = -gammaln(self.a) + self.a * np.log(self.b) +
+
[docs]class InverseGamma(Gamma): + """ + Implementation of the inverse-Gamma probability function, coupled with random variables. + + :param a: shape parameter + :param b: rate parameter (warning: it's the *inverse* of the scale) + + .. Note:: Bishop 2006 notation is used throughout the code + + """ + domain = _POSITIVE + _instances = [] + def __new__(cls, a=1, b=.5): # Singleton: + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if instance().a == a and instance().b == b: + return instance() + o = super(Prior, cls).__new__(cls, a, b) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, a, b): + self.a = float(a) + self.b = float(b) + self.constant = -gammaln(self.a) + a * np.log(b) + + def __str__(self): + return "iGa({:.2g}, {:.2g})".format(self.a, self.b) + +
[docs] def lnpdf(self, x): + return self.constant - (self.a + 1) * np.log(x) - self.b / x +
+
[docs] def lnpdf_grad(self, x): + return -(self.a + 1.) / x + self.b / x ** 2 +
+
[docs] def rvs(self, n): + return 1. / np.random.gamma(scale=1. / self.b, shape=self.a, size=n) +
+
[docs]class DGPLVM_KFDA(Prior): + """ + Implementation of the Discriminative Gaussian Process Latent Variable function using + Kernel Fisher Discriminant Analysis by Seung-Jean Kim for implementing Face paper + by Chaochao Lu. + + :param lambdaa: constant + :param sigma2: constant + + .. Note:: Surpassing Human-Level Face paper dgplvm implementation + + """ + domain = _REAL + # _instances = [] + # def __new__(cls, lambdaa, sigma2): # Singleton: + # if cls._instances: + # cls._instances[:] = [instance for instance in cls._instances if instance()] + # for instance in cls._instances: + # if instance().mu == mu and instance().sigma == sigma: + # return instance() + # o = super(Prior, cls).__new__(cls, mu, sigma) + # cls._instances.append(weakref.ref(o)) + # return cls._instances[-1]() + + def __init__(self, lambdaa, sigma2, lbl, kern, x_shape): + """A description for init""" + self.datanum = lbl.shape[0] + self.classnum = lbl.shape[1] + self.lambdaa = lambdaa + self.sigma2 = sigma2 + self.lbl = lbl + self.kern = kern + lst_ni = self.compute_lst_ni() + self.a = self.compute_a(lst_ni) + self.A = self.compute_A(lst_ni) + self.x_shape = x_shape + +
[docs] def get_class_label(self, y): + for idx, v in enumerate(y): + if v == 1: + return idx + return -1 + + # This function assigns each data point to its own class + # and returns the dictionary which contains the class name and parameters.
+
[docs] def compute_cls(self, x): + cls = {} + # Appending each data point to its proper class + for j in xrange(self.datanum): + class_label = self.get_class_label(self.lbl[j]) + if class_label not in cls: + cls[class_label] = [] + cls[class_label].append(x[j]) + if len(cls) > 2: + for i in range(2, self.classnum): + del cls[i] + return cls +
+
[docs] def x_reduced(self, cls): + x1 = cls[0] + x2 = cls[1] + x = np.concatenate((x1, x2), axis=0) + return x +
+
[docs] def compute_lst_ni(self): + lst_ni = [] + lst_ni1 = [] + lst_ni2 = [] + f1 = (np.where(self.lbl[:, 0] == 1)[0]) + f2 = (np.where(self.lbl[:, 1] == 1)[0]) + for idx in f1: + lst_ni1.append(idx) + for idx in f2: + lst_ni2.append(idx) + lst_ni.append(len(lst_ni1)) + lst_ni.append(len(lst_ni2)) + return lst_ni +
+
[docs] def compute_a(self, lst_ni): + a = np.ones((self.datanum, 1)) + count = 0 + for N_i in lst_ni: + if N_i == lst_ni[0]: + a[count:count + N_i] = (float(1) / N_i) * a[count] + count += N_i + else: + if N_i == lst_ni[1]: + a[count: count + N_i] = -(float(1) / N_i) * a[count] + count += N_i + return a +
+
[docs] def compute_A(self, lst_ni): + A = np.zeros((self.datanum, self.datanum)) + idx = 0 + for N_i in lst_ni: + B = float(1) / np.sqrt(N_i) * (np.eye(N_i) - ((float(1) / N_i) * np.ones((N_i, N_i)))) + A[idx:idx + N_i, idx:idx + N_i] = B + idx += N_i + return A + + # Here log function
+
[docs] def lnpdf(self, x): + x = x.reshape(self.x_shape) + K = self.kern.K(x) + a_trans = np.transpose(self.a) + paran = self.lambdaa * np.eye(x.shape[0]) + self.A.dot(K).dot(self.A) + inv_part = pdinv(paran)[0] + J = a_trans.dot(K).dot(self.a) - a_trans.dot(K).dot(self.A).dot(inv_part).dot(self.A).dot(K).dot(self.a) + J_star = (1. / self.lambdaa) * J + return (-1. / self.sigma2) * J_star + + # Here gradient function
+
[docs] def lnpdf_grad(self, x): + x = x.reshape(self.x_shape) + K = self.kern.K(x) + paran = self.lambdaa * np.eye(x.shape[0]) + self.A.dot(K).dot(self.A) + inv_part = pdinv(paran)[0] + b = self.A.dot(inv_part).dot(self.A).dot(K).dot(self.a) + a_Minus_b = self.a - b + a_b_trans = np.transpose(a_Minus_b) + DJ_star_DK = (1. / self.lambdaa) * (a_Minus_b.dot(a_b_trans)) + DJ_star_DX = self.kern.gradients_X(DJ_star_DK, x) + return (-1. / self.sigma2) * DJ_star_DX +
+
[docs] def rvs(self, n): + return np.random.rand(n) # A WRONG implementation +
+ def __str__(self): + return 'DGPLVM_prior' + + def __getstate___(self): + return self.lbl, self.lambdaa, self.sigma2, self.kern, self.x_shape + + def __setstate__(self, state): + lbl, lambdaa, sigma2, kern, a, A, x_shape = state + self.datanum = lbl.shape[0] + self.classnum = lbl.shape[1] + self.lambdaa = lambdaa + self.sigma2 = sigma2 + self.lbl = lbl + self.kern = kern + lst_ni = self.compute_lst_ni() + self.a = self.compute_a(lst_ni) + self.A = self.compute_A(lst_ni) + self.x_shape = x_shape +
+
[docs]class DGPLVM(Prior): + """ + Implementation of the Discriminative Gaussian Process Latent Variable model paper, by Raquel. + + :param sigma2: constant + + .. Note:: DGPLVM for Classification paper implementation + + """ + domain = _REAL + # _instances = [] + # def __new__(cls, mu, sigma): # Singleton: + # if cls._instances: + # cls._instances[:] = [instance for instance in cls._instances if instance()] + # for instance in cls._instances: + # if instance().mu == mu and instance().sigma == sigma: + # return instance() + # o = super(Prior, cls).__new__(cls, mu, sigma) + # cls._instances.append(weakref.ref(o)) + # return cls._instances[-1]() + + def __init__(self, sigma2, lbl, x_shape): + self.sigma2 = sigma2 + # self.x = x + self.lbl = lbl + self.classnum = lbl.shape[1] + self.datanum = lbl.shape[0] + self.x_shape = x_shape + self.dim = x_shape[1] + +
[docs] def get_class_label(self, y): + for idx, v in enumerate(y): + if v == 1: + return idx + return -1 + + # This function assigns each data point to its own class + # and returns the dictionary which contains the class name and parameters.
+
[docs] def compute_cls(self, x): + cls = {} + # Appending each data point to its proper class + for j in xrange(self.datanum): + class_label = self.get_class_label(self.lbl[j]) + if class_label not in cls: + cls[class_label] = [] + cls[class_label].append(x[j]) + return cls + + # This function computes mean of each class. The mean is calculated through each dimension
+
[docs] def compute_Mi(self, cls): + M_i = np.zeros((self.classnum, self.dim)) + for i in cls: + # Mean of each class + M_i[i] = np.mean(cls[i], axis=0) + return M_i + + # Adding data points as tuple to the dictionary so that we can access indices
+
[docs] def compute_indices(self, x): + data_idx = {} + for j in xrange(self.datanum): + class_label = self.get_class_label(self.lbl[j]) + if class_label not in data_idx: + data_idx[class_label] = [] + t = (j, x[j]) + data_idx[class_label].append(t) + return data_idx + + # Adding indices to the list so we can access whole the indices
+
[docs] def compute_listIndices(self, data_idx): + lst_idx = [] + lst_idx_all = [] + for i in data_idx: + if len(lst_idx) == 0: + pass + #Do nothing, because it is the first time list is created so is empty + else: + lst_idx = [] + # Here we put indices of each class in to the list called lst_idx_all + for m in xrange(len(data_idx[i])): + lst_idx.append(data_idx[i][m][0]) + lst_idx_all.append(lst_idx) + return lst_idx_all + + # This function calculates between classes variances
+
[docs] def compute_Sb(self, cls, M_i, M_0): + Sb = np.zeros((self.dim, self.dim)) + for i in cls: + B = (M_i[i] - M_0).reshape(self.dim, 1) + B_trans = B.transpose() + Sb += (float(len(cls[i])) / self.datanum) * B.dot(B_trans) + return Sb + + # This function calculates within classes variances
+
[docs] def compute_Sw(self, cls, M_i): + Sw = np.zeros((self.dim, self.dim)) + for i in cls: + N_i = float(len(cls[i])) + W_WT = np.zeros((self.dim, self.dim)) + for xk in cls[i]: + W = (xk - M_i[i]) + W_WT += np.outer(W, W) + Sw += (N_i / self.datanum) * ((1. / N_i) * W_WT) + return Sw + + # Calculating beta and Bi for Sb
+
[docs] def compute_sig_beta_Bi(self, data_idx, M_i, M_0, lst_idx_all): + # import pdb + # pdb.set_trace() + B_i = np.zeros((self.classnum, self.dim)) + Sig_beta_B_i_all = np.zeros((self.datanum, self.dim)) + for i in data_idx: + # pdb.set_trace() + # Calculating Bi + B_i[i] = (M_i[i] - M_0).reshape(1, self.dim) + for k in xrange(self.datanum): + for i in data_idx: + N_i = float(len(data_idx[i])) + if k in lst_idx_all[i]: + beta = (float(1) / N_i) - (float(1) / self.datanum) + Sig_beta_B_i_all[k] += float(N_i) / self.datanum * (beta * B_i[i]) + else: + beta = -(float(1) / self.datanum) + Sig_beta_B_i_all[k] += float(N_i) / self.datanum * (beta * B_i[i]) + Sig_beta_B_i_all = Sig_beta_B_i_all.transpose() + return Sig_beta_B_i_all + + + # Calculating W_j s separately so we can access all the W_j s anytime
+
[docs] def compute_wj(self, data_idx, M_i): + W_i = np.zeros((self.datanum, self.dim)) + for i in data_idx: + N_i = float(len(data_idx[i])) + for tpl in data_idx[i]: + xj = tpl[1] + j = tpl[0] + W_i[j] = (xj - M_i[i]) + return W_i + + # Calculating alpha and Wj for Sw
+
[docs] def compute_sig_alpha_W(self, data_idx, lst_idx_all, W_i): + Sig_alpha_W_i = np.zeros((self.datanum, self.dim)) + for i in data_idx: + N_i = float(len(data_idx[i])) + for tpl in data_idx[i]: + k = tpl[0] + for j in lst_idx_all[i]: + if k == j: + alpha = 1 - (float(1) / N_i) + Sig_alpha_W_i[k] += (alpha * W_i[j]) + else: + alpha = 0 - (float(1) / N_i) + Sig_alpha_W_i[k] += (alpha * W_i[j]) + Sig_alpha_W_i = (1. / self.datanum) * np.transpose(Sig_alpha_W_i) + return Sig_alpha_W_i + + # This function calculates log of our prior
+
[docs] def lnpdf(self, x): + x = x.reshape(self.x_shape) + cls = self.compute_cls(x) + M_0 = np.mean(x, axis=0) + M_i = self.compute_Mi(cls) + Sb = self.compute_Sb(cls, M_i, M_0) + Sw = self.compute_Sw(cls, M_i) + # Sb_inv_N = np.linalg.inv(Sb + np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1)) + #Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) + Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1))[0] + return (-1 / self.sigma2) * np.trace(Sb_inv_N.dot(Sw)) + + # This function calculates derivative of the log of prior function
+
[docs] def lnpdf_grad(self, x): + x = x.reshape(self.x_shape) + cls = self.compute_cls(x) + M_0 = np.mean(x, axis=0) + M_i = self.compute_Mi(cls) + Sb = self.compute_Sb(cls, M_i, M_0) + Sw = self.compute_Sw(cls, M_i) + data_idx = self.compute_indices(x) + lst_idx_all = self.compute_listIndices(data_idx) + Sig_beta_B_i_all = self.compute_sig_beta_Bi(data_idx, M_i, M_0, lst_idx_all) + W_i = self.compute_wj(data_idx, M_i) + Sig_alpha_W_i = self.compute_sig_alpha_W(data_idx, lst_idx_all, W_i) + + # Calculating inverse of Sb and its transpose and minus + # Sb_inv_N = np.linalg.inv(Sb + np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1)) + # Sb_inv_N = np.linalg.inv(Sb+np.eye(Sb.shape[0])*0.1) + Sb_inv_N = pdinv(Sb+ np.eye(Sb.shape[0]) * (np.diag(Sb).min() * 0.1))[0] + Sb_inv_N_trans = np.transpose(Sb_inv_N) + Sb_inv_N_trans_minus = -1 * Sb_inv_N_trans + Sw_trans = np.transpose(Sw) + + # Calculating DJ/DXk + DJ_Dxk = 2 * ( + Sb_inv_N_trans_minus.dot(Sw_trans).dot(Sb_inv_N_trans).dot(Sig_beta_B_i_all) + Sb_inv_N_trans.dot( + Sig_alpha_W_i)) + # Calculating derivative of the log of the prior + DPx_Dx = ((-1 / self.sigma2) * DJ_Dxk) + return DPx_Dx.T + + # def frb(self, x): + # from functools import partial + # from GPy.models import GradientChecker + # f = partial(self.lnpdf) + # df = partial(self.lnpdf_grad) + # grad = GradientChecker(f, df, x, 'X') + # grad.checkgrad(verbose=1) +
+
[docs] def rvs(self, n): + return np.random.rand(n) # A WRONG implementation +
+ def __str__(self): + return 'DGPLVM_prior' +
+
[docs]class HalfT(Prior): + """ + Implementation of the half student t probability function, coupled with random variables. + + :param A: scale parameter + :param nu: degrees of freedom + + """ + domain = _POSITIVE + _instances = [] + def __new__(cls, A, nu): # Singleton: + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if instance().A == A and instance().nu == nu: + return instance() + o = super(Prior, cls).__new__(cls, A, nu) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + def __init__(self, A, nu): + self.A = float(A) + self.nu = float(nu) + self.constant = gammaln(.5*(self.nu+1.)) - gammaln(.5*self.nu) - .5*np.log(np.pi*self.A*self.nu) + + def __str__(self): + return "hT({:.2g}, {:.2g})".format(self.A, self.nu) + +
[docs] def lnpdf(self,theta): + return (theta>0) * ( self.constant -.5*(self.nu+1) * np.log( 1.+ (1./self.nu) * (theta/self.A)**2 ) ) + + #theta = theta if isinstance(theta,np.ndarray) else np.array([theta]) + #lnpdfs = np.zeros_like(theta) + #theta = np.array([theta]) + #above_zero = theta.flatten()>1e-6 + #v = self.nu + #sigma2=self.A + #stop + #lnpdfs[above_zero] = (+ gammaln((v + 1) * 0.5) + # - gammaln(v * 0.5) + # - 0.5*np.log(sigma2 * v * np.pi) + # - 0.5*(v + 1)*np.log(1 + (1/np.float(v))*((theta[above_zero][0]**2)/sigma2)) + #) + #return lnpdfs +
+
[docs] def lnpdf_grad(self,theta): + theta = theta if isinstance(theta,np.ndarray) else np.array([theta]) + grad = np.zeros_like(theta) + above_zero = theta>1e-6 + v = self.nu + sigma2=self.A + grad[above_zero] = -0.5*(v+1)*(2*theta[above_zero])/(v*sigma2 + theta[above_zero][0]**2) + return grad +
+
[docs] def rvs(self, n): + #return np.random.randn(n) * self.sigma + self.mu + from scipy.stats import t + #[np.abs(x) for x in t.rvs(df=4,loc=0,scale=50, size=10000)]) + ret = t.rvs(self.nu,loc=0,scale=self.A, size=n) + ret[ret<0] = 0 + return ret +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/parameterization/ties_and_remappings.html b/doc/_build/html/_modules/GPy/core/parameterization/ties_and_remappings.html new file mode 100644 index 00000000..89eec658 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/parameterization/ties_and_remappings.html @@ -0,0 +1,314 @@ + + + + + + + + GPy.core.parameterization.ties_and_remappings — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.parameterization.ties_and_remappings

+# Copyright (c) 2014, James Hensman, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from parameterized import Parameterized
+from param import Param
+
+
[docs]class Remapping(Parameterized): +
[docs] def mapping(self): + """ + The return value of this function gives the values which the re-mapped + parameters should take. Implement in sub-classes. + """ + raise NotImplementedError +
+
[docs] def callback(self): + raise NotImplementedError +
+ def __str__(self): + return self.name + +
[docs] def parameters_changed(self): + #ensure all out parameters have the correct value, as specified by our mapping + index = self._highest_parent_.constraints[self] + self._highest_parent_.param_array[index] = self.mapping() + [p.notify_observers(which=self) for p in self.tied_parameters] +
+
[docs]class Fix(Remapping): + pass + + + +
+
[docs]class Tie(Parameterized): + """ + The new parameter tie framework. (under development) + + All the parameters tied together get a new parameter inside the *Tie* object. + Its value should always be equal to all the tied parameters, and its gradient + is the sum of all the tied parameters. + + =====Implementation Details===== + The *Tie* object should only exist on the top of param tree (the highest parent). + + self.label_buf: + It uses a label buffer that has the same length as all the parameters (self._highest_parent_.param_array). + The buffer keeps track of all the tied parameters. All the tied parameters have a label (an interger) higher + than 0, and the parameters that have the same label are tied together. + + self.buf_index: + An auxiliary index list for the global index of the tie parameter inside the *Tie* object. + + ================================ + + TODO: + * EVERYTHING + + """ + def __init__(self, name='tie'): + super(Tie, self).__init__(name) + self.tied_param = None + # The buffer keeps track of tie status + self.label_buf = None + # The global indices of the 'tied' param + self.buf_idx = None + # A boolean array indicating non-tied parameters + self._tie_ = None + +
[docs] def getTieFlag(self, p=None): + if self.tied_param is None: + if self._tie_ is None or self._tie_.size != self._highest_parent_.param_array.size: + self._tie_ = np.ones((self._highest_parent_.param_array.size,),dtype=np.bool) + if p is not None: + return self._tie_[p._highest_parent_._raveled_index_for(p)] + return self._tie_ +
+ def _init_labelBuf(self): + if self.label_buf is None: + self.label_buf = np.zeros(self._highest_parent_.param_array.shape, dtype=np.int) + if self._tie_ is None or self._tie_.size != self._highest_parent_.param_array.size: + self._tie_ = np.ones((self._highest_parent_.param_array.size,),dtype=np.bool) + + def _updateTieFlag(self): + if self._tie_.size != self.label_buf.size: + self._tie_ = np.ones((self._highest_parent_.param_array.size,),dtype=np.bool) + self._tie_[self.label_buf>0] = False + self._tie_[self.buf_idx] = True + +
[docs] def add_tied_parameter(self, p, p2=None): + """ + Tie the list of parameters p together (p2==None) or + Tie the list of parameters p with the list of parameters p2 (p2!=None) + """ + self._init_labelBuf() + if p2 is None: + idx = self._highest_parent_._raveled_index_for(p) + val = self._sync_val_group(idx) + if np.all(self.label_buf[idx]==0): + # None of p has been tied before. + tie_idx = self._expandTieParam(1) + print tie_idx + tie_id = self.label_buf.max()+1 + self.label_buf[tie_idx] = tie_id + else: + b = self.label_buf[idx] + ids = np.unique(b[b>0]) + tie_id, tie_idx = self._merge_tie_param(ids) + self._highest_parent_.param_array[tie_idx] = val + idx = self._highest_parent_._raveled_index_for(p) + self.label_buf[idx] = tie_id + else: + pass + self._updateTieFlag() +
+ def _merge_tie_param(self, ids): + """Merge the tie parameters with ids in the list.""" + if len(ids)==1: + id_final_idx = self.buf_idx[self.label_buf[self.buf_idx]==ids[0]][0] + return ids[0],id_final_idx + id_final = ids[0] + ids_rm = ids[1:] + label_buf_param = self.label_buf[self.buf_idx] + idx_param = [np.where(label_buf_param==i)[0][0] for i in ids_rm] + self._removeTieParam(idx_param) + [np.put(self.label_buf, np.where(self.label_buf==i), id_final) for i in ids_rm] + id_final_idx = self.buf_idx[self.label_buf[self.buf_idx]==id_final][0] + return id_final, id_final_idx + + def _sync_val_group(self, idx): + self._highest_parent_.param_array[idx] = self._highest_parent_.param_array[idx].mean() + return self._highest_parent_.param_array[idx][0] + + def _expandTieParam(self, num): + """Expand the tie param with the number of *num* parameters""" + if self.tied_param is None: + new_buf = np.empty((num,)) + else: + new_buf = np.empty((self.tied_param.size+num,)) + new_buf[:self.tied_param.size] = self.tied_param.param_array.copy() + self.remove_parameter(self.tied_param) + self.tied_param = Param('tied',new_buf) + self.add_parameter(self.tied_param) + buf_idx_new = self._highest_parent_._raveled_index_for(self.tied_param) + self._expand_label_buf(self.buf_idx, buf_idx_new) + self.buf_idx = buf_idx_new + return self.buf_idx[-num:] + + def _removeTieParam(self, idx): + """idx within tied_param""" + new_buf = np.empty((self.tied_param.size-len(idx),)) + bool_list = np.ones((self.tied_param.size,),dtype=np.bool) + bool_list[idx] = False + new_buf[:] = self.tied_param.param_array[bool_list] + self.remove_parameter(self.tied_param) + self.tied_param = Param('tied',new_buf) + self.add_parameter(self.tied_param) + buf_idx_new = self._highest_parent_._raveled_index_for(self.tied_param) + self._shrink_label_buf(self.buf_idx, buf_idx_new, bool_list) + self.buf_idx = buf_idx_new + + def _expand_label_buf(self, idx_old, idx_new): + """Expand label buffer accordingly""" + if idx_old is None: + self.label_buf = np.zeros(self._highest_parent_.param_array.shape, dtype=np.int) + else: + bool_old = np.zeros((self.label_buf.size,),dtype=np.bool) + bool_old[idx_old] = True + bool_new = np.zeros((self._highest_parent_.param_array.size,),dtype=np.bool) + bool_new[idx_new] = True + label_buf_new = np.zeros(self._highest_parent_.param_array.shape, dtype=np.int) + label_buf_new[np.logical_not(bool_new)] = self.label_buf[np.logical_not(bool_old)] + label_buf_new[idx_new[:len(idx_old)]] = self.label_buf[idx_old] + self.label_buf = label_buf_new + + def _shrink_label_buf(self, idx_old, idx_new, bool_list): + bool_old = np.zeros((self.label_buf.size,),dtype=np.bool) + bool_old[idx_old] = True + bool_new = np.zeros((self._highest_parent_.param_array.size,),dtype=np.bool) + bool_new[idx_new] = True + label_buf_new = np.empty(self._highest_parent_.param_array.shape, dtype=np.int) + label_buf_new[np.logical_not(bool_new)] = self.label_buf[np.logical_not(bool_old)] + label_buf_new[idx_new] = self.label_buf[idx_old[bool_list]] + self.label_buf = label_buf_new + + def _check_change(self): + changed = False + if self.tied_param is not None: + for i in xrange(self.tied_param.size): + b0 = self.label_buf==self.label_buf[self.buf_idx[i]] + b = self._highest_parent_.param_array[b0]!=self.tied_param[i] + if b.sum()==0: + print 'XXX' + continue + elif b.sum()==1: + print '!!!' + val = self._highest_parent_.param_array[b0][b][0] + self._highest_parent_.param_array[b0] = val + else: + print '@@@' + self._highest_parent_.param_array[b0] = self.tied_param[i] + changed = True + return changed + +
[docs] def parameters_changed(self): + #ensure all out parameters have the correct value, as specified by our mapping + changed = self._check_change() + if changed: + self._highest_parent_._trigger_params_changed() + self.collate_gradient() +
+
[docs] def collate_gradient(self): + if self.tied_param is not None: + self.tied_param.gradient = 0. + [np.put(self.tied_param.gradient, i, self._highest_parent_.gradient[self.label_buf==self.label_buf[self.buf_idx[i]]].sum()) + for i in xrange(self.tied_param.size)] +
+
[docs] def propagate_val(self): + if self.tied_param is not None: + for i in xrange(self.tied_param.size): + self._highest_parent_.param_array[self.label_buf==self.label_buf[self.buf_idx[i]]] = self.tied_param[i] +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/parameterization/transformations.html b/doc/_build/html/_modules/GPy/core/parameterization/transformations.html new file mode 100644 index 00000000..6bb2636f --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/parameterization/transformations.html @@ -0,0 +1,525 @@ + + + + + + + + GPy.core.parameterization.transformations — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.parameterization.transformations

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from domains import _POSITIVE,_NEGATIVE, _BOUNDED
+import weakref
+
+import sys
+
+_exp_lim_val = np.finfo(np.float64).max
+_lim_val = 36.0
+epsilon = np.finfo(np.float64).resolution
+
+#===============================================================================
+# Fixing constants
+__fixed__ = "fixed"
+FIXED = False
+UNFIXED = True
+#===============================================================================
+
+
+
[docs]class Transformation(object): + domain = None + _instance = None + def __new__(cls, *args, **kwargs): + if not cls._instance or cls._instance.__class__ is not cls: + cls._instance = super(Transformation, cls).__new__(cls, *args, **kwargs) + return cls._instance +
[docs] def f(self, opt_param): + raise NotImplementedError
+
[docs] def finv(self, model_param): + raise NotImplementedError
+
[docs] def gradfactor(self, model_param, dL_dmodel_param): + """ df(opt_param)_dopt_param evaluated at self.f(opt_param)=model_param, times the gradient dL_dmodel_param, + + i.e.: + define + + .. math:: + + \frac{\frac{\partial L}{\partial f}\left(\left.\partial f(x)}{\partial x}\right|_{x=f^{-1}(f)\right)} + """ + raise NotImplementedError
+
[docs] def initialize(self, f): + """ produce a sensible initial value for f(x)""" + raise NotImplementedError
+
[docs] def plot(self, xlabel=r'transformed $\theta$', ylabel=r'$\theta$', axes=None, *args,**kw): + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + import matplotlib.pyplot as plt + from ...plotting.matplot_dep import base_plots + x = np.linspace(-8,8) + base_plots.meanplot(x, self.f(x),axes=axes*args,**kw) + axes = plt.gca() + axes.set_xlabel(xlabel) + axes.set_ylabel(ylabel)
+ def __str__(self): + raise NotImplementedError + def __repr__(self): + return self.__class__.__name__ +
+
[docs]class Logexp(Transformation): + domain = _POSITIVE +
[docs] def f(self, x): + return np.where(x>_lim_val, x, np.log1p(np.exp(np.clip(x, -_lim_val, _lim_val)))) + epsilon + #raises overflow warning: return np.where(x>_lim_val, x, np.log(1. + np.exp(x)))
+
[docs] def finv(self, f): + return np.where(f>_lim_val, f, np.log(np.exp(f+1e-20) - 1.))
+
[docs] def gradfactor(self, f, df): + return np.einsum('i,i->i', df, np.where(f>_lim_val, 1., 1. - np.exp(-f)))
+
[docs] def initialize(self, f): + if np.any(f < 0.): + print "Warning: changing parameters to satisfy constraints" + return np.abs(f)
+ def __str__(self): + return '+ve' + +
+
[docs]class NormalTheta(Transformation): + _instances = [] + def __new__(cls, mu_indices, var_indices): + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if np.all(instance().mu_indices==mu_indices, keepdims=False) and np.all(instance().var_indices==var_indices, keepdims=False): + return instance() + o = super(Transformation, cls).__new__(cls, mu_indices, var_indices) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, mu_indices, var_indices): + self.mu_indices = mu_indices + self.var_indices = var_indices + +
[docs] def f(self, theta): + # In here abs is only a trick to make sure the numerics are ok. + # The variance will never go below zero, but at initialization we need to make sure + # that the values are ok + # Before: + theta[self.var_indices] = np.abs(-.5/theta[self.var_indices]) + theta[self.mu_indices] *= theta[self.var_indices] + return theta # which is now {mu, var} +
+
[docs] def finv(self, muvar): + # before: + varp = muvar[self.var_indices] + muvar[self.mu_indices] /= varp + muvar[self.var_indices] = -.5/varp + + return muvar # which is now {theta1, theta2} +
+
[docs] def gradfactor(self, muvar, dmuvar): + mu = muvar[self.mu_indices] + var = muvar[self.var_indices] + #======================================================================= + # theta gradients + # This works and the gradient checks! + dmuvar[self.mu_indices] *= var + dmuvar[self.var_indices] *= 2*(var)**2 + dmuvar[self.var_indices] += 2*dmuvar[self.mu_indices]*mu + #======================================================================= + + return dmuvar # which is now the gradient multiplicator for {theta1, theta2} +
+
[docs] def initialize(self, f): + if np.any(f[self.var_indices] < 0.): + print "Warning: changing parameters to satisfy constraints" + f[self.var_indices] = np.abs(f[self.var_indices]) + return f +
+ def __str__(self): + return "theta" + + def __getstate__(self): + return [self.mu_indices, self.var_indices] + + def __setstate__(self, state): + self.mu_indices = state[0] + self.var_indices = state[1] +
+
[docs]class NormalNaturalAntti(NormalTheta): + _instances = [] + _logexp = Logexp() + def __new__(cls, mu_indices, var_indices): + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if np.all(instance().mu_indices==mu_indices, keepdims=False) and np.all(instance().var_indices==var_indices, keepdims=False): + return instance() + o = super(Transformation, cls).__new__(cls, mu_indices, var_indices) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, mu_indices, var_indices): + self.mu_indices = mu_indices + self.var_indices = var_indices + +
[docs] def gradfactor(self, muvar, dmuvar): + mu = muvar[self.mu_indices] + var = muvar[self.var_indices] + + #======================================================================= + # theta gradients + # This works and the gradient checks! + dmuvar[self.mu_indices] *= var + dmuvar[self.var_indices] *= 2*var**2#np.einsum('i,i,i,i->i', dmuvar[self.var_indices], [2], var, var) + #======================================================================= + + return dmuvar # which is now the gradient multiplicator +
+
[docs] def initialize(self, f): + if np.any(f[self.var_indices] < 0.): + print "Warning: changing parameters to satisfy constraints" + f[self.var_indices] = np.abs(f[self.var_indices]) + return f +
+ def __str__(self): + return "natantti" +
+
[docs]class NormalEta(Transformation): + _instances = [] + def __new__(cls, mu_indices, var_indices): + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if np.all(instance().mu_indices==mu_indices, keepdims=False) and np.all(instance().var_indices==var_indices, keepdims=False): + return instance() + o = super(Transformation, cls).__new__(cls, mu_indices, var_indices) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, mu_indices, var_indices): + self.mu_indices = mu_indices + self.var_indices = var_indices + +
[docs] def f(self, theta): + theta[self.var_indices] = np.abs(theta[self.var_indices] - theta[self.mu_indices]**2) + return theta # which is now {mu, var} +
+
[docs] def finv(self, muvar): + muvar[self.var_indices] += muvar[self.mu_indices]**2 + return muvar # which is now {eta1, eta2} +
+
[docs] def gradfactor(self, muvar, dmuvar): + mu = muvar[self.mu_indices] + #======================================================================= + # Lets try natural gradients instead: Not working with bfgs... try stochastic! + dmuvar[self.mu_indices] -= 2*mu*dmuvar[self.var_indices] + #======================================================================= + return dmuvar # which is now the gradient multiplicator +
+
[docs] def initialize(self, f): + if np.any(f[self.var_indices] < 0.): + print "Warning: changing parameters to satisfy constraints" + f[self.var_indices] = np.abs(f[self.var_indices]) + return f +
+ def __str__(self): + return "eta" +
+
[docs]class NormalNaturalThroughTheta(NormalTheta): + _instances = [] + def __new__(cls, mu_indices, var_indices): + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if np.all(instance().mu_indices==mu_indices, keepdims=False) and np.all(instance().var_indices==var_indices, keepdims=False): + return instance() + o = super(Transformation, cls).__new__(cls, mu_indices, var_indices) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, mu_indices, var_indices): + self.mu_indices = mu_indices + self.var_indices = var_indices + +
[docs] def gradfactor(self, muvar, dmuvar): + mu = muvar[self.mu_indices] + var = muvar[self.var_indices] + + #======================================================================= + # This is just eta direction: + dmuvar[self.mu_indices] -= 2*mu*dmuvar[self.var_indices] + #======================================================================= + + + #======================================================================= + # This is by going through theta fully and then going into eta direction: + #dmu = dmuvar[self.mu_indices] + #dmuvar[self.var_indices] += dmu*mu*(var + 4/var) + #======================================================================= + return dmuvar # which is now the gradient multiplicator +
+ def __str__(self): + return "natgrad" +
+
[docs]class NormalNaturalThroughEta(NormalEta): + _instances = [] + def __new__(cls, mu_indices, var_indices): + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if np.all(instance().mu_indices==mu_indices, keepdims=False) and np.all(instance().var_indices==var_indices, keepdims=False): + return instance() + o = super(Transformation, cls).__new__(cls, mu_indices, var_indices) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + + def __init__(self, mu_indices, var_indices): + self.mu_indices = mu_indices + self.var_indices = var_indices + +
[docs] def gradfactor(self, muvar, dmuvar): + mu = muvar[self.mu_indices] + var = muvar[self.var_indices] + #======================================================================= + # theta gradients + # This works and the gradient checks! + dmuvar[self.mu_indices] *= var + dmuvar[self.var_indices] *= 2*(var)**2 + dmuvar[self.var_indices] += 2*dmuvar[self.mu_indices]*mu + #======================================================================= + return dmuvar +
+ def __str__(self): + return "natgrad" + +
+
[docs]class LogexpNeg(Transformation): + domain = _POSITIVE +
[docs] def f(self, x): + return np.where(x>_lim_val, -x, -np.log(1. + np.exp(np.clip(x, -np.inf, _lim_val)))) + #raises overflow warning: return np.where(x>_lim_val, x, np.log(1. + np.exp(x)))
+
[docs] def finv(self, f): + return np.where(f>_lim_val, 0, np.log(np.exp(-f) - 1.))
+
[docs] def gradfactor(self, f, df): + return np.einsum('i,i->i', df, np.where(f>_lim_val, -1, -1 + np.exp(-f)))
+
[docs] def initialize(self, f): + if np.any(f < 0.): + print "Warning: changing parameters to satisfy constraints" + return np.abs(f)
+ def __str__(self): + return '+ve' + +
+
[docs]class NegativeLogexp(Transformation): + domain = _NEGATIVE + logexp = Logexp() +
[docs] def f(self, x): + return -self.logexp.f(x) # np.log(1. + np.exp(x))
+
[docs] def finv(self, f): + return self.logexp.finv(-f) # np.log(np.exp(-f) - 1.)
+
[docs] def gradfactor(self, f, df): + return np.einsum('i,i->i', df, -self.logexp.gradfactor(-f))
+
[docs] def initialize(self, f): + return -self.logexp.initialize(f) # np.abs(f)
+ def __str__(self): + return '-ve' +
+
[docs]class LogexpClipped(Logexp): + max_bound = 1e100 + min_bound = 1e-10 + log_max_bound = np.log(max_bound) + log_min_bound = np.log(min_bound) + domain = _POSITIVE + _instances = [] + def __new__(cls, lower=1e-6, *args, **kwargs): + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if instance().lower == lower: + return instance() + o = super(Transformation, cls).__new__(cls, lower, *args, **kwargs) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + def __init__(self, lower=1e-6): + self.lower = lower +
[docs] def f(self, x): + exp = np.exp(np.clip(x, self.log_min_bound, self.log_max_bound)) + f = np.log(1. + exp) +# if np.isnan(f).any(): +# import ipdb;ipdb.set_trace() + return np.clip(f, self.min_bound, self.max_bound)
+
[docs] def finv(self, f): + return np.log(np.exp(f - 1.))
+
[docs] def gradfactor(self, f, df): + ef = np.exp(f) # np.clip(f, self.min_bound, self.max_bound)) + gf = (ef - 1.) / ef + return np.einsum('i,i->i', df, gf) # np.where(f < self.lower, 0, gf)
+
[docs] def initialize(self, f): + if np.any(f < 0.): + print "Warning: changing parameters to satisfy constraints" + return np.abs(f)
+ def __str__(self): + return '+ve_c' +
+
[docs]class Exponent(Transformation): + # TODO: can't allow this to go to zero, need to set a lower bound. Similar with negative Exponent below. See old MATLAB code. + domain = _POSITIVE +
[docs] def f(self, x): + return np.where(x<_lim_val, np.where(x>-_lim_val, np.exp(x), np.exp(-_lim_val)), np.exp(_lim_val))
+
[docs] def finv(self, x): + return np.log(x)
+
[docs] def gradfactor(self, f, df): + return np.einsum('i,i->i', df, f)
+
[docs] def initialize(self, f): + if np.any(f < 0.): + print "Warning: changing parameters to satisfy constraints" + return np.abs(f)
+ def __str__(self): + return '+ve' +
+
[docs]class NegativeExponent(Exponent): + domain = _NEGATIVE +
[docs] def f(self, x): + return -Exponent.f(x)
+
[docs] def finv(self, f): + return Exponent.finv(-f)
+
[docs] def gradfactor(self, f, df): + return np.einsum('i,i->i', df, f)
+
[docs] def initialize(self, f): + return -Exponent.initialize(f) #np.abs(f)
+ def __str__(self): + return '-ve' +
+
[docs]class Square(Transformation): + domain = _POSITIVE +
[docs] def f(self, x): + return x ** 2
+
[docs] def finv(self, x): + return np.sqrt(x)
+
[docs] def gradfactor(self, f, df): + return np.einsum('i,i->i', df, 2 * np.sqrt(f))
+
[docs] def initialize(self, f): + return np.abs(f)
+ def __str__(self): + return '+sq' +
+
[docs]class Logistic(Transformation): + domain = _BOUNDED + _instances = [] + def __new__(cls, lower=1e-6, upper=1e-6, *args, **kwargs): + if cls._instances: + cls._instances[:] = [instance for instance in cls._instances if instance()] + for instance in cls._instances: + if instance().lower == lower and instance().upper == upper: + return instance() + o = super(Transformation, cls).__new__(cls, lower, upper, *args, **kwargs) + cls._instances.append(weakref.ref(o)) + return cls._instances[-1]() + def __init__(self, lower, upper): + assert lower < upper + self.lower, self.upper = float(lower), float(upper) + self.difference = self.upper - self.lower +
[docs] def f(self, x): + if (x<-300.).any(): + x = x.copy() + x[x<-300.] = -300. + return self.lower + self.difference / (1. + np.exp(-x))
+
[docs] def finv(self, f): + return np.log(np.clip(f - self.lower, 1e-10, np.inf) / np.clip(self.upper - f, 1e-10, np.inf))
+
[docs] def gradfactor(self, f, df): + return np.einsum('i,i->i', df, (f - self.lower) * (self.upper - f) / self.difference)
+
[docs] def initialize(self, f): + if np.any(np.logical_or(f < self.lower, f > self.upper)): + print "Warning: changing parameters to satisfy constraints" + #return np.where(np.logical_or(f < self.lower, f > self.upper), self.f(f * 0.), f) + #FIXME: Max, zeros_like right? + return np.where(np.logical_or(f < self.lower, f > self.upper), self.f(np.zeros_like(f)), f)
+ def __str__(self): + return '{},{}'.format(self.lower, self.upper) +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/parameterization/variational.html b/doc/_build/html/_modules/GPy/core/parameterization/variational.html new file mode 100644 index 00000000..c779d18e --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/parameterization/variational.html @@ -0,0 +1,314 @@ + + + + + + + + GPy.core.parameterization.variational — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.parameterization.variational

+'''
+Created on 6 Nov 2013
+
+@author: maxz
+'''
+
+import numpy as np
+from parameterized import Parameterized
+from param import Param
+from transformations import Logexp, Logistic,__fixed__
+from GPy.util.misc import param_to_array
+from GPy.util.caching import Cache_this
+
+
[docs]class VariationalPrior(Parameterized): + def __init__(self, name='latent space', **kw): + super(VariationalPrior, self).__init__(name=name, **kw) + +
[docs] def KL_divergence(self, variational_posterior): + raise NotImplementedError, "override this for variational inference of latent space" +
+
[docs] def update_gradients_KL(self, variational_posterior): + """ + updates the gradients for mean and variance **in place** + """ + raise NotImplementedError, "override this for variational inference of latent space" +
+
[docs]class NormalPrior(VariationalPrior): +
[docs] def KL_divergence(self, variational_posterior): + var_mean = np.square(variational_posterior.mean).sum() + var_S = (variational_posterior.variance - np.log(variational_posterior.variance)).sum() + return 0.5 * (var_mean + var_S) - 0.5 * variational_posterior.input_dim * variational_posterior.num_data +
+
[docs] def update_gradients_KL(self, variational_posterior): + # dL: + variational_posterior.mean.gradient -= variational_posterior.mean + variational_posterior.variance.gradient -= (1. - (1. / (variational_posterior.variance))) * 0.5 +
+
[docs]class SpikeAndSlabPrior(VariationalPrior): + def __init__(self, pi=None, learnPi=False, variance = 1.0, name='SpikeAndSlabPrior', **kw): + super(SpikeAndSlabPrior, self).__init__(name=name, **kw) + self.variance = Param('variance',variance) + self.learnPi = learnPi + if learnPi: + self.pi = Param('Pi', pi, Logistic(1e-10,1.-1e-10)) + else: + self.pi = Param('Pi', pi, __fixed__) + self.link_parameter(self.pi) + + +
[docs] def KL_divergence(self, variational_posterior): + mu = variational_posterior.mean + S = variational_posterior.variance + gamma,gamma1 = variational_posterior.gamma_probabilities() + log_gamma,log_gamma1 = variational_posterior.gamma_log_prob() + if len(self.pi.shape)==2: + idx = np.unique(gamma._raveled_index()/gamma.shape[-1]) + pi = self.pi[idx] + else: + pi = self.pi + + var_mean = np.square(mu)/self.variance + var_S = (S/self.variance - np.log(S)) + var_gamma = (gamma*(log_gamma-np.log(pi))).sum()+(gamma1*(log_gamma1-np.log(1-pi))).sum() + return var_gamma+ (gamma* (np.log(self.variance)-1. +var_mean + var_S)).sum()/2. +
+
[docs] def update_gradients_KL(self, variational_posterior): + mu = variational_posterior.mean + S = variational_posterior.variance + gamma,gamma1 = variational_posterior.gamma_probabilities() + log_gamma,log_gamma1 = variational_posterior.gamma_log_prob() + if len(self.pi.shape)==2: + idx = np.unique(gamma._raveled_index()/gamma.shape[-1]) + pi = self.pi[idx] + else: + pi = self.pi + + variational_posterior.binary_prob.gradient -= (np.log((1-pi)/pi)+log_gamma-log_gamma1+((np.square(mu)+S)/self.variance-np.log(S)+np.log(self.variance)-1.)/2.)*gamma*gamma1 + mu.gradient -= gamma*mu/self.variance + S.gradient -= (1./self.variance - 1./S) * gamma /2. + if self.learnPi: + if len(self.pi)==1: + self.pi.gradient = (gamma/self.pi - (1.-gamma)/(1.-self.pi)).sum() + elif len(self.pi.shape)==1: + self.pi.gradient = (gamma/self.pi - (1.-gamma)/(1.-self.pi)).sum(axis=0) + else: + self.pi[idx].gradient = (gamma/self.pi[idx] - (1.-gamma)/(1.-self.pi[idx])) +
+
[docs]class VariationalPosterior(Parameterized): + def __init__(self, means=None, variances=None, name='latent space', *a, **kw): + super(VariationalPosterior, self).__init__(name=name, *a, **kw) + self.mean = Param("mean", means) + self.variance = Param("variance", variances, Logexp()) + self.ndim = self.mean.ndim + self.shape = self.mean.shape + self.num_data, self.input_dim = self.mean.shape + self.link_parameters(self.mean, self.variance) + self.num_data, self.input_dim = self.mean.shape + if self.has_uncertain_inputs(): + assert self.variance.shape == self.mean.shape, "need one variance per sample and dimenion" + +
[docs] def set_gradients(self, grad): + self.mean.gradient, self.variance.gradient = grad +
+ def _raveled_index(self): + index = np.empty(dtype=int, shape=0) + size = 0 + for p in self.parameters: + index = np.hstack((index, p._raveled_index()+size)) + size += p._realsize_ if hasattr(p, '_realsize_') else p.size + return index + +
[docs] def has_uncertain_inputs(self): + return not self.variance is None +
+ def __getitem__(self, s): + if isinstance(s, (int, slice, tuple, list, np.ndarray)): + import copy + n = self.__new__(self.__class__, self.name) + dc = self.__dict__.copy() + dc['mean'] = self.mean[s] + dc['variance'] = self.variance[s] + dc['parameters'] = copy.copy(self.parameters) + n.__dict__.update(dc) + n.parameters[dc['mean']._parent_index_] = dc['mean'] + n.parameters[dc['variance']._parent_index_] = dc['variance'] + n._gradient_array_ = None + oversize = self.size - self.mean.size - self.variance.size + n.size = n.mean.size + n.variance.size + oversize + n.ndim = n.mean.ndim + n.shape = n.mean.shape + n.num_data = n.mean.shape[0] + n.input_dim = n.mean.shape[1] if n.ndim != 1 else 1 + return n + else: + return super(VariationalPosterior, self).__getitem__(s) +
+
[docs]class NormalPosterior(VariationalPosterior): + ''' + NormalPosterior distribution for variational approximations. + + holds the means and variances for a factorizing multivariate normal distribution + ''' + +
[docs] def plot(self, *args): + """ + Plot latent space X in 1D: + + See GPy.plotting.matplot_dep.variational_plots + """ + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ...plotting.matplot_dep import variational_plots + import matplotlib + return variational_plots.plot(self,*args) +
+
[docs]class SpikeAndSlabPosterior(VariationalPosterior): + ''' + The SpikeAndSlab distribution for variational approximations. + ''' + def __init__(self, means, variances, binary_prob, name='latent space'): + """ + binary_prob : the probability of the distribution on the slab part. + """ + super(SpikeAndSlabPosterior, self).__init__(means, variances, name) + self.gamma = Param("binary_prob",binary_prob) + self.link_parameter(self.gamma) + + @Cache_this(limit=5) + def gamma_probabilities(self): + prob = np.zeros_like(param_to_array(self.gamma)) + prob[self.gamma>-710] = 1./(1.+np.exp(-self.gamma[self.gamma>-710])) + prob1 = -np.zeros_like(param_to_array(self.gamma)) + prob1[self.gamma<710] = 1./(1.+np.exp(self.gamma[self.gamma<710])) + return prob, prob1 + + @Cache_this(limit=5) + def gamma_log_prob(self): + loggamma = param_to_array(self.gamma).copy() + loggamma[loggamma>-40] = -np.log1p(np.exp(-loggamma[loggamma>-40])) + loggamma1 = -param_to_array(self.gamma).copy() + loggamma1[loggamma1>-40] = -np.log1p(np.exp(-loggamma1[loggamma1>-40])) + return loggamma,loggamma1 + +
[docs] def set_gradients(self, grad): + self.mean.gradient, self.variance.gradient, self.gamma.gradient = grad +
+ def __getitem__(self, s): + if isinstance(s, (int, slice, tuple, list, np.ndarray)): + import copy + n = self.__new__(self.__class__, self.name) + dc = self.__dict__.copy() + dc['mean'] = self.mean[s] + dc['variance'] = self.variance[s] + dc['binary_prob'] = self.binary_prob[s] + dc['parameters'] = copy.copy(self.parameters) + n.__dict__.update(dc) + n.parameters[dc['mean']._parent_index_] = dc['mean'] + n.parameters[dc['variance']._parent_index_] = dc['variance'] + n.parameters[dc['binary_prob']._parent_index_] = dc['binary_prob'] + n._gradient_array_ = None + oversize = self.size - self.mean.size - self.variance.size + n.size = n.mean.size + n.variance.size + oversize + n.ndim = n.mean.ndim + n.shape = n.mean.shape + n.num_data = n.mean.shape[0] + n.input_dim = n.mean.shape[1] if n.ndim != 1 else 1 + return n + else: + return super(VariationalPrior, self).__getitem__(s) + +
[docs] def plot(self, *args, **kwargs): + """ + Plot latent space X in 1D: + + See GPy.plotting.matplot_dep.variational_plots + """ + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ...plotting.matplot_dep import variational_plots + return variational_plots.plot_SpikeSlab(self,*args, **kwargs)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/sparse_gp.html b/doc/_build/html/_modules/GPy/core/sparse_gp.html new file mode 100644 index 00000000..fd6a53d9 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/sparse_gp.html @@ -0,0 +1,226 @@ + + + + + + + + GPy.core.sparse_gp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.sparse_gp

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from gp import GP
+from parameterization.param import Param
+from ..inference.latent_function_inference import var_dtc
+from .. import likelihoods
+from parameterization.variational import VariationalPosterior
+
+import logging
+from GPy.inference.latent_function_inference.posterior import Posterior
+from GPy.inference.optimization.stochastics import SparseGPStochastics,\
+    SparseGPMissing
+#no stochastics.py file added! from GPy.inference.optimization.stochastics import SparseGPStochastics,\
+    #SparseGPMissing
+logger = logging.getLogger("sparse gp")
+
+
[docs]class SparseGP(GP): + """ + A general purpose Sparse GP model + + This model allows (approximate) inference using variational DTC or FITC + (Gaussian likelihoods) as well as non-conjugate sparse methods based on + these. + + :param X: inputs + :type X: np.ndarray (num_data x input_dim) + :param likelihood: a likelihood instance, containing the observed data + :type likelihood: GPy.likelihood.(Gaussian | EP | Laplace) + :param kernel: the kernel (covariance function). See link kernels + :type kernel: a GPy.kern.kern instance + :param X_variance: The uncertainty in the measurements of X (Gaussian variance) + :type X_variance: np.ndarray (num_data x input_dim) | None + :param Z: inducing inputs + :type Z: np.ndarray (num_inducing x input_dim) + :param num_inducing: Number of inducing points (optional, default 10. Ignored if Z is not None) + :type num_inducing: int + + """ + + def __init__(self, X, Y, Z, kernel, likelihood, inference_method=None, + name='sparse gp', Y_metadata=None, normalizer=False): + #pick a sensible inference method + if inference_method is None: + if isinstance(likelihood, likelihoods.Gaussian): + inference_method = var_dtc.VarDTC(limit=1 if not self.missing_data else Y.shape[1]) + else: + #inference_method = ?? + raise NotImplementedError, "what to do what to do?" + print "defaulting to ", inference_method, "for latent function inference" + + self.Z = Param('inducing inputs', Z) + self.num_inducing = Z.shape[0] + + GP.__init__(self, X, Y, kernel, likelihood, inference_method=inference_method, name=name, Y_metadata=Y_metadata, normalizer=normalizer) + + logger.info("Adding Z as parameter") + self.link_parameter(self.Z, index=0) + self.posterior = None + +
[docs] def has_uncertain_inputs(self): + return isinstance(self.X, VariationalPosterior) +
+
[docs] def parameters_changed(self): + self.posterior, self._log_marginal_likelihood, self.grad_dict = self.inference_method.inference(self.kern, self.X, self.Z, self.likelihood, self.Y, self.Y_metadata) + + self.likelihood.update_gradients(self.grad_dict['dL_dthetaL']) + + if isinstance(self.X, VariationalPosterior): + #gradients wrt kernel + dL_dKmm = self.grad_dict['dL_dKmm'] + self.kern.update_gradients_full(dL_dKmm, self.Z, None) + kerngrad = self.kern.gradient.copy() + self.kern.update_gradients_expectations(variational_posterior=self.X, + Z=self.Z, + dL_dpsi0=self.grad_dict['dL_dpsi0'], + dL_dpsi1=self.grad_dict['dL_dpsi1'], + dL_dpsi2=self.grad_dict['dL_dpsi2']) + self.kern.gradient += kerngrad + + #gradients wrt Z + self.Z.gradient = self.kern.gradients_X(dL_dKmm, self.Z) + self.Z.gradient += self.kern.gradients_Z_expectations( + self.grad_dict['dL_dpsi0'], + self.grad_dict['dL_dpsi1'], + self.grad_dict['dL_dpsi2'], + Z=self.Z, + variational_posterior=self.X) + else: + #gradients wrt kernel + self.kern.update_gradients_diag(self.grad_dict['dL_dKdiag'], self.X) + kerngrad = self.kern.gradient.copy() + self.kern.update_gradients_full(self.grad_dict['dL_dKnm'], self.X, self.Z) + kerngrad += self.kern.gradient + self.kern.update_gradients_full(self.grad_dict['dL_dKmm'], self.Z, None) + self.kern.gradient += kerngrad + #gradients wrt Z + self.Z.gradient = self.kern.gradients_X(self.grad_dict['dL_dKmm'], self.Z) + self.Z.gradient += self.kern.gradients_X(self.grad_dict['dL_dKnm'].T, self.Z, self.X) + +
+ def _raw_predict(self, Xnew, full_cov=False, kern=None): + """ + Make a prediction for the latent function values + """ + + if kern is None: kern = self.kern + + if not isinstance(Xnew, VariationalPosterior): + Kx = kern.K(self.Z, Xnew) + mu = np.dot(Kx.T, self.posterior.woodbury_vector) + if full_cov: + Kxx = kern.K(Xnew) + if self.posterior.woodbury_inv.ndim == 2: + var = Kxx - np.dot(Kx.T, np.dot(self.posterior.woodbury_inv, Kx)) + elif self.posterior.woodbury_inv.ndim == 3: + var = Kxx[:,:,None] - np.tensordot(np.dot(np.atleast_3d(self.posterior.woodbury_inv).T, Kx).T, Kx, [1,0]).swapaxes(1,2) + var = var + else: + Kxx = kern.Kdiag(Xnew) + var = (Kxx - np.sum(np.dot(np.atleast_3d(self.posterior.woodbury_inv).T, Kx) * Kx[None,:,:], 1)).T + else: + Kx = kern.psi1(self.Z, Xnew) + mu = np.dot(Kx, self.posterior.woodbury_vector) + if full_cov: + raise NotImplementedError, "TODO" + else: + Kxx = kern.psi0(self.Z, Xnew) + psi2 = kern.psi2(self.Z, Xnew) + var = Kxx - np.sum(np.sum(psi2 * Kmmi_LmiBLmi[None, :, :], 1), 1) + return mu, var
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/core/sparse_gp_mpi.html b/doc/_build/html/_modules/GPy/core/sparse_gp_mpi.html new file mode 100644 index 00000000..72d9ebd3 --- /dev/null +++ b/doc/_build/html/_modules/GPy/core/sparse_gp_mpi.html @@ -0,0 +1,213 @@ + + + + + + + + GPy.core.sparse_gp_mpi — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.core.sparse_gp_mpi

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from sparse_gp import SparseGP
+from numpy.linalg.linalg import LinAlgError
+from ..inference.latent_function_inference.var_dtc_parallel import update_gradients, VarDTC_minibatch
+
+import logging
+logger = logging.getLogger("sparse gp mpi")
+
+
[docs]class SparseGP_MPI(SparseGP): + """ + A general purpose Sparse GP model with MPI parallelization support + + This model allows (approximate) inference using variational DTC or FITC + (Gaussian likelihoods) as well as non-conjugate sparse methods based on + these. + + :param X: inputs + :type X: np.ndarray (num_data x input_dim) + :param likelihood: a likelihood instance, containing the observed data + :type likelihood: GPy.likelihood.(Gaussian | EP | Laplace) + :param kernel: the kernel (covariance function). See link kernels + :type kernel: a GPy.kern.kern instance + :param X_variance: The uncertainty in the measurements of X (Gaussian variance) + :type X_variance: np.ndarray (num_data x input_dim) | None + :param Z: inducing inputs + :type Z: np.ndarray (num_inducing x input_dim) + :param num_inducing: Number of inducing points (optional, default 10. Ignored if Z is not None) + :type num_inducing: int + :param mpi_comm: The communication group of MPI, e.g. mpi4py.MPI.COMM_WORLD + :type mpi_comm: mpi4py.MPI.Intracomm + + """ + + def __init__(self, X, Y, Z, kernel, likelihood, variational_prior=None, inference_method=None, name='sparse gp mpi', Y_metadata=None, mpi_comm=None, normalizer=False): + self._IN_OPTIMIZATION_ = False + if mpi_comm != None: + if inference_method is None: + inference_method = VarDTC_minibatch(mpi_comm=mpi_comm) + else: + assert isinstance(inference_method, VarDTC_minibatch), 'inference_method has to support MPI!' + + super(SparseGP_MPI, self).__init__(X, Y, Z, kernel, likelihood, inference_method=inference_method, name=name, Y_metadata=Y_metadata, normalizer=normalizer) + self.update_model(False) + + if variational_prior is not None: + self.link_parameter(variational_prior) + + self.mpi_comm = mpi_comm + # Manage the data (Y) division + if mpi_comm != None: + from ..util.parallel import divide_data + N_start, N_end, N_list = divide_data(Y.shape[0], mpi_comm.rank, mpi_comm.size) + self.N_range = (N_start, N_end) + self.N_list = np.array(N_list) + self.Y_local = self.Y[N_start:N_end] + print 'MPI RANK '+str(self.mpi_comm.rank)+' with the data range '+str(self.N_range) + mpi_comm.Bcast(self.param_array, root=0) + self.update_model(True) + + def __getstate__(self): + dc = super(SparseGP_MPI, self).__getstate__() + dc['mpi_comm'] = None + if self.mpi_comm != None: + del dc['N_range'] + del dc['N_list'] + del dc['Y_local'] + if 'normalizer' not in dc: + dc['normalizer'] = None + dc['Y_normalized'] = dc['Y'] + return dc + + #===================================================== + # The MPI parallelization + # - can move to model at some point + #===================================================== + + @SparseGP.optimizer_array.setter + def optimizer_array(self, p): + if self.mpi_comm != None: + if self._IN_OPTIMIZATION_ and self.mpi_comm.rank==0: + self.mpi_comm.Bcast(np.int32(1),root=0) + self.mpi_comm.Bcast(p, root=0) + SparseGP.optimizer_array.fset(self,p) + +
[docs] def optimize(self, optimizer=None, start=None, **kwargs): + self._IN_OPTIMIZATION_ = True + if self.mpi_comm==None: + super(SparseGP_MPI, self).optimize(optimizer,start,**kwargs) + elif self.mpi_comm.rank==0: + super(SparseGP_MPI, self).optimize(optimizer,start,**kwargs) + self.mpi_comm.Bcast(np.int32(-1),root=0) + elif self.mpi_comm.rank>0: + x = self.optimizer_array.copy() + flag = np.empty(1,dtype=np.int32) + while True: + self.mpi_comm.Bcast(flag,root=0) + if flag==1: + try: + self.optimizer_array = x + self._fail_count = 0 + except (LinAlgError, ZeroDivisionError, ValueError): + if self._fail_count >= self._allowed_failures: + raise + self._fail_count += 1 + elif flag==-1: + break + else: + self._IN_OPTIMIZATION_ = False + raise Exception("Unrecognizable flag for synchronization!") + self._IN_OPTIMIZATION_ = False +
+
[docs] def parameters_changed(self): + if isinstance(self.inference_method,VarDTC_minibatch): + update_gradients(self, mpi_comm=self.mpi_comm) + else: + super(SparseGP_MPI,self).parameters_changed() +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/examples/classification.html b/doc/_build/html/_modules/GPy/examples/classification.html new file mode 100644 index 00000000..42ad8eb8 --- /dev/null +++ b/doc/_build/html/_modules/GPy/examples/classification.html @@ -0,0 +1,322 @@ + + + + + + + + GPy.examples.classification — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.examples.classification

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+"""
+Gaussian Processes classification examples
+"""
+import GPy
+
+default_seed = 10000
+
+
[docs]def oil(num_inducing=50, max_iters=100, kernel=None, optimize=True, plot=True): + """ + Run a Gaussian process classification on the three phase oil data. The demonstration calls the basic GP classification model and uses EP to approximate the likelihood. + + """ + try:import pods + except ImportError:print 'pods unavailable, see https://github.com/sods/ods for example datasets' + data = pods.datasets.oil() + X = data['X'] + Xtest = data['Xtest'] + Y = data['Y'][:, 0:1] + Ytest = data['Ytest'][:, 0:1] + Y[Y.flatten()==-1] = 0 + Ytest[Ytest.flatten()==-1] = 0 + + # Create GP model + m = GPy.models.SparseGPClassification(X, Y, kernel=kernel, num_inducing=num_inducing) + + # Contrain all parameters to be positive + #m.tie_params('.*len') + m['.*len'] = 10. + + # Optimize + if optimize: + for _ in range(5): + m.optimize(max_iters=int(max_iters/5)) + print(m) + + #Test + probs = m.predict(Xtest)[0] + GPy.util.classification.conf_matrix(probs, Ytest) + return m +
+
[docs]def toy_linear_1d_classification(seed=default_seed, optimize=True, plot=True): + """ + Simple 1D classification example using EP approximation + + :param seed: seed value for data generation (default is 4). + :type seed: int + + """ + + try:import pods + except ImportError:print 'pods unavailable, see https://github.com/sods/ods for example datasets' + data = pods.datasets.toy_linear_1d_classification(seed=seed) + Y = data['Y'][:, 0:1] + Y[Y.flatten() == -1] = 0 + + # Model definition + m = GPy.models.GPClassification(data['X'], Y) + + # Optimize + if optimize: + #m.update_likelihood_approximation() + # Parameters optimization: + m.optimize() + #m.update_likelihood_approximation() + #m.pseudo_EM() + + # Plot + if plot: + from matplotlib import pyplot as plt + fig, axes = plt.subplots(2, 1) + m.plot_f(ax=axes[0]) + m.plot(ax=axes[1]) + + print m + return m +
+
[docs]def toy_linear_1d_classification_laplace(seed=default_seed, optimize=True, plot=True): + """ + Simple 1D classification example using Laplace approximation + + :param seed: seed value for data generation (default is 4). + :type seed: int + + """ + + try:import pods + except ImportError:print 'pods unavailable, see https://github.com/sods/ods for example datasets' + data = pods.datasets.toy_linear_1d_classification(seed=seed) + Y = data['Y'][:, 0:1] + Y[Y.flatten() == -1] = 0 + + likelihood = GPy.likelihoods.Bernoulli() + laplace_inf = GPy.inference.latent_function_inference.Laplace() + kernel = GPy.kern.RBF(1) + + # Model definition + m = GPy.core.GP(data['X'], Y, kernel=kernel, likelihood=likelihood, inference_method=laplace_inf) + + # Optimize + if optimize: + try: + m.optimize('scg', messages=1) + except Exception as e: + return m + + # Plot + if plot: + from matplotlib import pyplot as plt + fig, axes = plt.subplots(2, 1) + m.plot_f(ax=axes[0]) + m.plot(ax=axes[1]) + + print m + return m +
+
[docs]def sparse_toy_linear_1d_classification(num_inducing=10, seed=default_seed, optimize=True, plot=True): + """ + Sparse 1D classification example + + :param seed: seed value for data generation (default is 4). + :type seed: int + + """ + + try:import pods + except ImportError:print 'pods unavailable, see https://github.com/sods/ods for example datasets' + data = pods.datasets.toy_linear_1d_classification(seed=seed) + Y = data['Y'][:, 0:1] + Y[Y.flatten() == -1] = 0 + + # Model definition + m = GPy.models.SparseGPClassification(data['X'], Y, num_inducing=num_inducing) + m['.*len'] = 4. + + # Optimize + if optimize: + m.optimize() + + # Plot + if plot: + from matplotlib import pyplot as plt + fig, axes = plt.subplots(2, 1) + m.plot_f(ax=axes[0]) + m.plot(ax=axes[1]) + + print m + return m +
+
[docs]def toy_heaviside(seed=default_seed, max_iters=100, optimize=True, plot=True): + """ + Simple 1D classification example using a heavy side gp transformation + + :param seed: seed value for data generation (default is 4). + :type seed: int + + """ + + try:import pods + except ImportError:print 'pods unavailable, see https://github.com/sods/ods for example datasets' + data = pods.datasets.toy_linear_1d_classification(seed=seed) + Y = data['Y'][:, 0:1] + Y[Y.flatten() == -1] = 0 + + # Model definition + kernel = GPy.kern.RBF(1) + likelihood = GPy.likelihoods.Bernoulli(gp_link=GPy.likelihoods.link_functions.Heaviside()) + ep = GPy.inference.latent_function_inference.expectation_propagation.EP() + m = GPy.core.GP(X=data['X'], Y=Y, kernel=kernel, likelihood=likelihood, inference_method=ep, name='gp_classification_heaviside') + #m = GPy.models.GPClassification(data['X'], likelihood=likelihood) + + # Optimize + if optimize: + # Parameters optimization: + for _ in range(5): + m.optimize(max_iters=int(max_iters/5)) + print m + + # Plot + if plot: + from matplotlib import pyplot as plt + fig, axes = plt.subplots(2, 1) + m.plot_f(ax=axes[0]) + m.plot(ax=axes[1]) + + print m + return m +
+
[docs]def crescent_data(model_type='Full', num_inducing=10, seed=default_seed, kernel=None, optimize=True, plot=True): + """ + Run a Gaussian process classification on the crescent data. The demonstration calls the basic GP classification model and uses EP to approximate the likelihood. + + :param model_type: type of model to fit ['Full', 'FITC', 'DTC']. + :param inducing: number of inducing variables (only used for 'FITC' or 'DTC'). + :type inducing: int + :param seed: seed value for data generation. + :type seed: int + :param kernel: kernel to use in the model + :type kernel: a GPy kernel + """ + try:import pods + except ImportError:print 'pods unavailable, see https://github.com/sods/ods for example datasets' + data = pods.datasets.crescent_data(seed=seed) + Y = data['Y'] + Y[Y.flatten()==-1] = 0 + + if model_type == 'Full': + m = GPy.models.GPClassification(data['X'], Y, kernel=kernel) + + elif model_type == 'DTC': + m = GPy.models.SparseGPClassification(data['X'], Y, kernel=kernel, num_inducing=num_inducing) + m['.*len'] = 10. + + elif model_type == 'FITC': + m = GPy.models.FITCClassification(data['X'], Y, kernel=kernel, num_inducing=num_inducing) + m['.*len'] = 3. + + if optimize: + m.pseudo_EM() + + if plot: + m.plot() + + print m + return m
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/examples/dimensionality_reduction.html b/doc/_build/html/_modules/GPy/examples/dimensionality_reduction.html new file mode 100644 index 00000000..2b490bf9 --- /dev/null +++ b/doc/_build/html/_modules/GPy/examples/dimensionality_reduction.html @@ -0,0 +1,762 @@ + + + + + + + + GPy.examples.dimensionality_reduction — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.examples.dimensionality_reduction

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+import numpy as _np
+
+# default_seed = _np.random.seed(123344)
+
+
[docs]def bgplvm_test_model(optimize=False, verbose=1, plot=False, output_dim=200, nan=False): + """ + model for testing purposes. Samples from a GP with rbf kernel and learns + the samples with a new kernel. Normally not for optimization, just model cheking + """ + import GPy + + num_inputs = 13 + num_inducing = 5 + if plot: + output_dim = 1 + input_dim = 3 + else: + input_dim = 2 + output_dim = output_dim + + # generate GPLVM-like data + X = _np.random.rand(num_inputs, input_dim) + lengthscales = _np.random.rand(input_dim) + k = GPy.kern.RBF(input_dim, .5, lengthscales, ARD=True) + K = k.K(X) + Y = _np.random.multivariate_normal(_np.zeros(num_inputs), K, (output_dim,)).T + + # k = GPy.kern.RBF_inv(input_dim, .5, _np.ones(input_dim) * 2., ARD=True) + GPy.kern.bias(input_dim) + GPy.kern.white(input_dim) + # k = GPy.kern.linear(input_dim)# + GPy.kern.bias(input_dim) + GPy.kern.white(input_dim, 0.00001) + # k = GPy.kern.RBF(input_dim, ARD = False) + GPy.kern.white(input_dim, 0.00001) + # k = GPy.kern.RBF(input_dim, .5, _np.ones(input_dim) * 2., ARD=True) + GPy.kern.RBF(input_dim, .3, _np.ones(input_dim) * .2, ARD=True) + # k = GPy.kern.RBF(input_dim, .5, 2., ARD=0) + GPy.kern.RBF(input_dim, .3, .2, ARD=0) + # k = GPy.kern.RBF(input_dim, .5, _np.ones(input_dim) * 2., ARD=True) + GPy.kern.linear(input_dim, _np.ones(input_dim) * .2, ARD=True) + + p = .3 + + m = GPy.models.BayesianGPLVM(Y, input_dim, kernel=k, num_inducing=num_inducing) + + if nan: + m.inference_method = GPy.inference.latent_function_inference.var_dtc.VarDTCMissingData() + m.Y[_np.random.binomial(1, p, size=(Y.shape)).astype(bool)] = _np.nan + m.parameters_changed() + + #=========================================================================== + # randomly obstruct data with percentage p + #=========================================================================== + # m2 = GPy.models.BayesianGPLVMWithMissingData(Y_obstruct, input_dim, kernel=k, num_inducing=num_inducing) + # m.lengthscales = lengthscales + + if plot: + import matplotlib.pyplot as pb + m.plot() + pb.title('PCA initialisation') + # m2.plot() + # pb.title('PCA initialisation') + + if optimize: + m.optimize('scg', messages=verbose) + # m2.optimize('scg', messages=verbose) + if plot: + m.plot() + pb.title('After optimisation') + # m2.plot() + # pb.title('After optimisation') + + return m +
+
[docs]def gplvm_oil_100(optimize=True, verbose=1, plot=True): + import GPy + import pods + data = pods.datasets.oil_100() + Y = data['X'] + # create simple GP model + kernel = GPy.kern.RBF(6, ARD=True) + GPy.kern.Bias(6) + m = GPy.models.GPLVM(Y, 6, kernel=kernel) + m.data_labels = data['Y'].argmax(axis=1) + if optimize: m.optimize('scg', messages=verbose) + if plot: m.plot_latent(labels=m.data_labels) + return m +
+
[docs]def sparse_gplvm_oil(optimize=True, verbose=0, plot=True, N=100, Q=6, num_inducing=15, max_iters=50): + import GPy + import pods + + _np.random.seed(0) + data = pods.datasets.oil() + Y = data['X'][:N] + Y = Y - Y.mean(0) + Y /= Y.std(0) + # Create the model + kernel = GPy.kern.RBF(Q, ARD=True) + GPy.kern.Bias(Q) + m = GPy.models.SparseGPLVM(Y, Q, kernel=kernel, num_inducing=num_inducing) + m.data_labels = data['Y'][:N].argmax(axis=1) + + if optimize: m.optimize('scg', messages=verbose, max_iters=max_iters) + if plot: + m.plot_latent(labels=m.data_labels) + m.kern.plot_ARD() + return m +
+
[docs]def swiss_roll(optimize=True, verbose=1, plot=True, N=1000, num_inducing=25, Q=4, sigma=.2): + import GPy + from pods.datasets import swiss_roll_generated + from GPy.models import BayesianGPLVM + + data = swiss_roll_generated(num_samples=N, sigma=sigma) + Y = data['Y'] + Y -= Y.mean() + Y /= Y.std() + + t = data['t'] + c = data['colors'] + + try: + from sklearn.manifold.isomap import Isomap + iso = Isomap().fit(Y) + X = iso.embedding_ + if Q > 2: + X = _np.hstack((X, _np.random.randn(N, Q - 2))) + except ImportError: + X = _np.random.randn(N, Q) + + if plot: + import matplotlib.pyplot as plt + from mpl_toolkits.mplot3d import Axes3D # @UnusedImport + fig = plt.figure("Swiss Roll Data") + ax = fig.add_subplot(121, projection='3d') + ax.scatter(*Y.T, c=c) + ax.set_title("Swiss Roll") + + ax = fig.add_subplot(122) + ax.scatter(*X.T[:2], c=c) + ax.set_title("BGPLVM init") + + var = .5 + S = (var * _np.ones_like(X) + _np.clip(_np.random.randn(N, Q) * var ** 2, + - (1 - var), + (1 - var))) + .001 + Z = _np.random.permutation(X)[:num_inducing] + + kernel = GPy.kern.RBF(Q, ARD=True) + GPy.kern.Bias(Q, _np.exp(-2)) + GPy.kern.White(Q, _np.exp(-2)) + + m = BayesianGPLVM(Y, Q, X=X, X_variance=S, num_inducing=num_inducing, Z=Z, kernel=kernel) + m.data_colors = c + m.data_t = t + + if optimize: + m.optimize('bfgs', messages=verbose, max_iters=2e3) + + if plot: + fig = plt.figure('fitted') + ax = fig.add_subplot(111) + s = m.input_sensitivity().argsort()[::-1][:2] + ax.scatter(*m.X.mean.T[s], c=c) + + return m +
+
[docs]def bgplvm_oil(optimize=True, verbose=1, plot=True, N=200, Q=7, num_inducing=40, max_iters=1000, **k): + import GPy + from matplotlib import pyplot as plt + import numpy as np + _np.random.seed(0) + try: + import pods + data = pods.datasets.oil() + except ImportError: + data = GPy.util.datasets.oil() + + + kernel = GPy.kern.RBF(Q, 1., 1. / _np.random.uniform(0, 1, (Q,)), ARD=True) # + GPy.kern.Bias(Q, _np.exp(-2)) + Y = data['X'][:N] + m = GPy.models.BayesianGPLVM(Y, Q, kernel=kernel, num_inducing=num_inducing, **k) + m.data_labels = data['Y'][:N].argmax(axis=1) + + if optimize: + m.optimize('bfgs', messages=verbose, max_iters=max_iters, gtol=.05) + + if plot: + fig, (latent_axes, sense_axes) = plt.subplots(1, 2) + m.plot_latent(ax=latent_axes, labels=m.data_labels) + data_show = GPy.plotting.matplot_dep.visualize.vector_show((m.Y[0, :])) + lvm_visualizer = GPy.plotting.matplot_dep.visualize.lvm_dimselect(m.X.mean.values[0:1, :], # @UnusedVariable + m, data_show, latent_axes=latent_axes, sense_axes=sense_axes, labels=m.data_labels) + raw_input('Press enter to finish') + plt.close(fig) + return m +
+
[docs]def ssgplvm_oil(optimize=True, verbose=1, plot=True, N=200, Q=7, num_inducing=40, max_iters=1000, **k): + import GPy + from matplotlib import pyplot as plt + import pods + + _np.random.seed(0) + data = pods.datasets.oil() + + kernel = GPy.kern.RBF(Q, 1., 1. / _np.random.uniform(0, 1, (Q,)), ARD=True) # + GPy.kern.Bias(Q, _np.exp(-2)) + Y = data['X'][:N] + m = GPy.models.SSGPLVM(Y, Q, kernel=kernel, num_inducing=num_inducing, **k) + m.data_labels = data['Y'][:N].argmax(axis=1) + + if optimize: + m.optimize('bfgs', messages=verbose, max_iters=max_iters, gtol=.05) + + if plot: + fig, (latent_axes, sense_axes) = plt.subplots(1, 2) + m.plot_latent(ax=latent_axes, labels=m.data_labels) + data_show = GPy.plotting.matplot_dep.visualize.vector_show((m.Y[0, :])) + lvm_visualizer = GPy.plotting.matplot_dep.visualize.lvm_dimselect(m.X.mean.values[0:1, :], # @UnusedVariable + m, data_show, latent_axes=latent_axes, sense_axes=sense_axes, labels=m.data_labels) + raw_input('Press enter to finish') + plt.close(fig) + return m +
+def _simulate_matern(D1, D2, D3, N, num_inducing, plot_sim=False): + Q_signal = 4 + import GPy + import numpy as np + np.random.seed(3000) + + k = GPy.kern.Matern32(Q_signal, 1., lengthscale=(np.random.uniform(1, 6, Q_signal)), ARD=1) + for i in range(Q_signal): + k += GPy.kern.PeriodicExponential(1, variance=1., active_dims=[i], period=3., lower=-2, upper=6) + t = np.c_[[np.linspace(-1, 5, N) for _ in range(Q_signal)]].T + K = k.K(t) + s2, s1, s3, sS = np.random.multivariate_normal(np.zeros(K.shape[0]), K, size=(4))[:, :, None] + + Y1, Y2, Y3, S1, S2, S3 = _generate_high_dimensional_output(D1, D2, D3, s1, s2, s3, sS) + + slist = [sS, s1, s2, s3] + slist_names = ["sS", "s1", "s2", "s3"] + Ylist = [Y1, Y2, Y3] + + if plot_sim: + from matplotlib import pyplot as plt + import matplotlib.cm as cm + import itertools + fig = plt.figure("MRD Simulation Data", figsize=(8, 6)) + fig.clf() + ax = fig.add_subplot(2, 1, 1) + labls = slist_names + for S, lab in itertools.izip(slist, labls): + ax.plot(S, label=lab) + ax.legend() + for i, Y in enumerate(Ylist): + ax = fig.add_subplot(2, len(Ylist), len(Ylist) + 1 + i) + ax.imshow(Y, aspect='auto', cmap=cm.gray) # @UndefinedVariable + ax.set_title("Y{}".format(i + 1)) + plt.draw() + plt.tight_layout() + + return slist, [S1, S2, S3], Ylist + +def _simulate_sincos(D1, D2, D3, N, num_inducing, plot_sim=False): + _np.random.seed(1234) + + x = _np.linspace(0, 4 * _np.pi, N)[:, None] + s1 = _np.vectorize(lambda x: _np.sin(x)) + s2 = _np.vectorize(lambda x: _np.cos(x) ** 2) + s3 = _np.vectorize(lambda x:-_np.exp(-_np.cos(2 * x))) + sS = _np.vectorize(lambda x: _np.cos(x)) + + s1 = s1(x) + s2 = s2(x) + s3 = s3(x) + sS = sS(x) + + s1 -= s1.mean(); s1 /= s1.std(0) + s2 -= s2.mean(); s2 /= s2.std(0) + s3 -= s3.mean(); s3 /= s3.std(0) + sS -= sS.mean(); sS /= sS.std(0) + + Y1, Y2, Y3, S1, S2, S3 = _generate_high_dimensional_output(D1, D2, D3, s1, s2, s3, sS) + + slist = [sS, s1, s2, s3] + slist_names = ["sS", "s1", "s2", "s3"] + Ylist = [Y1, Y2, Y3] + + if plot_sim: + from matplotlib import pyplot as plt + import matplotlib.cm as cm + import itertools + fig = plt.figure("MRD Simulation Data", figsize=(8, 6)) + fig.clf() + ax = fig.add_subplot(2, 1, 1) + labls = slist_names + for S, lab in itertools.izip(slist, labls): + ax.plot(S, label=lab) + ax.legend() + for i, Y in enumerate(Ylist): + ax = fig.add_subplot(2, len(Ylist), len(Ylist) + 1 + i) + ax.imshow(Y, aspect='auto', cmap=cm.gray) # @UndefinedVariable + ax.set_title("Y{}".format(i + 1)) + plt.draw() + plt.tight_layout() + + return slist, [S1, S2, S3], Ylist + +def _generate_high_dimensional_output(D1, D2, D3, s1, s2, s3, sS): + S1 = _np.hstack([s1, sS]) + S2 = _np.hstack([s2, s3, sS]) + S3 = _np.hstack([s3, sS]) + Y1 = S1.dot(_np.random.randn(S1.shape[1], D1)) + Y2 = S2.dot(_np.random.randn(S2.shape[1], D2)) + Y3 = S3.dot(_np.random.randn(S3.shape[1], D3)) + Y1 += .3 * _np.random.randn(*Y1.shape) + Y2 += .2 * _np.random.randn(*Y2.shape) + Y3 += .25 * _np.random.randn(*Y3.shape) + Y1 -= Y1.mean(0) + Y2 -= Y2.mean(0) + Y3 -= Y3.mean(0) + Y1 /= Y1.std(0) + Y2 /= Y2.std(0) + Y3 /= Y3.std(0) + return Y1, Y2, Y3, S1, S2, S3 + +
[docs]def bgplvm_simulation(optimize=True, verbose=1, + plot=True, plot_sim=False, + max_iters=2e4, + ): + from GPy import kern + from GPy.models import BayesianGPLVM + + D1, D2, D3, N, num_inducing, Q = 13, 5, 8, 45, 3, 9 + _, _, Ylist = _simulate_matern(D1, D2, D3, N, num_inducing, plot_sim) + Y = Ylist[0] + k = kern.Linear(Q, ARD=True) # + kern.white(Q, _np.exp(-2)) # + kern.bias(Q) + # k = kern.RBF(Q, ARD=True, lengthscale=10.) + m = BayesianGPLVM(Y, Q, init="PCA", num_inducing=num_inducing, kernel=k) + m.X.variance[:] = _np.random.uniform(0, .01, m.X.shape) + m.likelihood.variance = .1 + + if optimize: + print "Optimizing model:" + m.optimize('bfgs', messages=verbose, max_iters=max_iters, + gtol=.05) + if plot: + m.X.plot("BGPLVM Latent Space 1D") + m.kern.plot_ARD('BGPLVM Simulation ARD Parameters') + return m +
+
[docs]def ssgplvm_simulation(optimize=True, verbose=1, + plot=True, plot_sim=False, + max_iters=2e4, useGPU=False + ): + from GPy import kern + from GPy.models import SSGPLVM + + D1, D2, D3, N, num_inducing, Q = 13, 5, 8, 45, 3, 9 + _, _, Ylist = _simulate_matern(D1, D2, D3, N, num_inducing, plot_sim) + Y = Ylist[0] + k = kern.Linear(Q, ARD=True) # + kern.white(Q, _np.exp(-2)) # + kern.bias(Q) + # k = kern.RBF(Q, ARD=True, lengthscale=10.) + m = SSGPLVM(Y, Q, init="pca", num_inducing=num_inducing, kernel=k) + m.X.variance[:] = _np.random.uniform(0, .01, m.X.shape) + m.likelihood.variance = .1 + + if optimize: + print "Optimizing model:" + m.optimize('scg', messages=verbose, max_iters=max_iters, + gtol=.05) + if plot: + m.X.plot("SSGPLVM Latent Space 1D") + m.kern.plot_ARD('SSGPLVM Simulation ARD Parameters') + return m +
+
[docs]def bgplvm_simulation_missing_data(optimize=True, verbose=1, + plot=True, plot_sim=False, + max_iters=2e4, percent_missing=.1, + ): + from GPy import kern + from GPy.models.bayesian_gplvm_minibatch import BayesianGPLVMMiniBatch + + D1, D2, D3, N, num_inducing, Q = 13, 5, 8, 400, 3, 4 + _, _, Ylist = _simulate_matern(D1, D2, D3, N, num_inducing, plot_sim) + Y = Ylist[0] + k = kern.Linear(Q, ARD=True) # + kern.white(Q, _np.exp(-2)) # + kern.bias(Q) + + inan = _np.random.binomial(1, percent_missing, size=Y.shape).astype(bool) # 80% missing data + Ymissing = Y.copy() + Ymissing[inan] = _np.nan + + m = BayesianGPLVMMiniBatch(Ymissing, Q, init="random", num_inducing=num_inducing, + kernel=k, missing_data=True) + + m.Yreal = Y + + if optimize: + print "Optimizing model:" + m.optimize('bfgs', messages=verbose, max_iters=max_iters, + gtol=.05) + if plot: + m.X.plot("BGPLVM Latent Space 1D") + m.kern.plot_ARD('BGPLVM Simulation ARD Parameters') + return m + +
+
[docs]def mrd_simulation(optimize=True, verbose=True, plot=True, plot_sim=True, **kw): + from GPy import kern + from GPy.models import MRD + + D1, D2, D3, N, num_inducing, Q = 60, 20, 36, 60, 6, 5 + _, _, Ylist = _simulate_matern(D1, D2, D3, N, num_inducing, plot_sim) + + # Ylist = [Ylist[0]] + k = kern.Linear(Q, ARD=True) + m = MRD(Ylist, input_dim=Q, num_inducing=num_inducing, kernel=k, initx="PCA_concat", initz='permute', **kw) + + m['.*noise'] = [Y.var() / 40. for Y in Ylist] + + if optimize: + print "Optimizing Model:" + m.optimize(messages=verbose, max_iters=8e3) + if plot: + m.X.plot("MRD Latent Space 1D") + m.plot_scales("MRD Scales") + return m +
+
[docs]def mrd_simulation_missing_data(optimize=True, verbose=True, plot=True, plot_sim=True, **kw): + from GPy import kern + from GPy.models import MRD + + D1, D2, D3, N, num_inducing, Q = 60, 20, 36, 60, 6, 5 + _, _, Ylist = _simulate_matern(D1, D2, D3, N, num_inducing, plot_sim) + + # Ylist = [Ylist[0]] + k = kern.Linear(Q, ARD=True) + inanlist = [] + + for Y in Ylist: + inan = _np.random.binomial(1, .6, size=Y.shape).astype(bool) + inanlist.append(inan) + Y[inan] = _np.nan + + m = MRD(Ylist, input_dim=Q, num_inducing=num_inducing, + kernel=k, inference_method=None, + initx="random", initz='permute', **kw) + + if optimize: + print "Optimizing Model:" + m.optimize('bfgs', messages=verbose, max_iters=8e3, gtol=.1) + if plot: + m.X.plot("MRD Latent Space 1D") + m.plot_scales("MRD Scales") + return m +
+
[docs]def brendan_faces(optimize=True, verbose=True, plot=True): + import GPy + import pods + + data = pods.datasets.brendan_faces() + Q = 2 + Y = data['Y'] + Yn = Y - Y.mean() + Yn /= Yn.std() + + m = GPy.models.BayesianGPLVM(Yn, Q, num_inducing=20) + + # optimize + + if optimize: m.optimize('bfgs', messages=verbose, max_iters=1000) + + if plot: + ax = m.plot_latent(which_indices=(0, 1)) + y = m.Y[0, :] + data_show = GPy.plotting.matplot_dep.visualize.image_show(y[None, :], dimensions=(20, 28), transpose=True, order='F', invert=False, scale=False) + lvm = GPy.plotting.matplot_dep.visualize.lvm(m.X.mean[0, :].copy(), m, data_show, ax) + raw_input('Press enter to finish') + + return m +
+
[docs]def olivetti_faces(optimize=True, verbose=True, plot=True): + import GPy + import pods + + data = pods.datasets.olivetti_faces() + Q = 2 + Y = data['Y'] + Yn = Y - Y.mean() + Yn /= Yn.std() + + m = GPy.models.BayesianGPLVM(Yn, Q, num_inducing=20) + + if optimize: m.optimize('bfgs', messages=verbose, max_iters=1000) + if plot: + ax = m.plot_latent(which_indices=(0, 1)) + y = m.Y[0, :] + data_show = GPy.plotting.matplot_dep.visualize.image_show(y[None, :], dimensions=(112, 92), transpose=False, invert=False, scale=False) + lvm = GPy.plotting.matplot_dep.visualize.lvm(m.X.mean[0, :].copy(), m, data_show, ax) + raw_input('Press enter to finish') + + return m +
+
[docs]def stick_play(range=None, frame_rate=15, optimize=False, verbose=True, plot=True): + import GPy + import pods + + data = pods.datasets.osu_run1() + # optimize + if range == None: + Y = data['Y'].copy() + else: + Y = data['Y'][range[0]:range[1], :].copy() + if plot: + y = Y[0, :] + data_show = GPy.plotting.matplot_dep.visualize.stick_show(y[None, :], connect=data['connect']) + GPy.plotting.matplot_dep.visualize.data_play(Y, data_show, frame_rate) + return Y +
+
[docs]def stick(kernel=None, optimize=True, verbose=True, plot=True): + from matplotlib import pyplot as plt + import GPy + import pods + + data = pods.datasets.osu_run1() + # optimize + m = GPy.models.GPLVM(data['Y'], 2, kernel=kernel) + if optimize: m.optimize('bfgs', messages=verbose, max_f_eval=10000) + if plot: + plt.clf + ax = m.plot_latent() + y = m.Y[0, :] + data_show = GPy.plotting.matplot_dep.visualize.stick_show(y[None, :], connect=data['connect']) + lvm_visualizer = GPy.plotting.matplot_dep.visualize.lvm(m.X[:1, :].copy(), m, data_show, latent_axes=ax) + raw_input('Press enter to finish') + lvm_visualizer.close() + data_show.close() + return m +
+
[docs]def bcgplvm_linear_stick(kernel=None, optimize=True, verbose=True, plot=True): + from matplotlib import pyplot as plt + import GPy + import pods + + data = pods.datasets.osu_run1() + # optimize + mapping = GPy.mappings.Linear(data['Y'].shape[1], 2) + m = GPy.models.BCGPLVM(data['Y'], 2, kernel=kernel, mapping=mapping) + if optimize: m.optimize(messages=verbose, max_f_eval=10000) + if plot and GPy.plotting.matplot_dep.visualize.visual_available: + plt.clf + ax = m.plot_latent() + y = m.likelihood.Y[0, :] + data_show = GPy.plotting.matplot_dep.visualize.stick_show(y[None, :], connect=data['connect']) + GPy.plotting.matplot_dep.visualize.lvm(m.X[0, :].copy(), m, data_show, ax) + raw_input('Press enter to finish') + + return m +
+
[docs]def bcgplvm_stick(kernel=None, optimize=True, verbose=True, plot=True): + from matplotlib import pyplot as plt + import GPy + import pods + + data = pods.datasets.osu_run1() + # optimize + back_kernel = GPy.kern.RBF(data['Y'].shape[1], lengthscale=5.) + mapping = GPy.mappings.Kernel(X=data['Y'], output_dim=2, kernel=back_kernel) + m = GPy.models.BCGPLVM(data['Y'], 2, kernel=kernel, mapping=mapping) + if optimize: m.optimize(messages=verbose, max_f_eval=10000) + if plot and GPy.plotting.matplot_dep.visualize.visual_available: + plt.clf + ax = m.plot_latent() + y = m.likelihood.Y[0, :] + data_show = GPy.plotting.matplot_dep.visualize.stick_show(y[None, :], connect=data['connect']) + GPy.plotting.matplot_dep.visualize.lvm(m.X[0, :].copy(), m, data_show, ax) + # raw_input('Press enter to finish') + + return m +
+
[docs]def robot_wireless(optimize=True, verbose=True, plot=True): + from matplotlib import pyplot as plt + import GPy + import pods + + data = pods.datasets.robot_wireless() + # optimize + m = GPy.models.BayesianGPLVM(data['Y'], 4, num_inducing=25) + if optimize: m.optimize(messages=verbose, max_f_eval=10000) + if plot: + m.plot_latent() + + return m +
+
[docs]def stick_bgplvm(model=None, optimize=True, verbose=True, plot=True): + from GPy.models import BayesianGPLVM + from matplotlib import pyplot as plt + import numpy as np + import GPy + import pods + + data = pods.datasets.osu_run1() + Q = 6 + kernel = GPy.kern.RBF(Q, lengthscale=np.repeat(.5, Q), ARD=True) + m = BayesianGPLVM(data['Y'], Q, init="PCA", num_inducing=20, kernel=kernel) + + m.data = data + m.likelihood.variance = 0.001 + + # optimize + try: + if optimize: m.optimize('bfgs', messages=verbose, max_iters=5e3, bfgs_factor=10) + except KeyboardInterrupt: + print "Keyboard interrupt, continuing to plot and return" + + if plot: + fig, (latent_axes, sense_axes) = plt.subplots(1, 2) + plt.sca(latent_axes) + m.plot_latent(ax=latent_axes) + y = m.Y[:1, :].copy() + data_show = GPy.plotting.matplot_dep.visualize.stick_show(y, connect=data['connect']) + dim_select = GPy.plotting.matplot_dep.visualize.lvm_dimselect(m.X.mean[:1, :].copy(), m, data_show, latent_axes=latent_axes, sense_axes=sense_axes) + fig.canvas.draw() + fig.canvas.show() + raw_input('Press enter to finish') + + return m + +
+
[docs]def cmu_mocap(subject='35', motion=['01'], in_place=True, optimize=True, verbose=True, plot=True): + import GPy + import pods + + data = pods.datasets.cmu_mocap(subject, motion) + if in_place: + # Make figure move in place. + data['Y'][:, 0:3] = 0.0 + Y = data['Y'] + Y_mean = Y.mean(0) + Y_std = Y.std(0) + m = GPy.models.GPLVM((Y - Y_mean) / Y_std, 2) + + if optimize: m.optimize(messages=verbose, max_f_eval=10000) + if plot: + ax = m.plot_latent() + y = m.Y[0, :] + data_show = GPy.plotting.matplot_dep.visualize.skeleton_show(y[None, :], data['skel']) + lvm_visualizer = GPy.plotting.matplot_dep.visualize.lvm(m.X[0].copy(), m, data_show, latent_axes=ax) + raw_input('Press enter to finish') + lvm_visualizer.close() + data_show.close() + + return m +
+
[docs]def ssgplvm_simulation_linear(): + import numpy as np + import GPy + N, D, Q = 1000, 20, 5 + pi = 0.2 + + def sample_X(Q, pi): + x = np.empty(Q) + dies = np.random.rand(Q) + for q in xrange(Q): + if dies[q] < pi: + x[q] = np.random.randn() + else: + x[q] = 0. + return x + + Y = np.empty((N, D)) + X = np.empty((N, Q)) + # Generate data from random sampled weight matrices + for n in xrange(N): + X[n] = sample_X(Q, pi) + w = np.random.randn(D, Q) + Y[n] = np.dot(w, X[n]) +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/examples/non_gaussian.html b/doc/_build/html/_modules/GPy/examples/non_gaussian.html new file mode 100644 index 00000000..3f7fb9f7 --- /dev/null +++ b/doc/_build/html/_modules/GPy/examples/non_gaussian.html @@ -0,0 +1,389 @@ + + + + + + + + GPy.examples.non_gaussian — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.examples.non_gaussian

+# Copyright (c) 2014, Alan Saul
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import GPy
+import numpy as np
+from GPy.util import datasets
+try:
+    import matplotlib.pyplot as plt
+except:
+    pass
+
+
[docs]def student_t_approx(optimize=True, plot=True): + """ + Example of regressing with a student t likelihood using Laplace + """ + real_std = 0.1 + #Start a function, any function + X = np.linspace(0.0, np.pi*2, 100)[:, None] + Y = np.sin(X) + np.random.randn(*X.shape)*real_std + Y = Y/Y.max() + Yc = Y.copy() + + X_full = np.linspace(0.0, np.pi*2, 500)[:, None] + Y_full = np.sin(X_full) + Y_full = Y_full/Y_full.max() + + #Slightly noisy data + Yc[75:80] += 1 + + #Very noisy data + #Yc[10] += 100 + #Yc[25] += 10 + #Yc[23] += 10 + #Yc[26] += 1000 + #Yc[24] += 10 + #Yc = Yc/Yc.max() + + #Add student t random noise to datapoints + deg_free = 1 + print "Real noise: ", real_std + initial_var_guess = 0.5 + edited_real_sd = initial_var_guess + + # Kernel object + kernel1 = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) + kernel2 = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) + kernel3 = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) + kernel4 = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) + + #Gaussian GP model on clean data + m1 = GPy.models.GPRegression(X, Y.copy(), kernel=kernel1) + # optimize + m1['.*white'].constrain_fixed(1e-5) + m1.randomize() + + #Gaussian GP model on corrupt data + m2 = GPy.models.GPRegression(X, Yc.copy(), kernel=kernel2) + m2['.*white'].constrain_fixed(1e-5) + m2.randomize() + + #Student t GP model on clean data + t_distribution = GPy.likelihoods.StudentT(deg_free=deg_free, sigma2=edited_real_sd) + laplace_inf = GPy.inference.latent_function_inference.Laplace() + m3 = GPy.core.GP(X, Y.copy(), kernel3, likelihood=t_distribution, inference_method=laplace_inf) + m3['.*t_scale2'].constrain_bounded(1e-6, 10.) + m3['.*white'].constrain_fixed(1e-5) + m3.randomize() + + #Student t GP model on corrupt data + t_distribution = GPy.likelihoods.StudentT(deg_free=deg_free, sigma2=edited_real_sd) + laplace_inf = GPy.inference.latent_function_inference.Laplace() + m4 = GPy.core.GP(X, Yc.copy(), kernel4, likelihood=t_distribution, inference_method=laplace_inf) + m4['.*t_scale2'].constrain_bounded(1e-6, 10.) + m4['.*white'].constrain_fixed(1e-5) + m4.randomize() + print m4 + debug=True + if debug: + m4.optimize(messages=1) + import pylab as pb + pb.plot(m4.X, m4.inference_method.f_hat) + pb.plot(m4.X, m4.Y, 'rx') + m4.plot() + print m4 + return m4 + + if optimize: + optimizer='scg' + print "Clean Gaussian" + m1.optimize(optimizer, messages=1) + print "Corrupt Gaussian" + m2.optimize(optimizer, messages=1) + print "Clean student t" + m3.optimize(optimizer, messages=1) + print "Corrupt student t" + m4.optimize(optimizer, messages=1) + + if plot: + plt.figure(1) + plt.suptitle('Gaussian likelihood') + ax = plt.subplot(211) + m1.plot(ax=ax) + plt.plot(X_full, Y_full) + plt.ylim(-1.5, 1.5) + plt.title('Gaussian clean') + + ax = plt.subplot(212) + m2.plot(ax=ax) + plt.plot(X_full, Y_full) + plt.ylim(-1.5, 1.5) + plt.title('Gaussian corrupt') + + plt.figure(2) + plt.suptitle('Student-t likelihood') + ax = plt.subplot(211) + m3.plot(ax=ax) + plt.plot(X_full, Y_full) + plt.ylim(-1.5, 1.5) + plt.title('Student-t rasm clean') + + ax = plt.subplot(212) + m4.plot(ax=ax) + plt.plot(X_full, Y_full) + plt.ylim(-1.5, 1.5) + plt.title('Student-t rasm corrupt') + + return m1, m2, m3, m4 +
+
[docs]def boston_example(optimize=True, plot=True): + raise NotImplementedError("Needs updating") + import sklearn + from sklearn.cross_validation import KFold + optimizer='bfgs' + messages=0 + data = datasets.boston_housing() + degrees_freedoms = [3, 5, 8, 10] + X = data['X'].copy() + Y = data['Y'].copy() + X = X-X.mean(axis=0) + X = X/X.std(axis=0) + Y = Y-Y.mean() + Y = Y/Y.std() + num_folds = 10 + kf = KFold(len(Y), n_folds=num_folds, indices=True) + num_models = len(degrees_freedoms) + 3 #3 for baseline, gaussian, gaussian laplace approx + score_folds = np.zeros((num_models, num_folds)) + pred_density = score_folds.copy() + + def rmse(Y, Ystar): + return np.sqrt(np.mean((Y-Ystar)**2)) + + for n, (train, test) in enumerate(kf): + X_train, X_test, Y_train, Y_test = X[train], X[test], Y[train], Y[test] + print "Fold {}".format(n) + + noise = 1e-1 #np.exp(-2) + rbf_len = 0.5 + data_axis_plot = 4 + kernelstu = GPy.kern.RBF(X.shape[1]) + GPy.kern.white(X.shape[1]) + GPy.kern.bias(X.shape[1]) + kernelgp = GPy.kern.RBF(X.shape[1]) + GPy.kern.white(X.shape[1]) + GPy.kern.bias(X.shape[1]) + + #Baseline + score_folds[0, n] = rmse(Y_test, np.mean(Y_train)) + + #Gaussian GP + print "Gauss GP" + mgp = GPy.models.GPRegression(X_train.copy(), Y_train.copy(), kernel=kernelgp.copy()) + mgp.constrain_fixed('.*white', 1e-5) + mgp['.*len'] = rbf_len + mgp['.*noise'] = noise + print mgp + if optimize: + mgp.optimize(optimizer=optimizer, messages=messages) + Y_test_pred = mgp.predict(X_test) + score_folds[1, n] = rmse(Y_test, Y_test_pred[0]) + pred_density[1, n] = np.mean(mgp.log_predictive_density(X_test, Y_test)) + print mgp + print pred_density + + print "Gaussian Laplace GP" + N, D = Y_train.shape + g_distribution = GPy.likelihoods.noise_model_constructors.gaussian(variance=noise, N=N, D=D) + g_likelihood = GPy.likelihoods.Laplace(Y_train.copy(), g_distribution) + mg = GPy.models.GPRegression(X_train.copy(), Y_train.copy(), kernel=kernelstu.copy(), likelihood=g_likelihood) + mg.constrain_positive('noise_variance') + mg.constrain_fixed('.*white', 1e-5) + mg['rbf_len'] = rbf_len + mg['noise'] = noise + print mg + if optimize: + mg.optimize(optimizer=optimizer, messages=messages) + Y_test_pred = mg.predict(X_test) + score_folds[2, n] = rmse(Y_test, Y_test_pred[0]) + pred_density[2, n] = np.mean(mg.log_predictive_density(X_test, Y_test)) + print pred_density + print mg + + for stu_num, df in enumerate(degrees_freedoms): + #Student T + print "Student-T GP {}df".format(df) + t_distribution = GPy.likelihoods.noise_model_constructors.student_t(deg_free=df, sigma2=noise) + stu_t_likelihood = GPy.likelihoods.Laplace(Y_train.copy(), t_distribution) + mstu_t = GPy.models.GPRegression(X_train.copy(), Y_train.copy(), kernel=kernelstu.copy(), likelihood=stu_t_likelihood) + mstu_t.constrain_fixed('.*white', 1e-5) + mstu_t.constrain_bounded('.*t_scale2', 0.0001, 1000) + mstu_t['rbf_len'] = rbf_len + mstu_t['.*t_scale2'] = noise + print mstu_t + if optimize: + mstu_t.optimize(optimizer=optimizer, messages=messages) + Y_test_pred = mstu_t.predict(X_test) + score_folds[3+stu_num, n] = rmse(Y_test, Y_test_pred[0]) + pred_density[3+stu_num, n] = np.mean(mstu_t.log_predictive_density(X_test, Y_test)) + print pred_density + print mstu_t + + if plot: + plt.figure() + plt.scatter(X_test[:, data_axis_plot], Y_test_pred[0]) + plt.scatter(X_test[:, data_axis_plot], Y_test, c='r', marker='x') + plt.title('GP gauss') + + plt.figure() + plt.scatter(X_test[:, data_axis_plot], Y_test_pred[0]) + plt.scatter(X_test[:, data_axis_plot], Y_test, c='r', marker='x') + plt.title('Lap gauss') + + plt.figure() + plt.scatter(X_test[:, data_axis_plot], Y_test_pred[0]) + plt.scatter(X_test[:, data_axis_plot], Y_test, c='r', marker='x') + plt.title('Stu t {}df'.format(df)) + + print "Average scores: {}".format(np.mean(score_folds, 1)) + print "Average pred density: {}".format(np.mean(pred_density, 1)) + + if plot: + #Plotting + stu_t_legends = ['Student T, df={}'.format(df) for df in degrees_freedoms] + legends = ['Baseline', 'Gaussian', 'Laplace Approx Gaussian'] + stu_t_legends + + #Plot boxplots for RMSE density + fig = plt.figure() + ax=fig.add_subplot(111) + plt.title('RMSE') + bp = ax.boxplot(score_folds.T, notch=0, sym='+', vert=1, whis=1.5) + plt.setp(bp['boxes'], color='black') + plt.setp(bp['whiskers'], color='black') + plt.setp(bp['fliers'], color='red', marker='+') + xtickNames = plt.setp(ax, xticklabels=legends) + plt.setp(xtickNames, rotation=45, fontsize=8) + ax.set_ylabel('RMSE') + ax.set_xlabel('Distribution') + #Make grid and put it below boxes + ax.yaxis.grid(True, linestyle='-', which='major', color='lightgrey', + alpha=0.5) + ax.set_axisbelow(True) + + #Plot boxplots for predictive density + fig = plt.figure() + ax=fig.add_subplot(111) + plt.title('Predictive density') + bp = ax.boxplot(pred_density[1:,:].T, notch=0, sym='+', vert=1, whis=1.5) + plt.setp(bp['boxes'], color='black') + plt.setp(bp['whiskers'], color='black') + plt.setp(bp['fliers'], color='red', marker='+') + xtickNames = plt.setp(ax, xticklabels=legends[1:]) + plt.setp(xtickNames, rotation=45, fontsize=8) + ax.set_ylabel('Mean Log probability P(Y*|Y)') + ax.set_xlabel('Distribution') + #Make grid and put it below boxes + ax.yaxis.grid(True, linestyle='-', which='major', color='lightgrey', + alpha=0.5) + ax.set_axisbelow(True) + return mstu_t + +#def precipitation_example(): + #import sklearn + #from sklearn.cross_validation import KFold + #data = datasets.boston_housing() + #X = data['X'].copy() + #Y = data['Y'].copy() + #X = X-X.mean(axis=0) + #X = X/X.std(axis=0) + #Y = Y-Y.mean() + #Y = Y/Y.std() + #import ipdb; ipdb.set_trace() # XXX BREAKPOINT + #num_folds = 10 + #kf = KFold(len(Y), n_folds=num_folds, indices=True) + #score_folds = np.zeros((4, num_folds)) + #def rmse(Y, Ystar): + #return np.sqrt(np.mean((Y-Ystar)**2)) + ##for train, test in kf: + #for n, (train, test) in enumerate(kf): + #X_train, X_test, Y_train, Y_test = X[train], X[test], Y[train], Y[test] + #print "Fold {}".format(n) +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/examples/regression.html b/doc/_build/html/_modules/GPy/examples/regression.html new file mode 100644 index 00000000..f027e0ca --- /dev/null +++ b/doc/_build/html/_modules/GPy/examples/regression.html @@ -0,0 +1,601 @@ + + + + + + + + GPy.examples.regression — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.examples.regression

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+"""
+Gaussian Processes regression examples
+"""
+try:
+    import pylab as pb
+except:
+    pass
+import numpy as np
+import GPy
+
+
[docs]def olympic_marathon_men(optimize=True, plot=True): + """Run a standard Gaussian process regression on the Olympic marathon data.""" + try:import pods + except ImportError: + print 'pods unavailable, see https://github.com/sods/ods for example datasets' + return + data = pods.datasets.olympic_marathon_men() + + # create simple GP Model + m = GPy.models.GPRegression(data['X'], data['Y']) + + # set the lengthscale to be something sensible (defaults to 1) + m.kern.lengthscale = 10. + + if optimize: + m.optimize('bfgs', max_iters=200) + if plot: + m.plot(plot_limits=(1850, 2050)) + + return m +
+
[docs]def coregionalization_toy(optimize=True, plot=True): + """ + A simple demonstration of coregionalization on two sinusoidal functions. + """ + #build a design matrix with a column of integers indicating the output + X1 = np.random.rand(50, 1) * 8 + X2 = np.random.rand(30, 1) * 5 + + #build a suitable set of observed variables + Y1 = np.sin(X1) + np.random.randn(*X1.shape) * 0.05 + Y2 = np.sin(X2) + np.random.randn(*X2.shape) * 0.05 + 2. + + m = GPy.models.GPCoregionalizedRegression(X_list=[X1,X2], Y_list=[Y1,Y2]) + + if optimize: + m.optimize('bfgs', max_iters=100) + + if plot: + slices = GPy.util.multioutput.get_slices([X1,X2]) + m.plot(fixed_inputs=[(1,0)],which_data_rows=slices[0],Y_metadata={'output_index':0}) + m.plot(fixed_inputs=[(1,1)],which_data_rows=slices[1],Y_metadata={'output_index':1},ax=pb.gca()) + return m +
+
[docs]def coregionalization_sparse(optimize=True, plot=True): + """ + A simple demonstration of coregionalization on two sinusoidal functions using sparse approximations. + """ + #build a design matrix with a column of integers indicating the output + X1 = np.random.rand(50, 1) * 8 + X2 = np.random.rand(30, 1) * 5 + + #build a suitable set of observed variables + Y1 = np.sin(X1) + np.random.randn(*X1.shape) * 0.05 + Y2 = np.sin(X2) + np.random.randn(*X2.shape) * 0.05 + 2. + + m = GPy.models.SparseGPCoregionalizedRegression(X_list=[X1,X2], Y_list=[Y1,Y2]) + + if optimize: + m.optimize('bfgs', max_iters=100) + + if plot: + slices = GPy.util.multioutput.get_slices([X1,X2]) + m.plot(fixed_inputs=[(1,0)],which_data_rows=slices[0],Y_metadata={'output_index':0}) + m.plot(fixed_inputs=[(1,1)],which_data_rows=slices[1],Y_metadata={'output_index':1},ax=pb.gca()) + pb.ylim(-3,) + + return m +
+
[docs]def epomeo_gpx(max_iters=200, optimize=True, plot=True): + """ + Perform Gaussian process regression on the latitude and longitude data + from the Mount Epomeo runs. Requires gpxpy to be installed on your system + to load in the data. + """ + try:import pods + except ImportError: + print 'pods unavailable, see https://github.com/sods/ods for example datasets' + return + data = pods.datasets.epomeo_gpx() + num_data_list = [] + for Xpart in data['X']: + num_data_list.append(Xpart.shape[0]) + + num_data_array = np.array(num_data_list) + num_data = num_data_array.sum() + Y = np.zeros((num_data, 2)) + t = np.zeros((num_data, 2)) + start = 0 + for Xpart, index in zip(data['X'], range(len(data['X']))): + end = start+Xpart.shape[0] + t[start:end, :] = np.hstack((Xpart[:, 0:1], + index*np.ones((Xpart.shape[0], 1)))) + Y[start:end, :] = Xpart[:, 1:3] + + num_inducing = 200 + Z = np.hstack((np.linspace(t[:,0].min(), t[:, 0].max(), num_inducing)[:, None], + np.random.randint(0, 4, num_inducing)[:, None])) + + k1 = GPy.kern.RBF(1) + k2 = GPy.kern.Coregionalize(output_dim=5, rank=5) + k = k1**k2 + + m = GPy.models.SparseGPRegression(t, Y, kernel=k, Z=Z, normalize_Y=True) + m.constrain_fixed('.*variance', 1.) + m.inducing_inputs.constrain_fixed() + m.Gaussian_noise.variance.constrain_bounded(1e-3, 1e-1) + m.optimize(max_iters=max_iters,messages=True) + + return m +
+
[docs]def multiple_optima(gene_number=937, resolution=80, model_restarts=10, seed=10000, max_iters=300, optimize=True, plot=True): + """ + Show an example of a multimodal error surface for Gaussian process + regression. Gene 939 has bimodal behaviour where the noisy mode is + higher. + """ + + # Contour over a range of length scales and signal/noise ratios. + length_scales = np.linspace(0.1, 60., resolution) + log_SNRs = np.linspace(-3., 4., resolution) + + try:import pods + except ImportError: + print 'pods unavailable, see https://github.com/sods/ods for example datasets' + return + data = pods.datasets.della_gatta_TRP63_gene_expression(data_set='della_gatta',gene_number=gene_number) + # data['Y'] = data['Y'][0::2, :] + # data['X'] = data['X'][0::2, :] + + data['Y'] = data['Y'] - np.mean(data['Y']) + + lls = GPy.examples.regression._contour_data(data, length_scales, log_SNRs, GPy.kern.RBF) + if plot: + pb.contour(length_scales, log_SNRs, np.exp(lls), 20, cmap=pb.cm.jet) + ax = pb.gca() + pb.xlabel('length scale') + pb.ylabel('log_10 SNR') + + xlim = ax.get_xlim() + ylim = ax.get_ylim() + + # Now run a few optimizations + models = [] + optim_point_x = np.empty(2) + optim_point_y = np.empty(2) + np.random.seed(seed=seed) + for i in range(0, model_restarts): + # kern = GPy.kern.RBF(1, variance=np.random.exponential(1.), lengthscale=np.random.exponential(50.)) + kern = GPy.kern.RBF(1, variance=np.random.uniform(1e-3, 1), lengthscale=np.random.uniform(5, 50)) + + m = GPy.models.GPRegression(data['X'], data['Y'], kernel=kern) + m.likelihood.variance = np.random.uniform(1e-3, 1) + optim_point_x[0] = m.rbf.lengthscale + optim_point_y[0] = np.log10(m.rbf.variance) - np.log10(m.likelihood.variance); + + # optimize + if optimize: + m.optimize('scg', xtol=1e-6, ftol=1e-6, max_iters=max_iters) + + optim_point_x[1] = m.rbf.lengthscale + optim_point_y[1] = np.log10(m.rbf.variance) - np.log10(m.likelihood.variance); + + if plot: + pb.arrow(optim_point_x[0], optim_point_y[0], optim_point_x[1] - optim_point_x[0], optim_point_y[1] - optim_point_y[0], label=str(i), head_length=1, head_width=0.5, fc='k', ec='k') + models.append(m) + + if plot: + ax.set_xlim(xlim) + ax.set_ylim(ylim) + return m # (models, lls) +
+def _contour_data(data, length_scales, log_SNRs, kernel_call=GPy.kern.RBF): + """ + Evaluate the GP objective function for a given data set for a range of + signal to noise ratios and a range of lengthscales. + + :data_set: A data set from the utils.datasets director. + :length_scales: a list of length scales to explore for the contour plot. + :log_SNRs: a list of base 10 logarithm signal to noise ratios to explore for the contour plot. + :kernel: a kernel to use for the 'signal' portion of the data. + """ + + lls = [] + total_var = np.var(data['Y']) + kernel = kernel_call(1, variance=1., lengthscale=1.) + model = GPy.models.GPRegression(data['X'], data['Y'], kernel=kernel) + for log_SNR in log_SNRs: + SNR = 10.**log_SNR + noise_var = total_var / (1. + SNR) + signal_var = total_var - noise_var + model.kern['.*variance'] = signal_var + model.likelihood.variance = noise_var + length_scale_lls = [] + + for length_scale in length_scales: + model['.*lengthscale'] = length_scale + length_scale_lls.append(model.log_likelihood()) + + lls.append(length_scale_lls) + + return np.array(lls) + + +
[docs]def olympic_100m_men(optimize=True, plot=True): + """Run a standard Gaussian process regression on the Rogers and Girolami olympics data.""" + try:import pods + except ImportError: + print 'pods unavailable, see https://github.com/sods/ods for example datasets' + return + data = pods.datasets.olympic_100m_men() + + # create simple GP Model + m = GPy.models.GPRegression(data['X'], data['Y']) + + # set the lengthscale to be something sensible (defaults to 1) + m.rbf.lengthscale = 10 + + if optimize: + m.optimize('bfgs', max_iters=200) + + if plot: + m.plot(plot_limits=(1850, 2050)) + return m +
+
[docs]def toy_rbf_1d(optimize=True, plot=True): + """Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance.""" + try:import pods + except ImportError: + print 'pods unavailable, see https://github.com/sods/ods for example datasets' + return + data = pods.datasets.toy_rbf_1d() + + # create simple GP Model + m = GPy.models.GPRegression(data['X'], data['Y']) + + if optimize: + m.optimize('bfgs') + if plot: + m.plot() + + return m +
+
[docs]def toy_rbf_1d_50(optimize=True, plot=True): + """Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance.""" + try:import pods + except ImportError: + print 'pods unavailable, see https://github.com/sods/ods for example datasets' + return + data = pods.datasets.toy_rbf_1d_50() + + # create simple GP Model + m = GPy.models.GPRegression(data['X'], data['Y']) + + if optimize: + m.optimize('bfgs') + if plot: + m.plot() + + return m +
+
[docs]def toy_poisson_rbf_1d_laplace(optimize=True, plot=True): + """Run a simple demonstration of a standard Gaussian process fitting it to data sampled from an RBF covariance.""" + optimizer='scg' + x_len = 30 + X = np.linspace(0, 10, x_len)[:, None] + f_true = np.random.multivariate_normal(np.zeros(x_len), GPy.kern.RBF(1).K(X)) + Y = np.array([np.random.poisson(np.exp(f)) for f in f_true])[:,None] + + kern = GPy.kern.RBF(1) + poisson_lik = GPy.likelihoods.Poisson() + laplace_inf = GPy.inference.latent_function_inference.Laplace() + + # create simple GP Model + m = GPy.core.GP(X, Y, kernel=kern, likelihood=poisson_lik, inference_method=laplace_inf) + + if optimize: + m.optimize(optimizer) + if plot: + m.plot() + # plot the real underlying rate function + pb.plot(X, np.exp(f_true), '--k', linewidth=2) + + return m +
+
[docs]def toy_ARD(max_iters=1000, kernel_type='linear', num_samples=300, D=4, optimize=True, plot=True): + # Create an artificial dataset where the values in the targets (Y) + # only depend in dimensions 1 and 3 of the inputs (X). Run ARD to + # see if this dependency can be recovered + X1 = np.sin(np.sort(np.random.rand(num_samples, 1) * 10, 0)) + X2 = np.cos(np.sort(np.random.rand(num_samples, 1) * 10, 0)) + X3 = np.exp(np.sort(np.random.rand(num_samples, 1), 0)) + X4 = np.log(np.sort(np.random.rand(num_samples, 1), 0)) + X = np.hstack((X1, X2, X3, X4)) + + Y1 = np.asarray(2 * X[:, 0] + 3).reshape(-1, 1) + Y2 = np.asarray(4 * (X[:, 2] - 1.5 * X[:, 0])).reshape(-1, 1) + Y = np.hstack((Y1, Y2)) + + Y = np.dot(Y, np.random.rand(2, D)); + Y = Y + 0.2 * np.random.randn(Y.shape[0], Y.shape[1]) + Y -= Y.mean() + Y /= Y.std() + + if kernel_type == 'linear': + kernel = GPy.kern.Linear(X.shape[1], ARD=1) + elif kernel_type == 'rbf_inv': + kernel = GPy.kern.RBF_inv(X.shape[1], ARD=1) + else: + kernel = GPy.kern.RBF(X.shape[1], ARD=1) + kernel += GPy.kern.White(X.shape[1]) + GPy.kern.Bias(X.shape[1]) + m = GPy.models.GPRegression(X, Y, kernel) + # len_prior = GPy.priors.inverse_gamma(1,18) # 1, 25 + # m.set_prior('.*lengthscale',len_prior) + + if optimize: + m.optimize(optimizer='scg', max_iters=max_iters) + + if plot: + m.kern.plot_ARD() + + return m +
+
[docs]def toy_ARD_sparse(max_iters=1000, kernel_type='linear', num_samples=300, D=4, optimize=True, plot=True): + # Create an artificial dataset where the values in the targets (Y) + # only depend in dimensions 1 and 3 of the inputs (X). Run ARD to + # see if this dependency can be recovered + X1 = np.sin(np.sort(np.random.rand(num_samples, 1) * 10, 0)) + X2 = np.cos(np.sort(np.random.rand(num_samples, 1) * 10, 0)) + X3 = np.exp(np.sort(np.random.rand(num_samples, 1), 0)) + X4 = np.log(np.sort(np.random.rand(num_samples, 1), 0)) + X = np.hstack((X1, X2, X3, X4)) + + Y1 = np.asarray(2 * X[:, 0] + 3)[:, None] + Y2 = np.asarray(4 * (X[:, 2] - 1.5 * X[:, 0]))[:, None] + Y = np.hstack((Y1, Y2)) + + Y = np.dot(Y, np.random.rand(2, D)); + Y = Y + 0.2 * np.random.randn(Y.shape[0], Y.shape[1]) + Y -= Y.mean() + Y /= Y.std() + + if kernel_type == 'linear': + kernel = GPy.kern.Linear(X.shape[1], ARD=1) + elif kernel_type == 'rbf_inv': + kernel = GPy.kern.RBF_inv(X.shape[1], ARD=1) + else: + kernel = GPy.kern.RBF(X.shape[1], ARD=1) + #kernel += GPy.kern.Bias(X.shape[1]) + X_variance = np.ones(X.shape) * 0.5 + m = GPy.models.SparseGPRegression(X, Y, kernel, X_variance=X_variance) + # len_prior = GPy.priors.inverse_gamma(1,18) # 1, 25 + # m.set_prior('.*lengthscale',len_prior) + + if optimize: + m.optimize(optimizer='scg', max_iters=max_iters) + + if plot: + m.kern.plot_ARD() + + return m +
+
[docs]def robot_wireless(max_iters=100, kernel=None, optimize=True, plot=True): + """Predict the location of a robot given wirelss signal strength readings.""" + try:import pods + except ImportError: + print 'pods unavailable, see https://github.com/sods/ods for example datasets' + return + data = pods.datasets.robot_wireless() + + # create simple GP Model + m = GPy.models.GPRegression(data['Y'], data['X'], kernel=kernel) + + # optimize + if optimize: + m.optimize(max_iters=max_iters) + + Xpredict = m.predict(data['Ytest'])[0] + if plot: + pb.plot(data['Xtest'][:, 0], data['Xtest'][:, 1], 'r-') + pb.plot(Xpredict[:, 0], Xpredict[:, 1], 'b-') + pb.axis('equal') + pb.title('WiFi Localization with Gaussian Processes') + pb.legend(('True Location', 'Predicted Location')) + + sse = ((data['Xtest'] - Xpredict)**2).sum() + + print('Sum of squares error on test data: ' + str(sse)) + return m +
+
[docs]def silhouette(max_iters=100, optimize=True, plot=True): + """Predict the pose of a figure given a silhouette. This is a task from Agarwal and Triggs 2004 ICML paper.""" + try:import pods + except ImportError: + print 'pods unavailable, see https://github.com/sods/ods for example datasets' + return + data = pods.datasets.silhouette() + + # create simple GP Model + m = GPy.models.GPRegression(data['X'], data['Y']) + + # optimize + if optimize: + m.optimize(messages=True, max_iters=max_iters) + + print m + return m +
+
[docs]def sparse_GP_regression_1D(num_samples=400, num_inducing=5, max_iters=100, optimize=True, plot=True, checkgrad=False): + """Run a 1D example of a sparse GP regression.""" + # sample inputs and outputs + X = np.random.uniform(-3., 3., (num_samples, 1)) + Y = np.sin(X) + np.random.randn(num_samples, 1) * 0.05 + # construct kernel + rbf = GPy.kern.RBF(1) + # create simple GP Model + m = GPy.models.SparseGPRegression(X, Y, kernel=rbf, num_inducing=num_inducing) + + if checkgrad: + m.checkgrad() + + if optimize: + m.optimize('tnc', max_iters=max_iters) + + if plot: + m.plot() + + return m +
+
[docs]def sparse_GP_regression_2D(num_samples=400, num_inducing=50, max_iters=100, optimize=True, plot=True, nan=False): + """Run a 2D example of a sparse GP regression.""" + np.random.seed(1234) + X = np.random.uniform(-3., 3., (num_samples, 2)) + Y = np.sin(X[:, 0:1]) * np.sin(X[:, 1:2]) + np.random.randn(num_samples, 1) * 0.05 + if nan: + inan = np.random.binomial(1,.2,size=Y.shape) + Y[inan] = np.nan + + # construct kernel + rbf = GPy.kern.RBF(2) + + # create simple GP Model + m = GPy.models.SparseGPRegression(X, Y, kernel=rbf, num_inducing=num_inducing) + + # contrain all parameters to be positive (but not inducing inputs) + m['.*len'] = 2. + + m.checkgrad() + + # optimize + if optimize: + m.optimize('tnc', messages=1, max_iters=max_iters) + + # plot + if plot: + m.plot() + + print m + return m +
+
[docs]def uncertain_inputs_sparse_regression(max_iters=200, optimize=True, plot=True): + """Run a 1D example of a sparse GP regression with uncertain inputs.""" + fig, axes = pb.subplots(1, 2, figsize=(12, 5), sharex=True, sharey=True) + + # sample inputs and outputs + S = np.ones((20, 1)) + X = np.random.uniform(-3., 3., (20, 1)) + Y = np.sin(X) + np.random.randn(20, 1) * 0.05 + # likelihood = GPy.likelihoods.Gaussian(Y) + Z = np.random.uniform(-3., 3., (7, 1)) + + k = GPy.kern.RBF(1) + # create simple GP Model - no input uncertainty on this one + m = GPy.models.SparseGPRegression(X, Y, kernel=k, Z=Z) + + if optimize: + m.optimize('scg', messages=1, max_iters=max_iters) + + if plot: + m.plot(ax=axes[0]) + axes[0].set_title('no input uncertainty') + print m + + # the same Model with uncertainty + m = GPy.models.SparseGPRegression(X, Y, kernel=GPy.kern.RBF(1), Z=Z, X_variance=S) + if optimize: + m.optimize('scg', messages=1, max_iters=max_iters) + if plot: + m.plot(ax=axes[1]) + axes[1].set_title('with input uncertainty') + fig.canvas.draw() + + print m + return m
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference.html new file mode 100644 index 00000000..bf507670 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference.html @@ -0,0 +1,192 @@ + + + + + + + + GPy.inference.latent_function_inference — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference

+# Copyright (c) 2012, James Hensman
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+__doc__ = """
+Inference over Gaussian process latent functions
+
+In all our GP models, the consistency propery means that we have a Gaussian
+prior over a finite set of points f. This prior is
+
+  math:: N(f | 0, K)
+
+where K is the kernel matrix.
+
+We also have a likelihood (see GPy.likelihoods) which defines how the data are
+related to the latent function: p(y | f).  If the likelihood is also a Gaussian,
+the inference over f is tractable (see exact_gaussian_inference.py).
+
+If the likelihood object is something other than Gaussian, then exact inference
+is not tractable. We then resort to a Laplace approximation (laplace.py) or
+expectation propagation (ep.py).
+
+The inference methods return a
+:class:`~GPy.inference.latent_function_inference.posterior.Posterior`
+instance, which is a simple
+structure which contains a summary of the posterior. The model classes can then
+use this posterior object for making predictions, optimizing hyper-parameters,
+etc.
+
+"""
+
+
[docs]class LatentFunctionInference(object): +
[docs] def on_optimization_start(self): + """ + This function gets called, just before the optimization loop to start. + """ + pass +
+
[docs] def on_optimization_end(self): + """ + This function gets called, just after the optimization loop ended. + """ + pass +
+
[docs]class InferenceMethodList(LatentFunctionInference, list): + +
[docs] def on_optimization_start(self): + for inf in self: + inf.on_optimization_start() +
+
[docs] def on_optimization_end(self): + for inf in self: + inf.on_optimization_end() +
+ def __getstate__(self): + state = [] + for inf in self: + state.append(inf) + return state + + def __setstate__(self, state): + for inf in state: + self.append(inf) +
+from exact_gaussian_inference import ExactGaussianInference +from laplace import Laplace +from GPy.inference.latent_function_inference.var_dtc import VarDTC +from expectation_propagation import EP +from expectation_propagation_dtc import EPDTC +from dtc import DTC +from fitc import FITC +from var_dtc_parallel import VarDTC_minibatch + +# class FullLatentFunctionData(object): +# +# + +# class EMLikeLatentFunctionInference(LatentFunctionInference): +# def update_approximation(self): +# """ +# This function gets called when the +# """ +# +# def inference(self, kern, X, Z, likelihood, Y, Y_metadata=None): +# """ +# Do inference on the latent functions given a covariance function `kern`, +# inputs and outputs `X` and `Y`, inducing_inputs `Z`, and a likelihood `likelihood`. +# Additional metadata for the outputs `Y` can be given in `Y_metadata`. +# """ +# raise NotImplementedError, "Abstract base class for full inference" +# +# class VariationalLatentFunctionInference(LatentFunctionInference): +# def inference(self, kern, X, Z, likelihood, Y, Y_metadata=None): +# """ +# Do inference on the latent functions given a covariance function `kern`, +# inputs and outputs `X` and `Y`, inducing_inputs `Z`, and a likelihood `likelihood`. +# Additional metadata for the outputs `Y` can be given in `Y_metadata`. +# """ +# raise NotImplementedError, "Abstract base class for full inference" +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference/dtc.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference/dtc.html new file mode 100644 index 00000000..8abe6060 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference/dtc.html @@ -0,0 +1,256 @@ + + + + + + + + GPy.inference.latent_function_inference.dtc — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference.dtc

+# Copyright (c) 2012-2014, James Hensman
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from posterior import Posterior
+from ...util.linalg import jitchol, tdot, dtrtrs, dpotri, pdinv
+import numpy as np
+from . import LatentFunctionInference
+log_2_pi = np.log(2*np.pi)
+
+
[docs]class DTC(LatentFunctionInference): + """ + An object for inference when the likelihood is Gaussian, but we want to do sparse inference. + + The function self.inference returns a Posterior object, which summarizes + the posterior. + + NB. It's not recommended to use this function! It's here for historical purposes. + + """ + def __init__(self): + self.const_jitter = 1e-6 + +
[docs] def inference(self, kern, X, Z, likelihood, Y, Y_metadata=None): + assert X_variance is None, "cannot use X_variance with DTC. Try varDTC." + + num_inducing, _ = Z.shape + num_data, output_dim = Y.shape + + #make sure the noise is not hetero + beta = 1./likelihood.gaussian_variance(Y_metadata) + if beta.size > 1: + raise NotImplementedError, "no hetero noise with this implementation of DTC" + + Kmm = kern.K(Z) + Knn = kern.Kdiag(X) + Knm = kern.K(X, Z) + U = Knm + Uy = np.dot(U.T,Y) + + #factor Kmm + Kmmi, L, Li, _ = pdinv(Kmm) + + # Compute A + LiUTbeta = np.dot(Li, U.T)*np.sqrt(beta) + A = tdot(LiUTbeta) + np.eye(num_inducing) + + # factor A + LA = jitchol(A) + + # back substutue to get b, P, v + tmp, _ = dtrtrs(L, Uy, lower=1) + b, _ = dtrtrs(LA, tmp*beta, lower=1) + tmp, _ = dtrtrs(LA, b, lower=1, trans=1) + v, _ = dtrtrs(L, tmp, lower=1, trans=1) + tmp, _ = dtrtrs(LA, Li, lower=1, trans=0) + P = tdot(tmp.T) + + #compute log marginal + log_marginal = -0.5*num_data*output_dim*np.log(2*np.pi) + \ + -np.sum(np.log(np.diag(LA)))*output_dim + \ + 0.5*num_data*output_dim*np.log(beta) + \ + -0.5*beta*np.sum(np.square(Y)) + \ + 0.5*np.sum(np.square(b)) + + # Compute dL_dKmm + vvT_P = tdot(v.reshape(-1,1)) + P + dL_dK = 0.5*(Kmmi - vvT_P) + + # Compute dL_dU + vY = np.dot(v.reshape(-1,1),Y.T) + dL_dU = vY - np.dot(vvT_P, U.T) + dL_dU *= beta + + #compute dL_dR + Uv = np.dot(U, v) + dL_dR = 0.5*(np.sum(U*np.dot(U,P), 1) - 1./beta + np.sum(np.square(Y), 1) - 2.*np.sum(Uv*Y, 1) + np.sum(np.square(Uv), 1))*beta**2 + + dL_dthetaL = likelihood.exact_inference_gradients(dL_dR) + + grad_dict = {'dL_dKmm': dL_dK, 'dL_dKdiag':np.zeros_like(Knn), 'dL_dKnm':dL_dU.T, 'dL_dthetaL':dL_dthetaL} + + #construct a posterior object + post = Posterior(woodbury_inv=Kmmi-P, woodbury_vector=v, K=Kmm, mean=None, cov=None, K_chol=L) + + return post, log_marginal, grad_dict +
+
[docs]class vDTC(object): + def __init__(self): + self.const_jitter = 1e-6 + +
[docs] def inference(self, kern, X, X_variance, Z, likelihood, Y, Y_metadata): + assert X_variance is None, "cannot use X_variance with DTC. Try varDTC." + + num_inducing, _ = Z.shape + num_data, output_dim = Y.shape + + #make sure the noise is not hetero + beta = 1./likelihood.gaussian_variance(Y_metadata) + if beta.size > 1: + raise NotImplementedError, "no hetero noise with this implementation of DTC" + + Kmm = kern.K(Z) + Knn = kern.Kdiag(X) + Knm = kern.K(X, Z) + U = Knm + Uy = np.dot(U.T,Y) + + #factor Kmm + Kmmi, L, Li, _ = pdinv(Kmm) + + # Compute A + LiUTbeta = np.dot(Li, U.T)*np.sqrt(beta) + A_ = tdot(LiUTbeta) + trace_term = -0.5*(np.sum(Knn)*beta - np.trace(A_)) + A = A_ + np.eye(num_inducing) + + # factor A + LA = jitchol(A) + + # back substutue to get b, P, v + tmp, _ = dtrtrs(L, Uy, lower=1) + b, _ = dtrtrs(LA, tmp*beta, lower=1) + tmp, _ = dtrtrs(LA, b, lower=1, trans=1) + v, _ = dtrtrs(L, tmp, lower=1, trans=1) + tmp, _ = dtrtrs(LA, Li, lower=1, trans=0) + P = tdot(tmp.T) + stop + + #compute log marginal + log_marginal = -0.5*num_data*output_dim*np.log(2*np.pi) + \ + -np.sum(np.log(np.diag(LA)))*output_dim + \ + 0.5*num_data*output_dim*np.log(beta) + \ + -0.5*beta*np.sum(np.square(Y)) + \ + 0.5*np.sum(np.square(b)) + \ + trace_term + + # Compute dL_dKmm + vvT_P = tdot(v.reshape(-1,1)) + P + LAL = Li.T.dot(A).dot(Li) + dL_dK = Kmmi - 0.5*(vvT_P + LAL) + + # Compute dL_dU + vY = np.dot(v.reshape(-1,1),Y.T) + #dL_dU = vY - np.dot(vvT_P, U.T) + dL_dU = vY - np.dot(vvT_P - Kmmi, U.T) + dL_dU *= beta + + #compute dL_dR + Uv = np.dot(U, v) + dL_dR = 0.5*(np.sum(U*np.dot(U,P), 1) - 1./beta + np.sum(np.square(Y), 1) - 2.*np.sum(Uv*Y, 1) + np.sum(np.square(Uv), 1) )*beta**2 + dL_dR -=beta*trace_term/num_data + + dL_dthetaL = likelihood.exact_inference_gradients(dL_dR) + grad_dict = {'dL_dKmm': dL_dK, 'dL_dKdiag':np.zeros_like(Knn) + -0.5*beta, 'dL_dKnm':dL_dU.T, 'dL_dthetaL':dL_dthetaL} + + #construct a posterior object + post = Posterior(woodbury_inv=Kmmi-P, woodbury_vector=v, K=Kmm, mean=None, cov=None, K_chol=L) + + + return post, log_marginal, grad_dict +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference/exact_gaussian_inference.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference/exact_gaussian_inference.html new file mode 100644 index 00000000..7a4a7b3f --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference/exact_gaussian_inference.html @@ -0,0 +1,155 @@ + + + + + + + + GPy.inference.latent_function_inference.exact_gaussian_inference — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference.exact_gaussian_inference

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from posterior import Posterior
+from ...util.linalg import pdinv, dpotrs, tdot
+from ...util import diag
+import numpy as np
+from . import LatentFunctionInference
+log_2_pi = np.log(2*np.pi)
+
+
+
[docs]class ExactGaussianInference(LatentFunctionInference): + """ + An object for inference when the likelihood is Gaussian. + + The function self.inference returns a Posterior object, which summarizes + the posterior. + + For efficiency, we sometimes work with the cholesky of Y*Y.T. To save repeatedly recomputing this, we cache it. + + """ + def __init__(self): + pass#self._YYTfactor_cache = caching.cache() + +
[docs] def get_YYTfactor(self, Y): + """ + find a matrix L which satisfies LL^T = YY^T. + + Note that L may have fewer columns than Y, else L=Y. + """ + N, D = Y.shape + if (N>D): + return Y + else: + #if Y in self.cache, return self.Cache[Y], else store Y in cache and return L. + #print "WARNING: N>D of Y, we need caching of L, such that L*L^T = Y, returning Y still!" + return Y +
+
[docs] def inference(self, kern, X, likelihood, Y, Y_metadata=None): + """ + Returns a Posterior class containing essential quantities of the posterior + """ + YYT_factor = self.get_YYTfactor(Y) + + K = kern.K(X) + + Ky = K.copy() + diag.add(Ky, likelihood.gaussian_variance(Y_metadata)) + Wi, LW, LWi, W_logdet = pdinv(Ky) + + alpha, _ = dpotrs(LW, YYT_factor, lower=1) + + log_marginal = 0.5*(-Y.size * log_2_pi - Y.shape[1] * W_logdet - np.sum(alpha * YYT_factor)) + + dL_dK = 0.5 * (tdot(alpha) - Y.shape[1] * Wi) + + dL_dthetaL = likelihood.exact_inference_gradients(np.diag(dL_dK),Y_metadata) + + return Posterior(woodbury_chol=LW, woodbury_vector=alpha, K=K), log_marginal, {'dL_dK':dL_dK, 'dL_dthetaL':dL_dthetaL}
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference/expectation_propagation.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference/expectation_propagation.html new file mode 100644 index 00000000..5b36371d --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference/expectation_propagation.html @@ -0,0 +1,218 @@ + + + + + + + + GPy.inference.latent_function_inference.expectation_propagation — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference.expectation_propagation

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+import numpy as np
+from ...util.linalg import pdinv,jitchol,DSYR,tdot,dtrtrs, dpotrs
+from posterior import Posterior
+from . import LatentFunctionInference
+log_2_pi = np.log(2*np.pi)
+
+
[docs]class EP(LatentFunctionInference): + def __init__(self, epsilon=1e-6, eta=1., delta=1.): + """ + The expectation-propagation algorithm. + For nomenclature see Rasmussen & Williams 2006. + + :param epsilon: Convergence criterion, maximum squared difference allowed between mean updates to stop iterations (float) + :type epsilon: float + :param eta: parameter for fractional EP updates. + :type eta: float64 + :param delta: damping EP updates factor. + :type delta: float64 + """ + self.epsilon, self.eta, self.delta = epsilon, eta, delta + self.reset() + +
[docs] def reset(self): + self.old_mutilde, self.old_vtilde = None, None + self._ep_approximation = None +
+
[docs] def on_optimization_start(self): + self._ep_approximation = None +
+
[docs] def on_optimization_end(self): + # TODO: update approximation in the end as well? Maybe even with a switch? + pass +
+
[docs] def inference(self, kern, X, likelihood, Y, Y_metadata=None, Z=None): + num_data, output_dim = Y.shape + assert output_dim ==1, "ep in 1D only (for now!)" + + K = kern.K(X) + + if self._ep_approximation is None: + mu, Sigma, mu_tilde, tau_tilde, Z_hat = self._ep_approximation = self.expectation_propagation(K, Y, likelihood, Y_metadata) + else: + mu, Sigma, mu_tilde, tau_tilde, Z_hat = self._ep_approximation + + Wi, LW, LWi, W_logdet = pdinv(K + np.diag(1./tau_tilde)) + + alpha, _ = dpotrs(LW, mu_tilde, lower=1) + + log_marginal = 0.5*(-num_data * log_2_pi - W_logdet - np.sum(alpha * mu_tilde)) # TODO: add log Z_hat?? + + dL_dK = 0.5 * (tdot(alpha[:,None]) - Wi) + + dL_dthetaL = np.zeros(likelihood.size)#TODO: derivatives of the likelihood parameters + + return Posterior(woodbury_inv=Wi, woodbury_vector=alpha, K=K), log_marginal, {'dL_dK':dL_dK, 'dL_dthetaL':dL_dthetaL} +
+
[docs] def expectation_propagation(self, K, Y, likelihood, Y_metadata): + + num_data, data_dim = Y.shape + assert data_dim == 1, "This EP methods only works for 1D outputs" + + + #Initial values - Posterior distribution parameters: q(f|X,Y) = N(f|mu,Sigma) + mu = np.zeros(num_data) + Sigma = K.copy() + + #Initial values - Marginal moments + Z_hat = np.empty(num_data,dtype=np.float64) + mu_hat = np.empty(num_data,dtype=np.float64) + sigma2_hat = np.empty(num_data,dtype=np.float64) + + #initial values - Gaussian factors + if self.old_mutilde is None: + tau_tilde, mu_tilde, v_tilde = np.zeros((3, num_data)) + else: + assert old_mutilde.size == num_data, "data size mis-match: did you change the data? try resetting!" + mu_tilde, v_tilde = self.old_mutilde, self.old_vtilde + tau_tilde = v_tilde/mu_tilde + + #Approximation + tau_diff = self.epsilon + 1. + v_diff = self.epsilon + 1. + iterations = 0 + while (tau_diff > self.epsilon) or (v_diff > self.epsilon): + update_order = np.random.permutation(num_data) + for i in update_order: + #Cavity distribution parameters + tau_cav = 1./Sigma[i,i] - self.eta*tau_tilde[i] + v_cav = mu[i]/Sigma[i,i] - self.eta*v_tilde[i] + #Marginal moments + Z_hat[i], mu_hat[i], sigma2_hat[i] = likelihood.moments_match_ep(Y[i], tau_cav, v_cav)#, Y_metadata=None)#=(None if Y_metadata is None else Y_metadata[i])) + #Site parameters update + delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma[i,i]) + delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma[i,i]) + tau_tilde[i] += delta_tau + v_tilde[i] += delta_v + #Posterior distribution parameters update + DSYR(Sigma, Sigma[:,i].copy(), -delta_tau/(1.+ delta_tau*Sigma[i,i])) + mu = np.dot(Sigma, v_tilde) + + #(re) compute Sigma and mu using full Cholesky decompy + tau_tilde_root = np.sqrt(tau_tilde) + Sroot_tilde_K = tau_tilde_root[:,None] * K + B = np.eye(num_data) + Sroot_tilde_K * tau_tilde_root[None,:] + L = jitchol(B) + V, _ = dtrtrs(L, Sroot_tilde_K, lower=1) + Sigma = K - np.dot(V.T,V) + mu = np.dot(Sigma,v_tilde) + + #monitor convergence + if iterations>0: + tau_diff = np.mean(np.square(tau_tilde-tau_tilde_old)) + v_diff = np.mean(np.square(v_tilde-v_tilde_old)) + tau_tilde_old = tau_tilde.copy() + v_tilde_old = v_tilde.copy() + + iterations += 1 + + mu_tilde = v_tilde/tau_tilde + return mu, Sigma, mu_tilde, tau_tilde, Z_hat
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference/expectation_propagation_dtc.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference/expectation_propagation_dtc.html new file mode 100644 index 00000000..e2013da3 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference/expectation_propagation_dtc.html @@ -0,0 +1,447 @@ + + + + + + + + GPy.inference.latent_function_inference.expectation_propagation_dtc — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference.expectation_propagation_dtc

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ...util import diag
+from ...util.linalg import mdot, jitchol, backsub_both_sides, tdot, dtrtrs, dtrtri, dpotri, dpotrs, symmetrify, DSYR
+from ...core.parameterization.variational import VariationalPosterior
+from . import LatentFunctionInference
+from posterior import Posterior
+log_2_pi = np.log(2*np.pi)
+
+
[docs]class EPDTC(LatentFunctionInference): + const_jitter = 1e-6 + def __init__(self, epsilon=1e-6, eta=1., delta=1., limit=1): + from ...util.caching import Cacher + self.limit = limit + self.get_trYYT = Cacher(self._get_trYYT, limit) + self.get_YYTfactor = Cacher(self._get_YYTfactor, limit) + + self.epsilon, self.eta, self.delta = epsilon, eta, delta + self.reset() + +
[docs] def set_limit(self, limit): + self.get_trYYT.limit = limit + self.get_YYTfactor.limit = limit +
+
[docs] def on_optimization_start(self): + self._ep_approximation = None +
+
[docs] def on_optimization_end(self): + # TODO: update approximation in the end as well? Maybe even with a switch? + pass +
+ def _get_trYYT(self, Y): + return np.sum(np.square(Y)) + + def __getstate__(self): + # has to be overridden, as Cacher objects cannot be pickled. + return self.limit + + def __setstate__(self, state): + # has to be overridden, as Cacher objects cannot be pickled. + self.limit = state + from ...util.caching import Cacher + self.get_trYYT = Cacher(self._get_trYYT, self.limit) + self.get_YYTfactor = Cacher(self._get_YYTfactor, self.limit) + + def _get_YYTfactor(self, Y): + """ + find a matrix L which satisfies LLT = YYT. + + Note that L may have fewer columns than Y. + """ + N, D = Y.shape + if (N>=D): + return Y + else: + return jitchol(tdot(Y)) + +
[docs] def get_VVTfactor(self, Y, prec): + return Y * prec # TODO chache this, and make it effective +
+
[docs] def reset(self): + self.old_mutilde, self.old_vtilde = None, None + self._ep_approximation = None +
+
[docs] def inference(self, kern, X, Z, likelihood, Y, Y_metadata=None): + num_data, output_dim = Y.shape + assert output_dim ==1, "ep in 1D only (for now!)" + + Kmm = kern.K(Z) + Kmn = kern.K(Z,X) + + if self._ep_approximation is None: + mu, Sigma, mu_tilde, tau_tilde, Z_hat = self._ep_approximation = self.expectation_propagation(Kmm, Kmn, Y, likelihood, Y_metadata) + else: + mu, Sigma, mu_tilde, tau_tilde, Z_hat = self._ep_approximation + + + if isinstance(X, VariationalPosterior): + uncertain_inputs = True + psi0 = kern.psi0(Z, X) + psi1 = Kmn.T#kern.psi1(Z, X) + psi2 = kern.psi2(Z, X) + else: + uncertain_inputs = False + psi0 = kern.Kdiag(X) + psi1 = Kmn.T#kern.K(X, Z) + psi2 = None + + #see whether we're using variational uncertain inputs + + _, output_dim = Y.shape + + #see whether we've got a different noise variance for each datum + #beta = 1./np.fmax(likelihood.gaussian_variance(Y_metadata), 1e-6) + beta = tau_tilde + VVT_factor = beta[:,None]*mu_tilde[:,None] + trYYT = self.get_trYYT(mu_tilde[:,None]) + + # do the inference: + het_noise = beta.size > 1 + num_inducing = Z.shape[0] + num_data = Y.shape[0] + # kernel computations, using BGPLVM notation + + Kmm = kern.K(Z).copy() + diag.add(Kmm, self.const_jitter) + Lm = jitchol(Kmm) + + # The rather complex computations of A + if uncertain_inputs: + if het_noise: + psi2_beta = psi2 * (beta.flatten().reshape(num_data, 1, 1)).sum(0) + else: + psi2_beta = psi2.sum(0) * beta + LmInv = dtrtri(Lm) + A = LmInv.dot(psi2_beta.dot(LmInv.T)) + else: + if het_noise: + tmp = psi1 * (np.sqrt(beta.reshape(num_data, 1))) + else: + tmp = psi1 * (np.sqrt(beta)) + tmp, _ = dtrtrs(Lm, tmp.T, lower=1) + A = tdot(tmp) #print A.sum() + + # factor B + B = np.eye(num_inducing) + A + LB = jitchol(B) + psi1Vf = np.dot(psi1.T, VVT_factor) + # back substutue C into psi1Vf + tmp, _ = dtrtrs(Lm, psi1Vf, lower=1, trans=0) + _LBi_Lmi_psi1Vf, _ = dtrtrs(LB, tmp, lower=1, trans=0) + tmp, _ = dtrtrs(LB, _LBi_Lmi_psi1Vf, lower=1, trans=1) + Cpsi1Vf, _ = dtrtrs(Lm, tmp, lower=1, trans=1) + + # data fit and derivative of L w.r.t. Kmm + delit = tdot(_LBi_Lmi_psi1Vf) + data_fit = np.trace(delit) + DBi_plus_BiPBi = backsub_both_sides(LB, output_dim * np.eye(num_inducing) + delit) + delit = -0.5 * DBi_plus_BiPBi + delit += -0.5 * B * output_dim + delit += output_dim * np.eye(num_inducing) + # Compute dL_dKmm + dL_dKmm = backsub_both_sides(Lm, delit) + + # derivatives of L w.r.t. psi + dL_dpsi0, dL_dpsi1, dL_dpsi2 = _compute_dL_dpsi(num_inducing, num_data, output_dim, beta, Lm, + VVT_factor, Cpsi1Vf, DBi_plus_BiPBi, + psi1, het_noise, uncertain_inputs) + + # log marginal likelihood + log_marginal = _compute_log_marginal_likelihood(likelihood, num_data, output_dim, beta, het_noise, + psi0, A, LB, trYYT, data_fit, VVT_factor) + + #put the gradients in the right places + dL_dR = _compute_dL_dR(likelihood, + het_noise, uncertain_inputs, LB, + _LBi_Lmi_psi1Vf, DBi_plus_BiPBi, Lm, A, + psi0, psi1, beta, + data_fit, num_data, output_dim, trYYT, mu_tilde[:,None]) + + dL_dthetaL = 0#likelihood.exact_inference_gradients(dL_dR,Y_metadata) + + if uncertain_inputs: + grad_dict = {'dL_dKmm': dL_dKmm, + 'dL_dpsi0':dL_dpsi0, + 'dL_dpsi1':dL_dpsi1, + 'dL_dpsi2':dL_dpsi2, + 'dL_dthetaL':dL_dthetaL} + else: + grad_dict = {'dL_dKmm': dL_dKmm, + 'dL_dKdiag':dL_dpsi0, + 'dL_dKnm':dL_dpsi1, + 'dL_dthetaL':dL_dthetaL} + + #get sufficient things for posterior prediction + #TODO: do we really want to do this in the loop? + if VVT_factor.shape[1] == Y.shape[1]: + woodbury_vector = Cpsi1Vf # == Cpsi1V + else: + print 'foobar' + psi1V = np.dot(mu_tilde[:,None].T*beta, psi1).T + tmp, _ = dtrtrs(Lm, psi1V, lower=1, trans=0) + tmp, _ = dpotrs(LB, tmp, lower=1) + woodbury_vector, _ = dtrtrs(Lm, tmp, lower=1, trans=1) + Bi, _ = dpotri(LB, lower=1) + symmetrify(Bi) + Bi = -dpotri(LB, lower=1)[0] + diag.add(Bi, 1) + + woodbury_inv = backsub_both_sides(Lm, Bi) + + #construct a posterior object + post = Posterior(woodbury_inv=woodbury_inv, woodbury_vector=woodbury_vector, K=Kmm, mean=None, cov=None, K_chol=Lm) + return post, log_marginal, grad_dict + + + + +
+
[docs] def expectation_propagation(self, Kmm, Kmn, Y, likelihood, Y_metadata): + + num_data, data_dim = Y.shape + assert data_dim == 1, "This EP methods only works for 1D outputs" + + KmnKnm = np.dot(Kmn,Kmn.T) + Lm = jitchol(Kmm) + Lmi = dtrtrs(Lm,np.eye(Lm.shape[0]))[0] #chol_inv(Lm) + Kmmi = np.dot(Lmi.T,Lmi) + KmmiKmn = np.dot(Kmmi,Kmn) + Qnn_diag = np.sum(Kmn*KmmiKmn,-2) + LLT0 = Kmm.copy() + + #Initial values - Posterior distribution parameters: q(f|X,Y) = N(f|mu,Sigma) + mu = np.zeros(num_data) + LLT = Kmm.copy() #Sigma = K.copy() + Sigma_diag = Qnn_diag.copy() + + #Initial values - Marginal moments + Z_hat = np.empty(num_data,dtype=np.float64) + mu_hat = np.empty(num_data,dtype=np.float64) + sigma2_hat = np.empty(num_data,dtype=np.float64) + + #initial values - Gaussian factors + if self.old_mutilde is None: + tau_tilde, mu_tilde, v_tilde = np.zeros((3, num_data)) + else: + assert old_mutilde.size == num_data, "data size mis-match: did you change the data? try resetting!" + mu_tilde, v_tilde = self.old_mutilde, self.old_vtilde + tau_tilde = v_tilde/mu_tilde + + #Approximation + tau_diff = self.epsilon + 1. + v_diff = self.epsilon + 1. + iterations = 0 + while (tau_diff > self.epsilon) or (v_diff > self.epsilon): + update_order = np.random.permutation(num_data) + for i in update_order: + #Cavity distribution parameters + tau_cav = 1./Sigma_diag[i] - self.eta*tau_tilde[i] + v_cav = mu[i]/Sigma_diag[i] - self.eta*v_tilde[i] + #Marginal moments + Z_hat[i], mu_hat[i], sigma2_hat[i] = likelihood.moments_match_ep(Y[i], tau_cav, v_cav)#, Y_metadata=None)#=(None if Y_metadata is None else Y_metadata[i])) + #Site parameters update + delta_tau = self.delta/self.eta*(1./sigma2_hat[i] - 1./Sigma_diag[i]) + delta_v = self.delta/self.eta*(mu_hat[i]/sigma2_hat[i] - mu[i]/Sigma_diag[i]) + tau_tilde[i] += delta_tau + v_tilde[i] += delta_v + #Posterior distribution parameters update + + #DSYR(Sigma, Sigma[:,i].copy(), -delta_tau/(1.+ delta_tau*Sigma[i,i])) + DSYR(LLT,Kmn[:,i].copy(),delta_tau) + L = jitchol(LLT) + + V,info = dtrtrs(L,Kmn,lower=1) + Sigma_diag = np.sum(V*V,-2) + si = np.sum(V.T*V[:,i],-1) + mu += (delta_v-delta_tau*mu[i])*si + #mu = np.dot(Sigma, v_tilde) + + #(re) compute Sigma and mu using full Cholesky decompy + LLT = LLT0 + np.dot(Kmn*tau_tilde[None,:],Kmn.T) + L = jitchol(LLT) + V,info = dtrtrs(L,Kmn,lower=1) + V2,info = dtrtrs(L.T,V,lower=0) + #Sigma_diag = np.sum(V*V,-2) + #Knmv_tilde = np.dot(Kmn,v_tilde) + #mu = np.dot(V2.T,Knmv_tilde) + Sigma = np.dot(V2.T,V2) + mu = np.dot(Sigma,v_tilde) + + #monitor convergence + if iterations>0: + tau_diff = np.mean(np.square(tau_tilde-tau_tilde_old)) + v_diff = np.mean(np.square(v_tilde-v_tilde_old)) + tau_tilde_old = tau_tilde.copy() + v_tilde_old = v_tilde.copy() + + tau_diff = 0 + v_diff = 0 + iterations += 1 + + mu_tilde = v_tilde/tau_tilde + return mu, Sigma, mu_tilde, tau_tilde, Z_hat +
+def _compute_dL_dpsi(num_inducing, num_data, output_dim, beta, Lm, VVT_factor, Cpsi1Vf, DBi_plus_BiPBi, psi1, het_noise, uncertain_inputs): + dL_dpsi0 = -0.5 * output_dim * (beta[:,None] * np.ones([num_data, 1])).flatten() + dL_dpsi1 = np.dot(VVT_factor, Cpsi1Vf.T) + dL_dpsi2_beta = 0.5 * backsub_both_sides(Lm, output_dim * np.eye(num_inducing) - DBi_plus_BiPBi) + if het_noise: + if uncertain_inputs: + dL_dpsi2 = beta[:, None, None] * dL_dpsi2_beta[None, :, :] + else: + dL_dpsi1 += 2.*np.dot(dL_dpsi2_beta, (psi1 * beta.reshape(num_data, 1)).T).T + dL_dpsi2 = None + else: + dL_dpsi2 = beta * dL_dpsi2_beta + if uncertain_inputs: + # repeat for each of the N psi_2 matrices + dL_dpsi2 = np.repeat(dL_dpsi2[None, :, :], num_data, axis=0) + else: + # subsume back into psi1 (==Kmn) + dL_dpsi1 += 2.*np.dot(psi1, dL_dpsi2) + dL_dpsi2 = None + + return dL_dpsi0, dL_dpsi1, dL_dpsi2 + + +def _compute_dL_dR(likelihood, het_noise, uncertain_inputs, LB, _LBi_Lmi_psi1Vf, DBi_plus_BiPBi, Lm, A, psi0, psi1, beta, data_fit, num_data, output_dim, trYYT, Y): + # the partial derivative vector for the likelihood + if likelihood.size == 0: + # save computation here. + dL_dR = None + elif het_noise: + if uncertain_inputs: + raise NotImplementedError, "heteroscedatic derivates with uncertain inputs not implemented" + else: + #from ...util.linalg import chol_inv + #LBi = chol_inv(LB) + LBi, _ = dtrtrs(LB,np.eye(LB.shape[0])) + + Lmi_psi1, nil = dtrtrs(Lm, psi1.T, lower=1, trans=0) + _LBi_Lmi_psi1, _ = dtrtrs(LB, Lmi_psi1, lower=1, trans=0) + + dL_dR = -0.5 * beta + 0.5 * (beta*Y)**2 + dL_dR += 0.5 * output_dim * (psi0 - np.sum(Lmi_psi1**2,0))[:,None] * beta**2 + + dL_dR += 0.5*np.sum(mdot(LBi.T,LBi,Lmi_psi1)*Lmi_psi1,0)[:,None]*beta**2 + + dL_dR += -np.dot(_LBi_Lmi_psi1Vf.T,_LBi_Lmi_psi1).T * Y * beta**2 + dL_dR += 0.5*np.dot(_LBi_Lmi_psi1Vf.T,_LBi_Lmi_psi1).T**2 * beta**2 + else: + # likelihood is not heteroscedatic + dL_dR = -0.5 * num_data * output_dim * beta + 0.5 * trYYT * beta ** 2 + dL_dR += 0.5 * output_dim * (psi0.sum() * beta ** 2 - np.trace(A) * beta) + dL_dR += beta * (0.5 * np.sum(A * DBi_plus_BiPBi) - data_fit) + return dL_dR + +def _compute_log_marginal_likelihood(likelihood, num_data, output_dim, beta, het_noise, psi0, A, LB, trYYT, data_fit,Y): + #compute log marginal likelihood + if het_noise: + lik_1 = -0.5 * num_data * output_dim * np.log(2. * np.pi) + 0.5 * np.sum(np.log(beta)) - 0.5 * np.sum(beta * np.square(Y).sum(axis=-1)) + lik_2 = -0.5 * output_dim * (np.sum(beta.flatten() * psi0) - np.trace(A)) + else: + lik_1 = -0.5 * num_data * output_dim * (np.log(2. * np.pi) - np.log(beta)) - 0.5 * beta * trYYT + lik_2 = -0.5 * output_dim * (np.sum(beta * psi0) - np.trace(A)) + lik_3 = -output_dim * (np.sum(np.log(np.diag(LB)))) + lik_4 = 0.5 * data_fit + log_marginal = lik_1 + lik_2 + lik_3 + lik_4 + return log_marginal +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference/fitc.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference/fitc.html new file mode 100644 index 00000000..c089147c --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference/fitc.html @@ -0,0 +1,183 @@ + + + + + + + + GPy.inference.latent_function_inference.fitc — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference.fitc

+# Copyright (c) 2012, James Hensman
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from posterior import Posterior
+from ...util.linalg import jitchol, tdot, dtrtrs, dpotri, pdinv
+from ...util import diag
+import numpy as np
+from . import LatentFunctionInference
+log_2_pi = np.log(2*np.pi)
+
+
[docs]class FITC(LatentFunctionInference): + """ + An object for inference when the likelihood is Gaussian, but we want to do sparse inference. + + The function self.inference returns a Posterior object, which summarizes + the posterior. + + """ + const_jitter = 1e-6 + +
[docs] def inference(self, kern, X, Z, likelihood, Y, Y_metadata=None): + + num_inducing, _ = Z.shape + num_data, output_dim = Y.shape + + #make sure the noise is not hetero + sigma_n = likelihood.gaussian_variance(Y_metadata) + if sigma_n.size >1: + raise NotImplementedError, "no hetero noise with this implementation of FITC" + + Kmm = kern.K(Z) + Knn = kern.Kdiag(X) + Knm = kern.K(X, Z) + U = Knm + + #factor Kmm + diag.add(Kmm, self.const_jitter) + Kmmi, L, Li, _ = pdinv(Kmm) + + #compute beta_star, the effective noise precision + LiUT = np.dot(Li, U.T) + sigma_star = Knn + sigma_n - np.sum(np.square(LiUT),0) + beta_star = 1./sigma_star + + # Compute and factor A + A = tdot(LiUT*np.sqrt(beta_star)) + np.eye(num_inducing) + LA = jitchol(A) + + # back substutue to get b, P, v + URiy = np.dot(U.T*beta_star,Y) + tmp, _ = dtrtrs(L, URiy, lower=1) + b, _ = dtrtrs(LA, tmp, lower=1) + tmp, _ = dtrtrs(LA, b, lower=1, trans=1) + v, _ = dtrtrs(L, tmp, lower=1, trans=1) + tmp, _ = dtrtrs(LA, Li, lower=1, trans=0) + P = tdot(tmp.T) + + #compute log marginal + log_marginal = -0.5*num_data*output_dim*np.log(2*np.pi) + \ + -np.sum(np.log(np.diag(LA)))*output_dim + \ + 0.5*output_dim*np.sum(np.log(beta_star)) + \ + -0.5*np.sum(np.square(Y.T*np.sqrt(beta_star))) + \ + 0.5*np.sum(np.square(b)) + #compute dL_dR + Uv = np.dot(U, v) + dL_dR = 0.5*(np.sum(U*np.dot(U,P), 1) - 1./beta_star + np.sum(np.square(Y), 1) - 2.*np.sum(Uv*Y, 1) + np.sum(np.square(Uv), 1))*beta_star**2 + + + # Compute dL_dKmm + vvT_P = tdot(v.reshape(-1,1)) + P + dL_dK = 0.5*(Kmmi - vvT_P) + KiU = np.dot(Kmmi, U.T) + dL_dK += np.dot(KiU*dL_dR, KiU.T) + + # Compute dL_dU + vY = np.dot(v.reshape(-1,1),Y.T) + dL_dU = vY - np.dot(vvT_P, U.T) + dL_dU *= beta_star + dL_dU -= 2.*KiU*dL_dR + + dL_dthetaL = likelihood.exact_inference_gradients(dL_dR) + grad_dict = {'dL_dKmm': dL_dK, 'dL_dKdiag':dL_dR, 'dL_dKnm':dL_dU.T, 'dL_dthetaL':dL_dthetaL} + + #construct a posterior object + post = Posterior(woodbury_inv=Kmmi-P, woodbury_vector=v, K=Kmm, mean=None, cov=None, K_chol=L) + + return post, log_marginal, grad_dict +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference/inferenceX.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference/inferenceX.html new file mode 100644 index 00000000..8099181d --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference/inferenceX.html @@ -0,0 +1,257 @@ + + + + + + + + GPy.inference.latent_function_inference.inferenceX — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference.inferenceX

+# Copyright (c) 2014, Zhenwen Dai
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ...core import Model
+from ...core.parameterization import variational
+
+
[docs]def infer_newX(model, Y_new, optimize=True, init='L2'): + """ + Infer the distribution of X for the new observed data *Y_new*. + + :param model: the GPy model used in inference + :type model: GPy.core.Model + :param Y_new: the new observed data for inference + :type Y_new: numpy.ndarray + :param optimize: whether to optimize the location of new X (True by default) + :type optimize: boolean + :return: a tuple containing the estimated posterior distribution of X and the model that optimize X + :rtype: (GPy.core.parameterization.variational.VariationalPosterior, GPy.core.Model) + """ + infr_m = InferenceX(model, Y_new, init=init) + + if optimize: + infr_m.optimize() + + return infr_m.X, infr_m +
+
[docs]class InferenceX(Model): + """ + The class for inference of new X with given new Y. (do_test_latent) + + :param model: the GPy model used in inference + :type model: GPy.core.Model + :param Y: the new observed data for inference + :type Y: numpy.ndarray + """ + def __init__(self, model, Y, name='inferenceX', init='L2'): + if np.isnan(Y).any() or getattr(model, 'missing_data', False): + assert Y.shape[0]==1, "The current implementation of inference X only support one data point at a time with missing data!" + self.missing_data = True + self.valid_dim = np.logical_not(np.isnan(Y[0])) + self.ninan = getattr(model, 'ninan', None) + else: + self.missing_data = False + super(InferenceX, self).__init__(name) + self.likelihood = model.likelihood.copy() + self.kern = model.kern.copy() + if model.kern.useGPU: + from ...models import SSGPLVM + if isinstance(model, SSGPLVM): + self.kern.GPU_SSRBF(True) + else: + self.kern.GPU(True) + from copy import deepcopy + self.posterior = deepcopy(model.posterior) + if hasattr(model, 'variational_prior'): + self.uncertain_input = True + self.variational_prior = model.variational_prior.copy() + else: + self.uncertain_input = False + if hasattr(model, 'inducing_inputs'): + self.sparse_gp = True + self.Z = model.Z.copy() + else: + self.sparse_gp = False + self.uncertain_input = False + self.Z = model.X.copy() + self.Y = Y + self.X = self._init_X(model, Y, init=init) + self.compute_dL() + + self.link_parameter(self.X) + + def _init_X(self, model, Y_new, init='L2'): + # Initialize the new X by finding the nearest point in Y space. + + Y = model.Y + if self.missing_data: + Y = Y[:,self.valid_dim] + Y_new = Y_new[:,self.valid_dim] + dist = -2.*Y_new.dot(Y.T) + np.square(Y_new).sum(axis=1)[:,None]+ np.square(Y).sum(axis=1)[None,:] + else: + if init=='L2': + dist = -2.*Y_new.dot(Y.T) + np.square(Y_new).sum(axis=1)[:,None]+ np.square(Y).sum(axis=1)[None,:] + elif init=='NCC': + dist = Y_new.dot(Y.T) + elif init=='rand': + dist = np.random.rand(Y_new.shape[0],Y.shape[0]) + idx = dist.argmin(axis=1) + + from ...models import SSGPLVM + from ...util.misc import param_to_array + if isinstance(model, SSGPLVM): + X = variational.SpikeAndSlabPosterior(param_to_array(model.X.mean[idx]), param_to_array(model.X.variance[idx]), param_to_array(model.X.gamma[idx])) + if model.group_spike: + X.gamma.fix() + else: + if self.uncertain_input and self.sparse_gp: + X = variational.NormalPosterior(param_to_array(model.X.mean[idx]), param_to_array(model.X.variance[idx])) + else: + from ...core import Param + X = Param('latent mean',param_to_array(model.X[idx]).copy()) + + return X + +
[docs] def compute_dL(self): + # Common computation + beta = 1./np.fmax(self.likelihood.variance, 1e-6) + output_dim = self.Y.shape[-1] + wv = self.posterior.woodbury_vector + if self.missing_data: + wv = wv[:,self.valid_dim] + output_dim = self.valid_dim.sum() + if self.ninan is not None: + self.dL_dpsi2 = beta/2.*(self.posterior.woodbury_inv[:,:,self.valid_dim] - np.einsum('md,od->mo',wv, wv)[:, :, None]).sum(-1) + else: + self.dL_dpsi2 = beta/2.*(output_dim*self.posterior.woodbury_inv - np.einsum('md,od->mo',wv, wv)) + self.dL_dpsi1 = beta*np.dot(self.Y[:,self.valid_dim], wv.T) + self.dL_dpsi0 = - beta/2.* np.ones(self.Y.shape[0]) + else: + self.dL_dpsi2 = beta*(output_dim*self.posterior.woodbury_inv - np.einsum('md,od->mo',wv, wv))/2. + self.dL_dpsi1 = beta*np.dot(self.Y, wv.T) + self.dL_dpsi0 = -beta/2.*output_dim* np.ones(self.Y.shape[0]) +
+
[docs] def parameters_changed(self): + if self.uncertain_input: + psi0 = self.kern.psi0(self.Z, self.X) + psi1 = self.kern.psi1(self.Z, self.X) + psi2 = self.kern.psi2(self.Z, self.X) + else: + psi0 = self.kern.Kdiag(self.X) + psi1 = self.kern.K(self.X, self.Z) + psi2 = np.dot(psi1.T,psi1) + + self._log_marginal_likelihood = (self.dL_dpsi2*psi2).sum()+(self.dL_dpsi1*psi1).sum()+(self.dL_dpsi0*psi0).sum() + + if self.uncertain_input: + X_grad = self.kern.gradients_qX_expectations(variational_posterior=self.X, Z=self.Z, dL_dpsi0=self.dL_dpsi0, dL_dpsi1=self.dL_dpsi1, dL_dpsi2=self.dL_dpsi2) + self.X.set_gradients(X_grad) + else: + dL_dpsi1 = self.dL_dpsi1 + 2.*np.dot(psi1,self.dL_dpsi2) + X_grad = self.kern.gradients_X_diag(self.dL_dpsi0, self.X) + X_grad += self.kern.gradients_X(dL_dpsi1, self.X, self.Z) + self.X.gradient = X_grad + + if self.uncertain_input: + from ...core.parameterization.variational import SpikeAndSlabPrior + if isinstance(self.variational_prior, SpikeAndSlabPrior): + # Update Log-likelihood + KL_div = self.variational_prior.KL_divergence(self.X, N=self.Y.shape[0]) + # update for the KL divergence + self.variational_prior.update_gradients_KL(self.X, N=self.Y.shape[0]) + else: + # Update Log-likelihood + KL_div = self.variational_prior.KL_divergence(self.X) + # update for the KL divergence + self.variational_prior.update_gradients_KL(self.X) + self._log_marginal_likelihood += -KL_div +
+
[docs] def log_likelihood(self): + return self._log_marginal_likelihood +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference/laplace.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference/laplace.html new file mode 100644 index 00000000..d0041980 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference/laplace.html @@ -0,0 +1,346 @@ + + + + + + + + GPy.inference.latent_function_inference.laplace — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference.laplace

+# Copyright (c) 2013, 2014 Alan Saul
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+#
+#Parts of this file were influenced by the Matlab GPML framework written by
+#Carl Edward Rasmussen & Hannes Nickisch, however all bugs are our own.
+#
+#The GPML code is released under the FreeBSD License.
+#Copyright (c) 2005-2013 Carl Edward Rasmussen & Hannes Nickisch. All rights reserved.
+#
+#The code and associated documentation is available from
+#http://gaussianprocess.org/gpml/code.
+
+import numpy as np
+from ...util.linalg import mdot, jitchol, dpotrs, dtrtrs, dpotri, symmetrify, pdinv
+from posterior import Posterior
+import warnings
+
[docs]def warning_on_one_line(message, category, filename, lineno, file=None, line=None): + return ' %s:%s: %s:%s\n' % (filename, lineno, category.__name__, message)
+warnings.formatwarning = warning_on_one_line +from scipy import optimize +from . import LatentFunctionInference + +
[docs]class Laplace(LatentFunctionInference): + + def __init__(self): + """ + Laplace Approximation + + Find the moments \hat{f} and the hessian at this point + (using Newton-Raphson) of the unnormalised posterior + + """ + + self._mode_finding_tolerance = 1e-7 + self._mode_finding_max_iter = 60 + self.bad_fhat = False + #Store whether it is the first run of the inference so that we can choose whether we need + #to calculate things or reuse old variables + self.first_run = True + self._previous_Ki_fhat = None + +
[docs] def inference(self, kern, X, likelihood, Y, Y_metadata=None): + """ + Returns a Posterior class containing essential quantities of the posterior + """ + + # Compute K + K = kern.K(X) + + #Find mode + if self.bad_fhat or self.first_run: + Ki_f_init = np.zeros_like(Y) + first_run = False + else: + Ki_f_init = self._previous_Ki_fhat + + f_hat, Ki_fhat = self.rasm_mode(K, Y, likelihood, Ki_f_init, Y_metadata=Y_metadata) + self.f_hat = f_hat + self.Ki_fhat = Ki_fhat + self.K = K.copy() + #Compute hessian and other variables at mode + log_marginal, woodbury_inv, dL_dK, dL_dthetaL = self.mode_computations(f_hat, Ki_fhat, K, Y, likelihood, kern, Y_metadata) + + self._previous_Ki_fhat = Ki_fhat.copy() + return Posterior(woodbury_vector=Ki_fhat, woodbury_inv=woodbury_inv, K=K), log_marginal, {'dL_dK':dL_dK, 'dL_dthetaL':dL_dthetaL} +
+
[docs] def rasm_mode(self, K, Y, likelihood, Ki_f_init, Y_metadata=None): + """ + Rasmussen's numerically stable mode finding + For nomenclature see Rasmussen & Williams 2006 + Influenced by GPML (BSD) code, all errors are our own + + :param K: Covariance matrix evaluated at locations X + :type K: NxD matrix + :param Y: The data + :type Y: np.ndarray + :param likelihood: the likelihood of the latent function value for the given data + :type likelihood: a GPy.likelihood object + :param Ki_f_init: the initial guess at the mode + :type Ki_f_init: np.ndarray + :param Y_metadata: information about the data, e.g. which likelihood to take from a multi-likelihood object + :type Y_metadata: np.ndarray | None + :returns: f_hat, mode on which to make laplace approxmiation + :rtype: np.ndarray + """ + + Ki_f = Ki_f_init.copy() + f = np.dot(K, Ki_f) + + #define the objective function (to be maximised) + def obj(Ki_f, f): + return -0.5*np.dot(Ki_f.flatten(), f.flatten()) + np.sum(likelihood.logpdf(f, Y, Y_metadata=Y_metadata)) + + difference = np.inf + iteration = 0 + while difference > self._mode_finding_tolerance and iteration < self._mode_finding_max_iter: + W = -likelihood.d2logpdf_df2(f, Y, Y_metadata=Y_metadata) + if np.any(np.isnan(W)): + raise ValueError('One or more element(s) of W is NaN') + grad = likelihood.dlogpdf_df(f, Y, Y_metadata=Y_metadata) + if np.any(np.isnan(grad)): + raise ValueError('One or more element(s) of grad is NaN') + + W_f = W*f + + b = W_f + grad # R+W p46 line 6. + W12BiW12, _, _ = self._compute_B_statistics(K, W, likelihood.log_concave) + W12BiW12Kb = np.dot(W12BiW12, np.dot(K, b)) + + #Work out the DIRECTION that we want to move in, but don't choose the stepsize yet + full_step_Ki_f = b - W12BiW12Kb # full_step_Ki_f = a in R&W p46 line 6. + dKi_f = full_step_Ki_f - Ki_f + + #define an objective for the line search (minimize this one) + def inner_obj(step_size): + Ki_f_trial = Ki_f + step_size*dKi_f + f_trial = np.dot(K, Ki_f_trial) + return -obj(Ki_f_trial, f_trial) + + #use scipy for the line search, the compute new values of f, Ki_f + step = optimize.brent(inner_obj, tol=1e-4, maxiter=12) + Ki_f_new = Ki_f + step*dKi_f + f_new = np.dot(K, Ki_f_new) + + difference = np.abs(np.sum(f_new - f)) + np.abs(np.sum(Ki_f_new - Ki_f)) + Ki_f = Ki_f_new + f = f_new + iteration += 1 + + #Warn of bad fits + if difference > self._mode_finding_tolerance: + if not self.bad_fhat: + warnings.warn("Not perfect mode found (f_hat). difference: {}, iteration: {} out of max {}".format(difference, iteration, self._mode_finding_max_iter)) + self.bad_fhat = True + elif self.bad_fhat: + self.bad_fhat = False + warnings.warn("f_hat now fine again. difference: {}, iteration: {} out of max {}".format(difference, iteration, self._mode_finding_max_iter)) + + return f, Ki_f +
+
[docs] def mode_computations(self, f_hat, Ki_f, K, Y, likelihood, kern, Y_metadata): + """ + At the mode, compute the hessian and effective covariance matrix. + + returns: logZ : approximation to the marginal likelihood + woodbury_inv : variable required for calculating the approximation to the covariance matrix + dL_dthetaL : array of derivatives (1 x num_kernel_params) + dL_dthetaL : array of derivatives (1 x num_likelihood_params) + """ + #At this point get the hessian matrix (or vector as W is diagonal) + W = -likelihood.d2logpdf_df2(f_hat, Y, Y_metadata=Y_metadata) + if np.any(np.isnan(W)): + raise ValueError('One or more element(s) of W is NaN') + + K_Wi_i, L, LiW12 = self._compute_B_statistics(K, W, likelihood.log_concave) + + #compute vital matrices + C = np.dot(LiW12, K) + Ki_W_i = K - C.T.dot(C) + + #compute the log marginal + log_marginal = -0.5*np.dot(Ki_f.flatten(), f_hat.flatten()) + np.sum(likelihood.logpdf(f_hat, Y, Y_metadata=Y_metadata)) - np.sum(np.log(np.diag(L))) + + # Compute matrices for derivatives + dW_df = -likelihood.d3logpdf_df3(f_hat, Y, Y_metadata=Y_metadata) # -d3lik_d3fhat + if np.any(np.isnan(dW_df)): + raise ValueError('One or more element(s) of dW_df is NaN') + + dL_dfhat = -0.5*(np.diag(Ki_W_i)[:, None]*dW_df) # s2 in R&W p126 line 9. + #BiK, _ = dpotrs(L, K, lower=1) + #dL_dfhat = 0.5*np.diag(BiK)[:, None]*dW_df + I_KW_i = np.eye(Y.shape[0]) - np.dot(K, K_Wi_i) + + #################### + # compute dL_dK # + #################### + if kern.size > 0 and not kern.is_fixed: + #Explicit + explicit_part = 0.5*(np.dot(Ki_f, Ki_f.T) - K_Wi_i) + + #Implicit + implicit_part = np.dot(Ki_f, dL_dfhat.T).dot(I_KW_i) + + dL_dK = explicit_part + implicit_part + else: + dL_dK = np.zeros(likelihood.size) + + #################### + #compute dL_dthetaL# + #################### + if likelihood.size > 0 and not likelihood.is_fixed: + dlik_dthetaL, dlik_grad_dthetaL, dlik_hess_dthetaL = likelihood._laplace_gradients(f_hat, Y, Y_metadata=Y_metadata) + + num_params = likelihood.size + # make space for one derivative for each likelihood parameter + dL_dthetaL = np.zeros(num_params) + for thetaL_i in range(num_params): + #Explicit + dL_dthetaL_exp = ( np.sum(dlik_dthetaL[thetaL_i]) + # The + comes from the fact that dlik_hess_dthetaL == -dW_dthetaL + + 0.5*np.sum(np.diag(Ki_W_i).flatten()*dlik_hess_dthetaL[:, thetaL_i].flatten()) + ) + + #Implicit + dfhat_dthetaL = mdot(I_KW_i, K, dlik_grad_dthetaL[:, thetaL_i]) + #dfhat_dthetaL = mdot(Ki_W_i, dlik_grad_dthetaL[:, thetaL_i]) + dL_dthetaL_imp = np.dot(dL_dfhat.T, dfhat_dthetaL) + dL_dthetaL[thetaL_i] = dL_dthetaL_exp + dL_dthetaL_imp + + else: + dL_dthetaL = np.zeros(likelihood.size) + + return log_marginal, K_Wi_i, dL_dK, dL_dthetaL +
+ def _compute_B_statistics(self, K, W, log_concave): + """ + Rasmussen suggests the use of a numerically stable positive definite matrix B + Which has a positive diagonal elements and can be easily inverted + + :param K: Prior Covariance matrix evaluated at locations X + :type K: NxN matrix + :param W: Negative hessian at a point (diagonal matrix) + :type W: Vector of diagonal values of Hessian (1xN) + :returns: (W12BiW12, L_B, Li_W12) + """ + if not log_concave: + #print "Under 1e-10: {}".format(np.sum(W < 1e-6)) + W[W<1e-6] = 1e-6 + # NOTE: when setting a parameter inside parameters_changed it will allways come to closed update circles!!! + #W.__setitem__(W < 1e-6, 1e-6, update=False) # FIXME-HACK: This is a hack since GPy can't handle negative variances which can occur + # If the likelihood is non-log-concave. We wan't to say that there is a negative variance + # To cause the posterior to become less certain than the prior and likelihood, + # This is a property only held by non-log-concave likelihoods + if np.any(np.isnan(W)): + raise ValueError('One or more element(s) of W is NaN') + #W is diagonal so its sqrt is just the sqrt of the diagonal elements + W_12 = np.sqrt(W) + B = np.eye(K.shape[0]) + W_12*K*W_12.T + L = jitchol(B) + + LiW12, _ = dtrtrs(L, np.diagflat(W_12), lower=1, trans=0) + K_Wi_i = np.dot(LiW12.T, LiW12) # R = W12BiW12, in R&W p 126, eq 5.25 + + #here's a better way to compute the required matrix. + # you could do the model finding witha backsub, instead of a dot... + #L2 = L/W_12 + #K_Wi_i_2 , _= dpotri(L2) + #symmetrify(K_Wi_i_2) + + return K_Wi_i, L, LiW12 +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference/posterior.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference/posterior.html new file mode 100644 index 00000000..3557c290 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference/posterior.html @@ -0,0 +1,282 @@ + + + + + + + + GPy.inference.latent_function_inference.posterior — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference.posterior

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ...util.linalg import pdinv, dpotrs, dpotri, symmetrify, jitchol
+
+
[docs]class Posterior(object): + """ + An object to represent a Gaussian posterior over latent function values, p(f|D). + This may be computed exactly for Gaussian likelihoods, or approximated for + non-Gaussian likelihoods. + + The purpose of this class is to serve as an interface between the inference + schemes and the model classes. the model class can make predictions for + the function at any new point x_* by integrating over this posterior. + + """ + def __init__(self, woodbury_chol=None, woodbury_vector=None, K=None, mean=None, cov=None, K_chol=None, woodbury_inv=None): + """ + woodbury_chol : a lower triangular matrix L that satisfies posterior_covariance = K - K L^{-T} L^{-1} K + woodbury_vector : a matrix (or vector, as Nx1 matrix) M which satisfies posterior_mean = K M + K : the proir covariance (required for lazy computation of various quantities) + mean : the posterior mean + cov : the posterior covariance + + Not all of the above need to be supplied! You *must* supply: + + K (for lazy computation) + or + K_chol (for lazy computation) + + You may supply either: + + woodbury_chol + woodbury_vector + + Or: + + mean + cov + + Of course, you can supply more than that, but this class will lazily + compute all other quantites on demand. + + """ + #obligatory + self._K = K + + if ((woodbury_chol is not None) and (woodbury_vector is not None))\ + or ((woodbury_inv is not None) and (woodbury_vector is not None))\ + or ((woodbury_inv is not None) and (mean is not None))\ + or ((mean is not None) and (cov is not None)): + pass # we have sufficient to compute the posterior + else: + raise ValueError, "insufficient information to compute the posterior" + + self._K_chol = K_chol + self._K = K + #option 1: + self._woodbury_chol = woodbury_chol + self._woodbury_vector = woodbury_vector + + #option 2. + self._woodbury_inv = woodbury_inv + #and woodbury vector + + #option 2: + self._mean = mean + self._covariance = cov + + #compute this lazily + self._precision = None + + @property + def mean(self): + """ + Posterior mean + $$ + K_{xx}v + v := \texttt{Woodbury vector} + $$ + """ + if self._mean is None: + self._mean = np.dot(self._K, self.woodbury_vector) + return self._mean + + @property + def covariance(self): + """ + Posterior covariance + $$ + K_{xx} - K_{xx}W_{xx}^{-1}K_{xx} + W_{xx} := \texttt{Woodbury inv} + $$ + """ + if self._covariance is None: + #LiK, _ = dtrtrs(self.woodbury_chol, self._K, lower=1) + self._covariance = (np.atleast_3d(self._K) - np.tensordot(np.dot(np.atleast_3d(self.woodbury_inv).T, self._K), self._K, [1,0]).T).squeeze() + #self._covariance = self._K - self._K.dot(self.woodbury_inv).dot(self._K) + return self._covariance + + @property + def precision(self): + """ + Inverse of posterior covariance + """ + if self._precision is None: + cov = np.atleast_3d(self.covariance) + self._precision = np.zeros(cov.shape) # if one covariance per dimension + for p in xrange(cov.shape[-1]): + self._precision[:,:,p] = pdinv(cov[:,:,p])[0] + return self._precision + + @property + def woodbury_chol(self): + """ + return $L_{W}$ where L is the lower triangular Cholesky decomposition of the Woodbury matrix + $$ + L_{W}L_{W}^{\top} = W^{-1} + W^{-1} := \texttt{Woodbury inv} + $$ + """ + if self._woodbury_chol is None: + #compute woodbury chol from + if self._woodbury_inv is not None: + winv = np.atleast_3d(self._woodbury_inv) + self._woodbury_chol = np.zeros(winv.shape) + for p in xrange(winv.shape[-1]): + self._woodbury_chol[:,:,p] = pdinv(winv[:,:,p])[2] + #Li = jitchol(self._woodbury_inv) + #self._woodbury_chol, _ = dtrtri(Li) + #W, _, _, _, = pdinv(self._woodbury_inv) + #symmetrify(W) + #self._woodbury_chol = jitchol(W) + #try computing woodbury chol from cov + elif self._covariance is not None: + raise NotImplementedError, "TODO: check code here" + B = self._K - self._covariance + tmp, _ = dpotrs(self.K_chol, B) + self._woodbury_inv, _ = dpotrs(self.K_chol, tmp.T) + _, _, self._woodbury_chol, _ = pdinv(self._woodbury_inv) + else: + raise ValueError, "insufficient information to compute posterior" + return self._woodbury_chol + + @property + def woodbury_inv(self): + """ + The inverse of the woodbury matrix, in the gaussian likelihood case it is defined as + $$ + (K_{xx} + \Sigma_{xx})^{-1} + \Sigma_{xx} := \texttt{Likelihood.variance / Approximate likelihood covariance} + $$ + """ + if self._woodbury_inv is None: + if self._woodbury_chol is not None: + self._woodbury_inv, _ = dpotri(self._woodbury_chol, lower=1) + #self._woodbury_inv, _ = dpotrs(self.woodbury_chol, np.eye(self.woodbury_chol.shape[0]), lower=1) + symmetrify(self._woodbury_inv) + elif self._covariance is not None: + B = self._K - self._covariance + tmp, _ = dpotrs(self.K_chol, B) + self._woodbury_inv, _ = dpotrs(self.K_chol, tmp.T) + return self._woodbury_inv + + @property + def woodbury_vector(self): + """ + Woodbury vector in the gaussian likelihood case only is defined as + $$ + (K_{xx} + \Sigma)^{-1}Y + \Sigma := \texttt{Likelihood.variance / Approximate likelihood covariance} + $$ + """ + if self._woodbury_vector is None: + self._woodbury_vector, _ = dpotrs(self.K_chol, self.mean) + return self._woodbury_vector + + @property + def K_chol(self): + """ + Cholesky of the prior covariance K + """ + if self._K_chol is None: + self._K_chol = jitchol(self._K) + return self._K_chol
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference/var_dtc.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference/var_dtc.html new file mode 100644 index 00000000..b7a4d8b5 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference/var_dtc.html @@ -0,0 +1,345 @@ + + + + + + + + GPy.inference.latent_function_inference.var_dtc — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference.var_dtc

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from posterior import Posterior
+from ...util.linalg import mdot, jitchol, backsub_both_sides, tdot, dtrtrs, dtrtri, dpotri, dpotrs, symmetrify
+from ...util import diag
+from ...core.parameterization.variational import VariationalPosterior
+import numpy as np
+from . import LatentFunctionInference
+log_2_pi = np.log(2*np.pi)
+import logging, itertools
+logger = logging.getLogger('vardtc')
+
+
[docs]class VarDTC(LatentFunctionInference): + """ + An object for inference when the likelihood is Gaussian, but we want to do sparse inference. + + The function self.inference returns a Posterior object, which summarizes + the posterior. + + For efficiency, we sometimes work with the cholesky of Y*Y.T. To save repeatedly recomputing this, we cache it. + + """ + const_jitter = 1e-6 + def __init__(self, limit=1): + #self._YYTfactor_cache = caching.cache() + from ...util.caching import Cacher + self.limit = limit + self.get_trYYT = Cacher(self._get_trYYT, limit) + self.get_YYTfactor = Cacher(self._get_YYTfactor, limit) + +
[docs] def set_limit(self, limit): + self.get_trYYT.limit = limit + self.get_YYTfactor.limit = limit +
+ def _get_trYYT(self, Y): + return np.einsum("ij,ij->", Y, Y) + # faster than, but same as: + # return np.sum(np.square(Y)) + + def __getstate__(self): + # has to be overridden, as Cacher objects cannot be pickled. + return self.limit + + def __setstate__(self, state): + # has to be overridden, as Cacher objects cannot be pickled. + self.limit = state + from ...util.caching import Cacher + self.get_trYYT = Cacher(self._get_trYYT, self.limit) + self.get_YYTfactor = Cacher(self._get_YYTfactor, self.limit) + + def _get_YYTfactor(self, Y): + """ + find a matrix L which satisfies LLT = YYT. + + Note that L may have fewer columns than Y. + """ + N, D = Y.shape + if (N>=D): + return Y.view(np.ndarray) + else: + return jitchol(tdot(Y)) + +
[docs] def get_VVTfactor(self, Y, prec): + return Y * prec # TODO chache this, and make it effective + + +
+
[docs] def inference(self, kern, X, Z, likelihood, Y, Y_metadata=None, Lm=None, dL_dKmm=None): + + _, output_dim = Y.shape + uncertain_inputs = isinstance(X, VariationalPosterior) + + #see whether we've got a different noise variance for each datum + beta = 1./np.fmax(likelihood.gaussian_variance(Y_metadata), 1e-6) + # VVT_factor is a matrix such that tdot(VVT_factor) = VVT...this is for efficiency! + #self.YYTfactor = self.get_YYTfactor(Y) + #VVT_factor = self.get_VVTfactor(self.YYTfactor, beta) + het_noise = beta.size > 1 + if beta.ndim == 1: + beta = beta[:, None] + VVT_factor = beta*Y + #VVT_factor = beta*Y + trYYT = self.get_trYYT(Y) + + # do the inference: + num_inducing = Z.shape[0] + num_data = Y.shape[0] + # kernel computations, using BGPLVM notation + + Kmm = kern.K(Z).copy() + diag.add(Kmm, self.const_jitter) + if Lm is None: + Lm = jitchol(Kmm) + + # The rather complex computations of A, and the psi stats + if uncertain_inputs: + psi0 = kern.psi0(Z, X) + psi1 = kern.psi1(Z, X) + if het_noise: + psi2_beta = np.sum([kern.psi2(Z,X[i:i+1,:]) * beta_i for i,beta_i in enumerate(beta)],0) + else: + psi2_beta = kern.psi2(Z,X) * beta + LmInv = dtrtri(Lm) + A = LmInv.dot(psi2_beta.dot(LmInv.T)) + else: + psi0 = kern.Kdiag(X) + psi1 = kern.K(X, Z) + if het_noise: + tmp = psi1 * (np.sqrt(beta)) + else: + tmp = psi1 * (np.sqrt(beta)) + tmp, _ = dtrtrs(Lm, tmp.T, lower=1) + A = tdot(tmp) #print A.sum() + + # factor B + B = np.eye(num_inducing) + A + LB = jitchol(B) + psi1Vf = np.dot(psi1.T, VVT_factor) + # back substutue C into psi1Vf + tmp, _ = dtrtrs(Lm, psi1Vf, lower=1, trans=0) + _LBi_Lmi_psi1Vf, _ = dtrtrs(LB, tmp, lower=1, trans=0) + tmp, _ = dtrtrs(LB, _LBi_Lmi_psi1Vf, lower=1, trans=1) + Cpsi1Vf, _ = dtrtrs(Lm, tmp, lower=1, trans=1) + + # data fit and derivative of L w.r.t. Kmm + delit = tdot(_LBi_Lmi_psi1Vf) + data_fit = np.trace(delit) + DBi_plus_BiPBi = backsub_both_sides(LB, output_dim * np.eye(num_inducing) + delit) + if dL_dKmm is None: + delit = -0.5 * DBi_plus_BiPBi + delit += -0.5 * B * output_dim + delit += output_dim * np.eye(num_inducing) + # Compute dL_dKmm + dL_dKmm = backsub_both_sides(Lm, delit) + + # derivatives of L w.r.t. psi + dL_dpsi0, dL_dpsi1, dL_dpsi2 = _compute_dL_dpsi(num_inducing, num_data, output_dim, beta, Lm, + VVT_factor, Cpsi1Vf, DBi_plus_BiPBi, + psi1, het_noise, uncertain_inputs) + + # log marginal likelihood + log_marginal = _compute_log_marginal_likelihood(likelihood, num_data, output_dim, beta, het_noise, + psi0, A, LB, trYYT, data_fit, Y) + + #noise derivatives + dL_dR = _compute_dL_dR(likelihood, + het_noise, uncertain_inputs, LB, + _LBi_Lmi_psi1Vf, DBi_plus_BiPBi, Lm, A, + psi0, psi1, beta, + data_fit, num_data, output_dim, trYYT, Y, VVT_factor) + + dL_dthetaL = likelihood.exact_inference_gradients(dL_dR,Y_metadata) + + #put the gradients in the right places + if uncertain_inputs: + grad_dict = {'dL_dKmm': dL_dKmm, + 'dL_dpsi0':dL_dpsi0, + 'dL_dpsi1':dL_dpsi1, + 'dL_dpsi2':dL_dpsi2, + 'dL_dthetaL':dL_dthetaL} + else: + grad_dict = {'dL_dKmm': dL_dKmm, + 'dL_dKdiag':dL_dpsi0, + 'dL_dKnm':dL_dpsi1, + 'dL_dthetaL':dL_dthetaL} + + #get sufficient things for posterior prediction + #TODO: do we really want to do this in the loop? + if VVT_factor.shape[1] == Y.shape[1]: + woodbury_vector = Cpsi1Vf # == Cpsi1V + else: + print 'foobar' + import ipdb; ipdb.set_trace() + psi1V = np.dot(Y.T*beta, psi1).T + tmp, _ = dtrtrs(Lm, psi1V, lower=1, trans=0) + tmp, _ = dpotrs(LB, tmp, lower=1) + woodbury_vector, _ = dtrtrs(Lm, tmp, lower=1, trans=1) + Bi, _ = dpotri(LB, lower=1) + symmetrify(Bi) + Bi = -dpotri(LB, lower=1)[0] + diag.add(Bi, 1) + + woodbury_inv = backsub_both_sides(Lm, Bi) + + #construct a posterior object + post = Posterior(woodbury_inv=woodbury_inv, woodbury_vector=woodbury_vector, K=Kmm, mean=None, cov=None, K_chol=Lm) + return post, log_marginal, grad_dict +
+def _compute_dL_dpsi(num_inducing, num_data, output_dim, beta, Lm, VVT_factor, Cpsi1Vf, DBi_plus_BiPBi, psi1, het_noise, uncertain_inputs): + dL_dpsi0 = -0.5 * output_dim * (beta* np.ones([num_data, 1])).flatten() + dL_dpsi1 = np.dot(VVT_factor, Cpsi1Vf.T) + dL_dpsi2_beta = 0.5 * backsub_both_sides(Lm, output_dim * np.eye(num_inducing) - DBi_plus_BiPBi) + if het_noise: + if uncertain_inputs: + dL_dpsi2 = beta[:, None] * dL_dpsi2_beta[None, :, :] + else: + dL_dpsi1 += 2.*np.dot(dL_dpsi2_beta, (psi1 * beta).T).T + dL_dpsi2 = None + else: + dL_dpsi2 = beta * dL_dpsi2_beta + if not uncertain_inputs: + # subsume back into psi1 (==Kmn) + dL_dpsi1 += 2.*np.dot(psi1, dL_dpsi2) + dL_dpsi2 = None + return dL_dpsi0, dL_dpsi1, dL_dpsi2 + + +def _compute_dL_dR(likelihood, het_noise, uncertain_inputs, LB, _LBi_Lmi_psi1Vf, DBi_plus_BiPBi, Lm, A, psi0, psi1, beta, data_fit, num_data, output_dim, trYYT, Y, VVT_factr=None): + # the partial derivative vector for the likelihood + if likelihood.size == 0: + # save computation here. + dL_dR = None + elif het_noise: + if uncertain_inputs: + raise NotImplementedError, "heteroscedatic derivates with uncertain inputs not implemented" + else: + #from ...util.linalg import chol_inv + #LBi = chol_inv(LB) + LBi, _ = dtrtrs(LB,np.eye(LB.shape[0])) + + Lmi_psi1, nil = dtrtrs(Lm, psi1.T, lower=1, trans=0) + _LBi_Lmi_psi1, _ = dtrtrs(LB, Lmi_psi1, lower=1, trans=0) + dL_dR = -0.5 * beta + 0.5 * VVT_factr**2 + dL_dR += 0.5 * output_dim * (psi0 - np.sum(Lmi_psi1**2,0))[:,None] * beta**2 + + dL_dR += 0.5*np.sum(mdot(LBi.T,LBi,Lmi_psi1)*Lmi_psi1,0)[:,None]*beta**2 + + dL_dR += -np.dot(_LBi_Lmi_psi1Vf.T,_LBi_Lmi_psi1).T * Y * beta**2 + dL_dR += 0.5*np.dot(_LBi_Lmi_psi1Vf.T,_LBi_Lmi_psi1).T**2 * beta**2 + else: + # likelihood is not heteroscedatic + dL_dR = -0.5 * num_data * output_dim * beta + 0.5 * trYYT * beta ** 2 + dL_dR += 0.5 * output_dim * (psi0.sum() * beta ** 2 - np.trace(A) * beta) + dL_dR += beta * (0.5 * np.sum(A * DBi_plus_BiPBi) - data_fit) + return dL_dR + +def _compute_log_marginal_likelihood(likelihood, num_data, output_dim, beta, het_noise, psi0, A, LB, trYYT, data_fit, Y): + #compute log marginal likelihood + if het_noise: + lik_1 = -0.5 * num_data * output_dim * np.log(2. * np.pi) + 0.5 * output_dim * np.sum(np.log(beta)) - 0.5 * np.sum(beta.ravel() * np.square(Y).sum(axis=-1)) + lik_2 = -0.5 * output_dim * (np.sum(beta.flatten() * psi0) - np.trace(A)) + else: + lik_1 = -0.5 * num_data * output_dim * (np.log(2. * np.pi) - np.log(beta)) - 0.5 * beta * trYYT + lik_2 = -0.5 * output_dim * (np.sum(beta * psi0) - np.trace(A)) + lik_3 = -output_dim * (np.sum(np.log(np.diag(LB)))) + lik_4 = 0.5 * data_fit + log_marginal = lik_1 + lik_2 + lik_3 + lik_4 + return log_marginal +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/latent_function_inference/var_dtc_parallel.html b/doc/_build/html/_modules/GPy/inference/latent_function_inference/var_dtc_parallel.html new file mode 100644 index 00000000..a2a22ee3 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/latent_function_inference/var_dtc_parallel.html @@ -0,0 +1,575 @@ + + + + + + + + GPy.inference.latent_function_inference.var_dtc_parallel — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.latent_function_inference.var_dtc_parallel

+# Copyright (c) 2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from posterior import Posterior
+from ...util.linalg import jitchol, backsub_both_sides, tdot, dtrtrs, dtrtri,pdinv
+from ...util import diag
+from ...core.parameterization.variational import VariationalPosterior
+import numpy as np
+from . import LatentFunctionInference
+log_2_pi = np.log(2*np.pi)
+
+try:
+    from mpi4py import MPI
+except:
+    pass
+
+
[docs]class VarDTC_minibatch(LatentFunctionInference): + """ + An object for inference when the likelihood is Gaussian, but we want to do sparse inference. + + The function self.inference returns a Posterior object, which summarizes + the posterior. + + For efficiency, we sometimes work with the cholesky of Y*Y.T. To save repeatedly recomputing this, we cache it. + + """ + const_jitter = 1e-6 + def __init__(self, batchsize=None, limit=1, mpi_comm=None): + + self.batchsize = batchsize + self.mpi_comm = mpi_comm + self.limit = limit + + # Cache functions + from ...util.caching import Cacher + self.get_trYYT = Cacher(self._get_trYYT, limit) + self.get_YYTfactor = Cacher(self._get_YYTfactor, limit) + + self.midRes = {} + self.batch_pos = 0 # the starting position of the current mini-batch + self.Y_speedup = False # Replace Y with the cholesky factor of YY.T, but the computation of posterior object will be skipped. + + def __getstate__(self): + # has to be overridden, as Cacher objects cannot be pickled. + return self.batchsize, self.limit, self.Y_speedup + + def __setstate__(self, state): + # has to be overridden, as Cacher objects cannot be pickled. + self.batchsize, self.limit, self.Y_speedup = state + self.mpi_comm = None + self.midRes = {} + self.batch_pos = 0 + from ...util.caching import Cacher + self.get_trYYT = Cacher(self._get_trYYT, self.limit) + self.get_YYTfactor = Cacher(self._get_YYTfactor, self.limit) + +
[docs] def set_limit(self, limit): + self.get_trYYT.limit = limit + self.get_YYTfactor.limit = limit +
+ def _get_trYYT(self, Y): + return np.sum(np.square(Y)) + + def _get_YYTfactor(self, Y): + """ + find a matrix L which satisfies LLT = YYT. + + Note that L may have fewer columns than Y. + """ + N, D = Y.shape + if (N>=D): + return Y.view(np.ndarray) + else: + return jitchol(tdot(Y)) + +
[docs] def gatherPsiStat(self, kern, X, Z, Y, beta, uncertain_inputs): + + het_noise = beta.size > 1 + + assert beta.size == 1 + + trYYT = self.get_trYYT(Y) + if self.Y_speedup and not het_noise: + Y = self.get_YYTfactor(Y) + + num_inducing = Z.shape[0] + num_data, output_dim = Y.shape + batchsize = num_data if self.batchsize is None else self.batchsize + + psi2_full = np.zeros((num_inducing,num_inducing)) # MxM + psi1Y_full = np.zeros((output_dim,num_inducing)) # DxM + psi0_full = 0. + YRY_full = 0. + + for n_start in xrange(0,num_data,batchsize): + n_end = min(batchsize+n_start, num_data) + if batchsize==num_data: + Y_slice = Y + X_slice = X + else: + Y_slice = Y[n_start:n_end] + X_slice = X[n_start:n_end] + + if het_noise: + b = beta[n_start] + YRY_full += np.inner(Y_slice, Y_slice)*b + else: + b = beta + + if uncertain_inputs: + psi0 = kern.psi0(Z, X_slice) + psi1 = kern.psi1(Z, X_slice) + psi2_full += kern.psi2(Z, X_slice)*b + else: + psi0 = kern.Kdiag(X_slice) + psi1 = kern.K(X_slice, Z) + psi2_full += np.dot(psi1.T,psi1)*b + + psi0_full += psi0.sum()*b + psi1Y_full += np.dot(Y_slice.T,psi1)*b # DxM + + if not het_noise: + YRY_full = trYYT*beta + + if self.mpi_comm != None: + psi0_all = np.array(psi0_full) + psi1Y_all = psi1Y_full.copy() + psi2_all = psi2_full.copy() + YRY_all = np.array(YRY_full) + self.mpi_comm.Allreduce([psi0_full, MPI.DOUBLE], [psi0_all, MPI.DOUBLE]) + self.mpi_comm.Allreduce([psi1Y_full, MPI.DOUBLE], [psi1Y_all, MPI.DOUBLE]) + self.mpi_comm.Allreduce([psi2_full, MPI.DOUBLE], [psi2_all, MPI.DOUBLE]) + self.mpi_comm.Allreduce([YRY_full, MPI.DOUBLE], [YRY_all, MPI.DOUBLE]) + return psi0_all, psi1Y_all, psi2_all, YRY_all + + return psi0_full, psi1Y_full, psi2_full, YRY_full +
+
[docs] def inference_likelihood(self, kern, X, Z, likelihood, Y): + """ + The first phase of inference: + Compute: log-likelihood, dL_dKmm + + Cached intermediate results: Kmm, KmmInv, + """ + + num_data, output_dim = Y.shape + input_dim = Z.shape[0] + if self.mpi_comm != None: + num_data_all = np.array(num_data,dtype=np.int32) + self.mpi_comm.Allreduce([np.int32(num_data), MPI.INT], [num_data_all, MPI.INT]) + num_data = num_data_all + + if isinstance(X, VariationalPosterior): + uncertain_inputs = True + else: + uncertain_inputs = False + + #see whether we've got a different noise variance for each datum + beta = 1./np.fmax(likelihood.variance, 1e-6) + het_noise = beta.size > 1 + if het_noise: + self.batchsize = 1 + + psi0_full, psi1Y_full, psi2_full, YRY_full = self.gatherPsiStat(kern, X, Z, Y, beta, uncertain_inputs) + + #====================================================================== + # Compute Common Components + #====================================================================== + + Kmm = kern.K(Z).copy() + diag.add(Kmm, self.const_jitter) + Lm = jitchol(Kmm, maxtries=100) + + LmInvPsi2LmInvT = backsub_both_sides(Lm,psi2_full,transpose='right') + Lambda = np.eye(Kmm.shape[0])+LmInvPsi2LmInvT + LL = jitchol(Lambda, maxtries=100) + logdet_L = 2.*np.sum(np.log(np.diag(LL))) + b = dtrtrs(LL,dtrtrs(Lm,psi1Y_full.T)[0])[0] + bbt = np.square(b).sum() + v = dtrtrs(Lm,dtrtrs(LL,b,trans=1)[0],trans=1)[0] + + tmp = -backsub_both_sides(LL, tdot(b)+output_dim*np.eye(input_dim), transpose='left') + dL_dpsi2R = backsub_both_sides(Lm, tmp+output_dim*np.eye(input_dim), transpose='left')/2. + + # Cache intermediate results + self.midRes['dL_dpsi2R'] = dL_dpsi2R + self.midRes['v'] = v + + #====================================================================== + # Compute log-likelihood + #====================================================================== + if het_noise: + logL_R = -np.log(beta).sum() + else: + logL_R = -num_data*np.log(beta) + logL = -(output_dim*(num_data*log_2_pi+logL_R+psi0_full-np.trace(LmInvPsi2LmInvT))+YRY_full-bbt)/2.-output_dim*logdet_L/2. + + #====================================================================== + # Compute dL_dKmm + #====================================================================== + + dL_dKmm = dL_dpsi2R - output_dim*backsub_both_sides(Lm, LmInvPsi2LmInvT, transpose='left')/2. + + #====================================================================== + # Compute the Posterior distribution of inducing points p(u|Y) + #====================================================================== + + if not self.Y_speedup or het_noise: + wd_inv = backsub_both_sides(Lm, np.eye(input_dim)- backsub_both_sides(LL, np.identity(input_dim), transpose='left'), transpose='left') + post = Posterior(woodbury_inv=wd_inv, woodbury_vector=v, K=Kmm, mean=None, cov=None, K_chol=Lm) + else: + post = None + + #====================================================================== + # Compute dL_dthetaL for uncertian input and non-heter noise + #====================================================================== + + if not het_noise: + dL_dthetaL = (YRY_full*beta + beta*output_dim*psi0_full - num_data*output_dim*beta)/2. - beta*(dL_dpsi2R*psi2_full).sum() - beta*(v.T*psi1Y_full).sum() + self.midRes['dL_dthetaL'] = dL_dthetaL + + return logL, dL_dKmm, post +
+
[docs] def inference_minibatch(self, kern, X, Z, likelihood, Y): + """ + The second phase of inference: Computing the derivatives over a minibatch of Y + Compute: dL_dpsi0, dL_dpsi1, dL_dpsi2, dL_dthetaL + return a flag showing whether it reached the end of Y (isEnd) + """ + + num_data, output_dim = Y.shape + + if isinstance(X, VariationalPosterior): + uncertain_inputs = True + else: + uncertain_inputs = False + + #see whether we've got a different noise variance for each datum + beta = 1./np.fmax(likelihood.variance, 1e-6) + het_noise = beta.size > 1 + # VVT_factor is a matrix such that tdot(VVT_factor) = VVT...this is for efficiency! + #self.YYTfactor = beta*self.get_YYTfactor(Y) + if self.Y_speedup and not het_noise: + YYT_factor = self.get_YYTfactor(Y) + else: + YYT_factor = Y + + n_start = self.batch_pos + batchsize = num_data if self.batchsize is None else self.batchsize + n_end = min(batchsize+n_start, num_data) + if n_end==num_data: + isEnd = True + self.batch_pos = 0 + else: + isEnd = False + self.batch_pos = n_end + + if batchsize==num_data: + Y_slice = YYT_factor + X_slice =X + else: + Y_slice = YYT_factor[n_start:n_end] + X_slice = X[n_start:n_end] + + if not uncertain_inputs: + psi0 = kern.Kdiag(X_slice) + psi1 = kern.K(X_slice, Z) + psi2 = None + betapsi1 = np.einsum('n,nm->nm',beta,psi1) + elif het_noise: + psi0 = kern.psi0(Z, X_slice) + psi1 = kern.psi1(Z, X_slice) + psi2 = kern.psi2(Z, X_slice) + betapsi1 = np.einsum('n,nm->nm',beta,psi1) + + if het_noise: + beta = beta[n_start] # assuming batchsize==1 + + betaY = beta*Y_slice + + #====================================================================== + # Load Intermediate Results + #====================================================================== + + dL_dpsi2R = self.midRes['dL_dpsi2R'] + v = self.midRes['v'] + + #====================================================================== + # Compute dL_dpsi + #====================================================================== + + dL_dpsi0 = -output_dim * (beta * np.ones((n_end-n_start,)))/2. + + dL_dpsi1 = np.dot(betaY,v.T) + + if uncertain_inputs: + dL_dpsi2 = beta* dL_dpsi2R + else: + dL_dpsi1 += np.dot(betapsi1,dL_dpsi2R)*2. + dL_dpsi2 = None + + #====================================================================== + # Compute dL_dthetaL + #====================================================================== + + if het_noise: + if uncertain_inputs: + psiR = np.einsum('mo,mo->',dL_dpsi2R,psi2) + else: + psiR = np.einsum('nm,no,mo->',psi1,psi1,dL_dpsi2R) + + dL_dthetaL = ((np.square(betaY)).sum(axis=-1) + np.square(beta)*(output_dim*psi0)-output_dim*beta)/2. - np.square(beta)*psiR- (betaY*np.dot(betapsi1,v)).sum(axis=-1) + else: + if isEnd: + dL_dthetaL = self.midRes['dL_dthetaL'] + else: + dL_dthetaL = 0. + + if uncertain_inputs: + grad_dict = {'dL_dpsi0':dL_dpsi0, + 'dL_dpsi1':dL_dpsi1, + 'dL_dpsi2':dL_dpsi2, + 'dL_dthetaL':dL_dthetaL} + else: + grad_dict = {'dL_dKdiag':dL_dpsi0, + 'dL_dKnm':dL_dpsi1, + 'dL_dthetaL':dL_dthetaL} + + return isEnd, (n_start,n_end), grad_dict + +
+
[docs]def update_gradients(model, mpi_comm=None): + if mpi_comm == None: + Y = model.Y + X = model.X + else: + Y = model.Y_local + X = model.X[model.N_range[0]:model.N_range[1]] + + model._log_marginal_likelihood, dL_dKmm, model.posterior = model.inference_method.inference_likelihood(model.kern, X, model.Z, model.likelihood, Y) + + het_noise = model.likelihood.variance.size > 1 + + if het_noise: + dL_dthetaL = np.empty((model.Y.shape[0],)) + else: + dL_dthetaL = np.float64(0.) + + kern_grad = model.kern.gradient.copy() + kern_grad[:] = 0. + model.Z.gradient = 0. + + isEnd = False + while not isEnd: + isEnd, n_range, grad_dict = model.inference_method.inference_minibatch(model.kern, X, model.Z, model.likelihood, Y) + if isinstance(model.X, VariationalPosterior): + if (n_range[1]-n_range[0])==X.shape[0]: + X_slice = X + elif mpi_comm ==None: + X_slice = model.X[n_range[0]:n_range[1]] + else: + X_slice = model.X[model.N_range[0]+n_range[0]:model.N_range[0]+n_range[1]] + + #gradients w.r.t. kernel + model.kern.update_gradients_expectations(variational_posterior=X_slice, Z=model.Z, dL_dpsi0=grad_dict['dL_dpsi0'], dL_dpsi1=grad_dict['dL_dpsi1'], dL_dpsi2=grad_dict['dL_dpsi2']) + kern_grad += model.kern.gradient + + #gradients w.r.t. Z + model.Z.gradient += model.kern.gradients_Z_expectations( + dL_dpsi0=grad_dict['dL_dpsi0'], dL_dpsi1=grad_dict['dL_dpsi1'], dL_dpsi2=grad_dict['dL_dpsi2'], Z=model.Z, variational_posterior=X_slice) + + #gradients w.r.t. posterior parameters of X + X_grad = model.kern.gradients_qX_expectations(variational_posterior=X_slice, Z=model.Z, dL_dpsi0=grad_dict['dL_dpsi0'], dL_dpsi1=grad_dict['dL_dpsi1'], dL_dpsi2=grad_dict['dL_dpsi2']) + model.set_X_gradients(X_slice, X_grad) + + if het_noise: + dL_dthetaL[n_range[0]:n_range[1]] = grad_dict['dL_dthetaL'] + else: + dL_dthetaL += grad_dict['dL_dthetaL'] + + # Gather the gradients from multiple MPI nodes + if mpi_comm != None: + if het_noise: + raise "het_noise not implemented!" + kern_grad_all = kern_grad.copy() + Z_grad_all = model.Z.gradient.copy() + mpi_comm.Allreduce([kern_grad, MPI.DOUBLE], [kern_grad_all, MPI.DOUBLE]) + mpi_comm.Allreduce([model.Z.gradient, MPI.DOUBLE], [Z_grad_all, MPI.DOUBLE]) + kern_grad = kern_grad_all + model.Z.gradient = Z_grad_all + + #gradients w.r.t. kernel + model.kern.update_gradients_full(dL_dKmm, model.Z, None) + model.kern.gradient += kern_grad + + #gradients w.r.t. Z + model.Z.gradient += model.kern.gradients_X(dL_dKmm, model.Z) + + # Update Log-likelihood + KL_div = model.variational_prior.KL_divergence(X) + # update for the KL divergence + model.variational_prior.update_gradients_KL(X) + + if mpi_comm != None: + KL_div_all = np.array(KL_div) + mpi_comm.Allreduce([np.float64(KL_div), MPI.DOUBLE], [KL_div_all, MPI.DOUBLE]) + KL_div = KL_div_all + [mpi_comm.Allgatherv([pp.copy(), MPI.DOUBLE], [pa, (model.N_list*pa.shape[-1], None), MPI.DOUBLE]) for pp,pa in zip(model.get_X_gradients(X),model.get_X_gradients(model.X))] +# from ...models import SSGPLVM +# if isinstance(model, SSGPLVM): +# grad_pi = np.array(model.variational_prior.pi.gradient) +# mpi_comm.Allreduce([grad_pi.copy(), MPI.DOUBLE], [model.variational_prior.pi.gradient, MPI.DOUBLE]) + model._log_marginal_likelihood -= KL_div + + # dL_dthetaL + model.likelihood.update_gradients(dL_dthetaL) +
+
[docs]def update_gradients_sparsegp(model, mpi_comm=None): + if mpi_comm == None: + Y = model.Y + X = model.X + else: + Y = model.Y_local + X = model.X[model.N_range[0]:model.N_range[1]] + + model._log_marginal_likelihood, dL_dKmm, model.posterior = model.inference_method.inference_likelihood(model.kern, X, model.Z, model.likelihood, Y) + + het_noise = model.likelihood.variance.size > 1 + + if het_noise: + dL_dthetaL = np.empty((model.Y.shape[0],)) + else: + dL_dthetaL = np.float64(0.) + + kern_grad = model.kern.gradient.copy() + kern_grad[:] = 0. + model.Z.gradient = 0. + + isEnd = False + while not isEnd: + isEnd, n_range, grad_dict = model.inference_method.inference_minibatch(model.kern, X, model.Z, model.likelihood, Y) + + if (n_range[1]-n_range[0])==X.shape[0]: + X_slice = X + elif mpi_comm ==None: + X_slice = model.X[n_range[0]:n_range[1]] + else: + X_slice = model.X[model.N_range[0]+n_range[0]:model.N_range[0]+n_range[1]] + + model.kern.update_gradients_diag(grad_dict['dL_dKdiag'], X_slice) + kern_grad += model.kern.gradient + model.kern.update_gradients_full(grad_dict['dL_dKnm'], X_slice, model.Z) + kern_grad += model.kern.gradient + + model.Z.gradient += model.kern.gradients_X(grad_dict['dL_dKnm'].T, model.Z, X_slice) + + if het_noise: + dL_dthetaL[n_range[0]:n_range[1]] = grad_dict['dL_dthetaL'] + else: + dL_dthetaL += grad_dict['dL_dthetaL'] + + # Gather the gradients from multiple MPI nodes + if mpi_comm != None: + if het_noise: + raise "het_noise not implemented!" + kern_grad_all = kern_grad.copy() + Z_grad_all = model.Z.gradient.copy() + mpi_comm.Allreduce([kern_grad, MPI.DOUBLE], [kern_grad_all, MPI.DOUBLE]) + mpi_comm.Allreduce([model.Z.gradient, MPI.DOUBLE], [Z_grad_all, MPI.DOUBLE]) + kern_grad = kern_grad_all + model.Z.gradient = Z_grad_all + + model.kern.update_gradients_full(dL_dKmm, model.Z, None) + model.kern.gradient += kern_grad + + model.Z.gradient += model.kern.gradients_X(dL_dKmm, model.Z) + + # dL_dthetaL + model.likelihood.update_gradients(dL_dthetaL)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/mcmc/hmc.html b/doc/_build/html/_modules/GPy/inference/mcmc/hmc.html new file mode 100644 index 00000000..a5cc343b --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/mcmc/hmc.html @@ -0,0 +1,267 @@ + + + + + + + + GPy.inference.mcmc.hmc — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.mcmc.hmc

+# ## Copyright (c) 2014, Zhenwen Dai
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+
+
+
[docs]class HMC: + """ + An implementation of Hybrid Monte Carlo (HMC) for GPy models + + Initialize an object for HMC sampling. Note that the status of the model (model parameters) will be changed during sampling. + + :param model: the GPy model that will be sampled + :type model: GPy.core.Model + :param M: the mass matrix (an identity matrix by default) + :type M: numpy.ndarray + :param stepsize: the step size for HMC sampling + :type stepsize: float + """ + def __init__(self, model, M=None,stepsize=1e-1): + self.model = model + self.stepsize = stepsize + self.p = np.empty_like(model.optimizer_array.copy()) + if M is None: + self.M = np.eye(self.p.size) + else: + self.M = M + self.Minv = np.linalg.inv(self.M) + +
[docs] def sample(self, num_samples=1000, hmc_iters=20): + """ + Sample the (unfixed) model parameters. + + :param num_samples: the number of samples to draw (1000 by default) + :type num_samples: int + :param hmc_iters: the number of leap-frog iterations (20 by default) + :type hmc_iters: int + :return: the list of parameters samples with the size N x P (N - the number of samples, P - the number of parameters to sample) + :rtype: numpy.ndarray + """ + params = np.empty((num_samples,self.p.size)) + for i in xrange(num_samples): + self.p[:] = np.random.multivariate_normal(np.zeros(self.p.size),self.M) + H_old = self._computeH() + theta_old = self.model.optimizer_array.copy() + params[i] = self.model.unfixed_param_array + #Matropolis + self._update(hmc_iters) + H_new = self._computeH() + + if H_old>H_new: + k = 1. + else: + k = np.exp(H_old-H_new) + if np.random.rand()<k: + params[i] = self.model.unfixed_param_array + else: + self.model.optimizer_array = theta_old + return params +
+ def _update(self, hmc_iters): + for i in xrange(hmc_iters): + self.p[:] += -self.stepsize/2.*self.model._transform_gradients(self.model.objective_function_gradients()) + self.model.optimizer_array = self.model.optimizer_array + self.stepsize*np.dot(self.Minv, self.p) + self.p[:] += -self.stepsize/2.*self.model._transform_gradients(self.model.objective_function_gradients()) + + def _computeH(self,): + return self.model.objective_function()+self.p.size*np.log(2*np.pi)/2.+np.log(np.linalg.det(self.M))/2.+np.dot(self.p, np.dot(self.Minv,self.p[:,None]))/2. +
+
[docs]class HMC_shortcut: + def __init__(self,model,M=None,stepsize_range=[1e-6, 1e-1],groupsize=5, Hstd_th=[1e-5, 3.]): + self.model = model + self.stepsize_range = np.log(stepsize_range) + self.p = np.empty_like(model.optimizer_array.copy()) + self.groupsize = groupsize + self.Hstd_th = Hstd_th + if M is None: + self.M = np.eye(self.p.size) + else: + self.M = M + self.Minv = np.linalg.inv(self.M) + +
[docs] def sample(self, m_iters=1000, hmc_iters=20): + params = np.empty((m_iters,self.p.size)) + for i in xrange(m_iters): + # sample a stepsize from the uniform distribution + stepsize = np.exp(np.random.rand()*(self.stepsize_range[1]-self.stepsize_range[0])+self.stepsize_range[0]) + self.p[:] = np.random.multivariate_normal(np.zeros(self.p.size),self.M) + H_old = self._computeH() + params[i] = self.model.unfixed_param_array + theta_old = self.model.optimizer_array.copy() + #Matropolis + self._update(hmc_iters, stepsize) + H_new = self._computeH() + + if H_old>H_new: + k = 1. + else: + k = np.exp(H_old-H_new) + if np.random.rand()<k: + params[i] = self.model.unfixed_param_array + else: + self.model.optimizer_array = theta_old + return params +
+ def _update(self, hmc_iters, stepsize): + theta_buf = np.empty((2*hmc_iters+1,self.model.optimizer_array.size)) + p_buf = np.empty((2*hmc_iters+1,self.p.size)) + H_buf = np.empty((2*hmc_iters+1,)) + # Set initial position + theta_buf[hmc_iters] = self.model.optimizer_array + p_buf[hmc_iters] = self.p + H_buf[hmc_iters] = self._computeH() + + reversal = [] + pos = 1 + i=0 + while i<hmc_iters: + self.p[:] += -stepsize/2.*self.model._transform_gradients(self.model.objective_function_gradients()) + self.model.optimizer_array = self.model.optimizer_array + stepsize*np.dot(self.Minv, self.p) + self.p[:] += -stepsize/2.*self.model._transform_gradients(self.model.objective_function_gradients()) + + theta_buf[hmc_iters+pos] = self.model.optimizer_array + p_buf[hmc_iters+pos] = self.p + H_buf[hmc_iters+pos] = self._computeH() + i+=1 + + if i<self.groupsize: + pos += 1 + continue + else: + if len(reversal)==0: + Hlist = range(hmc_iters+pos,hmc_iters+pos-self.groupsize,-1) + if self._testH(H_buf[Hlist]): + pos += 1 + else: + # Reverse the trajectory for the 1st time + reversal.append(pos) + if hmc_iters-i>pos: + pos = -1 + i += pos + self.model.optimizer_array = theta_buf[hmc_iters] + self.p[:] = -p_buf[hmc_iters] + else: + pos_new = pos-hmc_iters+i + self.model.optimizer_array = theta_buf[hmc_iters+pos_new] + self.p[:] = -p_buf[hmc_iters+pos_new] + break + else: + Hlist = range(hmc_iters+pos,hmc_iters+pos+self.groupsize) + + if self._testH(H_buf[Hlist]): + pos += -1 + else: + # Reverse the trajectory for the 2nd time + r = (hmc_iters - i)%((reversal[0]-pos)*2) + if r>(reversal[0]-pos): + pos_new = 2*reversal[0] - r - pos + else: + pos_new = pos + r + self.model.optimizer_array = theta_buf[hmc_iters+pos_new] + self.p[:] = p_buf[hmc_iters+pos_new] # the sign of momentum might be wrong! + break + + def _testH(self, Hlist): + Hstd = np.std(Hlist) + if Hstd<self.Hstd_th[0] or Hstd>self.Hstd_th[1]: + return False + else: + return True + + def _computeH(self,): + return self.model.objective_function()+self.p.size*np.log(2*np.pi)/2.+np.log(np.linalg.det(self.M))/2.+np.dot(self.p, np.dot(self.Minv,self.p[:,None]))/2. +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/mcmc/samplers.html b/doc/_build/html/_modules/GPy/inference/mcmc/samplers.html new file mode 100644 index 00000000..2d0f6850 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/mcmc/samplers.html @@ -0,0 +1,175 @@ + + + + + + + + GPy.inference.mcmc.samplers — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.mcmc.samplers

+# ## Copyright (c) 2014, Zhenwen Dai
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from scipy import linalg, optimize
+import Tango
+import sys
+import re
+import numdifftools as ndt
+import pdb
+import cPickle
+
+
+
[docs]class Metropolis_Hastings: + def __init__(self,model,cov=None): + """Metropolis Hastings, with tunings according to Gelman et al. """ + self.model = model + current = self.model._get_params_transformed() + self.D = current.size + self.chains = [] + if cov is None: + self.cov = model.Laplace_covariance() + else: + self.cov = cov + self.scale = 2.4/np.sqrt(self.D) + self.new_chain(current) + +
[docs] def new_chain(self, start=None): + self.chains.append([]) + if start is None: + self.model.randomize() + else: + self.model._set_params_transformed(start) + + +
+
[docs] def sample(self, Ntotal, Nburn, Nthin, tune=True, tune_throughout=False, tune_interval=400): + current = self.model._get_params_transformed() + fcurrent = self.model.log_likelihood() + self.model.log_prior() + accepted = np.zeros(Ntotal,dtype=np.bool) + for it in range(Ntotal): + print "sample %d of %d\r"%(it,Ntotal), + sys.stdout.flush() + prop = np.random.multivariate_normal(current, self.cov*self.scale*self.scale) + self.model._set_params_transformed(prop) + fprop = self.model.log_likelihood() + self.model.log_prior() + + if fprop>fcurrent:#sample accepted, going 'uphill' + accepted[it] = True + current = prop + fcurrent = fprop + else: + u = np.random.rand() + if np.exp(fprop-fcurrent)>u:#sample accepted downhill + accepted[it] = True + current = prop + fcurrent = fprop + + #store current value + if (it > Nburn) & ((it%Nthin)==0): + self.chains[-1].append(current) + + #tuning! + if it & ((it%tune_interval)==0) & tune & ((it<Nburn) | (tune_throughout)): + pc = np.mean(accepted[it-tune_interval:it]) + self.cov = np.cov(np.vstack(self.chains[-1][-tune_interval:]).T) + if pc > .25: + self.scale *= 1.1 + if pc < .15: + self.scale /= 1.1 +
+
[docs] def predict(self,function,args): + """Make a prediction for the function, to which we will pass the additional arguments""" + param = self.model._get_params() + fs = [] + for p in self.chain: + self.model._set_params(p) + fs.append(function(*args)) + self.model._set_params(param)# reset model to starting state + return fs
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/optimization/conjugate_gradient_descent.html b/doc/_build/html/_modules/GPy/inference/optimization/conjugate_gradient_descent.html new file mode 100644 index 00000000..276b7fea --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/optimization/conjugate_gradient_descent.html @@ -0,0 +1,378 @@ + + + + + + + + GPy.inference.optimization.conjugate_gradient_descent — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.optimization.conjugate_gradient_descent

+# Copyright (c) 2012-2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from gradient_descent_update_rules import FletcherReeves, \
+    PolakRibiere
+from Queue import Empty
+from multiprocessing import Value
+from multiprocessing.queues import Queue
+from multiprocessing.synchronize import Event
+from scipy.optimize.linesearch import line_search_wolfe1, line_search_wolfe2
+from threading import Thread
+import numpy
+import sys
+import time
+
+RUNNING = "running"
+CONVERGED = "converged"
+MAXITER = "maximum number of iterations reached"
+MAX_F_EVAL = "maximum number of function calls reached"
+LINE_SEARCH = "line search failed"
+KBINTERRUPT = "interrupted"
+
+class _Async_Optimization(Thread):
+
+    def __init__(self, f, df, x0, update_rule, runsignal, SENTINEL,
+                 report_every=10, messages=0, maxiter=5e3, max_f_eval=15e3,
+                 gtol=1e-6, outqueue=None, *args, **kw):
+        """
+        Helper Process class for async optimization
+        
+        f_call and df_call are Multiprocessing Values, for synchronized assignment
+        """
+        self.f_call = Value('i', 0)
+        self.df_call = Value('i', 0)
+        self.f = self.f_wrapper(f, self.f_call)
+        self.df = self.f_wrapper(df, self.df_call)
+        self.x0 = x0
+        self.update_rule = update_rule
+        self.report_every = report_every
+        self.messages = messages
+        self.maxiter = maxiter
+        self.max_f_eval = max_f_eval
+        self.gtol = gtol
+        self.SENTINEL = SENTINEL
+        self.runsignal = runsignal
+#         self.parent = parent
+#         self.result = None
+        self.outq = outqueue
+        super(_Async_Optimization, self).__init__(target=self.run,
+                                            name="CG Optimization",
+                                            *args, **kw)
+
+#     def __enter__(self):
+#         return self
+#
+#     def __exit__(self, type, value, traceback):
+#         return isinstance(value, TypeError)
+
+    def f_wrapper(self, f, counter):
+        def f_w(*a, **kw):
+            counter.value += 1
+            return f(*a, **kw)
+        return f_w
+
+    def callback(self, *a):
+        if self.outq is not None:
+            self.outq.put(a)
+#         self.parent and self.parent.callback(*a, **kw)
+        pass
+        # print "callback done"
+
+    def callback_return(self, *a):
+        self.callback(*a)
+        if self.outq is not None:
+            self.outq.put(self.SENTINEL)
+        if self.messages:
+            print ""
+        self.runsignal.clear()
+
+    def run(self, *args, **kwargs):
+        raise NotImplementedError("Overwrite this with optimization (for async use)")
+        pass
+
+class _CGDAsync(_Async_Optimization):
+
+    def reset(self, xi, *a, **kw):
+        gi = -self.df(xi, *a, **kw)
+        si = gi
+        ur = self.update_rule(gi)
+        return gi, ur, si
+
+    def run(self, *a, **kw):
+        status = RUNNING
+
+        fi = self.f(self.x0)
+        fi_old = fi + 5000
+
+        gi, ur, si = self.reset(self.x0, *a, **kw)
+        xi = self.x0
+        xi_old = numpy.nan
+        it = 0
+
+        while it < self.maxiter:
+            if not self.runsignal.is_set():
+                break
+
+            if self.f_call.value > self.max_f_eval:
+                status = MAX_F_EVAL
+
+            gi = -self.df(xi, *a, **kw)
+            if numpy.dot(gi.T, gi) <= self.gtol:
+                status = CONVERGED
+                break
+            if numpy.isnan(numpy.dot(gi.T, gi)):
+                if numpy.any(numpy.isnan(xi_old)):
+                    status = CONVERGED
+                    break
+                self.reset(xi_old)
+
+            gammai = ur(gi)
+            if gammai < 1e-6 or it % xi.shape[0] == 0:
+                gi, ur, si = self.reset(xi, *a, **kw)
+            si = gi + gammai * si
+            alphai, _, _, fi2, fi_old2, gfi = line_search_wolfe1(self.f,
+                                                                 self.df,
+                                                                 xi,
+                                                                 si, gi,
+                                                                 fi, fi_old)
+            if alphai is None:
+                alphai, _, _, fi2, fi_old2, gfi = \
+                         line_search_wolfe2(self.f, self.df,
+                                            xi, si, gi,
+                                            fi, fi_old)
+                if alphai is None:
+                    # This line search also failed to find a better solution.
+                    status = LINE_SEARCH
+                    break
+            if fi2 < fi:
+                fi, fi_old = fi2, fi_old2
+            if gfi is not None:
+                gi = gfi
+
+            if numpy.isnan(fi) or fi_old < fi:
+                gi, ur, si = self.reset(xi, *a, **kw)
+
+            else:
+                xi += numpy.dot(alphai, si)
+                if self.messages:
+                    sys.stdout.write("\r")
+                    sys.stdout.flush()
+                    sys.stdout.write("iteration: {0:> 6g}  f:{1:> 12e}  |g|:{2:> 12e}".format(it, fi, numpy.dot(gi.T, gi)))
+
+            if it % self.report_every == 0:
+                self.callback(xi, fi, gi, it, self.f_call.value, self.df_call.value, status)
+            it += 1
+        else:
+            status = MAXITER
+        self.callback_return(xi, fi, gi, it, self.f_call.value, self.df_call.value, status)
+        self.result = [xi, fi, gi, it, self.f_call.value, self.df_call.value, status]
+
+
[docs]class Async_Optimize(object): + callback = lambda *x: None + runsignal = Event() + SENTINEL = "SENTINEL" + +
[docs] def async_callback_collect(self, q): + while self.runsignal.is_set(): + try: + for ret in iter(lambda: q.get(timeout=1), self.SENTINEL): + self.callback(*ret) + self.runsignal.clear() + except Empty: + pass +
+
[docs] def opt_async(self, f, df, x0, callback, update_rule=PolakRibiere, + messages=0, maxiter=5e3, max_f_eval=15e3, gtol=1e-6, + report_every=10, *args, **kwargs): + self.runsignal.set() + c = None + outqueue = None + if callback: + outqueue = Queue() + self.callback = callback + c = Thread(target=self.async_callback_collect, args=(outqueue,)) + c.start() + p = _CGDAsync(f, df, x0, update_rule, self.runsignal, self.SENTINEL, + report_every=report_every, messages=messages, maxiter=maxiter, + max_f_eval=max_f_eval, gtol=gtol, outqueue=outqueue, *args, **kwargs) + p.start() + return p, c +
+
[docs] def opt(self, f, df, x0, callback=None, update_rule=FletcherReeves, + messages=0, maxiter=5e3, max_f_eval=15e3, gtol=1e-6, + report_every=10, *args, **kwargs): + p, c = self.opt_async(f, df, x0, callback, update_rule, messages, + maxiter, max_f_eval, gtol, + report_every, *args, **kwargs) + while self.runsignal.is_set(): + try: + p.join(1) + if c: c.join(1) + except KeyboardInterrupt: + # print "^C" + self.runsignal.clear() + p.join() + if c: c.join() + if c and c.is_alive(): +# self.runsignal.set() +# while self.runsignal.is_set(): +# try: +# c.join(.1) +# except KeyboardInterrupt: +# # print "^C" +# self.runsignal.clear() +# c.join() + print "WARNING: callback still running, optimisation done!" + return p.result +
+
[docs]class CGD(Async_Optimize): + ''' + Conjugate gradient descent algorithm to minimize + function f with gradients df, starting at x0 + with update rule update_rule + + if df returns tuple (grad, natgrad) it will optimize according + to natural gradient rules + ''' + opt_name = "Conjugate Gradient Descent" + +
[docs] def opt_async(self, *a, **kw): + """ + opt_async(self, f, df, x0, callback, update_rule=FletcherReeves, + messages=0, maxiter=5e3, max_f_eval=15e3, gtol=1e-6, + report_every=10, \*args, \*\*kwargs) + + callback gets called every `report_every` iterations + + callback(xi, fi, gi, iteration, function_calls, gradient_calls, status_message) + + if df returns tuple (grad, natgrad) it will optimize according + to natural gradient rules + + f, and df will be called with + + f(xi, \*args, \*\*kwargs) + df(xi, \*args, \*\*kwargs) + + **Returns:** + + Started `Process` object, optimizing asynchronously + + **Calls:** + + callback(x_opt, f_opt, g_opt, iteration, function_calls, gradient_calls, status_message) + + at end of optimization! + """ + return super(CGD, self).opt_async(*a, **kw) +
+
[docs] def opt(self, *a, **kw): + """ + opt(self, f, df, x0, callback=None, update_rule=FletcherReeves, + messages=0, maxiter=5e3, max_f_eval=15e3, gtol=1e-6, + report_every=10, \*args, \*\*kwargs) + + Minimize f, calling callback every `report_every` iterations with following syntax: + + callback(xi, fi, gi, iteration, function_calls, gradient_calls, status_message) + + if df returns tuple (grad, natgrad) it will optimize according + to natural gradient rules + + f, and df will be called with + + f(xi, \*args, \*\*kwargs) + df(xi, \*args, \*\*kwargs) + + **returns** + + x_opt, f_opt, g_opt, iteration, function_calls, gradient_calls, status_message + + at end of optimization + """ + return super(CGD, self).opt(*a, **kw) +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/optimization/gradient_descent_update_rules.html b/doc/_build/html/_modules/GPy/inference/optimization/gradient_descent_update_rules.html new file mode 100644 index 00000000..ee11770d --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/optimization/gradient_descent_update_rules.html @@ -0,0 +1,145 @@ + + + + + + + + GPy.inference.optimization.gradient_descent_update_rules — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.optimization.gradient_descent_update_rules

+# Copyright (c) 2012-2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy
+
+
[docs]class GDUpdateRule(): + _gradnat = None + _gradnatold = None + def __init__(self, initgrad, initgradnat=None): + self.grad = initgrad + if initgradnat: + self.gradnat = initgradnat + else: + self.gradnat = initgrad + # self.grad, self.gradnat + def _gamma(self): + raise NotImplemented("""Implement gamma update rule here, + you can use self.grad and self.gradold for parameters, as well as + self.gradnat and self.gradnatold for natural gradients.""") + def __call__(self, grad, gradnat=None, si=None, *args, **kw): + """ + Return gamma for given gradients and optional natural gradients + """ + if not gradnat: + gradnat = grad + self.gradold = self.grad + self.gradnatold = self.gradnat + self.grad = grad + self.gradnat = gradnat + self.si = si + return self._gamma(*args, **kw) +
+
[docs]class FletcherReeves(GDUpdateRule): + ''' + Fletcher Reeves update rule for gamma + ''' + def _gamma(self, *a, **kw): + tmp = numpy.dot(self.grad.T, self.gradnat) + if tmp: + return tmp / numpy.dot(self.gradold.T, self.gradnatold) + return tmp +
+
[docs]class PolakRibiere(GDUpdateRule): + ''' + Fletcher Reeves update rule for gamma + ''' + def _gamma(self, *a, **kw): + tmp = numpy.dot((self.grad - self.gradold).T, self.gradnat) + if tmp: + return tmp / numpy.dot(self.gradold.T, self.gradnatold) + return tmp
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/optimization/optimization.html b/doc/_build/html/_modules/GPy/inference/optimization/optimization.html new file mode 100644 index 00000000..311a0745 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/optimization/optimization.html @@ -0,0 +1,335 @@ + + + + + + + + GPy.inference.optimization.optimization — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.optimization.optimization

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import datetime as dt
+from scipy import optimize
+from warnings import warn
+
+try:
+    import rasmussens_minimize as rasm
+    rasm_available = True
+except ImportError:
+    rasm_available = False
+from scg import SCG
+
+
[docs]class Optimizer(): + """ + Superclass for all the optimizers. + + :param x_init: initial set of parameters + :param f_fp: function that returns the function AND the gradients at the same time + :param f: function to optimize + :param fp: gradients + :param messages: print messages from the optimizer? + :type messages: (True | False) + :param max_f_eval: maximum number of function evaluations + + :rtype: optimizer object. + + """ + def __init__(self, x_init, messages=False, model=None, max_f_eval=1e4, max_iters=1e3, + ftol=None, gtol=None, xtol=None, bfgs_factor=None): + self.opt_name = None + self.x_init = x_init + self.messages = messages + self.f_opt = None + self.x_opt = None + self.funct_eval = None + self.status = None + self.max_f_eval = int(max_f_eval) + self.max_iters = int(max_iters) + self.bfgs_factor = bfgs_factor + self.trace = None + self.time = "Not available" + self.xtol = xtol + self.gtol = gtol + self.ftol = ftol + self.model = model + +
[docs] def run(self, **kwargs): + start = dt.datetime.now() + self.opt(**kwargs) + end = dt.datetime.now() + self.time = str(end - start) +
+
[docs] def opt(self, f_fp=None, f=None, fp=None): + raise NotImplementedError, "this needs to be implemented to use the optimizer class" +
+
[docs] def plot(self): + """ + See GPy.plotting.matplot_dep.inference_plots + """ + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ...plotting.matplot_dep import inference_plots + inference_plots.plot_optimizer(self) + +
+ def __str__(self): + diagnostics = "Optimizer: \t\t\t\t %s\n" % self.opt_name + diagnostics += "f(x_opt): \t\t\t\t %.3f\n" % self.f_opt + diagnostics += "Number of function evaluations: \t %d\n" % self.funct_eval + diagnostics += "Optimization status: \t\t\t %s\n" % self.status + diagnostics += "Time elapsed: \t\t\t\t %s\n" % self.time + return diagnostics +
+
[docs]class opt_tnc(Optimizer): + def __init__(self, *args, **kwargs): + Optimizer.__init__(self, *args, **kwargs) + self.opt_name = "TNC (Scipy implementation)" + +
[docs] def opt(self, f_fp=None, f=None, fp=None): + """ + Run the TNC optimizer + + """ + tnc_rcstrings = ['Local minimum', 'Converged', 'XConverged', 'Maximum number of f evaluations reached', + 'Line search failed', 'Function is constant'] + + assert f_fp != None, "TNC requires f_fp" + + opt_dict = {} + if self.xtol is not None: + opt_dict['xtol'] = self.xtol + if self.ftol is not None: + opt_dict['ftol'] = self.ftol + if self.gtol is not None: + opt_dict['pgtol'] = self.gtol + + opt_result = optimize.fmin_tnc(f_fp, self.x_init, messages=self.messages, + maxfun=self.max_f_eval, **opt_dict) + self.x_opt = opt_result[0] + self.f_opt = f_fp(self.x_opt)[0] + self.funct_eval = opt_result[1] + self.status = tnc_rcstrings[opt_result[2]] +
+
[docs]class opt_lbfgsb(Optimizer): + def __init__(self, *args, **kwargs): + Optimizer.__init__(self, *args, **kwargs) + self.opt_name = "L-BFGS-B (Scipy implementation)" + +
[docs] def opt(self, f_fp=None, f=None, fp=None): + """ + Run the optimizer + + """ + rcstrings = ['Converged', 'Maximum number of f evaluations reached', 'Error'] + + assert f_fp != None, "BFGS requires f_fp" + + if self.messages: + iprint = 1 + else: + iprint = -1 + + opt_dict = {} + if self.xtol is not None: + print "WARNING: l-bfgs-b doesn't have an xtol arg, so I'm going to ignore it" + if self.ftol is not None: + print "WARNING: l-bfgs-b doesn't have an ftol arg, so I'm going to ignore it" + if self.gtol is not None: + opt_dict['pgtol'] = self.gtol + if self.bfgs_factor is not None: + opt_dict['factr'] = self.bfgs_factor + + opt_result = optimize.fmin_l_bfgs_b(f_fp, self.x_init, iprint=iprint, + maxfun=self.max_iters, **opt_dict) + self.x_opt = opt_result[0] + self.f_opt = f_fp(self.x_opt)[0] + self.funct_eval = opt_result[2]['funcalls'] + self.status = rcstrings[opt_result[2]['warnflag']] +
+
[docs]class opt_simplex(Optimizer): + def __init__(self, *args, **kwargs): + Optimizer.__init__(self, *args, **kwargs) + self.opt_name = "Nelder-Mead simplex routine (via Scipy)" + +
[docs] def opt(self, f_fp=None, f=None, fp=None): + """ + The simplex optimizer does not require gradients. + """ + + statuses = ['Converged', 'Maximum number of function evaluations made', 'Maximum number of iterations reached'] + + opt_dict = {} + if self.xtol is not None: + opt_dict['xtol'] = self.xtol + if self.ftol is not None: + opt_dict['ftol'] = self.ftol + if self.gtol is not None: + print "WARNING: simplex doesn't have an gtol arg, so I'm going to ignore it" + + opt_result = optimize.fmin(f, self.x_init, (), disp=self.messages, + maxfun=self.max_f_eval, full_output=True, **opt_dict) + + self.x_opt = opt_result[0] + self.f_opt = opt_result[1] + self.funct_eval = opt_result[3] + self.status = statuses[opt_result[4]] + self.trace = None + +
+
[docs]class opt_rasm(Optimizer): + def __init__(self, *args, **kwargs): + Optimizer.__init__(self, *args, **kwargs) + self.opt_name = "Rasmussen's Conjugate Gradient" + +
[docs] def opt(self, f_fp=None, f=None, fp=None): + """ + Run Rasmussen's Conjugate Gradient optimizer + """ + + assert f_fp != None, "Rasmussen's minimizer requires f_fp" + statuses = ['Converged', 'Line search failed', 'Maximum number of f evaluations reached', + 'NaNs in optimization'] + + opt_dict = {} + if self.xtol is not None: + print "WARNING: minimize doesn't have an xtol arg, so I'm going to ignore it" + if self.ftol is not None: + print "WARNING: minimize doesn't have an ftol arg, so I'm going to ignore it" + if self.gtol is not None: + print "WARNING: minimize doesn't have an gtol arg, so I'm going to ignore it" + + opt_result = rasm.minimize(self.x_init, f_fp, (), messages=self.messages, + maxnumfuneval=self.max_f_eval) + self.x_opt = opt_result[0] + self.f_opt = opt_result[1][-1] + self.funct_eval = opt_result[2] + self.status = statuses[opt_result[3]] + + self.trace = opt_result[1] +
+
[docs]class opt_SCG(Optimizer): + def __init__(self, *args, **kwargs): + if 'max_f_eval' in kwargs: + warn("max_f_eval deprecated for SCG optimizer: use max_iters instead!\nIgnoring max_f_eval!", FutureWarning) + Optimizer.__init__(self, *args, **kwargs) + + self.opt_name = "Scaled Conjugate Gradients" + +
[docs] def opt(self, f_fp=None, f=None, fp=None): + assert not f is None + assert not fp is None + + opt_result = SCG(f, fp, self.x_init, display=self.messages, + maxiters=self.max_iters, + max_f_eval=self.max_f_eval, + xtol=self.xtol, ftol=self.ftol, + gtol=self.gtol) + + self.x_opt = opt_result[0] + self.trace = opt_result[1] + self.f_opt = self.trace[-1] + self.funct_eval = opt_result[2] + self.status = opt_result[3] +
+
[docs]def get_optimizer(f_min): + + optimizers = {'fmin_tnc': opt_tnc, + 'simplex': opt_simplex, + 'lbfgsb': opt_lbfgsb, + 'scg': opt_SCG} + + if rasm_available: + optimizers['rasmussen'] = opt_rasm + + for opt_name in optimizers.keys(): + if opt_name.lower().find(f_min.lower()) != -1: + return optimizers[opt_name] + + raise KeyError('No optimizer was found matching the name: %s' % f_min)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/optimization/scg.html b/doc/_build/html/_modules/GPy/inference/optimization/scg.html new file mode 100644 index 00000000..39e5f7c2 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/optimization/scg.html @@ -0,0 +1,285 @@ + + + + + + + + GPy.inference.optimization.scg — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.optimization.scg

+# Copyright I. Nabney, N.Lawrence and James Hensman (1996 - 2014)
+
+# Scaled Conjuagte Gradients, originally in Matlab as part of the Netlab toolbox by I. Nabney, converted to python N. Lawrence and given a pythonic interface by James Hensman
+
+#      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
+#      HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+#      EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+#      NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+#      MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+#      PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+#      REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+#      DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+#      EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+#      (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+#      OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#      DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+#      HOWEVER CAUSED AND ON ANY THEORY OF
+#      LIABILITY, WHETHER IN CONTRACT, STRICT
+#      LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+#      OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#      OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+#      POSSIBILITY OF SUCH DAMAGE.
+
+
+import numpy as np
+import sys
+
+
+
+
[docs]def exponents(fnow, current_grad): + exps = [np.abs(np.float(fnow)), current_grad] + return np.sign(exps) * np.log10(exps).astype(int) +
+
[docs]def SCG(f, gradf, x, optargs=(), maxiters=500, max_f_eval=np.inf, display=True, xtol=None, ftol=None, gtol=None): + """ + Optimisation through Scaled Conjugate Gradients (SCG) + + f: the objective function + gradf : the gradient function (should return a 1D np.ndarray) + x : the initial condition + + Returns + x the optimal value for x + flog : a list of all the objective values + function_eval number of fn evaluations + status: string describing convergence status + """ + if xtol is None: + xtol = 1e-6 + if ftol is None: + ftol = 1e-6 + if gtol is None: + gtol = 1e-5 + + sigma0 = 1.0e-7 + fold = f(x, *optargs) # Initial function value. + function_eval = 1 + fnow = fold + gradnew = gradf(x, *optargs) # Initial gradient. + #if any(np.isnan(gradnew)): + # raise UnexpectedInfOrNan, "Gradient contribution resulted in a NaN value" + current_grad = np.dot(gradnew, gradnew) + gradold = gradnew.copy() + d = -gradnew # Initial search direction. + success = True # Force calculation of directional derivs. + nsuccess = 0 # nsuccess counts number of successes. + beta = 1.0 # Initial scale parameter. + betamin = 1.0e-15 # Lower bound on scale. + betamax = 1.0e15 # Upper bound on scale. + status = "Not converged" + + flog = [fold] + + iteration = 0 + + len_maxiters = len(str(maxiters)) + if display: + print ' {0:{mi}s} {1:11s} {2:11s} {3:11s}'.format("I", "F", "Scale", "|g|", mi=len_maxiters) + exps = exponents(fnow, current_grad) + p_iter = iteration + + # Main optimization loop. + while iteration < maxiters: + + # Calculate first and second directional derivatives. + if success: + mu = np.dot(d, gradnew) + if mu >= 0: + d = -gradnew + mu = np.dot(d, gradnew) + kappa = np.dot(d, d) + sigma = sigma0 / np.sqrt(kappa) + xplus = x + sigma * d + gplus = gradf(xplus, *optargs) + theta = np.dot(d, (gplus - gradnew)) / sigma + + # Increase effective curvature and evaluate step size alpha. + delta = theta + beta * kappa + if delta <= 0: + delta = beta * kappa + beta = beta - theta / kappa + + alpha = -mu / delta + + # Calculate the comparison ratio. + xnew = x + alpha * d + fnew = f(xnew, *optargs) + function_eval += 1 + +# if function_eval >= max_f_eval: +# status = "maximum number of function evaluations exceeded" +# break +# return x, flog, function_eval, status + + Delta = 2.*(fnew - fold) / (alpha * mu) + if Delta >= 0.: + success = True + nsuccess += 1 + x = xnew + fnow = fnew + else: + success = False + fnow = fold + + # Store relevant variables + flog.append(fnow) # Current function value + + iteration += 1 + if display: + print_out(len_maxiters, fnow, current_grad, beta, iteration) + n_exps = exponents(fnow, current_grad) + if iteration - p_iter >= 20 * np.random.rand(): + a = iteration >= p_iter * 2.78 + b = np.any(n_exps < exps) + if a or b: + p_iter = iteration + print '' + if b: + exps = n_exps + + if success: + # Test for termination + + if (np.abs(fnew - fold) < ftol): + status = 'converged - relative reduction in objective' + break +# return x, flog, function_eval, status + elif (np.max(np.abs(alpha * d)) < xtol): + status = 'converged - relative stepsize' + break + else: + # Update variables for new position + gradold = gradnew + gradnew = gradf(x, *optargs) + current_grad = np.dot(gradnew, gradnew) + fold = fnew + # If the gradient is zero then we are done. + if current_grad <= gtol: + status = 'converged - relative reduction in gradient' + break + # return x, flog, function_eval, status + + # Adjust beta according to comparison ratio. + if Delta < 0.25: + beta = min(4.0 * beta, betamax) + if Delta > 0.75: + beta = max(0.25 * beta, betamin) + + # Update search direction using Polak-Ribiere formula, or re-start + # in direction of negative gradient after nparams steps. + if nsuccess == x.size: + d = -gradnew + beta = 1. # This is not in the original paper + nsuccess = 0 + elif success: + Gamma = np.dot(gradold - gradnew, gradnew) / (mu) + d = Gamma * d - gradnew + else: + # If we get here, then we haven't terminated in the given number of + # iterations. + status = "maxiter exceeded" + + if display: + print_out(len_maxiters, fnow, current_grad, beta, iteration) + print "" + print status + return x, flog, function_eval, status
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/inference/optimization/stochastics.html b/doc/_build/html/_modules/GPy/inference/optimization/stochastics.html new file mode 100644 index 00000000..6f5292f8 --- /dev/null +++ b/doc/_build/html/_modules/GPy/inference/optimization/stochastics.html @@ -0,0 +1,150 @@ + + + + + + + + GPy.inference.optimization.stochastics — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.inference.optimization.stochastics

+# Copyright (c) 2012-2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
[docs]class StochasticStorage(object): + ''' + This is a container for holding the stochastic parameters, + such as subset indices or step length and so on. + ''' + def __init__(self, model): + """ + Initialize this stochastic container using the given model + """ + +
[docs] def do_stochastics(self): + """ + Update the internal state to the next batch of the stochastic + descent algorithm. + """ + pass +
+
[docs] def reset(self): + """ + Reset the state of this stochastics generator. + """ +
+
[docs]class SparseGPMissing(StochasticStorage): + def __init__(self, model, batchsize=1): + """ + Here we want to loop over all dimensions everytime. + Thus, we can just make sure the loop goes over self.d every + time. + """ + self.d = xrange(model.Y_normalized.shape[1]) +
+
[docs]class SparseGPStochastics(StochasticStorage): + """ + For the sparse gp we need to store the dimension we are in, + and the indices corresponding to those + """ + def __init__(self, model, batchsize=1): + self.batchsize = batchsize + self.output_dim = model.Y.shape[1] + self.reset() + self.do_stochastics() + +
[docs] def do_stochastics(self): + if self.batchsize == 1: + self.current_dim = (self.current_dim+1)%self.output_dim + self.d = [self.current_dim] + else: + import numpy as np + self.d = np.random.choice(self.output_dim, size=self.batchsize, replace=False) +
+
[docs] def reset(self): + self.current_dim = -1 + self.d = None
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/ODE_UY.html b/doc/_build/html/_modules/GPy/kern/_src/ODE_UY.html new file mode 100644 index 00000000..98849cda --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/ODE_UY.html @@ -0,0 +1,375 @@ + + + + + + + + GPy.kern._src.ODE_UY — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.ODE_UY

+# Copyright (c) 2013, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from kern import Kern
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+import numpy as np
+from independent_outputs import index_to_slices
+
+
[docs]class ODE_UY(Kern): + def __init__(self, input_dim, variance_U=3., variance_Y=1., lengthscale_U=1., lengthscale_Y=1., active_dims=None, name='ode_uy'): + assert input_dim ==2, "only defined for 2 input dims" + super(ODE_UY, self).__init__(input_dim, active_dims, name) + + self.variance_Y = Param('variance_Y', variance_Y, Logexp()) + self.variance_U = Param('variance_U', variance_Y, Logexp()) + self.lengthscale_Y = Param('lengthscale_Y', lengthscale_Y, Logexp()) + self.lengthscale_U = Param('lengthscale_U', lengthscale_Y, Logexp()) + + self.link_parameters(self.variance_Y, self.variance_U, self.lengthscale_Y, self.lengthscale_U) + +
[docs] def K(self, X, X2=None): + # model : a * dy/dt + b * y = U + #lu=sqrt(3)/theta1 ly=1/theta2 theta2= a/b :thetay sigma2=1/(2ab) :sigmay + + X,slices = X[:,:-1],index_to_slices(X[:,-1]) + if X2 is None: + X2,slices2 = X,slices + K = np.zeros((X.shape[0], X.shape[0])) + else: + X2,slices2 = X2[:,:-1],index_to_slices(X2[:,-1]) + K = np.zeros((X.shape[0], X2.shape[0])) + + + #rdist = X[:,0][:,None] - X2[:,0][:,None].T + rdist = X - X2.T + ly=1/self.lengthscale_Y + lu=np.sqrt(3)/self.lengthscale_U + #iu=self.input_lengthU #dimention of U + Vu=self.variance_U + Vy=self.variance_Y + #Vy=ly/2 + #stop + + + # kernel for kuu matern3/2 + kuu = lambda dist:Vu * (1 + lu* np.abs(dist)) * np.exp(-lu * np.abs(dist)) + + # kernel for kyy + k1 = lambda dist:np.exp(-ly*np.abs(dist))*(2*lu+ly)/(lu+ly)**2 + k2 = lambda dist:(np.exp(-lu*dist)*(ly-2*lu+lu*ly*dist-lu**2*dist) + np.exp(-ly*dist)*(2*lu-ly) ) / (ly-lu)**2 + k3 = lambda dist:np.exp(-lu*dist) * ( (1+lu*dist)/(lu+ly) + (lu)/(lu+ly)**2 ) + kyy = lambda dist:Vu*Vy*(k1(dist) + k2(dist) + k3(dist)) + + + # cross covariance function + kyu3 = lambda dist:np.exp(-lu*dist)/(lu+ly)*(1+lu*(dist+1/(lu+ly))) + #kyu3 = lambda dist: 0 + + k1cros = lambda dist:np.exp(ly*dist)/(lu-ly) * ( 1- np.exp( (lu-ly)*dist) + lu* ( dist*np.exp( (lu-ly)*dist ) + (1- np.exp( (lu-ly)*dist ) ) /(lu-ly) ) ) + #k1cros = lambda dist:0 + + k2cros = lambda dist:np.exp(ly*dist)*( 1/(lu+ly) + lu/(lu+ly)**2 ) + #k2cros = lambda dist:0 + + Vyu=np.sqrt(Vy*ly*2) + + # cross covariance kuy + kuyp = lambda dist:Vu*Vyu*(kyu3(dist)) #t>0 kuy + kuyn = lambda dist:Vu*Vyu*(k1cros(dist)+k2cros(dist)) #t<0 kuy + # cross covariance kyu + kyup = lambda dist:Vu*Vyu*(k1cros(-dist)+k2cros(-dist)) #t>0 kyu + kyun = lambda dist:Vu*Vyu*(kyu3(-dist)) #t<0 kyu + + + for i, s1 in enumerate(slices): + for j, s2 in enumerate(slices2): + for ss1 in s1: + for ss2 in s2: + if i==0 and j==0: + K[ss1,ss2] = kuu(np.abs(rdist[ss1,ss2])) + elif i==0 and j==1: + #K[ss1,ss2]= np.where( rdist[ss1,ss2]>0 , kuyp(np.abs(rdist[ss1,ss2])), kuyn(np.abs(rdist[ss1,ss2]) ) ) + K[ss1,ss2]= np.where( rdist[ss1,ss2]>0 , kuyp(rdist[ss1,ss2]), kuyn(rdist[ss1,ss2] ) ) + elif i==1 and j==1: + K[ss1,ss2] = kyy(np.abs(rdist[ss1,ss2])) + else: + #K[ss1,ss2]= 0 + #K[ss1,ss2]= np.where( rdist[ss1,ss2]>0 , kyup(np.abs(rdist[ss1,ss2])), kyun(np.abs(rdist[ss1,ss2]) ) ) + K[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kyup(rdist[ss1,ss2]), kyun(rdist[ss1,ss2] ) ) + return K + + +
+
[docs] def Kdiag(self, X): + """Compute the diagonal of the covariance matrix associated to X.""" + Kdiag = np.zeros(X.shape[0]) + ly=1/self.lengthscale_Y + lu=np.sqrt(3)/self.lengthscale_U + + Vu = self.variance_U + Vy=self.variance_Y + + k1 = (2*lu+ly)/(lu+ly)**2 + k2 = (ly-2*lu + 2*lu-ly ) / (ly-lu)**2 + k3 = 1/(lu+ly) + (lu)/(lu+ly)**2 + + slices = index_to_slices(X[:,-1]) + + for i, ss1 in enumerate(slices): + for s1 in ss1: + if i==0: + Kdiag[s1]+= self.variance_U + elif i==1: + Kdiag[s1]+= Vu*Vy*(k1+k2+k3) + else: + raise ValueError, "invalid input/output index" + #Kdiag[slices[0][0]]+= self.variance_U #matern32 diag + #Kdiag[slices[1][0]]+= self.variance_U*self.variance_Y*(k1+k2+k3) # diag + return Kdiag + +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + """derivative of the covariance matrix with respect to the parameters.""" + X,slices = X[:,:-1],index_to_slices(X[:,-1]) + if X2 is None: + X2,slices2 = X,slices + else: + X2,slices2 = X2[:,:-1],index_to_slices(X2[:,-1]) + #rdist = X[:,0][:,None] - X2[:,0][:,None].T + + rdist = X - X2.T + ly=1/self.lengthscale_Y + lu=np.sqrt(3)/self.lengthscale_U + + Vu=self.variance_U + Vy=self.variance_Y + Vyu = np.sqrt(Vy*ly*2) + dVdly = 0.5/np.sqrt(ly)*np.sqrt(2*Vy) + dVdVy = 0.5/np.sqrt(Vy)*np.sqrt(2*ly) + + rd=rdist.shape + dktheta1 = np.zeros(rd) + dktheta2 = np.zeros(rd) + dkUdvar = np.zeros(rd) + dkYdvar = np.zeros(rd) + + # dk dtheta for UU + UUdtheta1 = lambda dist: np.exp(-lu* dist)*dist + (-dist)*np.exp(-lu* dist)*(1+lu*dist) + UUdtheta2 = lambda dist: 0 + #UUdvar = lambda dist: (1 + lu*dist)*np.exp(-lu*dist) + UUdvar = lambda dist: (1 + lu* np.abs(dist)) * np.exp(-lu * np.abs(dist)) + + # dk dtheta for YY + + dk1theta1 = lambda dist: np.exp(-ly*dist)*2*(-lu)/(lu+ly)**3 + + dk2theta1 = lambda dist: (1.0)*( + np.exp(-lu*dist)*dist*(-ly+2*lu-lu*ly*dist+dist*lu**2)*(ly-lu)**(-2) + np.exp(-lu*dist)*(-2+ly*dist-2*dist*lu)*(ly-lu)**(-2) + +np.exp(-dist*lu)*(ly-2*lu+ly*lu*dist-dist*lu**2)*2*(ly-lu)**(-3) + +np.exp(-dist*ly)*2*(ly-lu)**(-2) + +np.exp(-dist*ly)*2*(2*lu-ly)*(ly-lu)**(-3) + ) + + dk3theta1 = lambda dist: np.exp(-dist*lu)*(lu+ly)**(-2)*((2*lu+ly+dist*lu**2+lu*ly*dist)*(-dist-2/(lu+ly))+2+2*lu*dist+ly*dist) + + #dktheta1 = lambda dist: self.variance_U*self.variance_Y*(dk1theta1+dk2theta1+dk3theta1) + + + + + dk1theta2 = lambda dist: np.exp(-ly*dist) * ((lu+ly)**(-2)) * ( (-dist)*(2*lu+ly) + 1 + (-2)*(2*lu+ly)/(lu+ly) ) + + dk2theta2 =lambda dist: 1*( + np.exp(-dist*lu)*(ly-lu)**(-2) * ( 1+lu*dist+(-2)*(ly-2*lu+lu*ly*dist-dist*lu**2)*(ly-lu)**(-1) ) + +np.exp(-dist*ly)*(ly-lu)**(-2) * ( (-dist)*(2*lu-ly) -1+(2*lu-ly)*(-2)*(ly-lu)**(-1) ) + ) + + dk3theta2 = lambda dist: np.exp(-dist*lu) * (-3*lu-ly-dist*lu**2-lu*ly*dist)/(lu+ly)**3 + + #dktheta2 = lambda dist: self.variance_U*self.variance_Y*(dk1theta2 + dk2theta2 +dk3theta2) + + # kyy kernel + + k1 = lambda dist: np.exp(-ly*dist)*(2*lu+ly)/(lu+ly)**2 + k2 = lambda dist: (np.exp(-lu*dist)*(ly-2*lu+lu*ly*dist-lu**2*dist) + np.exp(-ly*dist)*(2*lu-ly) ) / (ly-lu)**2 + k3 = lambda dist: np.exp(-lu*dist) * ( (1+lu*dist)/(lu+ly) + (lu)/(lu+ly)**2 ) + #dkdvar = k1+k2+k3 + + + + # cross covariance function + kyu3 = lambda dist:np.exp(-lu*dist)/(lu+ly)*(1+lu*(dist+1/(lu+ly))) + + k1cros = lambda dist:np.exp(ly*dist)/(lu-ly) * ( 1- np.exp( (lu-ly)*dist) + lu* ( dist*np.exp( (lu-ly)*dist ) + (1- np.exp( (lu-ly)*dist ) ) /(lu-ly) ) ) + + k2cros = lambda dist:np.exp(ly*dist)*( 1/(lu+ly) + lu/(lu+ly)**2 ) + # cross covariance kuy + kuyp = lambda dist:(kyu3(dist)) #t>0 kuy + kuyn = lambda dist:(k1cros(dist)+k2cros(dist)) #t<0 kuy + # cross covariance kyu + kyup = lambda dist:(k1cros(-dist)+k2cros(-dist)) #t>0 kyu + kyun = lambda dist:(kyu3(-dist)) #t<0 kyu + + # dk dtheta for UY + + + dkyu3dtheta2 = lambda dist: np.exp(-lu*dist) * ( (-1)*(lu+ly)**(-2)*(1+lu*dist+lu*(lu+ly)**(-1)) + (lu+ly)**(-1)*(-lu)*(lu+ly)**(-2) ) + dkyu3dtheta1 = lambda dist: np.exp(-lu*dist)*(lu+ly)**(-1)* ( (-dist)*(1+dist*lu+lu*(lu+ly)**(-1)) -\ + (lu+ly)**(-1)*(1+dist*lu+lu*(lu+ly)**(-1)) +dist+(lu+ly)**(-1)-lu*(lu+ly)**(-2) ) + + dkcros2dtheta1 = lambda dist: np.exp(ly*dist)* ( -(ly+lu)**(-2) + (ly+lu)**(-2) + (-2)*lu*(lu+ly)**(-3) ) + dkcros2dtheta2 = lambda dist: np.exp(ly*dist)*dist* ( (ly+lu)**(-1) + lu*(lu+ly)**(-2) ) + \ + np.exp(ly*dist)*( -(lu+ly)**(-2) + lu*(-2)*(lu+ly)**(-3) ) + + dkcros1dtheta1 = lambda dist: np.exp(ly*dist)*( -(lu-ly)**(-2)*( 1-np.exp((lu-ly)*dist) + lu*dist*np.exp((lu-ly)*dist)+ \ + lu*(1-np.exp((lu-ly)*dist))/(lu-ly) ) + (lu-ly)**(-1)*( -np.exp( (lu-ly)*dist )*dist + dist*np.exp( (lu-ly)*dist)+\ + lu*dist**2*np.exp((lu-ly)*dist)+(1-np.exp((lu-ly)*dist))/(lu-ly) - lu*np.exp((lu-ly)*dist)*dist/(lu-ly) -\ + lu*(1-np.exp((lu-ly)*dist))/(lu-ly)**2 ) ) + + dkcros1dtheta2 = lambda t: np.exp(ly*t)*t/(lu-ly)*( 1-np.exp((lu-ly)*t) +lu*t*np.exp((lu-ly)*t)+\ + lu*(1-np.exp((lu-ly)*t))/(lu-ly) )+\ + np.exp(ly*t)/(lu-ly)**2* ( 1-np.exp((lu-ly)*t) +lu*t*np.exp((lu-ly)*t) + lu*( 1-np.exp((lu-ly)*t) )/(lu-ly) )+\ + np.exp(ly*t)/(lu-ly)*( np.exp((lu-ly)*t)*t -lu*t*t*np.exp((lu-ly)*t) +lu*t*np.exp((lu-ly)*t)/(lu-ly)+\ + lu*( 1-np.exp((lu-ly)*t) )/(lu-ly)**2 ) + + dkuypdtheta1 = lambda dist:(dkyu3dtheta1(dist)) #t>0 kuy + dkuyndtheta1 = lambda dist:(dkcros1dtheta1(dist)+dkcros2dtheta1(dist)) #t<0 kuy + # cross covariance kyu + dkyupdtheta1 = lambda dist:(dkcros1dtheta1(-dist)+dkcros2dtheta1(-dist)) #t>0 kyu + dkyundtheta1 = lambda dist:(dkyu3dtheta1(-dist)) #t<0 kyu + + dkuypdtheta2 = lambda dist:(dkyu3dtheta2(dist)) #t>0 kuy + dkuyndtheta2 = lambda dist:(dkcros1dtheta2(dist)+dkcros2dtheta2(dist)) #t<0 kuy + # cross covariance kyu + dkyupdtheta2 = lambda dist:(dkcros1dtheta2(-dist)+dkcros2dtheta2(-dist)) #t>0 kyu + dkyundtheta2 = lambda dist:(dkyu3dtheta2(-dist)) #t<0 kyu + + + for i, s1 in enumerate(slices): + for j, s2 in enumerate(slices2): + for ss1 in s1: + for ss2 in s2: + if i==0 and j==0: + #target[ss1,ss2] = kuu(np.abs(rdist[ss1,ss2])) + dktheta1[ss1,ss2] = Vu*UUdtheta1(np.abs(rdist[ss1,ss2])) + dktheta2[ss1,ss2] = 0 + dkUdvar[ss1,ss2] = UUdvar(np.abs(rdist[ss1,ss2])) + dkYdvar[ss1,ss2] = 0 + elif i==0 and j==1: + ########target[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kuyp(np.abs(rdist[ss1,ss2])), kuyn(np.abs(rdist[s1[0],s2[0]]) ) ) + #np.where( rdist[ss1,ss2]>0 , kuyp(np.abs(rdist[ss1,ss2])), kuyn(np.abs(rdist[s1[0],s2[0]]) ) ) + #dktheta1[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , self.variance_U*self.variance_Y*dkcrtheta1(np.abs(rdist[ss1,ss2])) ,self.variance_U*self.variance_Y*(dk1theta1(np.abs(rdist[ss1,ss2]))+dk2theta1(np.abs(rdist[ss1,ss2]))) ) + #dktheta2[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , self.variance_U*self.variance_Y*dkcrtheta2(np.abs(rdist[ss1,ss2])) ,self.variance_U*self.variance_Y*(dk1theta2(np.abs(rdist[ss1,ss2]))+dk2theta2(np.abs(rdist[ss1,ss2]))) ) + dktheta1[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*Vyu*dkuypdtheta1(rdist[ss1,ss2]),Vu*Vyu*dkuyndtheta1(rdist[ss1,ss2]) ) + dkUdvar[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vyu*kuyp(rdist[ss1,ss2]), Vyu* kuyn(rdist[ss1,ss2]) ) + dktheta2[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*Vyu*dkuypdtheta2(rdist[ss1,ss2])+Vu*dVdly*kuyp(rdist[ss1,ss2]),Vu*Vyu*dkuyndtheta2(rdist[ss1,ss2])+Vu*dVdly*kuyn(rdist[ss1,ss2]) ) + dkYdvar[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*dVdVy*kuyp(rdist[ss1,ss2]), Vu*dVdVy* kuyn(rdist[ss1,ss2]) ) + elif i==1 and j==1: + #target[ss1,ss2] = kyy(np.abs(rdist[ss1,ss2])) + dktheta1[ss1,ss2] = self.variance_U*self.variance_Y*(dk1theta1(np.abs(rdist[ss1,ss2]))+dk2theta1(np.abs(rdist[ss1,ss2]))+dk3theta1(np.abs(rdist[ss1,ss2]))) + dktheta2[ss1,ss2] = self.variance_U*self.variance_Y*(dk1theta2(np.abs(rdist[ss1,ss2])) + dk2theta2(np.abs(rdist[ss1,ss2])) +dk3theta2(np.abs(rdist[ss1,ss2]))) + dkUdvar[ss1,ss2] = self.variance_Y*(k1(np.abs(rdist[ss1,ss2]))+k2(np.abs(rdist[ss1,ss2]))+k3(np.abs(rdist[ss1,ss2])) ) + dkYdvar[ss1,ss2] = self.variance_U*(k1(np.abs(rdist[ss1,ss2]))+k2(np.abs(rdist[ss1,ss2]))+k3(np.abs(rdist[ss1,ss2])) ) + else: + #######target[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kyup(np.abs(rdist[ss1,ss2])), kyun(np.abs(rdist[s1[0],s2[0]]) ) ) + #dktheta1[ss1,ss2] = np.where( rdist[ss1,ss2]>0 ,self.variance_U*self.variance_Y*(dk1theta1(np.abs(rdist[ss1,ss2]))+dk2theta1(np.abs(rdist[ss1,ss2]))) , self.variance_U*self.variance_Y*dkcrtheta1(np.abs(rdist[ss1,ss2])) ) + #dktheta2[ss1,ss2] = np.where( rdist[ss1,ss2]>0 ,self.variance_U*self.variance_Y*(dk1theta2(np.abs(rdist[ss1,ss2]))+dk2theta2(np.abs(rdist[ss1,ss2]))) , self.variance_U*self.variance_Y*dkcrtheta2(np.abs(rdist[ss1,ss2])) ) + dktheta1[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*Vyu*dkyupdtheta1(rdist[ss1,ss2]),Vu*Vyu*dkyundtheta1(rdist[ss1,ss2]) ) + dkUdvar[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vyu*kyup(rdist[ss1,ss2]),Vyu*kyun(rdist[ss1,ss2])) + dktheta2[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*Vyu*dkyupdtheta2(rdist[ss1,ss2])+Vu*dVdly*kyup(rdist[ss1,ss2]),Vu*Vyu*dkyundtheta2(rdist[ss1,ss2])+Vu*dVdly*kyun(rdist[ss1,ss2]) ) + dkYdvar[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*dVdVy*kyup(rdist[ss1,ss2]), Vu*dVdVy*kyun(rdist[ss1,ss2])) + + #stop + self.variance_U.gradient = np.sum(dkUdvar * dL_dK) # Vu + + self.variance_Y.gradient = np.sum(dkYdvar * dL_dK) # Vy + + self.lengthscale_U.gradient = np.sum(dktheta1*(-np.sqrt(3)*self.lengthscale_U**(-2))* dL_dK) #lu + + self.lengthscale_Y.gradient = np.sum(dktheta2*(-self.lengthscale_Y**(-2)) * dL_dK) #ly +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/ODE_UYC.html b/doc/_build/html/_modules/GPy/kern/_src/ODE_UYC.html new file mode 100644 index 00000000..9f32a651 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/ODE_UYC.html @@ -0,0 +1,383 @@ + + + + + + + + GPy.kern._src.ODE_UYC — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.ODE_UYC

+# Copyright (c) 2013, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from kern import Kern
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+import numpy as np
+from independent_outputs import index_to_slices
+
+
[docs]class ODE_UYC(Kern): + def __init__(self, input_dim, variance_U=3., variance_Y=1., lengthscale_U=1., lengthscale_Y=1., ubias =1. ,active_dims=None, name='ode_uyc'): + assert input_dim ==2, "only defined for 2 input dims" + super(ODE_UYC, self).__init__(input_dim, active_dims, name) + + self.variance_Y = Param('variance_Y', variance_Y, Logexp()) + self.variance_U = Param('variance_U', variance_U, Logexp()) + self.lengthscale_Y = Param('lengthscale_Y', lengthscale_Y, Logexp()) + self.lengthscale_U = Param('lengthscale_U', lengthscale_U, Logexp()) + self.ubias = Param('ubias', ubias, Logexp()) + + self.add_parameters(self.variance_Y, self.variance_U, self.lengthscale_Y, self.lengthscale_U, self.ubias) + +
[docs] def K(self, X, X2=None): + # model : a * dy/dt + b * y = U + #lu=sqrt(3)/theta1 ly=1/theta2 theta2= a/b :thetay sigma2=1/(2ab) :sigmay + + X,slices = X[:,:-1],index_to_slices(X[:,-1]) + if X2 is None: + X2,slices2 = X,slices + K = np.zeros((X.shape[0], X.shape[0])) + else: + X2,slices2 = X2[:,:-1],index_to_slices(X2[:,-1]) + K = np.zeros((X.shape[0], X2.shape[0])) + + #stop + #rdist = X[:,0][:,None] - X2[:,0][:,None].T + rdist = X - X2.T + ly=1/self.lengthscale_Y + lu=np.sqrt(3)/self.lengthscale_U + #iu=self.input_lengthU #dimention of U + Vu=self.variance_U + Vy=self.variance_Y + #Vy=ly/2 + #stop + + + # kernel for kuu matern3/2 + kuu = lambda dist:Vu * (1 + lu* np.abs(dist)) * np.exp(-lu * np.abs(dist)) +self.ubias + + # kernel for kyy + k1 = lambda dist:np.exp(-ly*np.abs(dist))*(2*lu+ly)/(lu+ly)**2 + k2 = lambda dist:(np.exp(-lu*dist)*(ly-2*lu+lu*ly*dist-lu**2*dist) + np.exp(-ly*dist)*(2*lu-ly) ) / (ly-lu)**2 + k3 = lambda dist:np.exp(-lu*dist) * ( (1+lu*dist)/(lu+ly) + (lu)/(lu+ly)**2 ) + kyy = lambda dist:Vu*Vy*(k1(dist) + k2(dist) + k3(dist)) + + + # cross covariance function + kyu3 = lambda dist:np.exp(-lu*dist)/(lu+ly)*(1+lu*(dist+1/(lu+ly))) + #kyu3 = lambda dist: 0 + + k1cros = lambda dist:np.exp(ly*dist)/(lu-ly) * ( 1- np.exp( (lu-ly)*dist) + lu* ( dist*np.exp( (lu-ly)*dist ) + (1- np.exp( (lu-ly)*dist ) ) /(lu-ly) ) ) + #k1cros = lambda dist:0 + + k2cros = lambda dist:np.exp(ly*dist)*( 1/(lu+ly) + lu/(lu+ly)**2 ) + #k2cros = lambda dist:0 + + Vyu=np.sqrt(Vy*ly*2) + + # cross covariance kuy + kuyp = lambda dist:Vu*Vyu*(kyu3(dist)) #t>0 kuy + kuyn = lambda dist:Vu*Vyu*(k1cros(dist)+k2cros(dist)) #t<0 kuy + # cross covariance kyu + kyup = lambda dist:Vu*Vyu*(k1cros(-dist)+k2cros(-dist)) #t>0 kyu + kyun = lambda dist:Vu*Vyu*(kyu3(-dist)) #t<0 kyu + + + for i, s1 in enumerate(slices): + for j, s2 in enumerate(slices2): + for ss1 in s1: + for ss2 in s2: + if i==0 and j==0: + K[ss1,ss2] = kuu(np.abs(rdist[ss1,ss2])) + elif i==0 and j==1: + #K[ss1,ss2]= np.where( rdist[ss1,ss2]>0 , kuyp(np.abs(rdist[ss1,ss2])), kuyn(np.abs(rdist[ss1,ss2]) ) ) + K[ss1,ss2]= np.where( rdist[ss1,ss2]>0 , kuyp(rdist[ss1,ss2]), kuyn(rdist[ss1,ss2] ) ) + elif i==1 and j==1: + K[ss1,ss2] = kyy(np.abs(rdist[ss1,ss2])) + else: + #K[ss1,ss2]= 0 + #K[ss1,ss2]= np.where( rdist[ss1,ss2]>0 , kyup(np.abs(rdist[ss1,ss2])), kyun(np.abs(rdist[ss1,ss2]) ) ) + K[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kyup(rdist[ss1,ss2]), kyun(rdist[ss1,ss2] ) ) + return K + + +
+
[docs] def Kdiag(self, X): + """Compute the diagonal of the covariance matrix associated to X.""" + Kdiag = np.zeros(X.shape[0]) + ly=1/self.lengthscale_Y + lu=np.sqrt(3)/self.lengthscale_U + + Vu = self.variance_U + Vy=self.variance_Y + + k1 = (2*lu+ly)/(lu+ly)**2 + k2 = (ly-2*lu + 2*lu-ly ) / (ly-lu)**2 + k3 = 1/(lu+ly) + (lu)/(lu+ly)**2 + + slices = index_to_slices(X[:,-1]) + + for i, ss1 in enumerate(slices): + for s1 in ss1: + if i==0: + Kdiag[s1]+= self.variance_U + self.ubias + elif i==1: + Kdiag[s1]+= Vu*Vy*(k1+k2+k3) + else: + raise ValueError, "invalid input/output index" + #Kdiag[slices[0][0]]+= self.variance_U #matern32 diag + #Kdiag[slices[1][0]]+= self.variance_U*self.variance_Y*(k1+k2+k3) # diag + return Kdiag + +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + """derivative of the covariance matrix with respect to the parameters.""" + X,slices = X[:,:-1],index_to_slices(X[:,-1]) + if X2 is None: + X2,slices2 = X,slices + else: + X2,slices2 = X2[:,:-1],index_to_slices(X2[:,-1]) + #rdist = X[:,0][:,None] - X2[:,0][:,None].T + + rdist = X - X2.T + ly=1/self.lengthscale_Y + lu=np.sqrt(3)/self.lengthscale_U + + Vu=self.variance_U + Vy=self.variance_Y + Vyu = np.sqrt(Vy*ly*2) + dVdly = 0.5/np.sqrt(ly)*np.sqrt(2*Vy) + dVdVy = 0.5/np.sqrt(Vy)*np.sqrt(2*ly) + + rd=rdist.shape[0] + dktheta1 = np.zeros([rd,rd]) + dktheta2 = np.zeros([rd,rd]) + dkUdvar = np.zeros([rd,rd]) + dkYdvar = np.zeros([rd,rd]) + + dkdubias = np.zeros([rd,rd]) + + # dk dtheta for UU + UUdtheta1 = lambda dist: np.exp(-lu* dist)*dist + (-dist)*np.exp(-lu* dist)*(1+lu*dist) + UUdtheta2 = lambda dist: 0 + #UUdvar = lambda dist: (1 + lu*dist)*np.exp(-lu*dist) + UUdvar = lambda dist: (1 + lu* np.abs(dist)) * np.exp(-lu * np.abs(dist)) + + # dk dtheta for YY + + dk1theta1 = lambda dist: np.exp(-ly*dist)*2*(-lu)/(lu+ly)**3 + + dk2theta1 = lambda dist: (1.0)*( + np.exp(-lu*dist)*dist*(-ly+2*lu-lu*ly*dist+dist*lu**2)*(ly-lu)**(-2) + np.exp(-lu*dist)*(-2+ly*dist-2*dist*lu)*(ly-lu)**(-2) + +np.exp(-dist*lu)*(ly-2*lu+ly*lu*dist-dist*lu**2)*2*(ly-lu)**(-3) + +np.exp(-dist*ly)*2*(ly-lu)**(-2) + +np.exp(-dist*ly)*2*(2*lu-ly)*(ly-lu)**(-3) + ) + + dk3theta1 = lambda dist: np.exp(-dist*lu)*(lu+ly)**(-2)*((2*lu+ly+dist*lu**2+lu*ly*dist)*(-dist-2/(lu+ly))+2+2*lu*dist+ly*dist) + + #dktheta1 = lambda dist: self.variance_U*self.variance_Y*(dk1theta1+dk2theta1+dk3theta1) + + + + + dk1theta2 = lambda dist: np.exp(-ly*dist) * ((lu+ly)**(-2)) * ( (-dist)*(2*lu+ly) + 1 + (-2)*(2*lu+ly)/(lu+ly) ) + + dk2theta2 =lambda dist: 1*( + np.exp(-dist*lu)*(ly-lu)**(-2) * ( 1+lu*dist+(-2)*(ly-2*lu+lu*ly*dist-dist*lu**2)*(ly-lu)**(-1) ) + +np.exp(-dist*ly)*(ly-lu)**(-2) * ( (-dist)*(2*lu-ly) -1+(2*lu-ly)*(-2)*(ly-lu)**(-1) ) + ) + + dk3theta2 = lambda dist: np.exp(-dist*lu) * (-3*lu-ly-dist*lu**2-lu*ly*dist)/(lu+ly)**3 + + #dktheta2 = lambda dist: self.variance_U*self.variance_Y*(dk1theta2 + dk2theta2 +dk3theta2) + + # kyy kernel + + k1 = lambda dist: np.exp(-ly*dist)*(2*lu+ly)/(lu+ly)**2 + k2 = lambda dist: (np.exp(-lu*dist)*(ly-2*lu+lu*ly*dist-lu**2*dist) + np.exp(-ly*dist)*(2*lu-ly) ) / (ly-lu)**2 + k3 = lambda dist: np.exp(-lu*dist) * ( (1+lu*dist)/(lu+ly) + (lu)/(lu+ly)**2 ) + #dkdvar = k1+k2+k3 + + + + # cross covariance function + kyu3 = lambda dist:np.exp(-lu*dist)/(lu+ly)*(1+lu*(dist+1/(lu+ly))) + + k1cros = lambda dist:np.exp(ly*dist)/(lu-ly) * ( 1- np.exp( (lu-ly)*dist) + lu* ( dist*np.exp( (lu-ly)*dist ) + (1- np.exp( (lu-ly)*dist ) ) /(lu-ly) ) ) + + k2cros = lambda dist:np.exp(ly*dist)*( 1/(lu+ly) + lu/(lu+ly)**2 ) + # cross covariance kuy + kuyp = lambda dist:(kyu3(dist)) #t>0 kuy + kuyn = lambda dist:(k1cros(dist)+k2cros(dist)) #t<0 kuy + # cross covariance kyu + kyup = lambda dist:(k1cros(-dist)+k2cros(-dist)) #t>0 kyu + kyun = lambda dist:(kyu3(-dist)) #t<0 kyu + + # dk dtheta for UY + + + dkyu3dtheta2 = lambda dist: np.exp(-lu*dist) * ( (-1)*(lu+ly)**(-2)*(1+lu*dist+lu*(lu+ly)**(-1)) + (lu+ly)**(-1)*(-lu)*(lu+ly)**(-2) ) + dkyu3dtheta1 = lambda dist: np.exp(-lu*dist)*(lu+ly)**(-1)* ( (-dist)*(1+dist*lu+lu*(lu+ly)**(-1)) -\ + (lu+ly)**(-1)*(1+dist*lu+lu*(lu+ly)**(-1)) +dist+(lu+ly)**(-1)-lu*(lu+ly)**(-2) ) + + dkcros2dtheta1 = lambda dist: np.exp(ly*dist)* ( -(ly+lu)**(-2) + (ly+lu)**(-2) + (-2)*lu*(lu+ly)**(-3) ) + dkcros2dtheta2 = lambda dist: np.exp(ly*dist)*dist* ( (ly+lu)**(-1) + lu*(lu+ly)**(-2) ) + \ + np.exp(ly*dist)*( -(lu+ly)**(-2) + lu*(-2)*(lu+ly)**(-3) ) + + dkcros1dtheta1 = lambda dist: np.exp(ly*dist)*( -(lu-ly)**(-2)*( 1-np.exp((lu-ly)*dist) + lu*dist*np.exp((lu-ly)*dist)+ \ + lu*(1-np.exp((lu-ly)*dist))/(lu-ly) ) + (lu-ly)**(-1)*( -np.exp( (lu-ly)*dist )*dist + dist*np.exp( (lu-ly)*dist)+\ + lu*dist**2*np.exp((lu-ly)*dist)+(1-np.exp((lu-ly)*dist))/(lu-ly) - lu*np.exp((lu-ly)*dist)*dist/(lu-ly) -\ + lu*(1-np.exp((lu-ly)*dist))/(lu-ly)**2 ) ) + + dkcros1dtheta2 = lambda t: np.exp(ly*t)*t/(lu-ly)*( 1-np.exp((lu-ly)*t) +lu*t*np.exp((lu-ly)*t)+\ + lu*(1-np.exp((lu-ly)*t))/(lu-ly) )+\ + np.exp(ly*t)/(lu-ly)**2* ( 1-np.exp((lu-ly)*t) +lu*t*np.exp((lu-ly)*t) + lu*( 1-np.exp((lu-ly)*t) )/(lu-ly) )+\ + np.exp(ly*t)/(lu-ly)*( np.exp((lu-ly)*t)*t -lu*t*t*np.exp((lu-ly)*t) +lu*t*np.exp((lu-ly)*t)/(lu-ly)+\ + lu*( 1-np.exp((lu-ly)*t) )/(lu-ly)**2 ) + + dkuypdtheta1 = lambda dist:(dkyu3dtheta1(dist)) #t>0 kuy + dkuyndtheta1 = lambda dist:(dkcros1dtheta1(dist)+dkcros2dtheta1(dist)) #t<0 kuy + # cross covariance kyu + dkyupdtheta1 = lambda dist:(dkcros1dtheta1(-dist)+dkcros2dtheta1(-dist)) #t>0 kyu + dkyundtheta1 = lambda dist:(dkyu3dtheta1(-dist)) #t<0 kyu + + dkuypdtheta2 = lambda dist:(dkyu3dtheta2(dist)) #t>0 kuy + dkuyndtheta2 = lambda dist:(dkcros1dtheta2(dist)+dkcros2dtheta2(dist)) #t<0 kuy + # cross covariance kyu + dkyupdtheta2 = lambda dist:(dkcros1dtheta2(-dist)+dkcros2dtheta2(-dist)) #t>0 kyu + dkyundtheta2 = lambda dist:(dkyu3dtheta2(-dist)) #t<0 kyu + + + for i, s1 in enumerate(slices): + for j, s2 in enumerate(slices2): + for ss1 in s1: + for ss2 in s2: + if i==0 and j==0: + #target[ss1,ss2] = kuu(np.abs(rdist[ss1,ss2])) + dktheta1[ss1,ss2] = Vu*UUdtheta1(np.abs(rdist[ss1,ss2])) + dktheta2[ss1,ss2] = 0 + dkUdvar[ss1,ss2] = UUdvar(np.abs(rdist[ss1,ss2])) + dkYdvar[ss1,ss2] = 0 + dkdubias[ss1,ss2] = 1 + elif i==0 and j==1: + ########target[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kuyp(np.abs(rdist[ss1,ss2])), kuyn(np.abs(rdist[s1[0],s2[0]]) ) ) + #np.where( rdist[ss1,ss2]>0 , kuyp(np.abs(rdist[ss1,ss2])), kuyn(np.abs(rdist[s1[0],s2[0]]) ) ) + #dktheta1[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , self.variance_U*self.variance_Y*dkcrtheta1(np.abs(rdist[ss1,ss2])) ,self.variance_U*self.variance_Y*(dk1theta1(np.abs(rdist[ss1,ss2]))+dk2theta1(np.abs(rdist[ss1,ss2]))) ) + #dktheta2[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , self.variance_U*self.variance_Y*dkcrtheta2(np.abs(rdist[ss1,ss2])) ,self.variance_U*self.variance_Y*(dk1theta2(np.abs(rdist[ss1,ss2]))+dk2theta2(np.abs(rdist[ss1,ss2]))) ) + dktheta1[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*Vyu*dkuypdtheta1(rdist[ss1,ss2]),Vu*Vyu*dkuyndtheta1(rdist[ss1,ss2]) ) + dkUdvar[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vyu*kuyp(rdist[ss1,ss2]), Vyu* kuyn(rdist[ss1,ss2]) ) + dktheta2[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*Vyu*dkuypdtheta2(rdist[ss1,ss2])+Vu*dVdly*kuyp(rdist[ss1,ss2]),Vu*Vyu*dkuyndtheta2(rdist[ss1,ss2])+Vu*dVdly*kuyn(rdist[ss1,ss2]) ) + dkYdvar[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*dVdVy*kuyp(rdist[ss1,ss2]), Vu*dVdVy* kuyn(rdist[ss1,ss2]) ) + dkdubias[ss1,ss2] = 0 + elif i==1 and j==1: + #target[ss1,ss2] = kyy(np.abs(rdist[ss1,ss2])) + dktheta1[ss1,ss2] = self.variance_U*self.variance_Y*(dk1theta1(np.abs(rdist[ss1,ss2]))+dk2theta1(np.abs(rdist[ss1,ss2]))+dk3theta1(np.abs(rdist[ss1,ss2]))) + dktheta2[ss1,ss2] = self.variance_U*self.variance_Y*(dk1theta2(np.abs(rdist[ss1,ss2])) + dk2theta2(np.abs(rdist[ss1,ss2])) +dk3theta2(np.abs(rdist[ss1,ss2]))) + dkUdvar[ss1,ss2] = self.variance_Y*(k1(np.abs(rdist[ss1,ss2]))+k2(np.abs(rdist[ss1,ss2]))+k3(np.abs(rdist[ss1,ss2])) ) + dkYdvar[ss1,ss2] = self.variance_U*(k1(np.abs(rdist[ss1,ss2]))+k2(np.abs(rdist[ss1,ss2]))+k3(np.abs(rdist[ss1,ss2])) ) + dkdubias[ss1,ss2] = 0 + else: + #######target[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kyup(np.abs(rdist[ss1,ss2])), kyun(np.abs(rdist[s1[0],s2[0]]) ) ) + #dktheta1[ss1,ss2] = np.where( rdist[ss1,ss2]>0 ,self.variance_U*self.variance_Y*(dk1theta1(np.abs(rdist[ss1,ss2]))+dk2theta1(np.abs(rdist[ss1,ss2]))) , self.variance_U*self.variance_Y*dkcrtheta1(np.abs(rdist[ss1,ss2])) ) + #dktheta2[ss1,ss2] = np.where( rdist[ss1,ss2]>0 ,self.variance_U*self.variance_Y*(dk1theta2(np.abs(rdist[ss1,ss2]))+dk2theta2(np.abs(rdist[ss1,ss2]))) , self.variance_U*self.variance_Y*dkcrtheta2(np.abs(rdist[ss1,ss2])) ) + dktheta1[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*Vyu*dkyupdtheta1(rdist[ss1,ss2]),Vu*Vyu*dkyundtheta1(rdist[ss1,ss2]) ) + dkUdvar[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vyu*kyup(rdist[ss1,ss2]),Vyu*kyun(rdist[ss1,ss2])) + dktheta2[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*Vyu*dkyupdtheta2(rdist[ss1,ss2])+Vu*dVdly*kyup(rdist[ss1,ss2]),Vu*Vyu*dkyundtheta2(rdist[ss1,ss2])+Vu*dVdly*kyun(rdist[ss1,ss2]) ) + dkYdvar[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , Vu*dVdVy*kyup(rdist[ss1,ss2]), Vu*dVdVy*kyun(rdist[ss1,ss2])) + dkdubias[ss1,ss2] = 0 + #stop + self.variance_U.gradient = np.sum(dkUdvar * dL_dK) # Vu + + self.variance_Y.gradient = np.sum(dkYdvar * dL_dK) # Vy + + self.lengthscale_U.gradient = np.sum(dktheta1*(-np.sqrt(3)*self.lengthscale_U**(-2))* dL_dK) #lu + + self.lengthscale_Y.gradient = np.sum(dktheta2*(-self.lengthscale_Y**(-2)) * dL_dK) #ly + + self.ubias.gradient = np.sum(dkdubias * dL_dK) +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/ODE_st.html b/doc/_build/html/_modules/GPy/kern/_src/ODE_st.html new file mode 100644 index 00000000..290f8980 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/ODE_st.html @@ -0,0 +1,360 @@ + + + + + + + + GPy.kern._src.ODE_st — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.ODE_st

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+from kern import Kern
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+import numpy as np
+from independent_outputs import index_to_slices
+
+
+
[docs]class ODE_st(Kern): + """ + kernel resultiong from a first order ODE with OU driving GP + + :param input_dim: the number of input dimension, has to be equal to one + :type input_dim: int + :param varianceU: variance of the driving GP + :type varianceU: float + :param lengthscaleU: lengthscale of the driving GP (sqrt(3)/lengthscaleU) + :type lengthscaleU: float + :param varianceY: 'variance' of the transfer function + :type varianceY: float + :param lengthscaleY: 'lengthscale' of the transfer function (1/lengthscaleY) + :type lengthscaleY: float + :rtype: kernel object + + """ + + def __init__(self, input_dim, a=1.,b=1., c=1.,variance_Yx=3.,variance_Yt=1.5, lengthscale_Yx=1.5, lengthscale_Yt=1.5, active_dims=None, name='ode_st'): + assert input_dim ==3, "only defined for 3 input dims" + super(ODE_st, self).__init__(input_dim, active_dims, name) + + self.variance_Yt = Param('variance_Yt', variance_Yt, Logexp()) + self.variance_Yx = Param('variance_Yx', variance_Yx, Logexp()) + self.lengthscale_Yt = Param('lengthscale_Yt', lengthscale_Yt, Logexp()) + self.lengthscale_Yx = Param('lengthscale_Yx', lengthscale_Yx, Logexp()) + + self.a= Param('a', a, Logexp()) + self.b = Param('b', b, Logexp()) + self.c = Param('c', c, Logexp()) + + self.add_parameters(self.a, self.b, self.c, self.variance_Yt, self.variance_Yx, self.lengthscale_Yt,self.lengthscale_Yx) + + +
[docs] def K(self, X, X2=None): + # model : -a d^2y/dx^2 + b dy/dt + c * y = U + # kernel Kyy rbf spatiol temporal + # vyt Y temporal variance vyx Y spatiol variance lyt Y temporal lengthscale lyx Y spatiol lengthscale + # kernel Kuu doper( doper(Kyy)) + # a b c lyt lyx vyx*vyt + """Compute the covariance matrix between X and X2.""" + X,slices = X[:,:-1],index_to_slices(X[:,-1]) + if X2 is None: + X2,slices2 = X,slices + K = np.zeros((X.shape[0], X.shape[0])) + else: + X2,slices2 = X2[:,:-1],index_to_slices(X2[:,-1]) + K = np.zeros((X.shape[0], X2.shape[0])) + + + tdist = (X[:,0][:,None] - X2[:,0][None,:])**2 + xdist = (X[:,1][:,None] - X2[:,1][None,:])**2 + + ttdist = (X[:,0][:,None] - X2[:,0][None,:]) + #rdist = [tdist,xdist] + #dist = np.abs(X - X2.T) + vyt = self.variance_Yt + vyx = self.variance_Yx + + lyt=1/(2*self.lengthscale_Yt) + lyx=1/(2*self.lengthscale_Yx) + + a = self.a ## -a is used in the model, negtive diffusion + b = self.b + c = self.c + + kyy = lambda tdist,xdist: np.exp(-lyt*(tdist) -lyx*(xdist)) + + k1 = lambda tdist: (2*lyt - 4*lyt**2 * (tdist) ) + + k2 = lambda xdist: ( 4*lyx**2 * (xdist) - 2*lyx ) + + k3 = lambda xdist: ( 3*4*lyx**2 - 6*8*xdist*lyx**3 + 16*xdist**2*lyx**4 ) + + k4 = lambda ttdist: 2*lyt*(ttdist) + + for i, s1 in enumerate(slices): + for j, s2 in enumerate(slices2): + for ss1 in s1: + for ss2 in s2: + if i==0 and j==0: + K[ss1,ss2] = vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + elif i==0 and j==1: + K[ss1,ss2] = (-a*k2(xdist[ss1,ss2]) + b*k4(ttdist[ss1,ss2]) + c)*vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + #K[ss1,ss2]= np.where( rdist[ss1,ss2]>0 , kuyp(np.abs(rdist[ss1,ss2])), kuyn(np.abs(rdist[ss1,ss2]) ) ) + #K[ss1,ss2]= np.where( rdist[ss1,ss2]>0 , kuyp(rdist[ss1,ss2]), kuyn(rdist[ss1,ss2] ) ) + elif i==1 and j==1: + K[ss1,ss2] = ( b**2*k1(tdist[ss1,ss2]) - 2*a*c*k2(xdist[ss1,ss2]) + a**2*k3(xdist[ss1,ss2]) + c**2 )* vyt*vyx* kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + else: + K[ss1,ss2] = (-a*k2(xdist[ss1,ss2]) - b*k4(ttdist[ss1,ss2]) + c)*vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + #K[ss1,ss2]= np.where( rdist[ss1,ss2]>0 , kyup(np.abs(rdist[ss1,ss2])), kyun(np.abs(rdist[ss1,ss2]) ) ) + #K[ss1,ss2] = np.where( rdist[ss1,ss2]>0 , kyup(rdist[ss1,ss2]), kyun(rdist[ss1,ss2] ) ) + + #stop + return K +
+
[docs] def Kdiag(self, X): + """Compute the diagonal of the covariance matrix associated to X.""" + vyt = self.variance_Yt + vyx = self.variance_Yx + + lyt = 1./(2*self.lengthscale_Yt) + lyx = 1./(2*self.lengthscale_Yx) + + a = self.a + b = self.b + c = self.c + + ## dk^2/dtdt' + k1 = (2*lyt )*vyt*vyx + ## dk^2/dx^2 + k2 = ( - 2*lyx )*vyt*vyx + ## dk^4/dx^2dx'^2 + k3 = ( 4*3*lyx**2 )*vyt*vyx + + + Kdiag = np.zeros(X.shape[0]) + slices = index_to_slices(X[:,-1]) + + for i, ss1 in enumerate(slices): + for s1 in ss1: + if i==0: + Kdiag[s1]+= vyt*vyx + elif i==1: + #i=1 + Kdiag[s1]+= b**2*k1 - 2*a*c*k2 + a**2*k3 + c**2*vyt*vyx + #Kdiag[s1]+= Vu*Vy*(k1+k2+k3) + else: + raise ValueError, "invalid input/output index" + + return Kdiag + +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + #def dK_dtheta(self, dL_dK, X, X2, target): + """derivative of the covariance matrix with respect to the parameters.""" + X,slices = X[:,:-1],index_to_slices(X[:,-1]) + if X2 is None: + X2,slices2 = X,slices + K = np.zeros((X.shape[0], X.shape[0])) + else: + X2,slices2 = X2[:,:-1],index_to_slices(X2[:,-1]) + + vyt = self.variance_Yt + vyx = self.variance_Yx + + lyt = 1./(2*self.lengthscale_Yt) + lyx = 1./(2*self.lengthscale_Yx) + + a = self.a + b = self.b + c = self.c + + tdist = (X[:,0][:,None] - X2[:,0][None,:])**2 + xdist = (X[:,1][:,None] - X2[:,1][None,:])**2 + #rdist = [tdist,xdist] + ttdist = (X[:,0][:,None] - X2[:,0][None,:]) + + rd=tdist.shape[0] + + dka = np.zeros([rd,rd]) + dkb = np.zeros([rd,rd]) + dkc = np.zeros([rd,rd]) + dkYdvart = np.zeros([rd,rd]) + dkYdvarx = np.zeros([rd,rd]) + dkYdlent = np.zeros([rd,rd]) + dkYdlenx = np.zeros([rd,rd]) + + + kyy = lambda tdist,xdist: np.exp(-lyt*(tdist) -lyx*(xdist)) + #k1 = lambda tdist: (lyt - lyt**2 * (tdist) ) + #k2 = lambda xdist: ( lyx**2 * (xdist) - lyx ) + #k3 = lambda xdist: ( 3*lyx**2 - 6*xdist*lyx**3 + xdist**2*lyx**4 ) + #k4 = lambda tdist: -lyt*np.sqrt(tdist) + + k1 = lambda tdist: (2*lyt - 4*lyt**2 * (tdist) ) + + k2 = lambda xdist: ( 4*lyx**2 * (xdist) - 2*lyx ) + + k3 = lambda xdist: ( 3*4*lyx**2 - 6*8*xdist*lyx**3 + 16*xdist**2*lyx**4 ) + + k4 = lambda ttdist: 2*lyt*(ttdist) + + dkyydlyx = lambda tdist,xdist: kyy(tdist,xdist)*(-xdist) + dkyydlyt = lambda tdist,xdist: kyy(tdist,xdist)*(-tdist) + + dk1dlyt = lambda tdist: 2. - 4*2.*lyt*tdist + dk2dlyx = lambda xdist: (4.*2.*lyx*xdist -2.) + dk3dlyx = lambda xdist: (6.*4.*lyx - 18.*8*xdist*lyx**2 + 4*16*xdist**2*lyx**3) + + dk4dlyt = lambda ttdist: 2*(ttdist) + + for i, s1 in enumerate(slices): + for j, s2 in enumerate(slices2): + for ss1 in s1: + for ss2 in s2: + if i==0 and j==0: + dka[ss1,ss2] = 0 + dkb[ss1,ss2] = 0 + dkc[ss1,ss2] = 0 + dkYdvart[ss1,ss2] = vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkYdvarx[ss1,ss2] = vyt*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkYdlenx[ss1,ss2] = vyt*vyx*dkyydlyx(tdist[ss1,ss2],xdist[ss1,ss2]) + dkYdlent[ss1,ss2] = vyt*vyx*dkyydlyt(tdist[ss1,ss2],xdist[ss1,ss2]) + elif i==0 and j==1: + dka[ss1,ss2] = -k2(xdist[ss1,ss2])*vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkb[ss1,ss2] = k4(ttdist[ss1,ss2])*vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkc[ss1,ss2] = vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + #dkYdvart[ss1,ss2] = 0 + #dkYdvarx[ss1,ss2] = 0 + #dkYdlent[ss1,ss2] = 0 + #dkYdlenx[ss1,ss2] = 0 + dkYdvart[ss1,ss2] = (-a*k2(xdist[ss1,ss2])+b*k4(ttdist[ss1,ss2])+c)*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkYdvarx[ss1,ss2] = (-a*k2(xdist[ss1,ss2])+b*k4(ttdist[ss1,ss2])+c)*vyt*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkYdlent[ss1,ss2] = vyt*vyx*dkyydlyt(tdist[ss1,ss2],xdist[ss1,ss2])* (-a*k2(xdist[ss1,ss2])+b*k4(ttdist[ss1,ss2])+c)+\ + vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2])*b*dk4dlyt(ttdist[ss1,ss2]) + dkYdlenx[ss1,ss2] = vyt*vyx*dkyydlyx(tdist[ss1,ss2],xdist[ss1,ss2])*(-a*k2(xdist[ss1,ss2])+b*k4(ttdist[ss1,ss2])+c)+\ + vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2])*(-a*dk2dlyx(xdist[ss1,ss2])) + elif i==1 and j==1: + dka[ss1,ss2] = (2*a*k3(xdist[ss1,ss2]) - 2*c*k2(xdist[ss1,ss2]))*vyt*vyx* kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkb[ss1,ss2] = 2*b*k1(tdist[ss1,ss2])*vyt*vyx* kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkc[ss1,ss2] = (-2*a*k2(xdist[ss1,ss2]) + 2*c )*vyt*vyx* kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkYdvart[ss1,ss2] = ( b**2*k1(tdist[ss1,ss2]) - 2*a*c*k2(xdist[ss1,ss2]) + a**2*k3(xdist[ss1,ss2]) + c**2 )*vyx* kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkYdvarx[ss1,ss2] = ( b**2*k1(tdist[ss1,ss2]) - 2*a*c*k2(xdist[ss1,ss2]) + a**2*k3(xdist[ss1,ss2]) + c**2 )*vyt* kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkYdlent[ss1,ss2] = vyt*vyx*dkyydlyt(tdist[ss1,ss2],xdist[ss1,ss2])*( b**2*k1(tdist[ss1,ss2]) - 2*a*c*k2(xdist[ss1,ss2]) + a**2*k3(xdist[ss1,ss2]) + c**2 ) +\ + vyx*vyt*kyy(tdist[ss1,ss2],xdist[ss1,ss2])*b**2*dk1dlyt(tdist[ss1,ss2]) + dkYdlenx[ss1,ss2] = vyt*vyx*dkyydlyx(tdist[ss1,ss2],xdist[ss1,ss2])*( b**2*k1(tdist[ss1,ss2]) - 2*a*c*k2(xdist[ss1,ss2]) + a**2*k3(xdist[ss1,ss2]) + c**2 ) +\ + vyx*vyt*kyy(tdist[ss1,ss2],xdist[ss1,ss2])* (-2*a*c*dk2dlyx(xdist[ss1,ss2]) + a**2*dk3dlyx(xdist[ss1,ss2]) ) + else: + dka[ss1,ss2] = -k2(xdist[ss1,ss2])*vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkb[ss1,ss2] = -k4(ttdist[ss1,ss2])*vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkc[ss1,ss2] = vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + #dkYdvart[ss1,ss2] = 0 + #dkYdvarx[ss1,ss2] = 0 + #dkYdlent[ss1,ss2] = 0 + #dkYdlenx[ss1,ss2] = 0 + dkYdvart[ss1,ss2] = (-a*k2(xdist[ss1,ss2])-b*k4(ttdist[ss1,ss2])+c)*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkYdvarx[ss1,ss2] = (-a*k2(xdist[ss1,ss2])-b*k4(ttdist[ss1,ss2])+c)*vyt*kyy(tdist[ss1,ss2],xdist[ss1,ss2]) + dkYdlent[ss1,ss2] = vyt*vyx*dkyydlyt(tdist[ss1,ss2],xdist[ss1,ss2])* (-a*k2(xdist[ss1,ss2])-b*k4(ttdist[ss1,ss2])+c)+\ + vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2])*(-1)*b*dk4dlyt(ttdist[ss1,ss2]) + dkYdlenx[ss1,ss2] = vyt*vyx*dkyydlyx(tdist[ss1,ss2],xdist[ss1,ss2])*(-a*k2(xdist[ss1,ss2])-b*k4(ttdist[ss1,ss2])+c)+\ + vyt*vyx*kyy(tdist[ss1,ss2],xdist[ss1,ss2])*(-a*dk2dlyx(xdist[ss1,ss2])) + + self.a.gradient = np.sum(dka * dL_dK) + + self.b.gradient = np.sum(dkb * dL_dK) + + self.c.gradient = np.sum(dkc * dL_dK) + + + self.variance_Yt.gradient = np.sum(dkYdvart * dL_dK) # Vy + + self.variance_Yx.gradient = np.sum(dkYdvarx * dL_dK) + + self.lengthscale_Yt.gradient = np.sum(dkYdlent*(-0.5*self.lengthscale_Yt**(-2)) * dL_dK) #ly np.sum(dktheta2*(-self.lengthscale_Y**(-2)) * dL_dK) + + self.lengthscale_Yx.gradient = np.sum(dkYdlenx*(-0.5*self.lengthscale_Yx**(-2)) * dL_dK) +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/ODE_t.html b/doc/_build/html/_modules/GPy/kern/_src/ODE_t.html new file mode 100644 index 00000000..67173a47 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/ODE_t.html @@ -0,0 +1,259 @@ + + + + + + + + GPy.kern._src.ODE_t — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.ODE_t

+from kern import Kern
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+import numpy as np
+from independent_outputs import index_to_slices
+
+
+
[docs]class ODE_t(Kern): + + def __init__(self, input_dim, a=1., c=1.,variance_Yt=3., lengthscale_Yt=1.5,ubias =1., active_dims=None, name='ode_st'): + assert input_dim ==2, "only defined for 2 input dims" + super(ODE_t, self).__init__(input_dim, active_dims, name) + + self.variance_Yt = Param('variance_Yt', variance_Yt, Logexp()) + self.lengthscale_Yt = Param('lengthscale_Yt', lengthscale_Yt, Logexp()) + + self.a= Param('a', a, Logexp()) + self.c = Param('c', c, Logexp()) + self.ubias = Param('ubias', ubias, Logexp()) + self.add_parameters(self.a, self.c, self.variance_Yt, self.lengthscale_Yt,self.ubias) + +
[docs] def K(self, X, X2=None): + """Compute the covariance matrix between X and X2.""" + X,slices = X[:,:-1],index_to_slices(X[:,-1]) + if X2 is None: + X2,slices2 = X,slices + K = np.zeros((X.shape[0], X.shape[0])) + else: + X2,slices2 = X2[:,:-1],index_to_slices(X2[:,-1]) + K = np.zeros((X.shape[0], X2.shape[0])) + + tdist = (X[:,0][:,None] - X2[:,0][None,:])**2 + ttdist = (X[:,0][:,None] - X2[:,0][None,:]) + + vyt = self.variance_Yt + + lyt=1/(2*self.lengthscale_Yt) + + a = -self.a + c = self.c + + kyy = lambda tdist: np.exp(-lyt*(tdist)) + + k1 = lambda tdist: (2*lyt - 4*lyt**2 *(tdist) ) + + k4 = lambda tdist: 2*lyt*(tdist) + + for i, s1 in enumerate(slices): + for j, s2 in enumerate(slices2): + for ss1 in s1: + for ss2 in s2: + if i==0 and j==0: + K[ss1,ss2] = vyt*kyy(tdist[ss1,ss2]) + elif i==0 and j==1: + K[ss1,ss2] = (k4(ttdist[ss1,ss2])+1)*vyt*kyy(tdist[ss1,ss2]) + #K[ss1,ss2] = (2*lyt*(ttdist[ss1,ss2])+1)*vyt*kyy(tdist[ss1,ss2]) + elif i==1 and j==1: + K[ss1,ss2] = ( k1(tdist[ss1,ss2]) + 1. )*vyt* kyy(tdist[ss1,ss2])+self.ubias + else: + K[ss1,ss2] = (-k4(ttdist[ss1,ss2])+1)*vyt*kyy(tdist[ss1,ss2]) + #K[ss1,ss2] = (-2*lyt*(ttdist[ss1,ss2])+1)*vyt*kyy(tdist[ss1,ss2]) + #stop + return K + +
+
[docs] def Kdiag(self, X): + + vyt = self.variance_Yt + lyt = 1./(2*self.lengthscale_Yt) + + a = -self.a + c = self.c + + k1 = (2*lyt )*vyt + + Kdiag = np.zeros(X.shape[0]) + slices = index_to_slices(X[:,-1]) + + for i, ss1 in enumerate(slices): + for s1 in ss1: + if i==0: + Kdiag[s1]+= vyt + elif i==1: + #i=1 + Kdiag[s1]+= k1 + vyt+self.ubias + #Kdiag[s1]+= Vu*Vy*(k1+k2+k3) + else: + raise ValueError, "invalid input/output index" + + return Kdiag +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + """derivative of the covariance matrix with respect to the parameters.""" + X,slices = X[:,:-1],index_to_slices(X[:,-1]) + if X2 is None: + X2,slices2 = X,slices + K = np.zeros((X.shape[0], X.shape[0])) + else: + X2,slices2 = X2[:,:-1],index_to_slices(X2[:,-1]) + + + vyt = self.variance_Yt + + lyt = 1./(2*self.lengthscale_Yt) + + tdist = (X[:,0][:,None] - X2[:,0][None,:])**2 + ttdist = (X[:,0][:,None] - X2[:,0][None,:]) + #rdist = [tdist,xdist] + + rd=tdist.shape[0] + + dka = np.zeros([rd,rd]) + dkc = np.zeros([rd,rd]) + dkYdvart = np.zeros([rd,rd]) + dkYdlent = np.zeros([rd,rd]) + + dkdubias = np.zeros([rd,rd]) + + kyy = lambda tdist: np.exp(-lyt*(tdist)) + dkyydlyt = lambda tdist: kyy(tdist)*(-tdist) + + k1 = lambda tdist: (2*lyt - 4*lyt**2 * (tdist) ) + + k4 = lambda ttdist: 2*lyt*(ttdist) + + dk1dlyt = lambda tdist: 2. - 4*2.*lyt*tdist + + dk4dlyt = lambda ttdist: 2*(ttdist) + + for i, s1 in enumerate(slices): + for j, s2 in enumerate(slices2): + for ss1 in s1: + for ss2 in s2: + if i==0 and j==0: + dkYdvart[ss1,ss2] = kyy(tdist[ss1,ss2]) + dkYdlent[ss1,ss2] = vyt*dkyydlyt(tdist[ss1,ss2]) + dkdubias[ss1,ss2] = 0 + elif i==0 and j==1: + dkYdvart[ss1,ss2] = (k4(ttdist[ss1,ss2])+1)*kyy(tdist[ss1,ss2]) + #dkYdvart[ss1,ss2] = ((2*lyt*ttdist[ss1,ss2])+1)*kyy(tdist[ss1,ss2]) + dkYdlent[ss1,ss2] = vyt*dkyydlyt(tdist[ss1,ss2])* (k4(ttdist[ss1,ss2])+1.)+\ + vyt*kyy(tdist[ss1,ss2])*(dk4dlyt(ttdist[ss1,ss2])) + #dkYdlent[ss1,ss2] = vyt*dkyydlyt(tdist[ss1,ss2])* (2*lyt*(ttdist[ss1,ss2])+1.)+\ + #vyt*kyy(tdist[ss1,ss2])*(2*ttdist[ss1,ss2]) + dkdubias[ss1,ss2] = 0 + elif i==1 and j==1: + dkYdvart[ss1,ss2] = (k1(tdist[ss1,ss2]) + 1. )* kyy(tdist[ss1,ss2]) + dkYdlent[ss1,ss2] = vyt*dkyydlyt(tdist[ss1,ss2])*( k1(tdist[ss1,ss2]) + 1. ) +\ + vyt*kyy(tdist[ss1,ss2])*dk1dlyt(tdist[ss1,ss2]) + dkdubias[ss1,ss2] = 1 + else: + dkYdvart[ss1,ss2] = (-k4(ttdist[ss1,ss2])+1)*kyy(tdist[ss1,ss2]) + #dkYdvart[ss1,ss2] = (-2*lyt*(ttdist[ss1,ss2])+1)*kyy(tdist[ss1,ss2]) + dkYdlent[ss1,ss2] = vyt*dkyydlyt(tdist[ss1,ss2])* (-k4(ttdist[ss1,ss2])+1.)+\ + vyt*kyy(tdist[ss1,ss2])*(-dk4dlyt(ttdist[ss1,ss2]) ) + dkdubias[ss1,ss2] = 0 + #dkYdlent[ss1,ss2] = vyt*dkyydlyt(tdist[ss1,ss2])* (-2*lyt*(ttdist[ss1,ss2])+1.)+\ + #vyt*kyy(tdist[ss1,ss2])*(-2)*(ttdist[ss1,ss2]) + + + self.variance_Yt.gradient = np.sum(dkYdvart * dL_dK) + + self.lengthscale_Yt.gradient = np.sum(dkYdlent*(-0.5*self.lengthscale_Yt**(-2)) * dL_dK) + + self.ubias.gradient = np.sum(dkdubias * dL_dK)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/add.html b/doc/_build/html/_modules/GPy/kern/_src/add.html new file mode 100644 index 00000000..146487ac --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/add.html @@ -0,0 +1,282 @@ + + + + + + + + GPy.kern._src.add — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.add

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+import itertools
+from ...util.caching import Cache_this
+from kern import CombinationKernel
+
+
[docs]class Add(CombinationKernel): + """ + Add given list of kernels together. + propagates gradients through. + + This kernel will take over the active dims of it's subkernels passed in. + """ + def __init__(self, subkerns, name='add'): + for i, kern in enumerate(subkerns[:]): + if isinstance(kern, Add): + del subkerns[i] + for part in kern.parts[::-1]: + kern.unlink_parameter(part) + subkerns.insert(i, part) + + super(Add, self).__init__(subkerns, name) + + @Cache_this(limit=2, force_kwargs=['which_parts']) +
[docs] def K(self, X, X2=None, which_parts=None): + """ + Add all kernels together. + If a list of parts (of this kernel!) `which_parts` is given, only + the parts of the list are taken to compute the covariance. + """ + if which_parts is None: + which_parts = self.parts + elif not isinstance(which_parts, (list, tuple)): + # if only one part is given + which_parts = [which_parts] + return reduce(np.add, (p.K(X, X2) for p in which_parts)) +
+ @Cache_this(limit=2, force_kwargs=['which_parts']) +
[docs] def Kdiag(self, X, which_parts=None): + if which_parts is None: + which_parts = self.parts + elif not isinstance(which_parts, (list, tuple)): + # if only one part is given + which_parts = [which_parts] + return reduce(np.add, (p.Kdiag(X) for p in which_parts)) +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + [p.update_gradients_full(dL_dK, X, X2) for p in self.parts if not p.is_fixed] +
+
[docs] def update_gradients_diag(self, dL_dK, X): + [p.update_gradients_diag(dL_dK, X) for p in self.parts] +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + """Compute the gradient of the objective function with respect to X. + + :param dL_dK: An array of gradients of the objective function with respect to the covariance function. + :type dL_dK: np.ndarray (num_samples x num_inducing) + :param X: Observed data inputs + :type X: np.ndarray (num_samples x input_dim) + :param X2: Observed data inputs (optional, defaults to X) + :type X2: np.ndarray (num_inducing x input_dim)""" + + target = np.zeros(X.shape) + [target.__iadd__(p.gradients_X(dL_dK, X, X2)) for p in self.parts] + return target +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + target = np.zeros(X.shape) + [target.__iadd__(p.gradients_X_diag(dL_dKdiag, X)) for p in self.parts] + return target +
+ @Cache_this(limit=2, force_kwargs=['which_parts']) +
[docs] def psi0(self, Z, variational_posterior): + return reduce(np.add, (p.psi0(Z, variational_posterior) for p in self.parts)) +
+ @Cache_this(limit=2, force_kwargs=['which_parts']) +
[docs] def psi1(self, Z, variational_posterior): + return reduce(np.add, (p.psi1(Z, variational_posterior) for p in self.parts)) +
+ @Cache_this(limit=2, force_kwargs=['which_parts']) +
[docs] def psi2(self, Z, variational_posterior): + psi2 = reduce(np.add, (p.psi2(Z, variational_posterior) for p in self.parts)) + #return psi2 + # compute the "cross" terms + from static import White, Bias + from rbf import RBF + #from rbf_inv import RBFInv + from linear import Linear + #ffrom fixed import Fixed + + for p1, p2 in itertools.combinations(self.parts, 2): + # i1, i2 = p1.active_dims, p2.active_dims + # white doesn;t combine with anything + if isinstance(p1, White) or isinstance(p2, White): + pass + # rbf X bias + #elif isinstance(p1, (Bias, Fixed)) and isinstance(p2, (RBF, RBFInv)): + elif isinstance(p1, Bias) and isinstance(p2, (RBF, Linear)): + tmp = p2.psi1(Z, variational_posterior).sum(axis=0) + psi2 += p1.variance * (tmp[:,None]+tmp[None,:]) #(tmp[:, :, None] + tmp[:, None, :]) + #elif isinstance(p2, (Bias, Fixed)) and isinstance(p1, (RBF, RBFInv)): + elif isinstance(p2, Bias) and isinstance(p1, (RBF, Linear)): + tmp = p1.psi1(Z, variational_posterior).sum(axis=0) + psi2 += p2.variance * (tmp[:,None]+tmp[None,:]) #(tmp[:, :, None] + tmp[:, None, :]) + elif isinstance(p2, (RBF, Linear)) and isinstance(p1, (RBF, Linear)): + assert np.intersect1d(p1.active_dims, p2.active_dims).size == 0, "only non overlapping kernel dimensions allowed so far" + tmp1 = p1.psi1(Z, variational_posterior) + tmp2 = p2.psi1(Z, variational_posterior) + psi2 += np.einsum('nm,no->mo',tmp1,tmp2)+np.einsum('nm,no->mo',tmp2,tmp1) + #(tmp1[:, :, None] * tmp2[:, None, :]) + (tmp2[:, :, None] * tmp1[:, None, :]) + else: + raise NotImplementedError, "psi2 cannot be computed for this kernel" + return psi2 +
+
[docs] def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + from static import White, Bias + for p1 in self.parts: + #compute the effective dL_dpsi1. Extra terms appear becaue of the cross terms in psi2! + eff_dL_dpsi1 = dL_dpsi1.copy() + for p2 in self.parts: + if p2 is p1: + continue + if isinstance(p2, White): + continue + elif isinstance(p2, Bias): + eff_dL_dpsi1 += dL_dpsi2.sum(0) * p2.variance * 2. + else:# np.setdiff1d(p1.active_dims, ar2, assume_unique): # TODO: Careful, not correct for overlapping active_dims + eff_dL_dpsi1 += dL_dpsi2.sum(0) * p2.psi1(Z, variational_posterior) * 2. + p1.update_gradients_expectations(dL_dpsi0, eff_dL_dpsi1, dL_dpsi2, Z, variational_posterior) +
+
[docs] def gradients_Z_expectations(self, dL_psi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + from static import White, Bias + target = np.zeros(Z.shape) + for p1 in self.parts: + #compute the effective dL_dpsi1. extra terms appear becaue of the cross terms in psi2! + eff_dL_dpsi1 = dL_dpsi1.copy() + for p2 in self.parts: + if p2 is p1: + continue + if isinstance(p2, White): + continue + elif isinstance(p2, Bias): + eff_dL_dpsi1 += dL_dpsi2.sum(0) * p2.variance * 2. + else: + eff_dL_dpsi1 += dL_dpsi2.sum(0) * p2.psi1(Z, variational_posterior) * 2. + target += p1.gradients_Z_expectations(dL_psi0, eff_dL_dpsi1, dL_dpsi2, Z, variational_posterior) + return target +
+
[docs] def gradients_qX_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + from static import White, Bias + target_grads = [np.zeros(v.shape) for v in variational_posterior.parameters] + for p1 in self.parameters: + #compute the effective dL_dpsi1. extra terms appear becaue of the cross terms in psi2! + eff_dL_dpsi1 = dL_dpsi1.copy() + for p2 in self.parameters: + if p2 is p1: + continue + if isinstance(p2, White): + continue + elif isinstance(p2, Bias): + eff_dL_dpsi1 += dL_dpsi2.sum(0) * p2.variance * 2. + else: + eff_dL_dpsi1 += dL_dpsi2.sum(0) * p2.psi1(Z, variational_posterior) * 2. + grads = p1.gradients_qX_expectations(dL_dpsi0, eff_dL_dpsi1, dL_dpsi2, Z, variational_posterior) + [np.add(target_grads[i],grads[i],target_grads[i]) for i in xrange(len(grads))] + return target_grads +
+
[docs] def add(self, other): + if isinstance(other, Add): + other_params = other.parameters[:] + for p in other_params: + other.unlink_parameter(p) + self.link_parameters(*other_params) + else: + self.link_parameter(other) + self.input_dim, self.active_dims = self.get_input_dim_active_dims(self.parts) + return self +
+
[docs] def input_sensitivity(self, summarize=True): + if summarize: + return reduce(np.add, [k.input_sensitivity(summarize) for k in self.parts]) + else: + i_s = np.zeros((len(self.parts), self.input_dim)) + from operator import setitem + [setitem(i_s, (i, Ellipsis), k.input_sensitivity(summarize)) for i, k in enumerate(self.parts)] + return i_s
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/brownian.html b/doc/_build/html/_modules/GPy/kern/_src/brownian.html new file mode 100644 index 00000000..6662beb3 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/brownian.html @@ -0,0 +1,141 @@ + + + + + + + + GPy.kern._src.brownian — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.brownian

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from kern import Kern
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+import numpy as np
+
+
[docs]class Brownian(Kern): + """ + Brownian motion in 1D only. + + Negative times are treated as a separate (backwards!) Brownian motion. + + :param input_dim: the number of input dimensions + :type input_dim: int + :param variance: + :type variance: float + """ + def __init__(self, input_dim=1, variance=1., active_dims=None, name='Brownian'): + assert input_dim==1, "Brownian motion in 1D only" + super(Brownian, self).__init__(input_dim, active_dims, name) + + self.variance = Param('variance', variance, Logexp()) + self.link_parameters(self.variance) + +
[docs] def K(self,X,X2=None): + if X2 is None: + X2 = X + return self.variance*np.where(np.sign(X)==np.sign(X2.T),np.fmin(np.abs(X),np.abs(X2.T)), 0.) +
+
[docs] def Kdiag(self,X): + return self.variance*np.abs(X.flatten()) +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + if X2 is None: + X2 = X + self.variance.gradient = np.sum(dL_dK * np.where(np.sign(X)==np.sign(X2.T),np.fmin(np.abs(X),np.abs(X2.T)), 0.)) + + #def update_gradients_diag(self, dL_dKdiag, X): + #self.variance.gradient = np.dot(np.abs(X.flatten()), dL_dKdiag) + + #def gradients_X(self, dL_dK, X, X2=None): + #if X2 is None: + #return np.sum(self.variance*dL_dK*np.abs(X),1)[:,None] + #else: + #return np.sum(np.where(np.logical_and(np.abs(X)<np.abs(X2.T), np.sign(X)==np.sign(X2)), self.variance*dL_dK,0.),1)[:,None] +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/coregionalize.html b/doc/_build/html/_modules/GPy/kern/_src/coregionalize.html new file mode 100644 index 00000000..5a9ccbb8 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/coregionalize.html @@ -0,0 +1,267 @@ + + + + + + + + GPy.kern._src.coregionalize — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.coregionalize

+# Copyright (c) 2012, James Hensman and Ricardo Andrade
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from kern import Kern
+import numpy as np
+from scipy import weave
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+from ...util.config import config # for assesing whether to use weave
+
+
[docs]class Coregionalize(Kern): + """ + Covariance function for intrinsic/linear coregionalization models + + This covariance has the form: + .. math:: + \mathbf{B} = \mathbf{W}\mathbf{W}^\top + \text{diag}(kappa) + + An intrinsic/linear coregionalization covariance function of the form: + .. math:: + + k_2(x, y)=\mathbf{B} k(x, y) + + it is obtained as the tensor product between a covariance function + k(x, y) and B. + + :param output_dim: number of outputs to coregionalize + :type output_dim: int + :param rank: number of columns of the W matrix (this parameter is ignored if parameter W is not None) + :type rank: int + :param W: a low rank matrix that determines the correlations between the different outputs, together with kappa it forms the coregionalization matrix B + :type W: numpy array of dimensionality (num_outpus, W_columns) + :param kappa: a vector which allows the outputs to behave independently + :type kappa: numpy array of dimensionality (output_dim, ) + + .. note: see coregionalization examples in GPy.examples.regression for some usage. + """ + def __init__(self, input_dim, output_dim, rank=1, W=None, kappa=None, active_dims=None, name='coregion'): + super(Coregionalize, self).__init__(input_dim, active_dims, name=name) + self.output_dim = output_dim + self.rank = rank + if self.rank>output_dim: + print("Warning: Unusual choice of rank, it should normally be less than the output_dim.") + if W is None: + W = 0.5*np.random.randn(self.output_dim, self.rank)/np.sqrt(self.rank) + else: + assert W.shape==(self.output_dim, self.rank) + self.W = Param('W', W) + if kappa is None: + kappa = 0.5*np.ones(self.output_dim) + else: + assert kappa.shape==(self.output_dim, ) + self.kappa = Param('kappa', kappa, Logexp()) + self.link_parameters(self.W, self.kappa) + +
[docs] def parameters_changed(self): + self.B = np.dot(self.W, self.W.T) + np.diag(self.kappa) +
+
[docs] def K(self, X, X2=None): + if config.getboolean('weave', 'working'): + try: + return self._K_weave(X, X2) + except: + print "\n Weave compilation failed. Falling back to (slower) numpy implementation\n" + config.set('weave', 'working', 'False') + return self._K_numpy(X, X2) + else: + return self._K_numpy(X, X2) + +
+ def _K_numpy(self, X, X2=None): + index = np.asarray(X, dtype=np.int) + if X2 is None: + return self.B[index,index.T] + else: + index2 = np.asarray(X2, dtype=np.int) + return self.B[index,index2.T] + + def _K_weave(self, X, X2=None): + """compute the kernel function using scipy.weave""" + index = np.asarray(X, dtype=np.int) + + if X2 is None: + target = np.empty((X.shape[0], X.shape[0]), dtype=np.float64) + code=""" + for(int i=0;i<N; i++){ + target[i+i*N] = B[index[i]+output_dim*index[i]]; + for(int j=0; j<i; j++){ + target[j+i*N] = B[index[i]+output_dim*index[j]]; + target[i+j*N] = target[j+i*N]; + } + } + """ + N, B, output_dim = index.size, self.B, self.output_dim + weave.inline(code, ['target', 'index', 'N', 'B', 'output_dim']) + else: + index2 = np.asarray(X2, dtype=np.int) + target = np.empty((X.shape[0], X2.shape[0]), dtype=np.float64) + code=""" + for(int i=0;i<num_inducing; i++){ + for(int j=0; j<N; j++){ + target[i+j*num_inducing] = B[output_dim*index[j]+index2[i]]; + } + } + """ + N, num_inducing, B, output_dim = index.size, index2.size, self.B, self.output_dim + weave.inline(code, ['target', 'index', 'index2', 'N', 'num_inducing', 'B', 'output_dim']) + return target + + +
[docs] def Kdiag(self, X): + return np.diag(self.B)[np.asarray(X, dtype=np.int).flatten()] +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + index = np.asarray(X, dtype=np.int) + if X2 is None: + index2 = index + else: + index2 = np.asarray(X2, dtype=np.int) + + #attempt to use weave for a nasty double indexing loop: fall back to numpy + if config.getboolean('weave', 'working'): + try: + dL_dK_small = self._gradient_reduce_weave(dL_dK, index, index2) + except: + print "\n Weave compilation failed. Falling back to (slower) numpy implementation\n" + config.set('weave', 'working', 'False') + dL_dK_small = self._gradient_reduce_weave(dL_dK, index, index2) + else: + dL_dK_small = self._gradient_reduce_weave(dL_dK, index, index2) + + + + dkappa = np.diag(dL_dK_small) + dL_dK_small += dL_dK_small.T + dW = (self.W[:, None, :]*dL_dK_small[:, :, None]).sum(0) + + self.W.gradient = dW + self.kappa.gradient = dkappa +
+ def _gradient_reduce_weave(self, dL_dK, index, index2): + dL_dK_small = np.zeros_like(self.B) + code=""" + for(int i=0; i<num_inducing; i++){ + for(int j=0; j<N; j++){ + dL_dK_small[index[j] + output_dim*index2[i]] += dL_dK[i+j*num_inducing]; + } + } + """ + N, num_inducing, output_dim = index.size, index2.size, self.output_dim + weave.inline(code, ['N', 'num_inducing', 'output_dim', 'dL_dK', 'dL_dK_small', 'index', 'index2']) + return dL_dK_small + + def _gradient_reduce_numpy(self, dL_dK, index, index2): + index, index2 = index[:,0], index2[:,0] + dL_dK_small = np.zeros_like(self.B) + for i in range(k.output_dim): + tmp1 = dL_dK[index==i] + for j in range(k.output_dim): + dL_dK_small[j,i] = tmp1[:,index2==j].sum() + return dL_dK_small + +
[docs] def update_gradients_diag(self, dL_dKdiag, X): + index = np.asarray(X, dtype=np.int).flatten() + dL_dKdiag_small = np.array([dL_dKdiag[index==i].sum() for i in xrange(self.output_dim)]) + self.W.gradient = 2.*self.W*dL_dKdiag_small[:, None] + self.kappa.gradient = dL_dKdiag_small +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + return np.zeros(X.shape) +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + return np.zeros(X.shape) +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/independent_outputs.html b/doc/_build/html/_modules/GPy/kern/_src/independent_outputs.html new file mode 100644 index 00000000..759a0d28 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/independent_outputs.html @@ -0,0 +1,294 @@ + + + + + + + + GPy.kern._src.independent_outputs — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.independent_outputs

+# Copyright (c) 2012, James Hesnsman
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+from kern import Kern, CombinationKernel
+import numpy as np
+import itertools
+
+
[docs]def index_to_slices(index): + """ + take a numpy array of integers (index) and return a nested list of slices such that the slices describe the start, stop points for each integer in the index. + + e.g. + >>> index = np.asarray([0,0,0,1,1,1,2,2,2]) + returns + >>> [[slice(0,3,None)],[slice(3,6,None)],[slice(6,9,None)]] + + or, a more complicated example + >>> index = np.asarray([0,0,1,1,0,2,2,2,1,1]) + returns + >>> [[slice(0,2,None),slice(4,5,None)],[slice(2,4,None),slice(8,10,None)],[slice(5,8,None)]] + """ + if len(index)==0: + return[] + + #contruct the return structure + ind = np.asarray(index,dtype=np.int) + ret = [[] for i in range(ind.max()+1)] + + #find the switchpoints + ind_ = np.hstack((ind,ind[0]+ind[-1]+1)) + switchpoints = np.nonzero(ind_ - np.roll(ind_,+1))[0] + + [ret[ind_i].append(slice(*indexes_i)) for ind_i,indexes_i in zip(ind[switchpoints[:-1]],zip(switchpoints,switchpoints[1:]))] + return ret +
+
[docs]class IndependentOutputs(CombinationKernel): + """ + A kernel which can represent several independent functions. this kernel + 'switches off' parts of the matrix where the output indexes are different. + + The index of the functions is given by the last column in the input X the + rest of the columns of X are passed to the underlying kernel for + computation (in blocks). + + :param kernels: either a kernel, or list of kernels to work with. If it is + a list of kernels the indices in the index_dim, index the kernels you gave! + """ + def __init__(self, kernels, index_dim=-1, name='independ'): + assert isinstance(index_dim, int), "IndependentOutputs kernel is only defined with one input dimension being the index" + if not isinstance(kernels, list): + self.single_kern = True + self.kern = kernels + kernels = [kernels] + else: + self.single_kern = False + self.kern = kernels + super(IndependentOutputs, self).__init__(kernels=kernels, extra_dims=[index_dim], name=name) + self.index_dim = index_dim + +
[docs] def K(self,X ,X2=None): + slices = index_to_slices(X[:,self.index_dim]) + kerns = itertools.repeat(self.kern) if self.single_kern else self.kern + if X2 is None: + target = np.zeros((X.shape[0], X.shape[0])) + [[target.__setitem__((s,ss), kern.K(X[s,:], X[ss,:])) for s,ss in itertools.product(slices_i, slices_i)] for kern, slices_i in zip(kerns, slices)] + else: + slices2 = index_to_slices(X2[:,self.index_dim]) + target = np.zeros((X.shape[0], X2.shape[0])) + [[target.__setitem__((s,s2), kern.K(X[s,:],X2[s2,:])) for s,s2 in itertools.product(slices_i, slices_j)] for kern, slices_i,slices_j in zip(kerns, slices,slices2)] + return target +
+
[docs] def Kdiag(self,X): + slices = index_to_slices(X[:,self.index_dim]) + kerns = itertools.repeat(self.kern) if self.single_kern else self.kern + target = np.zeros(X.shape[0]) + [[np.copyto(target[s], kern.Kdiag(X[s])) for s in slices_i] for kern, slices_i in zip(kerns, slices)] + return target +
+
[docs] def update_gradients_full(self,dL_dK,X,X2=None): + slices = index_to_slices(X[:,self.index_dim]) + if self.single_kern: + target = np.zeros(self.kern.size) + kerns = itertools.repeat(self.kern) + else: + kerns = self.kern + target = [np.zeros(kern.size) for kern, _ in zip(kerns, slices)] + def collate_grads(kern, i, dL, X, X2): + kern.update_gradients_full(dL,X,X2) + if self.single_kern: target[:] += kern.gradient + else: target[i][:] += kern.gradient + if X2 is None: + [[collate_grads(kern, i, dL_dK[s,ss], X[s], X[ss]) for s,ss in itertools.product(slices_i, slices_i)] for i,(kern,slices_i) in enumerate(zip(kerns,slices))] + else: + slices2 = index_to_slices(X2[:,self.index_dim]) + [[[collate_grads(kern, i, dL_dK[s,s2],X[s],X2[s2]) for s in slices_i] for s2 in slices_j] for i,(kern,slices_i,slices_j) in enumerate(zip(kerns,slices,slices2))] + if self.single_kern: kern.gradient = target + else:[kern.gradient.__setitem__(Ellipsis, target[i]) for i, [kern, _] in enumerate(zip(kerns, slices))] +
+
[docs] def gradients_X(self,dL_dK, X, X2=None): + target = np.zeros(X.shape) + kerns = itertools.repeat(self.kern) if self.single_kern else self.kern + if X2 is None: + # TODO: make use of index_to_slices + values = np.unique(X[:,self.index_dim]) + slices = [X[:,self.index_dim]==i for i in values] + [target.__setitem__(s, kern.gradients_X(dL_dK[s,s],X[s],None)) + for kern, s in zip(kerns, slices)] + #slices = index_to_slices(X[:,self.index_dim]) + #[[np.add(target[s], kern.gradients_X(dL_dK[s,s], X[s]), out=target[s]) + # for s in slices_i] for kern, slices_i in zip(kerns, slices)] + #import ipdb;ipdb.set_trace() + #[[(np.add(target[s ], kern.gradients_X(dL_dK[s ,ss],X[s ], X[ss]), out=target[s ]), + # np.add(target[ss], kern.gradients_X(dL_dK[ss,s ],X[ss], X[s ]), out=target[ss])) + # for s, ss in itertools.combinations(slices_i, 2)] for kern, slices_i in zip(kerns, slices)] + else: + values = np.unique(X[:,self.index_dim]) + slices = [X[:,self.index_dim]==i for i in values] + slices2 = [X2[:,self.index_dim]==i for i in values] + [target.__setitem__(s, kern.gradients_X(dL_dK[s, :][:, s2],X[s],X2[s2])) + for kern, s, s2 in zip(kerns, slices, slices2)] + # TODO: make work with index_to_slices + #slices = index_to_slices(X[:,self.index_dim]) + #slices2 = index_to_slices(X2[:,self.index_dim]) + #[[target.__setitem__(s, target[s] + kern.gradients_X(dL_dK[s,s2], X[s], X2[s2])) for s, s2 in itertools.product(slices_i, slices_j)] for kern, slices_i,slices_j in zip(kerns, slices,slices2)] + return target +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + slices = index_to_slices(X[:,self.index_dim]) + kerns = itertools.repeat(self.kern) if self.single_kern else self.kern + target = np.zeros(X.shape) + [[target.__setitem__(s, kern.gradients_X_diag(dL_dKdiag[s],X[s])) for s in slices_i] for kern, slices_i in zip(kerns, slices)] + return target +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + slices = index_to_slices(X[:,self.index_dim]) + kerns = itertools.repeat(self.kern) if self.single_kern else self.kern + if self.single_kern: target = np.zeros(self.kern.size) + else: target = [np.zeros(kern.size) for kern, _ in zip(kerns, slices)] + def collate_grads(kern, i, dL, X): + kern.update_gradients_diag(dL,X) + if self.single_kern: target[:] += kern.gradient + else: target[i][:] += kern.gradient + [[collate_grads(kern, i, dL_dKdiag[s], X[s,:]) for s in slices_i] for i, (kern, slices_i) in enumerate(zip(kerns, slices))] + if self.single_kern: kern.gradient = target + else:[kern.gradient.__setitem__(Ellipsis, target[i]) for i, [kern, _] in enumerate(zip(kerns, slices))] +
+
[docs]class Hierarchical(CombinationKernel): + """ + A kernel which can represent a simple hierarchical model. + + See Hensman et al 2013, "Hierarchical Bayesian modelling of gene expression time + series across irregularly sampled replicates and clusters" + http://www.biomedcentral.com/1471-2105/14/252 + + To construct this kernel, you must pass a list of kernels. the first kernel + will be assumed to be the 'base' kernel, and will be computed everywhere. + For every additional kernel, we assume another layer in the hierachy, with + a corresponding column of the input matrix which indexes which function the + data are in at that level. + + For more, see the ipython notebook documentation on Hierarchical + covariances. + """ + def __init__(self, kernels, name='hierarchy'): + assert all([k.input_dim==kernels[0].input_dim for k in kernels]) + assert len(kernels) > 1 + self.levels = len(kernels) -1 + input_max = max([k.input_dim for k in kernels]) + super(Hierarchical, self).__init__(kernels=kernels, extra_dims = range(input_max, input_max + len(kernels)-1), name=name) + +
[docs] def K(self,X ,X2=None): + K = self.parts[0].K(X, X2) # compute 'base' kern everywhere + slices = [index_to_slices(X[:,i]) for i in self.extra_dims] + if X2 is None: + [[[np.add(K[s,s], k.K(X[s], None), K[s, s]) for s in slices_i] for slices_i in slices_k] for k, slices_k in zip(self.parts[1:], slices)] + else: + slices2 = [index_to_slices(X2[:,i]) for i in self.extra_dims] + [[[np.add(K[s,ss], k.K(X[s], X2[ss]), K[s, ss]) for s,ss in zip(slices_i, slices_j)] for slices_i, slices_j in zip(slices_k1, slices_k2)] for k, slices_k1, slices_k2 in zip(self.parts[1:], slices, slices2)] + return K +
+
[docs] def Kdiag(self,X): + return np.diag(self.K(X)) +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + raise NotImplementedError +
+
[docs] def update_gradients_full(self,dL_dK,X,X2=None): + slices = [index_to_slices(X[:,i]) for i in self.extra_dims] + if X2 is None: + self.parts[0].update_gradients_full(dL_dK, X, None) + for k, slices_k in zip(self.parts[1:], slices): + target = np.zeros(k.size) + def collate_grads(dL, X, X2, target): + k.update_gradients_full(dL,X,X2) + target += k.gradient + [[collate_grads(dL_dK[s,s], X[s], None, target) for s in slices_i] for slices_i in slices_k] + k.gradient[:] = target + else: + raise NotImplementedError +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/kern.html b/doc/_build/html/_modules/GPy/kern/_src/kern.html new file mode 100644 index 00000000..3ea1b0f9 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/kern.html @@ -0,0 +1,374 @@ + + + + + + + + GPy.kern._src.kern — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.kern

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import sys
+import numpy as np
+from ...core.parameterization.parameterized import Parameterized
+from kernel_slice_operations import KernCallsViaSlicerMeta
+from ...util.caching import Cache_this
+from GPy.core.parameterization.observable_array import ObsAr
+
+
+
+
[docs]class Kern(Parameterized): + #=========================================================================== + # This adds input slice support. The rather ugly code for slicing can be + # found in kernel_slice_operations + __metaclass__ = KernCallsViaSlicerMeta + #=========================================================================== + _support_GPU=False + def __init__(self, input_dim, active_dims, name, useGPU=False, *a, **kw): + """ + The base class for a kernel: a positive definite function + which forms of a covariance function (kernel). + + input_dim: + + is the number of dimensions to work on. Make sure to give the + tight dimensionality of inputs. + You most likely want this to be the integer telling the number of + input dimensions of the kernel. + If this is not an integer (!) we will work on the whole input matrix X, + and not check whether dimensions match or not (!). + + active_dims: + + is the active_dimensions of inputs X we will work on. + All kernels will get sliced Xes as inputs, if active_dims is not None + Only positive integers are allowed in active_dims! + if active_dims is None, slicing is switched off and all X will be passed through as given. + + :param int input_dim: the number of input dimensions to the function + :param array-like|None active_dims: list of indices on which dimensions this kernel works on, or none if no slicing + + Do not instantiate. + """ + super(Kern, self).__init__(name=name, *a, **kw) + self.input_dim = int(input_dim) + + if active_dims is None: + active_dims = np.arange(input_dim) + + self.active_dims = np.atleast_1d(active_dims).astype(int) + + assert self.active_dims.size == self.input_dim, "input_dim={} does not match len(active_dim)={}, active_dims={}".format(self.input_dim, self.active_dims.size, self.active_dims) + + self._sliced_X = 0 + self.useGPU = self._support_GPU and useGPU + self._return_psi2_n_flag = ObsAr(np.zeros(1)).astype(bool) + + @property + def return_psi2_n(self): + """ + Flag whether to pass back psi2 as NxMxM or MxM, by summing out N. + """ + return self._return_psi2_n_flag[0] + @return_psi2_n.setter + def return_psi2_n(self, val): + def visit(self): + if isinstance(self, Kern): + self._return_psi2_n_flag[0]=val + self.traverse(visit) + + @Cache_this(limit=20) + def _slice_X(self, X): + return X[:, self.active_dims] + +
[docs] def K(self, X, X2): + """ + Compute the kernel function. + + :param X: the first set of inputs to the kernel + :param X2: (optional) the second set of arguments to the kernel. If X2 + is None, this is passed throgh to the 'part' object, which + handLes this as X2 == X. + """ + raise NotImplementedError
+
[docs] def Kdiag(self, X): + raise NotImplementedError
+
[docs] def psi0(self, Z, variational_posterior): + raise NotImplementedError
+
[docs] def psi1(self, Z, variational_posterior): + raise NotImplementedError
+
[docs] def psi2(self, Z, variational_posterior): + raise NotImplementedError
+
[docs] def gradients_X(self, dL_dK, X, X2): + raise NotImplementedError
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + raise NotImplementedError +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + """ update the gradients of all parameters when using only the diagonal elements of the covariance matrix""" + raise NotImplementedError +
+
[docs] def update_gradients_full(self, dL_dK, X, X2): + """Set the gradients of all parameters when doing full (N) inference.""" + raise NotImplementedError +
+
[docs] def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + """ + Set the gradients of all parameters when doing inference with + uncertain inputs, using expectations of the kernel. + + The esential maths is + + dL_d{theta_i} = dL_dpsi0 * dpsi0_d{theta_i} + + dL_dpsi1 * dpsi1_d{theta_i} + + dL_dpsi2 * dpsi2_d{theta_i} + """ + raise NotImplementedError +
+
[docs] def gradients_Z_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + """ + Returns the derivative of the objective wrt Z, using the chain rule + through the expectation variables. + """ + raise NotImplementedError +
+
[docs] def gradients_qX_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + """ + Compute the gradients wrt the parameters of the variational + distruibution q(X), chain-ruling via the expectations of the kernel + """ + raise NotImplementedError +
+
[docs] def plot(self, x=None, fignum=None, ax=None, title=None, plot_limits=None, resolution=None, **mpl_kwargs): + """ + plot this kernel. + :param x: the value to use for the other kernel argument (kernels are a function of two variables!) + :param fignum: figure number of the plot + :param ax: matplotlib axis to plot on + :param title: the matplotlib title + :param plot_limits: the range over which to plot the kernel + :resolution: the resolution of the lines used in plotting + :mpl_kwargs avalid keyword arguments to pass through to matplotlib (e.g. lw=7) + """ + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ...plotting.matplot_dep import kernel_plots + kernel_plots.plot(self, x, fignum, ax, title, plot_limits, resolution, **mpl_kwargs) +
+
[docs] def plot_ARD(self, *args, **kw): + """ + See :class:`~GPy.plotting.matplot_dep.kernel_plots` + """ + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ...plotting.matplot_dep import kernel_plots + return kernel_plots.plot_ARD(self,*args,**kw) +
+
[docs] def input_sensitivity(self, summarize=True): + """ + Returns the sensitivity for each dimension of this kernel. + """ + return np.zeros(self.input_dim) +
+ def __add__(self, other): + """ Overloading of the '+' operator. for more control, see self.add """ + return self.add(other) + + def __iadd__(self, other): + return self.add(other) + +
[docs] def add(self, other, name='add'): + """ + Add another kernel to this one. + + :param other: the other kernel to be added + :type other: GPy.kern + + """ + assert isinstance(other, Kern), "only kernels can be added to kernels..." + from add import Add + return Add([self, other], name=name) +
+ def __mul__(self, other): + """ Here we overload the '*' operator. See self.prod for more information""" + return self.prod(other) + + def __imul__(self, other): + """ Here we overload the '*' operator. See self.prod for more information""" + return self.prod(other) + + def __pow__(self, other): + """ + Shortcut for tensor `prod`. + """ + assert np.all(self.active_dims == range(self.input_dim)), "Can only use kernels, which have their input_dims defined from 0" + assert np.all(other.active_dims == range(other.input_dim)), "Can only use kernels, which have their input_dims defined from 0" + other.active_dims += self.input_dim + return self.prod(other) + +
[docs] def prod(self, other, name='mul'): + """ + Multiply two kernels (either on the same space, or on the tensor + product of the input space). + + :param other: the other kernel to be added + :type other: GPy.kern + :param tensor: whether or not to use the tensor space (default is false). + :type tensor: bool + + """ + assert isinstance(other, Kern), "only kernels can be multiplied to kernels..." + from prod import Prod + #kernels = [] + #if isinstance(self, Prod): kernels.extend(self.parameters) + #else: kernels.append(self) + #if isinstance(other, Prod): kernels.extend(other.parameters) + #else: kernels.append(other) + return Prod([self, other], name) +
+ def _check_input_dim(self, X): + assert X.shape[1] == self.input_dim, "{} did not specify active_dims and X has wrong shape: X_dim={}, whereas input_dim={}".format(self.name, X.shape[1], self.input_dim) + + def _check_active_dims(self, X): + assert X.shape[1] >= len(self.active_dims), "At least {} dimensional X needed, X.shape={!s}".format(len(self.active_dims), X.shape) + +
+
[docs]class CombinationKernel(Kern): + """ + Abstract super class for combination kernels. + A combination kernel combines (a list of) kernels and works on those. + Examples are the HierarchicalKernel or Add and Prod kernels. + """ + def __init__(self, kernels, name, extra_dims=[]): + """ + Abstract super class for combination kernels. + A combination kernel combines (a list of) kernels and works on those. + Examples are the HierarchicalKernel or Add and Prod kernels. + + :param list kernels: List of kernels to combine (can be only one element) + :param str name: name of the combination kernel + :param array-like extra_dims: if needed extra dimensions for the combination kernel to work on + """ + assert all([isinstance(k, Kern) for k in kernels]) + extra_dims = np.array(extra_dims, dtype=int) + input_dim, active_dims = self.get_input_dim_active_dims(kernels, extra_dims) + # initialize the kernel with the full input_dim + super(CombinationKernel, self).__init__(input_dim, active_dims, name) + self.extra_dims = extra_dims + self.link_parameters(*kernels) + + @property + def parts(self): + return self.parameters + +
[docs] def get_input_dim_active_dims(self, kernels, extra_dims = None): + #active_dims = reduce(np.union1d, (np.r_[x.active_dims] for x in kernels), np.array([], dtype=int)) + #active_dims = np.array(np.concatenate((active_dims, extra_dims if extra_dims is not None else [])), dtype=int) + input_dim = reduce(max, (k.active_dims.max() for k in kernels)) + 1 + + if extra_dims is not None: + input_dim += extra_dims.size + + active_dims = np.arange(input_dim) + return input_dim, active_dims +
+
[docs] def input_sensitivity(self, summarize=True): + """ + If summize is true, we want to get the summerized view of the sensitivities, + otherwise put everything into an array with shape (#kernels, input_dim) + in the order of appearance of the kernels in the parameterized object. + """ + raise NotImplementedError("Choose the kernel you want to get the sensitivity for. You need to override the default behaviour for getting the input sensitivity to be able to get the input sensitivity. For sum kernel it is the sum of all sensitivities, TODO: product kernel? Other kernels?, also TODO: shall we return all the sensitivities here in the combination kernel? So we can combine them however we want? This could lead to just plot all the sensitivities here...") +
+ def _check_active_dims(self, X): + return + + def _check_input_dim(self, X): + # As combination kernels cannot always know, what their inner kernels have as input dims, the check will be done inside them, respectively + return
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/kernel_slice_operations.html b/doc/_build/html/_modules/GPy/kern/_src/kernel_slice_operations.html new file mode 100644 index 00000000..77ca8b56 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/kernel_slice_operations.html @@ -0,0 +1,237 @@ + + + + + + + + GPy.kern._src.kernel_slice_operations — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.kernel_slice_operations

+'''
+Created on 11 Mar 2014
+
+@author: maxz
+'''
+from ...core.parameterization.parameterized import ParametersChangedMeta
+import numpy as np
+from functools import wraps
+
+
[docs]def put_clean(dct, name, func): + if name in dct: + dct['_clean_{}'.format(name)] = dct[name] + dct[name] = func(dct[name]) +
+
[docs]class KernCallsViaSlicerMeta(ParametersChangedMeta): + def __new__(cls, name, bases, dct): + put_clean(dct, 'K', _slice_K) + put_clean(dct, 'Kdiag', _slice_Kdiag) + put_clean(dct, 'update_gradients_full', _slice_update_gradients_full) + put_clean(dct, 'update_gradients_diag', _slice_update_gradients_diag) + put_clean(dct, 'gradients_X', _slice_gradients_X) + put_clean(dct, 'gradients_X_diag', _slice_gradients_X_diag) + + put_clean(dct, 'psi0', _slice_psi) + put_clean(dct, 'psi1', _slice_psi) + put_clean(dct, 'psi2', _slice_psi) + put_clean(dct, 'update_gradients_expectations', _slice_update_gradients_expectations) + put_clean(dct, 'gradients_Z_expectations', _slice_gradients_Z_expectations) + put_clean(dct, 'gradients_qX_expectations', _slice_gradients_qX_expectations) + return super(KernCallsViaSlicerMeta, cls).__new__(cls, name, bases, dct) +
+class _Slice_wrap(object): + def __init__(self, k, X, X2=None): + self.k = k + self.shape = X.shape + assert X.ndim == 2, "only matrices are allowed as inputs to kernels for now, given X.shape={!s}".format(X.shape) + if X2 is not None: + assert X2.ndim == 2, "only matrices are allowed as inputs to kernels for now, given X2.shape={!s}".format(X2.shape) + if (self.k.active_dims is not None) and (self.k._sliced_X == 0): + self.k._check_active_dims(X) + self.X = self.k._slice_X(X) + self.X2 = self.k._slice_X(X2) if X2 is not None else X2 + self.ret = True + else: + self.k._check_input_dim(X) + self.X = X + self.X2 = X2 + self.ret = False + def __enter__(self): + self.k._sliced_X += 1 + return self + def __exit__(self, *a): + self.k._sliced_X -= 1 + def handle_return_array(self, return_val): + if self.ret: + ret = np.zeros(self.shape) + ret[:, self.k.active_dims] = return_val + return ret + return return_val + +def _slice_K(f): + @wraps(f) + def wrap(self, X, X2 = None, *a, **kw): + with _Slice_wrap(self, X, X2) as s: + ret = f(self, s.X, s.X2, *a, **kw) + return ret + return wrap + +def _slice_Kdiag(f): + @wraps(f) + def wrap(self, X, *a, **kw): + with _Slice_wrap(self, X, None) as s: + ret = f(self, s.X, *a, **kw) + return ret + return wrap + +def _slice_update_gradients_full(f): + @wraps(f) + def wrap(self, dL_dK, X, X2=None): + with _Slice_wrap(self, X, X2) as s: + ret = f(self, dL_dK, s.X, s.X2) + return ret + return wrap + +def _slice_update_gradients_diag(f): + @wraps(f) + def wrap(self, dL_dKdiag, X): + with _Slice_wrap(self, X, None) as s: + ret = f(self, dL_dKdiag, s.X) + return ret + return wrap + +def _slice_gradients_X(f): + @wraps(f) + def wrap(self, dL_dK, X, X2=None): + with _Slice_wrap(self, X, X2) as s: + ret = s.handle_return_array(f(self, dL_dK, s.X, s.X2)) + return ret + return wrap + +def _slice_gradients_X_diag(f): + @wraps(f) + def wrap(self, dL_dKdiag, X): + with _Slice_wrap(self, X, None) as s: + ret = s.handle_return_array(f(self, dL_dKdiag, s.X)) + return ret + return wrap + +def _slice_psi(f): + @wraps(f) + def wrap(self, Z, variational_posterior): + with _Slice_wrap(self, Z, variational_posterior) as s: + ret = f(self, s.X, s.X2) + return ret + return wrap + +def _slice_update_gradients_expectations(f): + @wraps(f) + def wrap(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + with _Slice_wrap(self, Z, variational_posterior) as s: + ret = f(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, s.X, s.X2) + return ret + return wrap + +def _slice_gradients_Z_expectations(f): + @wraps(f) + def wrap(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + with _Slice_wrap(self, Z, variational_posterior) as s: + ret = s.handle_return_array(f(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, s.X, s.X2)) + return ret + return wrap + +def _slice_gradients_qX_expectations(f): + @wraps(f) + def wrap(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + with _Slice_wrap(self, variational_posterior, Z) as s: + ret = list(f(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, s.X2, s.X)) + r2 = ret[:2] + ret[0] = s.handle_return_array(r2[0]) + ret[1] = s.handle_return_array(r2[1]) + del r2 + return ret + return wrap +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/linear.html b/doc/_build/html/_modules/GPy/kern/_src/linear.html new file mode 100644 index 00000000..8ed9a433 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/linear.html @@ -0,0 +1,269 @@ + + + + + + + + GPy.kern._src.linear — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.linear

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from kern import Kern
+from ...util.linalg import tdot
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+from ...util.caching import Cache_this
+from ...util.config import *
+from .psi_comp import PSICOMP_Linear
+
+
[docs]class Linear(Kern): + """ + Linear kernel + + .. math:: + + k(x,y) = \sum_{i=1}^input_dim \sigma^2_i x_iy_i + + :param input_dim: the number of input dimensions + :type input_dim: int + :param variances: the vector of variances :math:`\sigma^2_i` + :type variances: array or list of the appropriate size (or float if there + is only one variance parameter) + :param ARD: Auto Relevance Determination. If False, the kernel has only one + variance parameter \sigma^2, otherwise there is one variance + parameter per dimension. + :type ARD: Boolean + :rtype: kernel object + + """ + + def __init__(self, input_dim, variances=None, ARD=False, active_dims=None, name='linear'): + super(Linear, self).__init__(input_dim, active_dims, name) + self.ARD = ARD + if not ARD: + if variances is not None: + variances = np.asarray(variances) + assert variances.size == 1, "Only one variance needed for non-ARD kernel" + else: + variances = np.ones(1) + else: + if variances is not None: + variances = np.asarray(variances) + assert variances.size == self.input_dim, "bad number of variances, need one ARD variance per input_dim" + else: + variances = np.ones(self.input_dim) + + self.variances = Param('variances', variances, Logexp()) + self.link_parameter(self.variances) + self.psicomp = PSICOMP_Linear() + + @Cache_this(limit=2) +
[docs] def K(self, X, X2=None): + if self.ARD: + if X2 is None: + return tdot(X*np.sqrt(self.variances)) + else: + rv = np.sqrt(self.variances) + return np.dot(X*rv, (X2*rv).T) + else: + return self._dot_product(X, X2) * self.variances +
+ @Cache_this(limit=1, ignore_args=(0,)) + def _dot_product(self, X, X2=None): + if X2 is None: + return tdot(X) + else: + return np.dot(X, X2.T) + +
[docs] def Kdiag(self, X): + return np.sum(self.variances * np.square(X), -1) +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + if self.ARD: + if X2 is None: + #self.variances.gradient = np.array([np.sum(dL_dK * tdot(X[:, i:i + 1])) for i in range(self.input_dim)]) + self.variances.gradient = np.einsum('ij,iq,jq->q', dL_dK, X, X) + else: + #product = X[:, None, :] * X2[None, :, :] + #self.variances.gradient = (dL_dK[:, :, None] * product).sum(0).sum(0) + self.variances.gradient = np.einsum('ij,iq,jq->q', dL_dK, X, X2) + else: + self.variances.gradient = np.sum(self._dot_product(X, X2) * dL_dK) +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + tmp = dL_dKdiag[:, None] * X ** 2 + if self.ARD: + self.variances.gradient = tmp.sum(0) + else: + self.variances.gradient = np.atleast_1d(tmp.sum()) + +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + if X2 is None: + return np.einsum('jq,q,ij->iq', X, 2*self.variances, dL_dK) + else: + #return (((X2[None,:, :] * self.variances)) * dL_dK[:, :, None]).sum(1) + return np.einsum('jq,q,ij->iq', X2, self.variances, dL_dK) +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + return 2.*self.variances*dL_dKdiag[:,None]*X +
+
[docs] def input_sensitivity(self, summarize=True): + return np.ones(self.input_dim) * self.variances + + #---------------------------------------# + # PSI statistics # + #---------------------------------------# +
+
[docs] def psi0(self, Z, variational_posterior): + return self.psicomp.psicomputations(self.variances, Z, variational_posterior)[0] +
+
[docs] def psi1(self, Z, variational_posterior): + return self.psicomp.psicomputations(self.variances, Z, variational_posterior)[1] +
+
[docs] def psi2(self, Z, variational_posterior): + return self.psicomp.psicomputations(self.variances, Z, variational_posterior)[2] +
+
[docs] def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + dL_dvar = self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variances, Z, variational_posterior)[0] + if self.ARD: + self.variances.gradient = dL_dvar + else: + self.variances.gradient = dL_dvar.sum() +
+
[docs] def gradients_Z_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + return self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variances, Z, variational_posterior)[1] +
+
[docs] def gradients_qX_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + return self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variances, Z, variational_posterior)[2:] +
+
[docs]class LinearFull(Kern): + def __init__(self, input_dim, rank, W=None, kappa=None, active_dims=None, name='linear_full'): + super(LinearFull, self).__init__(input_dim, active_dims, name) + if W is None: + W = np.ones((input_dim, rank)) + if kappa is None: + kappa = np.ones(input_dim) + assert W.shape == (input_dim, rank) + assert kappa.shape == (input_dim,) + + self.W = Param('W', W) + self.kappa = Param('kappa', kappa, Logexp()) + self.link_parameters(self.W, self.kappa) + +
[docs] def K(self, X, X2=None): + P = np.dot(self.W, self.W.T) + np.diag(self.kappa) + return np.einsum('ij,jk,lk->il', X, P, X if X2 is None else X2) +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + self.kappa.gradient = np.einsum('ij,ik,kj->j', X, dL_dK, X if X2 is None else X2) + self.W.gradient = np.einsum('ij,kl,ik,lm->jm', X, X if X2 is None else X2, dL_dK, self.W) + self.W.gradient += np.einsum('ij,kl,ik,jm->lm', X, X if X2 is None else X2, dL_dK, self.W) +
+
[docs] def Kdiag(self, X): + P = np.dot(self.W, self.W.T) + np.diag(self.kappa) + return np.einsum('ij,jk,ik->i', X, P, X) +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + self.kappa.gradient = np.einsum('ij,i->j', np.square(X), dL_dKdiag) + self.W.gradient = 2.*np.einsum('ij,ik,jl,i->kl', X, X, self.W, dL_dKdiag) +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + P = np.dot(self.W, self.W.T) + np.diag(self.kappa) + if X2 is None: + return 2.*np.einsum('ij,jk,kl->il', dL_dK, X, P) + else: + return np.einsum('ij,jk,kl->il', dL_dK, X2, P) +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + P = np.dot(self.W, self.W.T) + np.diag(self.kappa) + return 2.*np.einsum('jk,i,ij->ik', P, dL_dKdiag, X) +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/mlp.html b/doc/_build/html/_modules/GPy/kern/_src/mlp.html new file mode 100644 index 00000000..76a31a8e --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/mlp.html @@ -0,0 +1,223 @@ + + + + + + + + GPy.kern._src.mlp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.mlp

+# Copyright (c) 2013, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from kern import Kern
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+import numpy as np
+four_over_tau = 2./np.pi
+
+
[docs]class MLP(Kern): + """ + + Multi layer perceptron kernel (also known as arc sine kernel or neural network kernel) + + .. math:: + + k(x,y) = \\sigma^{2}\\frac{2}{\\pi } \\text{asin} \\left ( \\frac{ \\sigma_w^2 x^\\top y+\\sigma_b^2}{\\sqrt{\\sigma_w^2x^\\top x + \\sigma_b^2 + 1}\\sqrt{\\sigma_w^2 y^\\top y \\sigma_b^2 +1}} \\right ) + + + :param input_dim: the number of input dimensions + :type input_dim: int + :param variance: the variance :math:`\sigma^2` + :type variance: float + :param weight_variance: the vector of the variances of the prior over input weights in the neural network :math:`\sigma^2_w` + :type weight_variance: array or list of the appropriate size (or float if there is only one weight variance parameter) + :param bias_variance: the variance of the prior over bias parameters :math:`\sigma^2_b` + :param ARD: Auto Relevance Determination. If equal to "False", the kernel is isotropic (ie. one weight variance parameter \sigma^2_w), otherwise there is one weight variance parameter per dimension. + :type ARD: Boolean + :rtype: Kernpart object + + + """ + + def __init__(self, input_dim, variance=1., weight_variance=1., bias_variance=100., active_dims=None, name='mlp'): + super(MLP, self).__init__(input_dim, active_dims, name) + self.variance = Param('variance', variance, Logexp()) + self.weight_variance = Param('weight_variance', weight_variance, Logexp()) + self.bias_variance = Param('bias_variance', bias_variance, Logexp()) + self.link_parameters(self.variance, self.weight_variance, self.bias_variance) + + +
[docs] def K(self, X, X2=None): + self._K_computations(X, X2) + return self.variance*self._K_dvar +
+
[docs] def Kdiag(self, X): + """Compute the diagonal of the covariance matrix for X.""" + self._K_diag_computations(X) + return self.variance*self._K_diag_dvar +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + """Derivative of the covariance with respect to the parameters.""" + self._K_computations(X, X2) + self.variance.gradient = np.sum(self._K_dvar*dL_dK) + + denom3 = self._K_denom**3 + base = four_over_tau*self.variance/np.sqrt(1-self._K_asin_arg*self._K_asin_arg) + base_cov_grad = base*dL_dK + + if X2 is None: + vec = np.diag(self._K_inner_prod) + self.weight_variance.gradient = ((self._K_inner_prod/self._K_denom + -.5*self._K_numer/denom3 + *(np.outer((self.weight_variance*vec+self.bias_variance+1.), vec) + +np.outer(vec,(self.weight_variance*vec+self.bias_variance+1.))))*base_cov_grad).sum() + self.bias_variance.gradient = ((1./self._K_denom + -.5*self._K_numer/denom3 + *((vec[None, :]+vec[:, None])*self.weight_variance + +2.*self.bias_variance + 2.))*base_cov_grad).sum() + else: + vec1 = (X*X).sum(1) + vec2 = (X2*X2).sum(1) + self.weight_variance.gradient = ((self._K_inner_prod/self._K_denom + -.5*self._K_numer/denom3 + *(np.outer((self.weight_variance*vec1+self.bias_variance+1.), vec2) + np.outer(vec1, self.weight_variance*vec2 + self.bias_variance+1.)))*base_cov_grad).sum() + self.bias_variance.gradient = ((1./self._K_denom + -.5*self._K_numer/denom3 + *((vec1[:, None]+vec2[None, :])*self.weight_variance + + 2*self.bias_variance + 2.))*base_cov_grad).sum() +
+
[docs] def update_gradients_diag(self, X): + raise NotImplementedError, "TODO" + +
+
[docs] def gradients_X(self, dL_dK, X, X2): + """Derivative of the covariance matrix with respect to X""" + self._K_computations(X, X2) + arg = self._K_asin_arg + numer = self._K_numer + denom = self._K_denom + denom3 = denom*denom*denom + if X2 is not None: + vec2 = (X2*X2).sum(1)*self.weight_variance+self.bias_variance + 1. + return four_over_tau*self.weight_variance*self.variance*((X2[None, :, :]/denom[:, :, None] - vec2[None, :, None]*X[:, None, :]*(numer/denom3)[:, :, None])*(dL_dK/np.sqrt(1-arg*arg))[:, :, None]).sum(1) + else: + vec = (X*X).sum(1)*self.weight_variance+self.bias_variance + 1. + return 2*four_over_tau*self.weight_variance*self.variance*((X[None, :, :]/denom[:, :, None] - vec[None, :, None]*X[:, None, :]*(numer/denom3)[:, :, None])*(dL_dK/np.sqrt(1-arg*arg))[:, :, None]).sum(1) +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + """Gradient of diagonal of covariance with respect to X""" + self._K_diag_computations(X) + arg = self._K_diag_asin_arg + denom = self._K_diag_denom + #numer = self._K_diag_numer + return four_over_tau*2.*self.weight_variance*self.variance*X*(1./denom*(1. - arg)*dL_dKdiag/(np.sqrt(1-arg*arg)))[:, None] + +
+ def _K_computations(self, X, X2): + """Pre-computations for the covariance matrix (used for computing the covariance and its gradients.""" + if X2 is None: + self._K_inner_prod = np.dot(X,X.T) + self._K_numer = self._K_inner_prod*self.weight_variance + self.bias_variance + vec = np.diag(self._K_numer) + 1. + self._K_denom = np.sqrt(np.outer(vec,vec)) + else: + self._K_inner_prod = np.dot(X,X2.T) + self._K_numer = self._K_inner_prod*self.weight_variance + self.bias_variance + vec1 = (X*X).sum(1)*self.weight_variance + self.bias_variance + 1. + vec2 = (X2*X2).sum(1)*self.weight_variance + self.bias_variance + 1. + self._K_denom = np.sqrt(np.outer(vec1,vec2)) + self._K_asin_arg = self._K_numer/self._K_denom + self._K_dvar = four_over_tau*np.arcsin(self._K_asin_arg) + + def _K_diag_computations(self, X): + """Pre-computations concerning the diagonal terms (used for computation of diagonal and its gradients).""" + self._K_diag_numer = (X*X).sum(1)*self.weight_variance + self.bias_variance + self._K_diag_denom = self._K_diag_numer+1. + self._K_diag_asin_arg = self._K_diag_numer/self._K_diag_denom + self._K_diag_dvar = four_over_tau*np.arcsin(self._K_diag_asin_arg)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/periodic.html b/doc/_build/html/_modules/GPy/kern/_src/periodic.html new file mode 100644 index 00000000..f5c13619 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/periodic.html @@ -0,0 +1,498 @@ + + + + + + + + GPy.kern._src.periodic — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.periodic

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from kern import Kern
+from ...util.linalg import mdot
+from ...util.decorators import silence_errors
+from ...core.parameterization.param import Param
+from ...core.parameterization.transformations import Logexp
+
+
[docs]class Periodic(Kern): + def __init__(self, input_dim, variance, lengthscale, period, n_freq, lower, upper, active_dims, name): + """ + :type input_dim: int + :param variance: the variance of the Matern kernel + :type variance: float + :param lengthscale: the lengthscale of the Matern kernel + :type lengthscale: np.ndarray of size (input_dim,) + :param period: the period + :type period: float + :param n_freq: the number of frequencies considered for the periodic subspace + :type n_freq: int + :rtype: kernel object + """ + + assert input_dim==1, "Periodic kernels are only defined for input_dim=1" + super(Periodic, self).__init__(input_dim, active_dims, name) + self.input_dim = input_dim + self.lower,self.upper = lower, upper + self.n_freq = n_freq + self.n_basis = 2*n_freq + self.variance = Param('variance', np.float64(variance), Logexp()) + self.lengthscale = Param('lengthscale', np.float64(lengthscale), Logexp()) + self.period = Param('period', np.float64(period), Logexp()) + self.link_parameters(self.variance, self.lengthscale, self.period) + + def _cos(self, alpha, omega, phase): + def f(x): + return alpha*np.cos(omega*x + phase) + return f + + @silence_errors + def _cos_factorization(self, alpha, omega, phase): + r1 = np.sum(alpha*np.cos(phase),axis=1)[:,None] + r2 = np.sum(alpha*np.sin(phase),axis=1)[:,None] + r = np.sqrt(r1**2 + r2**2) + psi = np.where(r1 != 0, (np.arctan(r2/r1) + (r1<0.)*np.pi),np.arcsin(r2)) + return r,omega[:,0:1], psi + + @silence_errors + def _int_computation(self,r1,omega1,phi1,r2,omega2,phi2): + Gint1 = 1./(omega1+omega2.T)*( np.sin((omega1+omega2.T)*self.upper+phi1+phi2.T) - np.sin((omega1+omega2.T)*self.lower+phi1+phi2.T)) + 1./(omega1-omega2.T)*( np.sin((omega1-omega2.T)*self.upper+phi1-phi2.T) - np.sin((omega1-omega2.T)*self.lower+phi1-phi2.T) ) + Gint2 = 1./(omega1+omega2.T)*( np.sin((omega1+omega2.T)*self.upper+phi1+phi2.T) - np.sin((omega1+omega2.T)*self.lower+phi1+phi2.T)) + np.cos(phi1-phi2.T)*(self.upper-self.lower) + Gint = np.dot(r1,r2.T)/2 * np.where(np.isnan(Gint1),Gint2,Gint1) + return Gint + +
[docs] def K(self, X, X2=None): + FX = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X) + if X2 is None: + FX2 = FX + else: + FX2 = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X2) + return mdot(FX,self.Gi,FX2.T) +
+
[docs] def Kdiag(self,X): + return np.diag(self.K(X)) + + + +
+
[docs]class PeriodicExponential(Periodic): + """ + Kernel of the periodic subspace (up to a given frequency) of a exponential + (Matern 1/2) RKHS. + + Only defined for input_dim=1. + """ + + def __init__(self, input_dim=1, variance=1., lengthscale=1., period=2.*np.pi, n_freq=10, lower=0., upper=4*np.pi, active_dims=None, name='periodic_exponential'): + super(PeriodicExponential, self).__init__(input_dim, variance, lengthscale, period, n_freq, lower, upper, active_dims, name) + +
[docs] def parameters_changed(self): + self.a = [1./self.lengthscale, 1.] + self.b = [1] + + self.basis_alpha = np.ones((self.n_basis,)) + self.basis_omega = (2*np.pi*np.arange(1,self.n_freq+1)/self.period).repeat(2) + self.basis_phi = np.zeros(self.n_freq * 2) + self.basis_phi[::2] = -np.pi/2 + + self.G = self.Gram_matrix() + self.Gi = np.linalg.inv(self.G) +
+
[docs] def Gram_matrix(self): + La = np.column_stack((self.a[0]*np.ones((self.n_basis,1)),self.a[1]*self.basis_omega)) + Lo = np.column_stack((self.basis_omega,self.basis_omega)) + Lp = np.column_stack((self.basis_phi,self.basis_phi+np.pi/2)) + r,omega,phi = self._cos_factorization(La,Lo,Lp) + Gint = self._int_computation( r,omega,phi, r,omega,phi) + Flower = np.array(self._cos(self.basis_alpha,self.basis_omega,self.basis_phi)(self.lower))[:,None] + return(self.lengthscale/(2*self.variance) * Gint + 1./self.variance*np.dot(Flower,Flower.T)) +
+ @silence_errors +
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + """derivative of the covariance matrix with respect to the parameters (shape is N x num_inducing x num_params)""" + if X2 is None: X2 = X + FX = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X) + FX2 = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X2) + + La = np.column_stack((self.a[0]*np.ones((self.n_basis,1)),self.a[1]*self.basis_omega)) + Lo = np.column_stack((self.basis_omega,self.basis_omega)) + Lp = np.column_stack((self.basis_phi,self.basis_phi+np.pi/2)) + r,omega,phi = self._cos_factorization(La,Lo,Lp) + Gint = self._int_computation( r,omega,phi, r,omega,phi) + + Flower = np.array(self._cos(self.basis_alpha,self.basis_omega,self.basis_phi)(self.lower))[:,None] + + #dK_dvar + dK_dvar = 1./self.variance*mdot(FX,self.Gi,FX2.T) + + #dK_dlen + da_dlen = [-1./self.lengthscale**2,0.] + dLa_dlen = np.column_stack((da_dlen[0]*np.ones((self.n_basis,1)),da_dlen[1]*self.basis_omega)) + r1,omega1,phi1 = self._cos_factorization(dLa_dlen,Lo,Lp) + dGint_dlen = self._int_computation(r1,omega1,phi1, r,omega,phi) + dGint_dlen = dGint_dlen + dGint_dlen.T + dG_dlen = 1./2*Gint + self.lengthscale/2*dGint_dlen + dK_dlen = -mdot(FX,self.Gi,dG_dlen/self.variance,self.Gi,FX2.T) + + #dK_dper + dFX_dper = self._cos(-self.basis_alpha[None,:]*self.basis_omega[None,:]/self.period*X ,self.basis_omega[None,:],self.basis_phi[None,:]+np.pi/2)(X) + dFX2_dper = self._cos(-self.basis_alpha[None,:]*self.basis_omega[None,:]/self.period*X2,self.basis_omega[None,:],self.basis_phi[None,:]+np.pi/2)(X2) + + dLa_dper = np.column_stack((-self.a[0]*self.basis_omega/self.period, -self.a[1]*self.basis_omega**2/self.period)) + dLp_dper = np.column_stack((self.basis_phi+np.pi/2,self.basis_phi+np.pi)) + r1,omega1,phi1 = self._cos_factorization(dLa_dper,Lo,dLp_dper) + + IPPprim1 = self.upper*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi/2) + 1./(omega-omega1.T)*np.cos((omega-omega1.T)*self.upper+phi-phi1.T-np.pi/2)) + IPPprim1 -= self.lower*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi/2) + 1./(omega-omega1.T)*np.cos((omega-omega1.T)*self.lower+phi-phi1.T-np.pi/2)) + # SIMPLIFY!!! IPPprim1 = (self.upper - self.lower)*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi/2) + 1./(omega-omega1.T)*np.cos((omega-omega1.T)*self.upper+phi-phi1.T-np.pi/2)) + IPPprim2 = self.upper*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi/2) + self.upper*np.cos(phi-phi1.T)) + IPPprim2 -= self.lower*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi/2) + self.lower*np.cos(phi-phi1.T)) + IPPprim = np.where(np.logical_or(np.isnan(IPPprim1), np.isinf(IPPprim1)), IPPprim2, IPPprim1) + + + IPPint1 = 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi) + 1./(omega-omega1.T)**2*np.cos((omega-omega1.T)*self.upper+phi-phi1.T-np.pi) + IPPint1 -= 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi) + 1./(omega-omega1.T)**2*np.cos((omega-omega1.T)*self.lower+phi-phi1.T-np.pi) + IPPint2 = 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi) + 1./2*self.upper**2*np.cos(phi-phi1.T) + IPPint2 -= 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi) + 1./2*self.lower**2*np.cos(phi-phi1.T) + #IPPint2[0,0] = (self.upper**2 - self.lower**2)*np.cos(phi[0,0])*np.cos(phi1[0,0]) + IPPint = np.where(np.isnan(IPPint1),IPPint2,IPPint1) + + dLa_dper2 = np.column_stack((-self.a[1]*self.basis_omega/self.period)) + dLp_dper2 = np.column_stack((self.basis_phi+np.pi/2)) + r2,omega2,phi2 = dLa_dper2.T,Lo[:,0:1],dLp_dper2.T + + dGint_dper = np.dot(r,r1.T)/2 * (IPPprim - IPPint) + self._int_computation(r2,omega2,phi2, r,omega,phi) + dGint_dper = dGint_dper + dGint_dper.T + + dFlower_dper = np.array(self._cos(-self.lower*self.basis_alpha*self.basis_omega/self.period,self.basis_omega,self.basis_phi+np.pi/2)(self.lower))[:,None] + + dG_dper = 1./self.variance*(self.lengthscale/2*dGint_dper + self.b[0]*(np.dot(dFlower_dper,Flower.T)+np.dot(Flower,dFlower_dper.T))) + + dK_dper = mdot(dFX_dper,self.Gi,FX2.T) - mdot(FX,self.Gi,dG_dper,self.Gi,FX2.T) + mdot(FX,self.Gi,dFX2_dper.T) + + self.variance.gradient = np.sum(dK_dvar*dL_dK) + self.lengthscale.gradient = np.sum(dK_dlen*dL_dK) + self.period.gradient = np.sum(dK_dper*dL_dK) + + +
+
[docs]class PeriodicMatern32(Periodic): + """ + Kernel of the periodic subspace (up to a given frequency) of a Matern 3/2 RKHS. Only defined for input_dim=1. + + :param input_dim: the number of input dimensions + :type input_dim: int + :param variance: the variance of the Matern kernel + :type variance: float + :param lengthscale: the lengthscale of the Matern kernel + :type lengthscale: np.ndarray of size (input_dim,) + :param period: the period + :type period: float + :param n_freq: the number of frequencies considered for the periodic subspace + :type n_freq: int + :rtype: kernel object + + """ + + def __init__(self, input_dim=1, variance=1., lengthscale=1., period=2.*np.pi, n_freq=10, lower=0., upper=4*np.pi, active_dims=None, name='periodic_Matern32'): + super(PeriodicMatern32, self).__init__(input_dim, variance, lengthscale, period, n_freq, lower, upper, active_dims, name) +
[docs] def parameters_changed(self): + self.a = [3./self.lengthscale**2, 2*np.sqrt(3)/self.lengthscale, 1.] + self.b = [1,self.lengthscale**2/3] + + self.basis_alpha = np.ones((self.n_basis,)) + self.basis_omega = (2*np.pi*np.arange(1,self.n_freq+1)/self.period).repeat(2) + self.basis_phi = np.zeros(self.n_freq * 2) + self.basis_phi[::2] = -np.pi/2 + + self.G = self.Gram_matrix() + self.Gi = np.linalg.inv(self.G) +
+
[docs] def Gram_matrix(self): + La = np.column_stack((self.a[0]*np.ones((self.n_basis,1)),self.a[1]*self.basis_omega,self.a[2]*self.basis_omega**2)) + Lo = np.column_stack((self.basis_omega,self.basis_omega,self.basis_omega)) + Lp = np.column_stack((self.basis_phi,self.basis_phi+np.pi/2,self.basis_phi+np.pi)) + r,omega,phi = self._cos_factorization(La,Lo,Lp) + Gint = self._int_computation( r,omega,phi, r,omega,phi) + + Flower = np.array(self._cos(self.basis_alpha,self.basis_omega,self.basis_phi)(self.lower))[:,None] + F1lower = np.array(self._cos(self.basis_alpha*self.basis_omega,self.basis_omega,self.basis_phi+np.pi/2)(self.lower))[:,None] + return(self.lengthscale**3/(12*np.sqrt(3)*self.variance) * Gint + 1./self.variance*np.dot(Flower,Flower.T) + self.lengthscale**2/(3.*self.variance)*np.dot(F1lower,F1lower.T)) + +
+ @silence_errors +
[docs] def update_gradients_full(self,dL_dK,X,X2): + """derivative of the covariance matrix with respect to the parameters (shape is num_data x num_inducing x num_params)""" + if X2 is None: X2 = X + FX = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X) + FX2 = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X2) + + La = np.column_stack((self.a[0]*np.ones((self.n_basis,1)),self.a[1]*self.basis_omega,self.a[2]*self.basis_omega**2)) + Lo = np.column_stack((self.basis_omega,self.basis_omega,self.basis_omega)) + Lp = np.column_stack((self.basis_phi,self.basis_phi+np.pi/2,self.basis_phi+np.pi)) + r,omega,phi = self._cos_factorization(La,Lo,Lp) + Gint = self._int_computation( r,omega,phi, r,omega,phi) + + Flower = np.array(self._cos(self.basis_alpha,self.basis_omega,self.basis_phi)(self.lower))[:,None] + F1lower = np.array(self._cos(self.basis_alpha*self.basis_omega,self.basis_omega,self.basis_phi+np.pi/2)(self.lower))[:,None] + + #dK_dvar + dK_dvar = 1./self.variance*mdot(FX,self.Gi,FX2.T) + + #dK_dlen + da_dlen = [-6/self.lengthscale**3,-2*np.sqrt(3)/self.lengthscale**2,0.] + db_dlen = [0.,2*self.lengthscale/3.] + dLa_dlen = np.column_stack((da_dlen[0]*np.ones((self.n_basis,1)),da_dlen[1]*self.basis_omega,da_dlen[2]*self.basis_omega**2)) + r1,omega1,phi1 = self._cos_factorization(dLa_dlen,Lo,Lp) + dGint_dlen = self._int_computation(r1,omega1,phi1, r,omega,phi) + dGint_dlen = dGint_dlen + dGint_dlen.T + dG_dlen = self.lengthscale**2/(4*np.sqrt(3))*Gint + self.lengthscale**3/(12*np.sqrt(3))*dGint_dlen + db_dlen[0]*np.dot(Flower,Flower.T) + db_dlen[1]*np.dot(F1lower,F1lower.T) + dK_dlen = -mdot(FX,self.Gi,dG_dlen/self.variance,self.Gi,FX2.T) + + #dK_dper + dFX_dper = self._cos(-self.basis_alpha[None,:]*self.basis_omega[None,:]/self.period*X ,self.basis_omega[None,:],self.basis_phi[None,:]+np.pi/2)(X) + dFX2_dper = self._cos(-self.basis_alpha[None,:]*self.basis_omega[None,:]/self.period*X2,self.basis_omega[None,:],self.basis_phi[None,:]+np.pi/2)(X2) + + dLa_dper = np.column_stack((-self.a[0]*self.basis_omega/self.period, -self.a[1]*self.basis_omega**2/self.period, -self.a[2]*self.basis_omega**3/self.period)) + dLp_dper = np.column_stack((self.basis_phi+np.pi/2,self.basis_phi+np.pi,self.basis_phi+np.pi*3/2)) + r1,omega1,phi1 = self._cos_factorization(dLa_dper,Lo,dLp_dper) + + IPPprim1 = self.upper*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi/2) + 1./(omega-omega1.T)*np.cos((omega-omega1.T)*self.upper+phi-phi1.T-np.pi/2)) + IPPprim1 -= self.lower*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi/2) + 1./(omega-omega1.T)*np.cos((omega-omega1.T)*self.lower+phi-phi1.T-np.pi/2)) + IPPprim2 = self.upper*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi/2) + self.upper*np.cos(phi-phi1.T)) + IPPprim2 -= self.lower*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi/2) + self.lower*np.cos(phi-phi1.T)) + IPPprim = np.where(np.isnan(IPPprim1),IPPprim2,IPPprim1) + + IPPint1 = 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi) + 1./(omega-omega1.T)**2*np.cos((omega-omega1.T)*self.upper+phi-phi1.T-np.pi) + IPPint1 -= 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi) + 1./(omega-omega1.T)**2*np.cos((omega-omega1.T)*self.lower+phi-phi1.T-np.pi) + IPPint2 = 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi) + 1./2*self.upper**2*np.cos(phi-phi1.T) + IPPint2 -= 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi) + 1./2*self.lower**2*np.cos(phi-phi1.T) + IPPint = np.where(np.isnan(IPPint1),IPPint2,IPPint1) + + dLa_dper2 = np.column_stack((-self.a[1]*self.basis_omega/self.period, -2*self.a[2]*self.basis_omega**2/self.period)) + dLp_dper2 = np.column_stack((self.basis_phi+np.pi/2,self.basis_phi+np.pi)) + r2,omega2,phi2 = self._cos_factorization(dLa_dper2,Lo[:,0:2],dLp_dper2) + + dGint_dper = np.dot(r,r1.T)/2 * (IPPprim - IPPint) + self._int_computation(r2,omega2,phi2, r,omega,phi) + dGint_dper = dGint_dper + dGint_dper.T + + dFlower_dper = np.array(self._cos(-self.lower*self.basis_alpha*self.basis_omega/self.period,self.basis_omega,self.basis_phi+np.pi/2)(self.lower))[:,None] + dF1lower_dper = np.array(self._cos(-self.lower*self.basis_alpha*self.basis_omega**2/self.period,self.basis_omega,self.basis_phi+np.pi)(self.lower)+self._cos(-self.basis_alpha*self.basis_omega/self.period,self.basis_omega,self.basis_phi+np.pi/2)(self.lower))[:,None] + + dG_dper = 1./self.variance*(self.lengthscale**3/(12*np.sqrt(3))*dGint_dper + self.b[0]*(np.dot(dFlower_dper,Flower.T)+np.dot(Flower,dFlower_dper.T)) + self.b[1]*(np.dot(dF1lower_dper,F1lower.T)+np.dot(F1lower,dF1lower_dper.T))) + + dK_dper = mdot(dFX_dper,self.Gi,FX2.T) - mdot(FX,self.Gi,dG_dper,self.Gi,FX2.T) + mdot(FX,self.Gi,dFX2_dper.T) + + self.variance.gradient = np.sum(dK_dvar*dL_dK) + self.lengthscale.gradient = np.sum(dK_dlen*dL_dK) + self.period.gradient = np.sum(dK_dper*dL_dK) + + +
+
[docs]class PeriodicMatern52(Periodic): + """ + Kernel of the periodic subspace (up to a given frequency) of a Matern 5/2 RKHS. Only defined for input_dim=1. + + :param input_dim: the number of input dimensions + :type input_dim: int + :param variance: the variance of the Matern kernel + :type variance: float + :param lengthscale: the lengthscale of the Matern kernel + :type lengthscale: np.ndarray of size (input_dim,) + :param period: the period + :type period: float + :param n_freq: the number of frequencies considered for the periodic subspace + :type n_freq: int + :rtype: kernel object + + """ + + def __init__(self, input_dim=1, variance=1., lengthscale=1., period=2.*np.pi, n_freq=10, lower=0., upper=4*np.pi, active_dims=None, name='periodic_Matern52'): + super(PeriodicMatern52, self).__init__(input_dim, variance, lengthscale, period, n_freq, lower, upper, active_dims, name) + +
[docs] def parameters_changed(self): + self.a = [5*np.sqrt(5)/self.lengthscale**3, 15./self.lengthscale**2,3*np.sqrt(5)/self.lengthscale, 1.] + self.b = [9./8, 9*self.lengthscale**4/200., 3*self.lengthscale**2/5., 3*self.lengthscale**2/(5*8.), 3*self.lengthscale**2/(5*8.)] + + self.basis_alpha = np.ones((2*self.n_freq,)) + self.basis_omega = (2*np.pi*np.arange(1,self.n_freq+1)/self.period).repeat(2) + self.basis_phi = np.zeros(self.n_freq * 2) + self.basis_phi[::2] = -np.pi/2 + + self.G = self.Gram_matrix() + self.Gi = np.linalg.inv(self.G) +
+
[docs] def Gram_matrix(self): + La = np.column_stack((self.a[0]*np.ones((self.n_basis,1)), self.a[1]*self.basis_omega, self.a[2]*self.basis_omega**2, self.a[3]*self.basis_omega**3)) + Lo = np.column_stack((self.basis_omega, self.basis_omega, self.basis_omega, self.basis_omega)) + Lp = np.column_stack((self.basis_phi, self.basis_phi+np.pi/2, self.basis_phi+np.pi, self.basis_phi+np.pi*3/2)) + r,omega,phi = self._cos_factorization(La,Lo,Lp) + Gint = self._int_computation( r,omega,phi, r,omega,phi) + + Flower = np.array(self._cos(self.basis_alpha,self.basis_omega,self.basis_phi)(self.lower))[:,None] + F1lower = np.array(self._cos(self.basis_alpha*self.basis_omega,self.basis_omega,self.basis_phi+np.pi/2)(self.lower))[:,None] + F2lower = np.array(self._cos(self.basis_alpha*self.basis_omega**2,self.basis_omega,self.basis_phi+np.pi)(self.lower))[:,None] + lower_terms = self.b[0]*np.dot(Flower,Flower.T) + self.b[1]*np.dot(F2lower,F2lower.T) + self.b[2]*np.dot(F1lower,F1lower.T) + self.b[3]*np.dot(F2lower,Flower.T) + self.b[4]*np.dot(Flower,F2lower.T) + return(3*self.lengthscale**5/(400*np.sqrt(5)*self.variance) * Gint + 1./self.variance*lower_terms) +
+ @silence_errors +
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + if X2 is None: X2 = X + FX = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X) + FX2 = self._cos(self.basis_alpha[None,:],self.basis_omega[None,:],self.basis_phi[None,:])(X2) + + La = np.column_stack((self.a[0]*np.ones((self.n_basis,1)), self.a[1]*self.basis_omega, self.a[2]*self.basis_omega**2, self.a[3]*self.basis_omega**3)) + Lo = np.column_stack((self.basis_omega, self.basis_omega, self.basis_omega, self.basis_omega)) + Lp = np.column_stack((self.basis_phi, self.basis_phi+np.pi/2, self.basis_phi+np.pi, self.basis_phi+np.pi*3/2)) + r,omega,phi = self._cos_factorization(La,Lo,Lp) + Gint = self._int_computation( r,omega,phi, r,omega,phi) + + Flower = np.array(self._cos(self.basis_alpha,self.basis_omega,self.basis_phi)(self.lower))[:,None] + F1lower = np.array(self._cos(self.basis_alpha*self.basis_omega,self.basis_omega,self.basis_phi+np.pi/2)(self.lower))[:,None] + F2lower = np.array(self._cos(self.basis_alpha*self.basis_omega**2,self.basis_omega,self.basis_phi+np.pi)(self.lower))[:,None] + + #dK_dvar + dK_dvar = 1./self.variance*mdot(FX,self.Gi,FX2.T) + + #dK_dlen + da_dlen = [-3*self.a[0]/self.lengthscale, -2*self.a[1]/self.lengthscale, -self.a[2]/self.lengthscale, 0.] + db_dlen = [0., 4*self.b[1]/self.lengthscale, 2*self.b[2]/self.lengthscale, 2*self.b[3]/self.lengthscale, 2*self.b[4]/self.lengthscale] + dLa_dlen = np.column_stack((da_dlen[0]*np.ones((self.n_basis,1)), da_dlen[1]*self.basis_omega, da_dlen[2]*self.basis_omega**2, da_dlen[3]*self.basis_omega**3)) + r1,omega1,phi1 = self._cos_factorization(dLa_dlen,Lo,Lp) + dGint_dlen = self._int_computation(r1,omega1,phi1, r,omega,phi) + dGint_dlen = dGint_dlen + dGint_dlen.T + dlower_terms_dlen = db_dlen[0]*np.dot(Flower,Flower.T) + db_dlen[1]*np.dot(F2lower,F2lower.T) + db_dlen[2]*np.dot(F1lower,F1lower.T) + db_dlen[3]*np.dot(F2lower,Flower.T) + db_dlen[4]*np.dot(Flower,F2lower.T) + dG_dlen = 15*self.lengthscale**4/(400*np.sqrt(5))*Gint + 3*self.lengthscale**5/(400*np.sqrt(5))*dGint_dlen + dlower_terms_dlen + dK_dlen = -mdot(FX,self.Gi,dG_dlen/self.variance,self.Gi,FX2.T) + + #dK_dper + dFX_dper = self._cos(-self.basis_alpha[None,:]*self.basis_omega[None,:]/self.period*X ,self.basis_omega[None,:],self.basis_phi[None,:]+np.pi/2)(X) + dFX2_dper = self._cos(-self.basis_alpha[None,:]*self.basis_omega[None,:]/self.period*X2,self.basis_omega[None,:],self.basis_phi[None,:]+np.pi/2)(X2) + + dLa_dper = np.column_stack((-self.a[0]*self.basis_omega/self.period, -self.a[1]*self.basis_omega**2/self.period, -self.a[2]*self.basis_omega**3/self.period, -self.a[3]*self.basis_omega**4/self.period)) + dLp_dper = np.column_stack((self.basis_phi+np.pi/2,self.basis_phi+np.pi,self.basis_phi+np.pi*3/2,self.basis_phi)) + r1,omega1,phi1 = self._cos_factorization(dLa_dper,Lo,dLp_dper) + + IPPprim1 = self.upper*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi/2) + 1./(omega-omega1.T)*np.cos((omega-omega1.T)*self.upper+phi-phi1.T-np.pi/2)) + IPPprim1 -= self.lower*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi/2) + 1./(omega-omega1.T)*np.cos((omega-omega1.T)*self.lower+phi-phi1.T-np.pi/2)) + IPPprim2 = self.upper*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi/2) + self.upper*np.cos(phi-phi1.T)) + IPPprim2 -= self.lower*(1./(omega+omega1.T)*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi/2) + self.lower*np.cos(phi-phi1.T)) + IPPprim = np.where(np.isnan(IPPprim1),IPPprim2,IPPprim1) + + IPPint1 = 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi) + 1./(omega-omega1.T)**2*np.cos((omega-omega1.T)*self.upper+phi-phi1.T-np.pi) + IPPint1 -= 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi) + 1./(omega-omega1.T)**2*np.cos((omega-omega1.T)*self.lower+phi-phi1.T-np.pi) + IPPint2 = 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.upper+phi+phi1.T-np.pi) + 1./2*self.upper**2*np.cos(phi-phi1.T) + IPPint2 -= 1./(omega+omega1.T)**2*np.cos((omega+omega1.T)*self.lower+phi+phi1.T-np.pi) + 1./2*self.lower**2*np.cos(phi-phi1.T) + IPPint = np.where(np.isnan(IPPint1),IPPint2,IPPint1) + + dLa_dper2 = np.column_stack((-self.a[1]*self.basis_omega/self.period, -2*self.a[2]*self.basis_omega**2/self.period, -3*self.a[3]*self.basis_omega**3/self.period)) + dLp_dper2 = np.column_stack((self.basis_phi+np.pi/2, self.basis_phi+np.pi, self.basis_phi+np.pi*3/2)) + r2,omega2,phi2 = self._cos_factorization(dLa_dper2,Lo[:,0:2],dLp_dper2) + + dGint_dper = np.dot(r,r1.T)/2 * (IPPprim - IPPint) + self._int_computation(r2,omega2,phi2, r,omega,phi) + dGint_dper = dGint_dper + dGint_dper.T + + dFlower_dper = np.array(self._cos(-self.lower*self.basis_alpha*self.basis_omega/self.period,self.basis_omega,self.basis_phi+np.pi/2)(self.lower))[:,None] + dF1lower_dper = np.array(self._cos(-self.lower*self.basis_alpha*self.basis_omega**2/self.period,self.basis_omega,self.basis_phi+np.pi)(self.lower)+self._cos(-self.basis_alpha*self.basis_omega/self.period,self.basis_omega,self.basis_phi+np.pi/2)(self.lower))[:,None] + dF2lower_dper = np.array(self._cos(-self.lower*self.basis_alpha*self.basis_omega**3/self.period,self.basis_omega,self.basis_phi+np.pi*3/2)(self.lower) + self._cos(-2*self.basis_alpha*self.basis_omega**2/self.period,self.basis_omega,self.basis_phi+np.pi)(self.lower))[:,None] + + dlower_terms_dper = self.b[0] * (np.dot(dFlower_dper,Flower.T) + np.dot(Flower.T,dFlower_dper)) + dlower_terms_dper += self.b[1] * (np.dot(dF2lower_dper,F2lower.T) + np.dot(F2lower,dF2lower_dper.T)) - 4*self.b[1]/self.period*np.dot(F2lower,F2lower.T) + dlower_terms_dper += self.b[2] * (np.dot(dF1lower_dper,F1lower.T) + np.dot(F1lower,dF1lower_dper.T)) - 2*self.b[2]/self.period*np.dot(F1lower,F1lower.T) + dlower_terms_dper += self.b[3] * (np.dot(dF2lower_dper,Flower.T) + np.dot(F2lower,dFlower_dper.T)) - 2*self.b[3]/self.period*np.dot(F2lower,Flower.T) + dlower_terms_dper += self.b[4] * (np.dot(dFlower_dper,F2lower.T) + np.dot(Flower,dF2lower_dper.T)) - 2*self.b[4]/self.period*np.dot(Flower,F2lower.T) + + dG_dper = 1./self.variance*(3*self.lengthscale**5/(400*np.sqrt(5))*dGint_dper + 0.5*dlower_terms_dper) + dK_dper = mdot(dFX_dper,self.Gi,FX2.T) - mdot(FX,self.Gi,dG_dper,self.Gi,FX2.T) + mdot(FX,self.Gi,dFX2_dper.T) + + self.variance.gradient = np.sum(dK_dvar*dL_dK) + self.lengthscale.gradient = np.sum(dK_dlen*dL_dK) + self.period.gradient = np.sum(dK_dper*dL_dK) +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/poly.html b/doc/_build/html/_modules/GPy/kern/_src/poly.html new file mode 100644 index 00000000..9d77898f --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/poly.html @@ -0,0 +1,135 @@ + + + + + + + + GPy.kern._src.poly — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.poly

+# Copyright (c) 2014, James Hensman
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from kern import Kern
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+
[docs]class Poly(Kern): + """ + Polynomial kernel + """ + + def __init__(self, input_dim, variance=1., order=3., active_dims=None, name='poly'): + super(Poly, self).__init__(input_dim, active_dims, name) + self.variance = Param('variance', variance, Logexp()) + self.link_parameter(self.variance) + self.order=order + +
[docs] def K(self, X, X2=None): + return (self._dot_product(X, X2) + 1.)**self.order * self.variance +
+ def _dot_product(self, X, X2=None): + if X2 is None: + return np.dot(X, X.T) + else: + return np.dot(X, X2.T) + +
[docs] def Kdiag(self, X): + return self.variance*(np.square(X).sum(1) + 1.)**self.order +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + self.variance.gradient = np.sum(dL_dK * (self._dot_product(X, X2) + 1.)**self.order) +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + raise NotImplementedError +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + raise NotImplementedError +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + raise NotImplementedError
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/prod.html b/doc/_build/html/_modules/GPy/kern/_src/prod.html new file mode 100644 index 00000000..1988b28c --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/prod.html @@ -0,0 +1,160 @@ + + + + + + + + GPy.kern._src.prod — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.prod

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from kern import CombinationKernel
+from ...util.caching import Cache_this
+import itertools
+
+
[docs]class Prod(CombinationKernel): + """ + Computes the product of 2 kernels + + :param k1, k2: the kernels to multiply + :type k1, k2: Kern + :param tensor: The kernels are either multiply as functions defined on the same input space (default) or on the product of the input spaces + :type tensor: Boolean + :rtype: kernel object + + """ + def __init__(self, kernels, name='mul'): + for i, kern in enumerate(kernels[:]): + if isinstance(kern, Prod): + del kernels[i] + for part in kern.parts[::-1]: + kern.unlink_parameter(part) + kernels.insert(i, part) + super(Prod, self).__init__(kernels, name) + + @Cache_this(limit=2, force_kwargs=['which_parts']) +
[docs] def K(self, X, X2=None, which_parts=None): + if which_parts is None: + which_parts = self.parts + elif not isinstance(which_parts, (list, tuple)): + # if only one part is given + which_parts = [which_parts] + return reduce(np.multiply, (p.K(X, X2) for p in which_parts)) +
+ @Cache_this(limit=2, force_kwargs=['which_parts']) +
[docs] def Kdiag(self, X, which_parts=None): + if which_parts is None: + which_parts = self.parts + return reduce(np.multiply, (p.Kdiag(X) for p in which_parts)) +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + k = self.K(X,X2)*dL_dK + for p in self.parts: + p.update_gradients_full(k/p.K(X,X2),X,X2) +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + k = self.Kdiag(X)*dL_dKdiag + for p in self.parts: + p.update_gradients_diag(k/p.Kdiag(X),X) +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + target = np.zeros(X.shape) + k = self.K(X,X2)*dL_dK + for p in self.parts: + target += p.gradients_X(k/p.K(X,X2),X,X2) + return target +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + target = np.zeros(X.shape) + k = self.Kdiag(X)*dL_dKdiag + for p in self.parts: + target += p.gradients_X_diag(k/p.Kdiag(X),X) + return target
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/psi_comp.html b/doc/_build/html/_modules/GPy/kern/_src/psi_comp.html new file mode 100644 index 00000000..21672469 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/psi_comp.html @@ -0,0 +1,149 @@ + + + + + + + + GPy.kern._src.psi_comp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.psi_comp

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from ....core.parameterization.parameter_core import Pickleable
+from GPy.util.caching import Cache_this
+from ....core.parameterization import variational
+import rbf_psi_comp
+import ssrbf_psi_comp
+import sslinear_psi_comp
+import linear_psi_comp
+
+
[docs]class PSICOMP_RBF(Pickleable): + @Cache_this(limit=2, ignore_args=(0,)) + def psicomputations(self, variance, lengthscale, Z, variational_posterior): + if isinstance(variational_posterior, variational.NormalPosterior): + return rbf_psi_comp.psicomputations(variance, lengthscale, Z, variational_posterior) + elif isinstance(variational_posterior, variational.SpikeAndSlabPosterior): + return ssrbf_psi_comp.psicomputations(variance, lengthscale, Z, variational_posterior) + else: + raise ValueError, "unknown distriubtion received for psi-statistics" + + @Cache_this(limit=2, ignore_args=(0,1,2,3)) + def psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior): + if isinstance(variational_posterior, variational.NormalPosterior): + return rbf_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior) + elif isinstance(variational_posterior, variational.SpikeAndSlabPosterior): + return ssrbf_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior) + else: + raise ValueError, "unknown distriubtion received for psi-statistics" + + def _setup_observers(self): + pass +
+
[docs]class PSICOMP_Linear(Pickleable): + + @Cache_this(limit=2, ignore_args=(0,)) + def psicomputations(self, variance, Z, variational_posterior): + if isinstance(variational_posterior, variational.NormalPosterior): + return linear_psi_comp.psicomputations(variance, Z, variational_posterior) + elif isinstance(variational_posterior, variational.SpikeAndSlabPosterior): + return sslinear_psi_comp.psicomputations(variance, Z, variational_posterior) + else: + raise ValueError, "unknown distriubtion received for psi-statistics" + + @Cache_this(limit=2, ignore_args=(0,1,2,3)) + def psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior): + if isinstance(variational_posterior, variational.NormalPosterior): + return linear_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior) + elif isinstance(variational_posterior, variational.SpikeAndSlabPosterior): + return sslinear_psi_comp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior) + else: + raise ValueError, "unknown distriubtion received for psi-statistics" + + def _setup_observers(self): + pass
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/psi_comp/linear_psi_comp.html b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/linear_psi_comp.html new file mode 100644 index 00000000..bfd33eb2 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/linear_psi_comp.html @@ -0,0 +1,173 @@ + + + + + + + + GPy.kern._src.psi_comp.linear_psi_comp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.psi_comp.linear_psi_comp

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+"""
+The package for the Psi statistics computation of the linear kernel for Bayesian GPLVM
+"""
+
+import numpy as np
+from ....util.linalg import tdot
+
+
[docs]def psicomputations(variance, Z, variational_posterior): + """ + Compute psi-statistics for ss-linear kernel + """ + # here are the "statistics" for psi0, psi1 and psi2 + # Produced intermediate results: + # psi0 N + # psi1 NxM + # psi2 MxM + mu = variational_posterior.mean + S = variational_posterior.variance + + psi0 = (variance*(np.square(mu)+S)).sum(axis=1) + psi1 = np.dot(mu,(variance*Z).T) + psi2 = np.dot(S.sum(axis=0)*np.square(variance)*Z,Z.T)+ tdot(psi1.T) + + return psi0, psi1, psi2 +
+
[docs]def psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior): + mu = variational_posterior.mean + S = variational_posterior.variance + + dL_dvar, dL_dmu, dL_dS, dL_dZ = _psi2computations(dL_dpsi2, variance, Z, mu, S) + + # Compute for psi0 and psi1 + mu2S = np.square(mu)+S + dL_dpsi0_var = dL_dpsi0[:,None]*variance[None,:] + dL_dpsi1_mu = np.dot(dL_dpsi1.T,mu) + dL_dvar += (dL_dpsi0[:,None]*mu2S).sum(axis=0)+ (dL_dpsi1_mu*Z).sum(axis=0) + dL_dmu += 2.*dL_dpsi0_var*mu+np.dot(dL_dpsi1,Z)*variance + dL_dS += dL_dpsi0_var + dL_dZ += dL_dpsi1_mu*variance + + return dL_dvar, dL_dZ, dL_dmu, dL_dS +
+def _psi2computations(dL_dpsi2, variance, Z, mu, S): + """ + Z - MxQ + mu - NxQ + S - NxQ + gamma - NxQ + """ + # here are the "statistics" for psi1 and psi2 + # Produced intermediate results: + # _psi2_dvariance Q + # _psi2_dZ MxQ + # _psi2_dmu NxQ + # _psi2_dS NxQ + + variance2 = np.square(variance) + common_sum = np.dot(mu,(variance*Z).T) + Z_expect = (np.dot(dL_dpsi2,Z)*Z).sum(axis=0) + dL_dpsi2T = dL_dpsi2+dL_dpsi2.T + common_expect = np.dot(common_sum,np.dot(dL_dpsi2T,Z)) + Z2_expect = np.inner(common_sum,dL_dpsi2T) + Z1_expect = np.dot(dL_dpsi2T,Z) + + dL_dvar = 2.*S.sum(axis=0)*variance*Z_expect+(common_expect*mu).sum(axis=0) + + dL_dmu = common_expect*variance + + dL_dS = np.empty(S.shape) + dL_dS[:] = Z_expect*variance2 + + dL_dZ = variance2*S.sum(axis=0)*Z1_expect+np.dot(Z2_expect.T,variance*mu) + + return dL_dvar, dL_dmu, dL_dS, dL_dZ +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/psi_comp/rbf_psi_comp.html b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/rbf_psi_comp.html new file mode 100644 index 00000000..5d746f8d --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/rbf_psi_comp.html @@ -0,0 +1,257 @@ + + + + + + + + GPy.kern._src.psi_comp.rbf_psi_comp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.psi_comp.rbf_psi_comp

+"""
+The module for psi-statistics for RBF kernel
+"""
+
+import numpy as np
+from GPy.util.caching import Cacher
+
+
[docs]def psicomputations(variance, lengthscale, Z, variational_posterior): + """ + Z - MxQ + mu - NxQ + S - NxQ + gamma - NxQ + """ + # here are the "statistics" for psi0, psi1 and psi2 + # Produced intermediate results: + # _psi1 NxM + mu = variational_posterior.mean + S = variational_posterior.variance + + psi0 = np.empty(mu.shape[0]) + psi0[:] = variance + psi1 = _psi1computations(variance, lengthscale, Z, mu, S) + psi2 = _psi2computations(variance, lengthscale, Z, mu, S).sum(axis=0) + return psi0, psi1, psi2 +
+def __psi1computations(variance, lengthscale, Z, mu, S): + """ + Z - MxQ + mu - NxQ + S - NxQ + gamma - NxQ + """ + # here are the "statistics" for psi1 + # Produced intermediate results: + # _psi1 NxM + + lengthscale2 = np.square(lengthscale) + + # psi1 + _psi1_logdenom = np.log(S/lengthscale2+1.).sum(axis=-1) # N + _psi1_log = (_psi1_logdenom[:,None]+np.einsum('nmq,nq->nm',np.square(mu[:,None,:]-Z[None,:,:]),1./(S+lengthscale2)))/(-2.) + _psi1 = variance*np.exp(_psi1_log) + + return _psi1 + +def __psi2computations(variance, lengthscale, Z, mu, S): + """ + Z - MxQ + mu - NxQ + S - NxQ + gamma - NxQ + """ + # here are the "statistics" for psi2 + # Produced intermediate results: + # _psi2 MxM + + lengthscale2 = np.square(lengthscale) + + _psi2_logdenom = np.log(2.*S/lengthscale2+1.).sum(axis=-1)/(-2.) # N + _psi2_exp1 = (np.square(Z[:,None,:]-Z[None,:,:])/lengthscale2).sum(axis=-1)/(-4.) #MxM + Z_hat = (Z[:,None,:]+Z[None,:,:])/2. #MxMxQ + denom = 1./(2.*S+lengthscale2) + _psi2_exp2 = -(np.square(mu)*denom).sum(axis=-1)[:,None,None]+2.*np.einsum('nq,moq,nq->nmo',mu,Z_hat,denom)-np.einsum('moq,nq->nmo',np.square(Z_hat),denom) + _psi2 = variance*variance*np.exp(_psi2_logdenom[:,None,None]+_psi2_exp1[None,:,:]+_psi2_exp2) + + + return _psi2 + +
[docs]def psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior): + ARD = (len(lengthscale)!=1) + + dvar_psi1, dl_psi1, dZ_psi1, dmu_psi1, dS_psi1 = _psi1compDer(dL_dpsi1, variance, lengthscale, Z, variational_posterior.mean, variational_posterior.variance) + dvar_psi2, dl_psi2, dZ_psi2, dmu_psi2, dS_psi2 = _psi2compDer(dL_dpsi2, variance, lengthscale, Z, variational_posterior.mean, variational_posterior.variance) + + dL_dvar = np.sum(dL_dpsi0) + dvar_psi1 + dvar_psi2 + + dL_dlengscale = dl_psi1 + dl_psi2 + if not ARD: + dL_dlengscale = dL_dlengscale.sum() + + dL_dmu = dmu_psi1 + dmu_psi2 + dL_dS = dS_psi1 + dS_psi2 + dL_dZ = dZ_psi1 + dZ_psi2 + + return dL_dvar, dL_dlengscale, dL_dZ, dL_dmu, dL_dS +
+def _psi1compDer(dL_dpsi1, variance, lengthscale, Z, mu, S): + """ + dL_dpsi1 - NxM + Z - MxQ + mu - NxQ + S - NxQ + gamma - NxQ + """ + # here are the "statistics" for psi1 + # Produced intermediate results: dL_dparams w.r.t. psi1 + # _dL_dvariance 1 + # _dL_dlengthscale Q + # _dL_dZ MxQ + # _dL_dgamma NxQ + # _dL_dmu NxQ + # _dL_dS NxQ + + lengthscale2 = np.square(lengthscale) + + _psi1 = _psi1computations(variance, lengthscale, Z, mu, S) + Lpsi1 = dL_dpsi1*_psi1 + Zmu = Z[None,:,:]-mu[:,None,:] # NxMxQ + denom = 1./(S+lengthscale2) + Zmu2_denom = np.square(Zmu)*denom[:,None,:] #NxMxQ + _dL_dvar = Lpsi1.sum()/variance + _dL_dmu = np.einsum('nm,nmq,nq->nq',Lpsi1,Zmu,denom) + _dL_dS = np.einsum('nm,nmq,nq->nq',Lpsi1,(Zmu2_denom-1.),denom)/2. + _dL_dZ = -np.einsum('nm,nmq,nq->mq',Lpsi1,Zmu,denom) + _dL_dl = np.einsum('nm,nmq,nq->q',Lpsi1,(Zmu2_denom+(S/lengthscale2)[:,None,:]),denom*lengthscale) + + return _dL_dvar, _dL_dl, _dL_dZ, _dL_dmu, _dL_dS + +def _psi2compDer(dL_dpsi2, variance, lengthscale, Z, mu, S): + """ + Z - MxQ + mu - NxQ + S - NxQ + gamma - NxQ + dL_dpsi2 - MxM + """ + # here are the "statistics" for psi2 + # Produced the derivatives w.r.t. psi2: + # _dL_dvariance 1 + # _dL_dlengthscale Q + # _dL_dZ MxQ + # _dL_dgamma NxQ + # _dL_dmu NxQ + # _dL_dS NxQ + + lengthscale2 = np.square(lengthscale) + denom = 1./(2*S+lengthscale2) + denom2 = np.square(denom) + + _psi2 = _psi2computations(variance, lengthscale, Z, mu, S) # NxMxM + Lpsi2 = dL_dpsi2*_psi2 # dL_dpsi2 is MxM, using broadcast to multiply N out + Lpsi2sum = np.einsum('nmo->n',Lpsi2) #N + Lpsi2Z = np.einsum('nmo,oq->nq',Lpsi2,Z) #NxQ + Lpsi2Z2 = np.einsum('nmo,oq,oq->nq',Lpsi2,Z,Z) #NxQ + Lpsi2Z2p = np.einsum('nmo,mq,oq->nq',Lpsi2,Z,Z) #NxQ + Lpsi2Zhat = Lpsi2Z + Lpsi2Zhat2 = (Lpsi2Z2+Lpsi2Z2p)/2 + + _dL_dvar = Lpsi2sum.sum()*2/variance + _dL_dmu = (-2*denom) * (mu*Lpsi2sum[:,None]-Lpsi2Zhat) + _dL_dS = (2*np.square(denom))*(np.square(mu)*Lpsi2sum[:,None]-2*mu*Lpsi2Zhat+Lpsi2Zhat2) - denom*Lpsi2sum[:,None] + _dL_dZ = -np.einsum('nmo,oq->oq',Lpsi2,Z)/lengthscale2+np.einsum('nmo,oq->mq',Lpsi2,Z)/lengthscale2+ \ + 2*np.einsum('nmo,nq,nq->mq',Lpsi2,mu,denom) - np.einsum('nmo,nq,mq->mq',Lpsi2,denom,Z) - np.einsum('nmo,oq,nq->mq',Lpsi2,Z,denom) + _dL_dl = 2*lengthscale* ((S/lengthscale2*denom+np.square(mu*denom))*Lpsi2sum[:,None]+(Lpsi2Z2-Lpsi2Z2p)/(2*np.square(lengthscale2))- + (2*mu*denom2)*Lpsi2Zhat+denom2*Lpsi2Zhat2).sum(axis=0) + + return _dL_dvar, _dL_dl, _dL_dZ, _dL_dmu, _dL_dS + +_psi1computations = Cacher(__psi1computations, limit=1) +_psi2computations = Cacher(__psi2computations, limit=1) +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/psi_comp/rbf_psi_gpucomp.html b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/rbf_psi_gpucomp.html new file mode 100644 index 00000000..520fe9e3 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/rbf_psi_gpucomp.html @@ -0,0 +1,506 @@ + + + + + + + + GPy.kern._src.psi_comp.rbf_psi_gpucomp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.psi_comp.rbf_psi_gpucomp

+"""
+The module for psi-statistics for RBF kernel
+"""
+
+import numpy as np
+from ....util.caching import Cache_this
+from . import PSICOMP_RBF
+from ....util import gpu_init
+
+try:
+    import pycuda.gpuarray as gpuarray
+    from pycuda.compiler import SourceModule
+    from ....util.linalg_gpu import sum_axis
+except:
+    pass    
+
+gpu_code = """
+    // define THREADNUM
+
+    #define IDX_NMQ(n,m,q) ((q*M+m)*N+n)
+    #define IDX_NMM(n,m1,m2) ((m2*M+m1)*N+n)
+    #define IDX_NQ(n,q) (q*N+n)
+    #define IDX_NM(n,m) (m*N+n)
+    #define IDX_MQ(m,q) (q*M+m)
+    #define IDX_MM(m1,m2) (m2*M+m1)
+    #define IDX_NQB(n,q,b) ((b*Q+q)*N+n)
+    #define IDX_QB(q,b) (b*Q+q)
+
+    // Divide data evenly
+    __device__ void divide_data(int total_data, int psize, int pidx, int *start, int *end) {
+        int residue = (total_data)%psize;
+        if(pidx<residue) {
+            int size = total_data/psize+1;
+            *start = size*pidx;
+            *end = *start+size;
+        } else {
+            int size = total_data/psize;
+            *start = size*pidx+residue;
+            *end = *start+size;
+        }
+    }
+    
+    __device__ void reduce_sum(double* array, int array_size) {
+        int s;
+        if(array_size >= blockDim.x) {
+            for(int i=blockDim.x+threadIdx.x; i<array_size; i+= blockDim.x) {
+                array[threadIdx.x] += array[i];
+            }
+            array_size = blockDim.x;
+        }
+        __syncthreads();
+        for(int i=1; i<=array_size;i*=2) {s=i;}
+        if(threadIdx.x < array_size-s) {array[threadIdx.x] += array[s+threadIdx.x];}
+        __syncthreads();
+        for(s=s/2;s>=1;s=s/2) {
+            if(threadIdx.x < s) {array[threadIdx.x] += array[s+threadIdx.x];}
+            __syncthreads();
+        }
+    }
+
+    __global__ void compDenom(double *log_denom1, double *log_denom2, double *l, double *S, int N, int Q)
+    {
+        int n_start, n_end;
+        divide_data(N, gridDim.x, blockIdx.x, &n_start, &n_end);
+        
+        for(int i=n_start*Q+threadIdx.x; i<n_end*Q; i+=blockDim.x) {
+            int n=i/Q;
+            int q=i%Q;
+
+            double Snq = S[IDX_NQ(n,q)];
+            double lq = l[q]*l[q];
+            log_denom1[IDX_NQ(n,q)] = log(Snq/lq+1.);
+            log_denom2[IDX_NQ(n,q)] = log(2.*Snq/lq+1.);
+        }
+    }
+
+    __global__ void psi1computations(double *psi1, double *log_denom1, double var, double *l, double *Z, double *mu, double *S, int N, int M, int Q)
+    {
+        int m_start, m_end;
+        divide_data(M, gridDim.x, blockIdx.x, &m_start, &m_end);
+        
+        for(int m=m_start; m<m_end; m++) {
+            for(int n=threadIdx.x; n<N; n+= blockDim.x) {            
+                double log_psi1 = 0;
+                for(int q=0;q<Q;q++) {
+                    double muZ = mu[IDX_NQ(n,q)]-Z[IDX_MQ(m,q)];
+                    double Snq = S[IDX_NQ(n,q)];
+                    double lq = l[q]*l[q];
+                    log_psi1 += (muZ*muZ/(Snq+lq)+log_denom1[IDX_NQ(n,q)])/(-2.);
+                }
+                psi1[IDX_NM(n,m)] = var*exp(log_psi1);
+            }
+        }
+    }
+    
+    __global__ void psi2computations(double *psi2, double *psi2n, double *log_denom2, double var, double *l, double *Z, double *mu, double *S, int N, int M, int Q)
+    {
+        int psi2_idx_start, psi2_idx_end;
+        __shared__ double psi2_local[THREADNUM];
+        divide_data((M+1)*M/2, gridDim.x, blockIdx.x, &psi2_idx_start, &psi2_idx_end);
+        
+        for(int psi2_idx=psi2_idx_start; psi2_idx<psi2_idx_end; psi2_idx++) {
+            int m1 = int((sqrt(8.*psi2_idx+1.)-1.)/2.);
+            int m2 = psi2_idx - (m1+1)*m1/2;
+            
+            psi2_local[threadIdx.x] = 0;
+            for(int n=threadIdx.x;n<N;n+=blockDim.x) {
+                double log_psi2_n = 0;
+                for(int q=0;q<Q;q++) {
+                    double dZ = Z[IDX_MQ(m1,q)] - Z[IDX_MQ(m2,q)];
+                    double muZhat = mu[IDX_NQ(n,q)]- (Z[IDX_MQ(m1,q)]+Z[IDX_MQ(m2,q)])/2.;
+                    double Snq = S[IDX_NQ(n,q)];
+                    double lq = l[q]*l[q];
+                    log_psi2_n += dZ*dZ/(-4.*lq)-muZhat*muZhat/(2.*Snq+lq) + log_denom2[IDX_NQ(n,q)]/(-2.);
+                }
+                double exp_psi2_n = exp(log_psi2_n);
+                psi2n[IDX_NMM(n,m1,m2)] = var*var*exp_psi2_n;
+                if(m1!=m2) { psi2n[IDX_NMM(n,m2,m1)] = var*var*exp_psi2_n;}
+                psi2_local[threadIdx.x] += exp_psi2_n;
+            }
+            __syncthreads();
+            reduce_sum(psi2_local, THREADNUM);
+            if(threadIdx.x==0) {
+                psi2[IDX_MM(m1,m2)] = var*var*psi2_local[0];
+                if(m1!=m2) { psi2[IDX_MM(m2,m1)] = var*var*psi2_local[0]; }
+            }
+            __syncthreads();
+        }
+    }
+    
+    __global__ void psi1compDer(double *dvar, double *dl, double *dZ, double *dmu, double *dS, double *dL_dpsi1, double *psi1, double var, double *l, double *Z, double *mu, double *S, int N, int M, int Q)
+    {
+        int m_start, m_end;
+        __shared__ double g_local[THREADNUM];
+        divide_data(M, gridDim.x, blockIdx.x, &m_start, &m_end);
+        int P = int(ceil(double(N)/THREADNUM));
+
+        double dvar_local = 0;
+        for(int q=0;q<Q;q++) {
+            double lq_sqrt = l[q];
+            double lq = lq_sqrt*lq_sqrt;
+            double dl_local = 0;
+            for(int p=0;p<P;p++) {
+                int n = p*THREADNUM + threadIdx.x;
+                double dmu_local = 0;
+                double dS_local = 0;
+                double Snq,mu_nq;
+                if(n<N) {Snq = S[IDX_NQ(n,q)]; mu_nq=mu[IDX_NQ(n,q)];}
+                for(int m=m_start; m<m_end; m++) {
+                    if(n<N) {
+                        double lpsi1 = psi1[IDX_NM(n,m)]*dL_dpsi1[IDX_NM(n,m)];
+                        if(q==0) {dvar_local += lpsi1;}
+                        
+                        double Zmu = Z[IDX_MQ(m,q)] - mu_nq;
+                        double denom = Snq+lq;
+                        double Zmu2_denom = Zmu*Zmu/denom;
+                        
+                        dmu_local += lpsi1*Zmu/denom;
+                        dS_local += lpsi1*(Zmu2_denom-1.)/denom;
+                        dl_local += lpsi1*(Zmu2_denom+Snq/lq)/denom;
+                        g_local[threadIdx.x] = -lpsi1*Zmu/denom;
+                    }
+                    __syncthreads();
+                    reduce_sum(g_local, p<P-1?THREADNUM:N-(P-1)*THREADNUM);
+                    if(threadIdx.x==0) {dZ[IDX_MQ(m,q)] += g_local[0];}
+                }
+                if(n<N) {
+                    dmu[IDX_NQB(n,q,blockIdx.x)] += dmu_local;
+                    dS[IDX_NQB(n,q,blockIdx.x)] += dS_local/2.;
+                }
+                __threadfence_block();
+            }
+            g_local[threadIdx.x] = dl_local*lq_sqrt;
+            __syncthreads();
+            reduce_sum(g_local, THREADNUM);
+            if(threadIdx.x==0) {dl[IDX_QB(q,blockIdx.x)] += g_local[0];}
+        }
+        g_local[threadIdx.x] = dvar_local;
+        __syncthreads();
+        reduce_sum(g_local, THREADNUM);
+        if(threadIdx.x==0) {dvar[blockIdx.x] += g_local[0]/var;}        
+    }
+    
+    __global__ void psi2compDer(double *dvar, double *dl, double *dZ, double *dmu, double *dS, double *dL_dpsi2, double *psi2n, double var, double *l, double *Z, double *mu, double *S, int N, int M, int Q)
+    {
+        int m_start, m_end;
+        __shared__ double g_local[THREADNUM];
+        divide_data(M, gridDim.x, blockIdx.x, &m_start, &m_end);
+        int P = int(ceil(double(N)/THREADNUM));
+
+        double dvar_local = 0;
+        for(int q=0;q<Q;q++) {
+            double lq_sqrt = l[q];
+            double lq = lq_sqrt*lq_sqrt;
+            double dl_local = 0;
+            for(int p=0;p<P;p++) {
+                int n = p*THREADNUM + threadIdx.x;
+                double dmu_local = 0;
+                double dS_local = 0;
+                double Snq,mu_nq;
+                if(n<N) {Snq = S[IDX_NQ(n,q)]; mu_nq=mu[IDX_NQ(n,q)];}
+                for(int m1=m_start; m1<m_end; m1++) {
+                    g_local[threadIdx.x] = 0;
+                    for(int m2=0;m2<M;m2++) {
+                        if(n<N) {
+                            double lpsi2 = psi2n[IDX_NMM(n,m1,m2)]*dL_dpsi2[IDX_MM(m1,m2)];
+                            if(q==0) {dvar_local += lpsi2;}
+                            
+                            double dZ = Z[IDX_MQ(m1,q)] - Z[IDX_MQ(m2,q)];
+                            double muZhat =  mu_nq - (Z[IDX_MQ(m1,q)] + Z[IDX_MQ(m2,q)])/2.;
+                            double denom = 2.*Snq+lq;
+                            double muZhat2_denom = muZhat*muZhat/denom;
+                            
+                            dmu_local += lpsi2*muZhat/denom;
+                            dS_local += lpsi2*(2.*muZhat2_denom-1.)/denom;
+                            dl_local += lpsi2*((Snq/lq+muZhat2_denom)/denom+dZ*dZ/(4.*lq*lq));
+                            g_local[threadIdx.x] += 2.*lpsi2*(muZhat/denom-dZ/(2*lq));
+                        }
+                    }
+                    __syncthreads();
+                    reduce_sum(g_local, p<P-1?THREADNUM:N-(P-1)*THREADNUM);
+                    if(threadIdx.x==0) {dZ[IDX_MQ(m1,q)] += g_local[0];}
+                }
+                if(n<N) {
+                    dmu[IDX_NQB(n,q,blockIdx.x)] += -2.*dmu_local;
+                    dS[IDX_NQB(n,q,blockIdx.x)] += dS_local;
+                }
+                __threadfence_block();
+            }
+            g_local[threadIdx.x] = dl_local*2.*lq_sqrt;
+            __syncthreads();
+            reduce_sum(g_local, THREADNUM);
+            if(threadIdx.x==0) {dl[IDX_QB(q,blockIdx.x)] += g_local[0];}
+        }
+        g_local[threadIdx.x] = dvar_local;
+        __syncthreads();
+        reduce_sum(g_local, THREADNUM);
+        if(threadIdx.x==0) {dvar[blockIdx.x] += g_local[0]*2/var;}
+    }
+    """
+
+
[docs]class PSICOMP_RBF_GPU(PSICOMP_RBF): + + def __init__(self, threadnum=128, blocknum=15, GPU_direct=False): + self.GPU_direct = GPU_direct + self.gpuCache = None + + self.threadnum = threadnum + self.blocknum = blocknum + module = SourceModule("#define THREADNUM "+str(self.threadnum)+"\n"+gpu_code) + self.g_psi1computations = module.get_function('psi1computations') + self.g_psi1computations.prepare('PPdPPPPiii') + self.g_psi2computations = module.get_function('psi2computations') + self.g_psi2computations.prepare('PPPdPPPPiii') + self.g_psi1compDer = module.get_function('psi1compDer') + self.g_psi1compDer.prepare('PPPPPPPdPPPPiii') + self.g_psi2compDer = module.get_function('psi2compDer') + self.g_psi2compDer.prepare('PPPPPPPdPPPPiii') + self.g_compDenom = module.get_function('compDenom') + self.g_compDenom.prepare('PPPPii') + + def __deepcopy__(self, memo): + s = PSICOMP_RBF_GPU(threadnum=self.threadnum, blocknum=self.blocknum, GPU_direct=self.GPU_direct) + memo[id(self)] = s + return s + + def _initGPUCache(self, N, M, Q): + if self.gpuCache == None: + self.gpuCache = { + 'l_gpu' :gpuarray.empty((Q,),np.float64,order='F'), + 'Z_gpu' :gpuarray.empty((M,Q),np.float64,order='F'), + 'mu_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + 'S_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + 'psi1_gpu' :gpuarray.empty((N,M),np.float64,order='F'), + 'psi2_gpu' :gpuarray.empty((M,M),np.float64,order='F'), + 'psi2n_gpu' :gpuarray.empty((N,M,M),np.float64,order='F'), + 'dL_dpsi1_gpu' :gpuarray.empty((N,M),np.float64,order='F'), + 'dL_dpsi2_gpu' :gpuarray.empty((M,M),np.float64,order='F'), + 'log_denom1_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + 'log_denom2_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + # derivatives + 'dvar_gpu' :gpuarray.empty((self.blocknum,),np.float64, order='F'), + 'dl_gpu' :gpuarray.empty((Q,self.blocknum),np.float64, order='F'), + 'dZ_gpu' :gpuarray.empty((M,Q),np.float64, order='F'), + 'dmu_gpu' :gpuarray.empty((N,Q,self.blocknum),np.float64, order='F'), + 'dS_gpu' :gpuarray.empty((N,Q,self.blocknum),np.float64, order='F'), + # grad + 'grad_l_gpu' :gpuarray.empty((Q,),np.float64, order='F'), + 'grad_mu_gpu' :gpuarray.empty((N,Q,),np.float64, order='F'), + 'grad_S_gpu' :gpuarray.empty((N,Q,),np.float64, order='F'), + } + else: + assert N==self.gpuCache['mu_gpu'].shape[0] + assert M==self.gpuCache['Z_gpu'].shape[0] + assert Q==self.gpuCache['l_gpu'].shape[0] + +
[docs] def sync_params(self, lengthscale, Z, mu, S): + if len(lengthscale)==1: + self.gpuCache['l_gpu'].fill(lengthscale) + else: + self.gpuCache['l_gpu'].set(np.asfortranarray(lengthscale)) + self.gpuCache['Z_gpu'].set(np.asfortranarray(Z)) + self.gpuCache['mu_gpu'].set(np.asfortranarray(mu)) + self.gpuCache['S_gpu'].set(np.asfortranarray(S)) + N,Q = self.gpuCache['S_gpu'].shape + # t=self.g_compDenom(self.gpuCache['log_denom1_gpu'],self.gpuCache['log_denom2_gpu'],self.gpuCache['l_gpu'],self.gpuCache['S_gpu'], np.int32(N), np.int32(Q), block=(self.threadnum,1,1), grid=(self.blocknum,1),time_kernel=True) + # print 'g_compDenom '+str(t) + self.g_compDenom.prepared_call((self.blocknum,1),(self.threadnum,1,1), self.gpuCache['log_denom1_gpu'].gpudata,self.gpuCache['log_denom2_gpu'].gpudata,self.gpuCache['l_gpu'].gpudata,self.gpuCache['S_gpu'].gpudata, np.int32(N), np.int32(Q)) +
+
[docs] def reset_derivative(self): + self.gpuCache['dvar_gpu'].fill(0.) + self.gpuCache['dl_gpu'].fill(0.) + self.gpuCache['dZ_gpu'].fill(0.) + self.gpuCache['dmu_gpu'].fill(0.) + self.gpuCache['dS_gpu'].fill(0.) + self.gpuCache['grad_l_gpu'].fill(0.) + self.gpuCache['grad_mu_gpu'].fill(0.) + self.gpuCache['grad_S_gpu'].fill(0.) +
+
[docs] def get_dimensions(self, Z, variational_posterior): + return variational_posterior.mean.shape[0], Z.shape[0], Z.shape[1] +
+ @Cache_this(limit=1, ignore_args=(0,)) + def psicomputations(self, variance, lengthscale, Z, variational_posterior): + """ + Z - MxQ + mu - NxQ + S - NxQ + """ + N,M,Q = self.get_dimensions(Z, variational_posterior) + self._initGPUCache(N,M,Q) + self.sync_params(lengthscale, Z, variational_posterior.mean, variational_posterior.variance) + + psi1_gpu = self.gpuCache['psi1_gpu'] + psi2_gpu = self.gpuCache['psi2_gpu'] + psi2n_gpu = self.gpuCache['psi2n_gpu'] + l_gpu = self.gpuCache['l_gpu'] + Z_gpu = self.gpuCache['Z_gpu'] + mu_gpu = self.gpuCache['mu_gpu'] + S_gpu = self.gpuCache['S_gpu'] + log_denom1_gpu = self.gpuCache['log_denom1_gpu'] + log_denom2_gpu = self.gpuCache['log_denom2_gpu'] + + psi0 = np.empty((N,)) + psi0[:] = variance + self.g_psi1computations.prepared_call((self.blocknum,1),(self.threadnum,1,1),psi1_gpu.gpudata, log_denom1_gpu.gpudata, np.float64(variance),l_gpu.gpudata,Z_gpu.gpudata,mu_gpu.gpudata,S_gpu.gpudata, np.int32(N), np.int32(M), np.int32(Q)) + self.g_psi2computations.prepared_call((self.blocknum,1),(self.threadnum,1,1),psi2_gpu.gpudata, psi2n_gpu.gpudata, log_denom2_gpu.gpudata, np.float64(variance),l_gpu.gpudata,Z_gpu.gpudata,mu_gpu.gpudata,S_gpu.gpudata, np.int32(N), np.int32(M), np.int32(Q)) + # t = self.g_psi1computations(psi1_gpu, log_denom1_gpu, np.float64(variance),l_gpu,Z_gpu,mu_gpu,S_gpu, np.int32(N), np.int32(M), np.int32(Q), block=(self.threadnum,1,1), grid=(self.blocknum,1),time_kernel=True) + # print 'g_psi1computations '+str(t) + # t = self.g_psi2computations(psi2_gpu, psi2n_gpu, log_denom2_gpu, np.float64(variance),l_gpu,Z_gpu,mu_gpu,S_gpu, np.int32(N), np.int32(M), np.int32(Q), block=(self.threadnum,1,1), grid=(self.blocknum,1),time_kernel=True) + # print 'g_psi2computations '+str(t) + + if self.GPU_direct: + return psi0, psi1_gpu, psi2_gpu + else: + return psi0, psi1_gpu.get(), psi2_gpu.get() + + @Cache_this(limit=1, ignore_args=(0,1,2,3)) + def psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior): + ARD = (len(lengthscale)!=1) + + N,M,Q = self.get_dimensions(Z, variational_posterior) + psi1_gpu = self.gpuCache['psi1_gpu'] + psi2n_gpu = self.gpuCache['psi2n_gpu'] + l_gpu = self.gpuCache['l_gpu'] + Z_gpu = self.gpuCache['Z_gpu'] + mu_gpu = self.gpuCache['mu_gpu'] + S_gpu = self.gpuCache['S_gpu'] + dvar_gpu = self.gpuCache['dvar_gpu'] + dl_gpu = self.gpuCache['dl_gpu'] + dZ_gpu = self.gpuCache['dZ_gpu'] + dmu_gpu = self.gpuCache['dmu_gpu'] + dS_gpu = self.gpuCache['dS_gpu'] + grad_l_gpu = self.gpuCache['grad_l_gpu'] + grad_mu_gpu = self.gpuCache['grad_mu_gpu'] + grad_S_gpu = self.gpuCache['grad_S_gpu'] + + if self.GPU_direct: + dL_dpsi1_gpu = dL_dpsi1 + dL_dpsi2_gpu = dL_dpsi2 + dL_dpsi0_sum = dL_dpsi0.get().sum() #gpuarray.sum(dL_dpsi0).get() + else: + dL_dpsi1_gpu = self.gpuCache['dL_dpsi1_gpu'] + dL_dpsi2_gpu = self.gpuCache['dL_dpsi2_gpu'] + dL_dpsi1_gpu.set(np.asfortranarray(dL_dpsi1)) + dL_dpsi2_gpu.set(np.asfortranarray(dL_dpsi2)) + dL_dpsi0_sum = dL_dpsi0.sum() + + self.reset_derivative() + # t=self.g_psi1compDer(dvar_gpu,dl_gpu,dZ_gpu,dmu_gpu,dS_gpu,dL_dpsi1_gpu,psi1_gpu, np.float64(variance),l_gpu,Z_gpu,mu_gpu,S_gpu, np.int32(N), np.int32(M), np.int32(Q), block=(self.threadnum,1,1), grid=(self.blocknum,1),time_kernel=True) + # print 'g_psi1compDer '+str(t) + # t=self.g_psi2compDer(dvar_gpu,dl_gpu,dZ_gpu,dmu_gpu,dS_gpu,dL_dpsi2_gpu,psi2n_gpu, np.float64(variance),l_gpu,Z_gpu,mu_gpu,S_gpu, np.int32(N), np.int32(M), np.int32(Q), block=(self.threadnum,1,1), grid=(self.blocknum,1),time_kernel=True) + # print 'g_psi2compDer '+str(t) + self.g_psi1compDer.prepared_call((self.blocknum,1),(self.threadnum,1,1),dvar_gpu.gpudata,dl_gpu.gpudata,dZ_gpu.gpudata,dmu_gpu.gpudata,dS_gpu.gpudata,dL_dpsi1_gpu.gpudata,psi1_gpu.gpudata, np.float64(variance),l_gpu.gpudata,Z_gpu.gpudata,mu_gpu.gpudata,S_gpu.gpudata, np.int32(N), np.int32(M), np.int32(Q)) + self.g_psi2compDer.prepared_call((self.blocknum,1),(self.threadnum,1,1),dvar_gpu.gpudata,dl_gpu.gpudata,dZ_gpu.gpudata,dmu_gpu.gpudata,dS_gpu.gpudata,dL_dpsi2_gpu.gpudata,psi2n_gpu.gpudata, np.float64(variance),l_gpu.gpudata,Z_gpu.gpudata,mu_gpu.gpudata,S_gpu.gpudata, np.int32(N), np.int32(M), np.int32(Q)) + + dL_dvar = dL_dpsi0_sum + dvar_gpu.get().sum()#gpuarray.sum(dvar_gpu).get() + sum_axis(grad_mu_gpu,dmu_gpu,N*Q,self.blocknum) + dL_dmu = grad_mu_gpu.get() + sum_axis(grad_S_gpu,dS_gpu,N*Q,self.blocknum) + dL_dS = grad_S_gpu.get() + dL_dZ = dZ_gpu.get() + if ARD: + sum_axis(grad_l_gpu,dl_gpu,Q,self.blocknum) + dL_dlengscale = grad_l_gpu.get() + else: + dL_dlengscale = dl_gpu.get().sum() #gpuarray.sum(dl_gpu).get() + + return dL_dvar, dL_dlengscale, dL_dZ, dL_dmu, dL_dS + +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/psi_comp/sslinear_psi_comp.html b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/sslinear_psi_comp.html new file mode 100644 index 00000000..32632cb9 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/sslinear_psi_comp.html @@ -0,0 +1,188 @@ + + + + + + + + GPy.kern._src.psi_comp.sslinear_psi_comp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.psi_comp.sslinear_psi_comp

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+"""
+The package for the Psi statistics computation of the linear kernel for SSGPLVM
+"""
+
+from ....util.linalg import tdot
+
+import numpy as np
+
+
[docs]def psicomputations(variance, Z, variational_posterior): + """ + Compute psi-statistics for ss-linear kernel + """ + # here are the "statistics" for psi0, psi1 and psi2 + # Produced intermediate results: + # psi0 N + # psi1 NxM + # psi2 MxM + mu = variational_posterior.mean + S = variational_posterior.variance + gamma = variational_posterior.binary_prob + + psi0 = (gamma*(np.square(mu)+S)*variance).sum(axis=-1) + psi1 = np.inner(variance*gamma*mu,Z) + psi2 = np.inner(np.square(variance)*(gamma*((1-gamma)*np.square(mu)+S)).sum(axis=0)*Z,Z)+tdot(psi1.T) + + return psi0, psi1, psi2 +
+
[docs]def psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, Z, variational_posterior): + mu = variational_posterior.mean + S = variational_posterior.variance + gamma = variational_posterior.binary_prob + + dL_dvar, dL_dgamma, dL_dmu, dL_dS, dL_dZ = _psi2computations(dL_dpsi2, variance, Z, mu, S, gamma) + + # Compute for psi0 and psi1 + mu2S = np.square(mu)+S + dL_dvar += np.einsum('n,nq,nq->q',dL_dpsi0,gamma,mu2S) + np.einsum('nm,nq,mq,nq->q',dL_dpsi1,gamma,Z,mu) + dL_dgamma += np.einsum('n,q,nq->nq',dL_dpsi0,variance,mu2S) + np.einsum('nm,q,mq,nq->nq',dL_dpsi1,variance,Z,mu) + dL_dmu += np.einsum('n,nq,q,nq->nq',dL_dpsi0,gamma,2.*variance,mu) + np.einsum('nm,nq,q,mq->nq',dL_dpsi1,gamma,variance,Z) + dL_dS += np.einsum('n,nq,q->nq',dL_dpsi0,gamma,variance) + dL_dZ += np.einsum('nm,nq,q,nq->mq',dL_dpsi1,gamma, variance,mu) + + return dL_dvar, dL_dZ, dL_dmu, dL_dS, dL_dgamma +
+def _psi2computations(dL_dpsi2, variance, Z, mu, S, gamma): + """ + Z - MxQ + mu - NxQ + S - NxQ + gamma - NxQ + """ + # here are the "statistics" for psi1 and psi2 + # Produced intermediate results: + # _psi2_dvariance Q + # _psi2_dZ MxQ + # _psi2_dgamma NxQ + # _psi2_dmu NxQ + # _psi2_dS NxQ + + mu2 = np.square(mu) + gamma2 = np.square(gamma) + variance2 = np.square(variance) + mu2S = mu2+S # NxQ + gvm = np.einsum('nq,nq,q->nq',gamma,mu,variance) + common_sum = np.einsum('nq,mq->nm',gvm,Z) +# common_sum = np.einsum('nq,q,mq,nq->nm',gamma,variance,Z,mu) # NxM + Z_expect = np.einsum('mo,mq,oq->q',dL_dpsi2,Z,Z) + dL_dpsi2T = dL_dpsi2+dL_dpsi2.T + tmp = np.einsum('mo,oq->mq',dL_dpsi2T,Z) + common_expect = np.einsum('mq,nm->nq',tmp,common_sum) +# common_expect = np.einsum('mo,mq,no->nq',dL_dpsi2+dL_dpsi2.T,Z,common_sum) + Z2_expect = np.einsum('om,nm->no',dL_dpsi2T,common_sum) + Z1_expect = np.einsum('om,mq->oq',dL_dpsi2T,Z) + + dL_dvar = np.einsum('nq,q,q->q',2.*(gamma*mu2S-gamma2*mu2),variance,Z_expect)+\ + np.einsum('nq,nq,nq->q',common_expect,gamma,mu) + + dL_dgamma = np.einsum('q,q,nq->nq',Z_expect,variance2,(mu2S-2.*gamma*mu2))+\ + np.einsum('nq,q,nq->nq',common_expect,variance,mu) + + dL_dmu = np.einsum('q,q,nq,nq->nq',Z_expect,variance2,mu,2.*(gamma-gamma2))+\ + np.einsum('nq,nq,q->nq',common_expect,gamma,variance) + + dL_dS = np.einsum('q,nq,q->nq',Z_expect,gamma,variance2) + +# dL_dZ = 2.*(np.einsum('om,nq,q,mq,nq->oq',dL_dpsi2,gamma,variance2,Z,(mu2S-gamma*mu2))+np.einsum('om,nq,q,nq,nm->oq',dL_dpsi2,gamma,variance,mu,common_sum)) + dL_dZ = Z1_expect*np.einsum('nq,q,nq->q',gamma,variance2,(mu2S-gamma*mu2))+np.einsum('nq,q,nq,nm->mq',gamma,variance,mu,Z2_expect) + + return dL_dvar, dL_dgamma, dL_dmu, dL_dS, dL_dZ +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/psi_comp/ssrbf_psi_comp.html b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/ssrbf_psi_comp.html new file mode 100644 index 00000000..1fbc74ce --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/ssrbf_psi_comp.html @@ -0,0 +1,490 @@ + + + + + + + + GPy.kern._src.psi_comp.ssrbf_psi_comp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.psi_comp.ssrbf_psi_comp

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+"""
+The package for the psi statistics computation
+"""
+
+import numpy as np
+
+try:
+    from scipy import weave
+     
+    def _psicomputations(variance, lengthscale, Z, variational_posterior):
+        """
+        Z - MxQ
+        mu - NxQ
+        S - NxQ
+        gamma - NxQ
+        """
+        # here are the "statistics" for psi0, psi1 and psi2
+        # Produced intermediate results:
+        # _psi1                NxM
+        mu = variational_posterior.mean
+        S = variational_posterior.variance
+         
+        N,M,Q = mu.shape[0],Z.shape[0],mu.shape[1]
+        l2 = np.square(lengthscale)
+        log_denom1 = np.log(S/l2+1)
+        log_denom2 = np.log(2*S/l2+1)
+        log_gamma,log_gamma1 = variational_posterior.gamma_log_prob()
+        variance = float(variance)
+        psi0 = np.empty(N)
+        psi0[:] = variance
+        psi1 = np.empty((N,M))
+        psi2n = np.empty((N,M,M))
+         
+        from ....util.misc import param_to_array
+        S = param_to_array(S)
+        mu = param_to_array(mu)
+        Z = param_to_array(Z)
+         
+        support_code = """
+        #include <math.h>
+        """
+        code = """
+        for(int n=0; n<N; n++) {
+            for(int m1=0;m1<M;m1++) {
+                double log_psi1=0;
+                for(int m2=0;m2<=m1;m2++) {
+                    double log_psi2_n=0;
+                    for(int q=0;q<Q;q++) {
+                        double Snq = S(n,q);
+                        double lq = l2(q);
+                        double Zm1q = Z(m1,q);
+                        double Zm2q = Z(m2,q);
+                         
+                        if(m2==0) {
+                            // Compute Psi_1
+                            double muZ = mu(n,q)-Z(m1,q);
+                             
+                            double psi1_exp1 = log_gamma(n,q) - (muZ*muZ/(Snq+lq) +log_denom1(n,q))/2.;
+                            double psi1_exp2 = log_gamma1(n,q) -Zm1q*Zm1q/(2.*lq);
+                            log_psi1 += (psi1_exp1>psi1_exp2)?psi1_exp1+log1p(exp(psi1_exp2-psi1_exp1)):psi1_exp2+log1p(exp(psi1_exp1-psi1_exp2));
+                        }
+                        // Compute Psi_2
+                        double muZhat = mu(n,q) - (Zm1q+Zm2q)/2.;
+                        double Z2 = Zm1q*Zm1q+ Zm2q*Zm2q;
+                        double dZ = Zm1q - Zm2q;
+                         
+                        double psi2_exp1 = dZ*dZ/(-4.*lq)-muZhat*muZhat/(2.*Snq+lq) - log_denom2(n,q)/2. + log_gamma(n,q);
+                        double psi2_exp2 = log_gamma1(n,q) - Z2/(2.*lq);
+                        log_psi2_n += (psi2_exp1>psi2_exp2)?psi2_exp1+log1p(exp(psi2_exp2-psi2_exp1)):psi2_exp2+log1p(exp(psi2_exp1-psi2_exp2));                    
+                    }
+                    double exp_psi2_n = exp(log_psi2_n);
+                    psi2n(n,m1,m2) = variance*variance*exp_psi2_n;
+                    if(m1!=m2) { psi2n(n,m2,m1) = variance*variance*exp_psi2_n;}
+                }
+                psi1(n,m1) = variance*exp(log_psi1);
+            }
+        }
+        """
+        weave.inline(code, support_code=support_code, arg_names=['psi1','psi2n','N','M','Q','variance','l2','Z','mu','S','log_denom1','log_denom2','log_gamma','log_gamma1'], type_converters=weave.converters.blitz)
+     
+        psi2 = psi2n.sum(axis=0)
+        return psi0,psi1,psi2,psi2n
+     
+    from GPy.util.caching import Cacher
+    psicomputations = Cacher(_psicomputations, limit=1)
+     
+    def psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior):
+        ARD = (len(lengthscale)!=1)
+         
+        _,psi1,_,psi2n = psicomputations(variance, lengthscale, Z, variational_posterior)
+     
+        mu = variational_posterior.mean
+        S = variational_posterior.variance
+        N,M,Q = mu.shape[0],Z.shape[0],mu.shape[1]
+        l2 = np.square(lengthscale)
+        log_denom1 = np.log(S/l2+1)
+        log_denom2 = np.log(2*S/l2+1)
+        log_gamma,log_gamma1 = variational_posterior.gamma_log_prob()
+        gamma, gamma1 = variational_posterior.gamma_probabilities()
+        variance = float(variance)
+     
+        dvar = np.zeros(1)
+        dmu = np.zeros((N,Q))
+        dS = np.zeros((N,Q))
+        dgamma = np.zeros((N,Q))
+        dl = np.zeros(Q)
+        dZ = np.zeros((M,Q))
+        dvar += np.sum(dL_dpsi0)
+         
+        from ....util.misc import param_to_array
+        S = param_to_array(S)
+        mu = param_to_array(mu)
+        Z = param_to_array(Z)
+         
+        support_code = """
+        #include <math.h>
+        """
+        code = """
+        for(int n=0; n<N; n++) {
+            for(int m1=0;m1<M;m1++) {
+                double log_psi1=0;
+                for(int m2=0;m2<M;m2++) {
+                    double log_psi2_n=0;
+                    for(int q=0;q<Q;q++) {
+                        double Snq = S(n,q);
+                        double lq = l2(q);
+                        double Zm1q = Z(m1,q);
+                        double Zm2q = Z(m2,q);
+                        double gnq = gamma(n,q);
+                        double g1nq = gamma1(n,q);
+                        double mu_nq = mu(n,q);
+                         
+                        if(m2==0) {
+                            // Compute Psi_1                        
+                            double lpsi1 = psi1(n,m1)*dL_dpsi1(n,m1);
+                            if(q==0) {dvar(0) += lpsi1/variance;}
+                             
+                            double Zmu = Zm1q - mu_nq;
+                            double denom = Snq+lq;
+                            double Zmu2_denom = Zmu*Zmu/denom;
+                             
+                            double exp1 = log_gamma(n,q)-(Zmu*Zmu/(Snq+lq)+log_denom1(n,q))/(2.);
+                            double exp2 = log_gamma1(n,q)-Zm1q*Zm1q/(2.*lq);
+                            double d_exp1,d_exp2;
+                            if(exp1>exp2) {
+                                d_exp1 = 1.;
+                                d_exp2 = exp(exp2-exp1);
+                            } else {
+                                d_exp1 = exp(exp1-exp2);
+                                d_exp2 = 1.;
+                            }
+                            double exp_sum = d_exp1+d_exp2;
+                             
+                            dmu(n,q) += lpsi1*Zmu*d_exp1/(denom*exp_sum);
+                            dS(n,q) += lpsi1*(Zmu2_denom-1.)*d_exp1/(denom*exp_sum)/2.;
+                            dgamma(n,q) += lpsi1*(d_exp1*g1nq-d_exp2*gnq)/exp_sum;
+                            dl(q) += lpsi1*((Zmu2_denom+Snq/lq)/denom*d_exp1+Zm1q*Zm1q/(lq*lq)*d_exp2)/(2.*exp_sum);
+                            dZ(m1,q) += lpsi1*(-Zmu/denom*d_exp1-Zm1q/lq*d_exp2)/exp_sum;
+                        }
+                        // Compute Psi_2
+                        double lpsi2 = psi2n(n,m1,m2)*dL_dpsi2(m1,m2);
+                        if(q==0) {dvar(0) += lpsi2*2/variance;}
+                         
+                        double dZm1m2 = Zm1q - Zm2q;
+                        double Z2 = Zm1q*Zm1q+Zm2q*Zm2q;
+                        double muZhat =  mu_nq - (Zm1q + Zm2q)/2.;
+                        double denom = 2.*Snq+lq;
+                        double muZhat2_denom = muZhat*muZhat/denom;
+                         
+                        double exp1 = dZm1m2*dZm1m2/(-4.*lq)-muZhat*muZhat/(2.*Snq+lq) - log_denom2(n,q)/2. + log_gamma(n,q);
+                        double exp2 = log_gamma1(n,q) - Z2/(2.*lq);
+                        double d_exp1,d_exp2;
+                        if(exp1>exp2) {
+                            d_exp1 = 1.;
+                            d_exp2 = exp(exp2-exp1);
+                        } else {
+                            d_exp1 = exp(exp1-exp2);
+                            d_exp2 = 1.;
+                        }
+                        double exp_sum = d_exp1+d_exp2;
+                         
+                        dmu(n,q) += -2.*lpsi2*muZhat/denom*d_exp1/exp_sum;
+                        dS(n,q) += lpsi2*(2.*muZhat2_denom-1.)/denom*d_exp1/exp_sum;
+                        dgamma(n,q) += lpsi2*(d_exp1*g1nq-d_exp2*gnq)/exp_sum;
+                        dl(q) += lpsi2*(((Snq/lq+muZhat2_denom)/denom+dZm1m2*dZm1m2/(4.*lq*lq))*d_exp1+Z2/(2.*lq*lq)*d_exp2)/exp_sum;
+                        dZ(m1,q) += 2.*lpsi2*((muZhat/denom-dZm1m2/(2*lq))*d_exp1-Zm1q/lq*d_exp2)/exp_sum;                   
+                    }
+                }
+            }
+        }
+        """
+        weave.inline(code, support_code=support_code, arg_names=['dL_dpsi1','dL_dpsi2','psi1','psi2n','N','M','Q','variance','l2','Z','mu','S','gamma','gamma1','log_denom1','log_denom2','log_gamma','log_gamma1','dvar','dl','dmu','dS','dgamma','dZ'], type_converters=weave.converters.blitz)
+     
+        dl *= 2.*lengthscale
+        if not ARD:
+            dl = dl.sum()
+         
+        return dvar, dl, dZ, dmu, dS, dgamma
+
+except:
+
+    def psicomputations(variance, lengthscale, Z, variational_posterior):
+        """
+        Z - MxQ
+        mu - NxQ
+        S - NxQ
+        gamma - NxQ
+        """
+        # here are the "statistics" for psi0, psi1 and psi2
+        # Produced intermediate results:
+        # _psi1                NxM
+        mu = variational_posterior.mean
+        S = variational_posterior.variance
+        gamma = variational_posterior.binary_prob
+         
+        psi0 = np.empty(mu.shape[0])
+        psi0[:] = variance
+        psi1 = _psi1computations(variance, lengthscale, Z, mu, S, gamma)
+        psi2 = _psi2computations(variance, lengthscale, Z, mu, S, gamma)
+        return psi0, psi1, psi2
+    
+    def _psi1computations(variance, lengthscale, Z, mu, S, gamma):
+        """
+        Z - MxQ
+        mu - NxQ
+        S - NxQ
+        gamma - NxQ
+        """
+        # here are the "statistics" for psi1
+        # Produced intermediate results:
+        # _psi1                NxM
+    
+        lengthscale2 = np.square(lengthscale)
+    
+        # psi1
+        _psi1_denom = S[:, None, :] / lengthscale2 + 1.  # Nx1xQ
+        _psi1_denom_sqrt = np.sqrt(_psi1_denom) #Nx1xQ
+        _psi1_dist = Z[None, :, :] - mu[:, None, :]  # NxMxQ
+        _psi1_dist_sq = np.square(_psi1_dist) / (lengthscale2 * _psi1_denom) # NxMxQ
+        _psi1_common = gamma[:,None,:] / (lengthscale2*_psi1_denom*_psi1_denom_sqrt) #Nx1xQ
+        _psi1_exponent1 = np.log(gamma[:,None,:]) - (_psi1_dist_sq + np.log(_psi1_denom))/2. # NxMxQ
+        _psi1_exponent2 = np.log(1.-gamma[:,None,:]) - (np.square(Z[None,:,:])/lengthscale2)/2. # NxMxQ
+        _psi1_exponent_max = np.maximum(_psi1_exponent1,_psi1_exponent2)
+        _psi1_exponent = _psi1_exponent_max+np.log(np.exp(_psi1_exponent1-_psi1_exponent_max) + np.exp(_psi1_exponent2-_psi1_exponent_max)) #NxMxQ
+        _psi1_exp_sum = _psi1_exponent.sum(axis=-1) #NxM
+        _psi1 = variance * np.exp(_psi1_exp_sum) # NxM
+    
+        return _psi1
+    
+    def _psi2computations(variance, lengthscale, Z, mu, S, gamma):
+        """
+        Z - MxQ
+        mu - NxQ
+        S - NxQ
+        gamma - NxQ
+        """
+        # here are the "statistics" for psi2
+        # Produced intermediate results:
+        # _psi2                MxM
+        
+        lengthscale2 = np.square(lengthscale)
+        
+        _psi2_Zhat = 0.5 * (Z[:, None, :] + Z[None, :, :]) # M,M,Q
+        _psi2_Zdist = 0.5 * (Z[:, None, :] - Z[None, :, :]) # M,M,Q
+        _psi2_Zdist_sq = np.square(_psi2_Zdist / lengthscale) # M,M,Q
+        _psi2_Z_sq_sum = (np.square(Z[:,None,:])+np.square(Z[None,:,:]))/lengthscale2 # MxMxQ
+    
+        # psi2
+        _psi2_denom = 2.*S[:, None, None, :] / lengthscale2 + 1. # Nx1x1xQ
+        _psi2_denom_sqrt = np.sqrt(_psi2_denom)
+        _psi2_mudist = mu[:,None,None,:]-_psi2_Zhat #N,M,M,Q
+        _psi2_mudist_sq = np.square(_psi2_mudist)/(lengthscale2*_psi2_denom)
+        _psi2_common = gamma[:,None,None,:]/(lengthscale2 * _psi2_denom * _psi2_denom_sqrt) # Nx1x1xQ
+        _psi2_exponent1 = -_psi2_Zdist_sq -_psi2_mudist_sq -0.5*np.log(_psi2_denom)+np.log(gamma[:,None,None,:]) #N,M,M,Q
+        _psi2_exponent2 = np.log(1.-gamma[:,None,None,:]) - 0.5*(_psi2_Z_sq_sum) # NxMxMxQ
+        _psi2_exponent_max = np.maximum(_psi2_exponent1, _psi2_exponent2)
+        _psi2_exponent = _psi2_exponent_max+np.log(np.exp(_psi2_exponent1-_psi2_exponent_max) + np.exp(_psi2_exponent2-_psi2_exponent_max))
+        _psi2_exp_sum = _psi2_exponent.sum(axis=-1) #NxM
+        _psi2 = variance*variance * (np.exp(_psi2_exp_sum).sum(axis=0)) # MxM
+    
+        return _psi2
+    
+
[docs] def psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior): + ARD = (len(lengthscale)!=1) + + dvar_psi1, dl_psi1, dZ_psi1, dmu_psi1, dS_psi1, dgamma_psi1 = _psi1compDer(dL_dpsi1, variance, lengthscale, Z, variational_posterior.mean, variational_posterior.variance, variational_posterior.binary_prob) + dvar_psi2, dl_psi2, dZ_psi2, dmu_psi2, dS_psi2, dgamma_psi2 = _psi2compDer(dL_dpsi2, variance, lengthscale, Z, variational_posterior.mean, variational_posterior.variance, variational_posterior.binary_prob) + + dL_dvar = np.sum(dL_dpsi0) + dvar_psi1 + dvar_psi2 + + dL_dlengscale = dl_psi1 + dl_psi2 + if not ARD: + dL_dlengscale = dL_dlengscale.sum() + + dL_dgamma = dgamma_psi1 + dgamma_psi2 + dL_dmu = dmu_psi1 + dmu_psi2 + dL_dS = dS_psi1 + dS_psi2 + dL_dZ = dZ_psi1 + dZ_psi2 + + return dL_dvar, dL_dlengscale, dL_dZ, dL_dmu, dL_dS, dL_dgamma +
+ def _psi1compDer(dL_dpsi1, variance, lengthscale, Z, mu, S, gamma): + """ + dL_dpsi1 - NxM + Z - MxQ + mu - NxQ + S - NxQ + gamma - NxQ + """ + # here are the "statistics" for psi1 + # Produced intermediate results: dL_dparams w.r.t. psi1 + # _dL_dvariance 1 + # _dL_dlengthscale Q + # _dL_dZ MxQ + # _dL_dgamma NxQ + # _dL_dmu NxQ + # _dL_dS NxQ + + lengthscale2 = np.square(lengthscale) + + # psi1 + _psi1_denom = S / lengthscale2 + 1. # NxQ + _psi1_denom_sqrt = np.sqrt(_psi1_denom) #NxQ + _psi1_dist = Z[None, :, :] - mu[:, None, :] # NxMxQ + _psi1_dist_sq = np.square(_psi1_dist) / (lengthscale2 * _psi1_denom[:,None,:]) # NxMxQ + _psi1_common = gamma / (lengthscale2*_psi1_denom*_psi1_denom_sqrt) #NxQ + _psi1_exponent1 = np.log(gamma[:,None,:]) -0.5 * (_psi1_dist_sq + np.log(_psi1_denom[:, None,:])) # NxMxQ + _psi1_exponent2 = np.log(1.-gamma[:,None,:]) -0.5 * (np.square(Z[None,:,:])/lengthscale2) # NxMxQ + _psi1_exponent_max = np.maximum(_psi1_exponent1,_psi1_exponent2) + _psi1_exponent = _psi1_exponent_max+np.log(np.exp(_psi1_exponent1-_psi1_exponent_max) + np.exp(_psi1_exponent2-_psi1_exponent_max)) #NxMxQ + _psi1_exp_sum = _psi1_exponent.sum(axis=-1) #NxM + _psi1_exp_dist_sq = np.exp(-0.5*_psi1_dist_sq) # NxMxQ + _psi1_exp_Z = np.exp(-0.5*np.square(Z[None,:,:])/lengthscale2) # 1xMxQ + _psi1_q = variance * np.exp(_psi1_exp_sum[:,:,None] - _psi1_exponent) # NxMxQ + _psi1 = variance * np.exp(_psi1_exp_sum) # NxM + _dL_dvariance = np.einsum('nm,nm->',dL_dpsi1, _psi1)/variance # 1 + _dL_dgamma = np.einsum('nm,nmq,nmq->nq',dL_dpsi1, _psi1_q, (_psi1_exp_dist_sq/_psi1_denom_sqrt[:,None,:]-_psi1_exp_Z)) # NxQ + _dL_dmu = np.einsum('nm, nmq, nmq, nmq, nq->nq',dL_dpsi1,_psi1_q,_psi1_exp_dist_sq,_psi1_dist,_psi1_common) # NxQ + _dL_dS = np.einsum('nm,nmq,nmq,nq,nmq->nq',dL_dpsi1,_psi1_q,_psi1_exp_dist_sq,_psi1_common,(_psi1_dist_sq-1.))/2. # NxQ + _dL_dZ = np.einsum('nm,nmq,nmq->mq',dL_dpsi1,_psi1_q, (- _psi1_common[:,None,:] * _psi1_dist * _psi1_exp_dist_sq - (1-gamma[:,None,:])/lengthscale2*Z[None,:,:]*_psi1_exp_Z)) + _dL_dlengthscale = lengthscale* np.einsum('nm,nmq,nmq->q',dL_dpsi1,_psi1_q,(_psi1_common[:,None,:]*(S[:,None,:]/lengthscale2+_psi1_dist_sq)*_psi1_exp_dist_sq + (1-gamma[:,None,:])*np.square(Z[None,:,:]/lengthscale2)*_psi1_exp_Z)) + + return _dL_dvariance, _dL_dlengthscale, _dL_dZ, _dL_dmu, _dL_dS, _dL_dgamma + + def _psi2compDer(dL_dpsi2, variance, lengthscale, Z, mu, S, gamma): + """ + Z - MxQ + mu - NxQ + S - NxQ + gamma - NxQ + dL_dpsi2 - MxM + """ + # here are the "statistics" for psi2 + # Produced the derivatives w.r.t. psi2: + # _dL_dvariance 1 + # _dL_dlengthscale Q + # _dL_dZ MxQ + # _dL_dgamma NxQ + # _dL_dmu NxQ + # _dL_dS NxQ + + lengthscale2 = np.square(lengthscale) + + _psi2_Zhat = 0.5 * (Z[:, None, :] + Z[None, :, :]) # M,M,Q + _psi2_Zdist = 0.5 * (Z[:, None, :] - Z[None, :, :]) # M,M,Q + _psi2_Zdist_sq = np.square(_psi2_Zdist / lengthscale) # M,M,Q + _psi2_Z_sq_sum = (np.square(Z[:,None,:])+np.square(Z[None,:,:]))/lengthscale2 # MxMxQ + + # psi2 + _psi2_denom = 2.*S / lengthscale2 + 1. # NxQ + _psi2_denom_sqrt = np.sqrt(_psi2_denom) + _psi2_mudist = mu[:,None,None,:]-_psi2_Zhat #N,M,M,Q + _psi2_mudist_sq = np.square(_psi2_mudist)/(lengthscale2*_psi2_denom[:,None,None,:]) + _psi2_common = gamma/(lengthscale2 * _psi2_denom * _psi2_denom_sqrt) # NxQ + _psi2_exponent1 = -_psi2_Zdist_sq -_psi2_mudist_sq -0.5*np.log(_psi2_denom[:,None,None,:])+np.log(gamma[:,None,None,:]) #N,M,M,Q + _psi2_exponent2 = np.log(1.-gamma[:,None,None,:]) - 0.5*(_psi2_Z_sq_sum) # NxMxMxQ + _psi2_exponent_max = np.maximum(_psi2_exponent1, _psi2_exponent2) + _psi2_exponent = _psi2_exponent_max+np.log(np.exp(_psi2_exponent1-_psi2_exponent_max) + np.exp(_psi2_exponent2-_psi2_exponent_max)) + _psi2_exp_sum = _psi2_exponent.sum(axis=-1) #NxM + _psi2_q = variance*variance * np.exp(_psi2_exp_sum[:,:,:,None]-_psi2_exponent) # NxMxMxQ + _psi2_exp_dist_sq = np.exp(-_psi2_Zdist_sq -_psi2_mudist_sq) # NxMxMxQ + _psi2_exp_Z = np.exp(-0.5*_psi2_Z_sq_sum) # MxMxQ + _psi2 = variance*variance * (np.exp(_psi2_exp_sum).sum(axis=0)) # MxM + _dL_dvariance = np.einsum('mo,mo->',dL_dpsi2,_psi2)*2./variance + _dL_dgamma = np.einsum('mo,nmoq,nmoq->nq',dL_dpsi2,_psi2_q,(_psi2_exp_dist_sq/_psi2_denom_sqrt[:,None,None,:] - _psi2_exp_Z)) + _dL_dmu = -2.*np.einsum('mo,nmoq,nq,nmoq,nmoq->nq',dL_dpsi2,_psi2_q,_psi2_common,_psi2_mudist,_psi2_exp_dist_sq) + _dL_dS = np.einsum('mo,nmoq,nq,nmoq,nmoq->nq',dL_dpsi2,_psi2_q, _psi2_common, (2.*_psi2_mudist_sq-1.), _psi2_exp_dist_sq) + _dL_dZ = 2.*np.einsum('mo,nmoq,nmoq->mq',dL_dpsi2,_psi2_q,(_psi2_common[:,None,None,:]*(-_psi2_Zdist*_psi2_denom[:,None,None,:]+_psi2_mudist)*_psi2_exp_dist_sq - (1-gamma[:,None,None,:])*Z[:,None,:]/lengthscale2*_psi2_exp_Z)) + _dL_dlengthscale = 2.*lengthscale* np.einsum('mo,nmoq,nmoq->q',dL_dpsi2,_psi2_q,(_psi2_common[:,None,None,:]*(S[:,None,None,:]/lengthscale2+_psi2_Zdist_sq*_psi2_denom[:,None,None,:]+_psi2_mudist_sq)*_psi2_exp_dist_sq+(1-gamma[:,None,None,:])*_psi2_Z_sq_sum*0.5/lengthscale2*_psi2_exp_Z)) + + return _dL_dvariance, _dL_dlengthscale, _dL_dZ, _dL_dmu, _dL_dS, _dL_dgamma +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/psi_comp/ssrbf_psi_gpucomp.html b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/ssrbf_psi_gpucomp.html new file mode 100644 index 00000000..2a32598f --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/psi_comp/ssrbf_psi_gpucomp.html @@ -0,0 +1,568 @@ + + + + + + + + GPy.kern._src.psi_comp.ssrbf_psi_gpucomp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.psi_comp.ssrbf_psi_gpucomp

+"""
+The module for psi-statistics for RBF kernel for Spike-and-Slab GPLVM
+"""
+
+import numpy as np
+from ....util.caching import Cache_this
+from . import PSICOMP_RBF
+from ....util import gpu_init
+
+try:
+    import pycuda.gpuarray as gpuarray
+    from pycuda.compiler import SourceModule
+    from ....util.linalg_gpu import sum_axis
+except:
+    pass    
+
+gpu_code = """
+    // define THREADNUM
+
+    #define IDX_NMQ(n,m,q) ((q*M+m)*N+n)
+    #define IDX_NMM(n,m1,m2) ((m2*M+m1)*N+n)
+    #define IDX_NQ(n,q) (q*N+n)
+    #define IDX_NM(n,m) (m*N+n)
+    #define IDX_MQ(m,q) (q*M+m)
+    #define IDX_MM(m1,m2) (m2*M+m1)
+    #define IDX_NQB(n,q,b) ((b*Q+q)*N+n)
+    #define IDX_QB(q,b) (b*Q+q)
+
+    // Divide data evenly
+    __device__ void divide_data(int total_data, int psize, int pidx, int *start, int *end) {
+        int residue = (total_data)%psize;
+        if(pidx<residue) {
+            int size = total_data/psize+1;
+            *start = size*pidx;
+            *end = *start+size;
+        } else {
+            int size = total_data/psize;
+            *start = size*pidx+residue;
+            *end = *start+size;
+        }
+    }
+    
+    __device__ void reduce_sum(double* array, int array_size) {
+        int s;
+        if(array_size >= blockDim.x) {
+            for(int i=blockDim.x+threadIdx.x; i<array_size; i+= blockDim.x) {
+                array[threadIdx.x] += array[i];
+            }
+            array_size = blockDim.x;
+        }
+        __syncthreads();
+        for(int i=1; i<=array_size;i*=2) {s=i;}
+        if(threadIdx.x < array_size-s) {array[threadIdx.x] += array[s+threadIdx.x];}
+        __syncthreads();
+        for(s=s/2;s>=1;s=s/2) {
+            if(threadIdx.x < s) {array[threadIdx.x] += array[s+threadIdx.x];}
+            __syncthreads();
+        }
+    }
+
+    __global__ void compDenom(double *log_denom1, double *log_denom2, double *log_gamma, double*log_gamma1, double *gamma, double *l, double *S, int N, int Q)
+    {
+        int n_start, n_end;
+        divide_data(N, gridDim.x, blockIdx.x, &n_start, &n_end);
+        
+        for(int i=n_start*Q+threadIdx.x; i<n_end*Q; i+=blockDim.x) {
+            int n=i/Q;
+            int q=i%Q;
+
+            double Snq = S[IDX_NQ(n,q)];
+            double lq = l[q]*l[q];
+            double gnq = gamma[IDX_NQ(n,q)];
+            log_denom1[IDX_NQ(n,q)] = log(Snq/lq+1.);
+            log_denom2[IDX_NQ(n,q)] = log(2.*Snq/lq+1.);
+            log_gamma[IDX_NQ(n,q)] = log(gnq);
+            log_gamma1[IDX_NQ(n,q)] = log(1.-gnq);
+        }
+    }
+
+    __global__ void psi1computations(double *psi1, double *log_denom1, double *log_gamma, double*log_gamma1, double var, double *l, double *Z, double *mu, double *S, int N, int M, int Q)
+    {
+        int m_start, m_end;
+        divide_data(M, gridDim.x, blockIdx.x, &m_start, &m_end);
+        
+        for(int m=m_start; m<m_end; m++) {
+            for(int n=threadIdx.x; n<N; n+= blockDim.x) {            
+                double log_psi1 = 0;
+                for(int q=0;q<Q;q++) {
+                    double Zmq = Z[IDX_MQ(m,q)];
+                    double muZ = mu[IDX_NQ(n,q)]-Zmq;
+                    double Snq = S[IDX_NQ(n,q)];
+                    double lq = l[q]*l[q];
+                    double exp1 = log_gamma[IDX_NQ(n,q)]-(muZ*muZ/(Snq+lq)+log_denom1[IDX_NQ(n,q)])/(2.);
+                    double exp2 = log_gamma1[IDX_NQ(n,q)]-Zmq*Zmq/(2.*lq);
+                    log_psi1 += (exp1>exp2)?exp1+log1p(exp(exp2-exp1)):exp2+log1p(exp(exp1-exp2));
+                }
+                psi1[IDX_NM(n,m)] = var*exp(log_psi1);
+            }
+        }
+    }
+    
+    __global__ void psi2computations(double *psi2, double *psi2n, double *log_denom2, double *log_gamma, double*log_gamma1, double var, double *l, double *Z, double *mu, double *S, int N, int M, int Q)
+    {
+        int psi2_idx_start, psi2_idx_end;
+        __shared__ double psi2_local[THREADNUM];
+        divide_data((M+1)*M/2, gridDim.x, blockIdx.x, &psi2_idx_start, &psi2_idx_end);
+        
+        for(int psi2_idx=psi2_idx_start; psi2_idx<psi2_idx_end; psi2_idx++) {
+            int m1 = int((sqrt(8.*psi2_idx+1.)-1.)/2.);
+            int m2 = psi2_idx - (m1+1)*m1/2;
+            
+            psi2_local[threadIdx.x] = 0;
+            for(int n=threadIdx.x;n<N;n+=blockDim.x) {
+                double log_psi2_n = 0;
+                for(int q=0;q<Q;q++) {
+                    double Zm1q = Z[IDX_MQ(m1,q)];
+                    double Zm2q = Z[IDX_MQ(m2,q)];
+                    double dZ = Zm1q - Zm2q;
+                    double muZhat = mu[IDX_NQ(n,q)]- (Zm1q+Zm2q)/2.;
+                    double Z2 = Zm1q*Zm1q+Zm2q*Zm2q;
+                    double Snq = S[IDX_NQ(n,q)];
+                    double lq = l[q]*l[q];
+                    double exp1 = dZ*dZ/(-4.*lq)-muZhat*muZhat/(2.*Snq+lq) - log_denom2[IDX_NQ(n,q)]/2. + log_gamma[IDX_NQ(n,q)];
+                    double exp2 = log_gamma1[IDX_NQ(n,q)] - Z2/(2.*lq);
+                    log_psi2_n += (exp1>exp2)?exp1+log1p(exp(exp2-exp1)):exp2+log1p(exp(exp1-exp2));
+                }
+                double exp_psi2_n = exp(log_psi2_n);
+                psi2n[IDX_NMM(n,m1,m2)] = var*var*exp_psi2_n;
+                if(m1!=m2) { psi2n[IDX_NMM(n,m2,m1)] = var*var*exp_psi2_n;}
+                psi2_local[threadIdx.x] += exp_psi2_n;
+            }
+            __syncthreads();
+            reduce_sum(psi2_local, THREADNUM);
+            if(threadIdx.x==0) {
+                psi2[IDX_MM(m1,m2)] = var*var*psi2_local[0];
+                if(m1!=m2) { psi2[IDX_MM(m2,m1)] = var*var*psi2_local[0]; }
+            }
+            __syncthreads();
+        }
+    }
+    
+    __global__ void psi1compDer(double *dvar, double *dl, double *dZ, double *dmu, double *dS, double *dgamma, double *dL_dpsi1, double *psi1, double *log_denom1, double *log_gamma, double*log_gamma1, double var, double *l, double *Z, double *mu, double *S, double *gamma, int N, int M, int Q)
+    {
+        int m_start, m_end;
+        __shared__ double g_local[THREADNUM];
+        divide_data(M, gridDim.x, blockIdx.x, &m_start, &m_end);
+        int P = int(ceil(double(N)/THREADNUM));
+
+        double dvar_local = 0;
+        for(int q=0;q<Q;q++) {
+            double lq_sqrt = l[q];
+            double lq = lq_sqrt*lq_sqrt;
+            double dl_local = 0;
+            for(int p=0;p<P;p++) {
+                int n = p*THREADNUM + threadIdx.x;
+                double dmu_local = 0;
+                double dS_local = 0;
+                double dgamma_local = 0;
+                double Snq,mu_nq,gnq,log_gnq,log_gnq1,log_de;
+                if(n<N) {Snq = S[IDX_NQ(n,q)]; mu_nq=mu[IDX_NQ(n,q)]; gnq = gamma[IDX_NQ(n,q)];
+                        log_gnq = log_gamma[IDX_NQ(n,q)]; log_gnq1 = log_gamma1[IDX_NQ(n,q)];
+                        log_de = log_denom1[IDX_NQ(n,q)];}
+                for(int m=m_start; m<m_end; m++) {
+                    if(n<N) {
+                        double lpsi1 = psi1[IDX_NM(n,m)]*dL_dpsi1[IDX_NM(n,m)];
+                        if(q==0) {dvar_local += lpsi1;}
+                        
+                        double Zmq = Z[IDX_MQ(m,q)];
+                        double Zmu = Zmq - mu_nq;
+                        double denom = Snq+lq;
+                        double Zmu2_denom = Zmu*Zmu/denom;
+                        
+                        double exp1 = log_gnq-(Zmu*Zmu/(Snq+lq)+log_de)/(2.);
+                        double exp2 = log_gnq1-Zmq*Zmq/(2.*lq);
+                        double d_exp1,d_exp2;
+                        if(exp1>exp2) {
+                            d_exp1 = 1.;
+                            d_exp2 = exp(exp2-exp1);
+                        } else {
+                            d_exp1 = exp(exp1-exp2);
+                            d_exp2 = 1.;
+                        }
+                        double exp_sum = d_exp1+d_exp2;
+                        
+                        dmu_local += lpsi1*Zmu*d_exp1/(denom*exp_sum);
+                        dS_local += lpsi1*(Zmu2_denom-1.)*d_exp1/(denom*exp_sum);
+                        dgamma_local += lpsi1*(d_exp1/gnq-d_exp2/(1.-gnq))/exp_sum;
+                        dl_local += lpsi1*((Zmu2_denom+Snq/lq)/denom*d_exp1+Zmq*Zmq/(lq*lq)*d_exp2)/(2.*exp_sum);
+                        g_local[threadIdx.x] = lpsi1*(-Zmu/denom*d_exp1-Zmq/lq*d_exp2)/exp_sum;
+                    }
+                    __syncthreads();
+                    reduce_sum(g_local, p<P-1?THREADNUM:N-(P-1)*THREADNUM);
+                    if(threadIdx.x==0) {dZ[IDX_MQ(m,q)] += g_local[0];}
+                }
+                if(n<N) {
+                    dmu[IDX_NQB(n,q,blockIdx.x)] += dmu_local;
+                    dS[IDX_NQB(n,q,blockIdx.x)] += dS_local/2.;
+                    dgamma[IDX_NQB(n,q,blockIdx.x)] += dgamma_local;
+                }
+                __threadfence_block();
+            }
+            g_local[threadIdx.x] = dl_local*2.*lq_sqrt;
+            __syncthreads();
+            reduce_sum(g_local, THREADNUM);
+            if(threadIdx.x==0) {dl[IDX_QB(q,blockIdx.x)] += g_local[0];}
+        }
+        g_local[threadIdx.x] = dvar_local;
+        __syncthreads();
+        reduce_sum(g_local, THREADNUM);
+        if(threadIdx.x==0) {dvar[blockIdx.x] += g_local[0]/var;}
+    }
+    
+    __global__ void psi2compDer(double *dvar, double *dl, double *dZ, double *dmu, double *dS, double *dgamma, double *dL_dpsi2, double *psi2n, double *log_denom2, double *log_gamma, double*log_gamma1, double var, double *l, double *Z, double *mu, double *S, double *gamma, int N, int M, int Q)
+    {
+        int m_start, m_end;
+        __shared__ double g_local[THREADNUM];
+        divide_data(M, gridDim.x, blockIdx.x, &m_start, &m_end);
+        int P = int(ceil(double(N)/THREADNUM));
+
+        double dvar_local = 0;
+        for(int q=0;q<Q;q++) {
+            double lq_sqrt = l[q];
+            double lq = lq_sqrt*lq_sqrt;
+            double dl_local = 0;
+            for(int p=0;p<P;p++) {
+                int n = p*THREADNUM + threadIdx.x;
+                double dmu_local = 0;
+                double dS_local = 0;
+                double dgamma_local = 0;
+                double Snq,mu_nq,gnq,log_gnq,log_gnq1,log_de;
+                if(n<N) {Snq = S[IDX_NQ(n,q)]; mu_nq=mu[IDX_NQ(n,q)]; gnq = gamma[IDX_NQ(n,q)];
+                        log_gnq = log_gamma[IDX_NQ(n,q)]; log_gnq1 = log_gamma1[IDX_NQ(n,q)];
+                        log_de = log_denom2[IDX_NQ(n,q)];}
+                for(int m1=m_start; m1<m_end; m1++) {
+                    g_local[threadIdx.x] = 0;
+                    for(int m2=0;m2<M;m2++) {
+                        if(n<N) {
+                            double lpsi2 = psi2n[IDX_NMM(n,m1,m2)]*dL_dpsi2[IDX_MM(m1,m2)];
+                            if(q==0) {dvar_local += lpsi2;}
+                            
+                            double Zm1q = Z[IDX_MQ(m1,q)];
+                            double Zm2q = Z[IDX_MQ(m2,q)];
+                            double dZ = Zm1q - Zm2q;
+                            double Z2 = Zm1q*Zm1q+Zm2q*Zm2q;
+                            double muZhat =  mu_nq - (Zm1q + Zm2q)/2.;
+                            double denom = 2.*Snq+lq;
+                            double muZhat2_denom = muZhat*muZhat/denom;
+                            
+                            double exp1 = dZ*dZ/(-4.*lq)-muZhat*muZhat/(2.*Snq+lq) - log_de/2. + log_gnq;
+                            double exp2 = log_gnq1 - Z2/(2.*lq);
+                            double d_exp1,d_exp2;
+                            if(exp1>exp2) {
+                                d_exp1 = 1.;
+                                d_exp2 = exp(exp2-exp1);
+                            } else {
+                                d_exp1 = exp(exp1-exp2);
+                                d_exp2 = 1.;
+                            }
+                            double exp_sum = d_exp1+d_exp2;
+                            
+                            dmu_local += lpsi2*muZhat/denom*d_exp1/exp_sum;
+                            dS_local += lpsi2*(2.*muZhat2_denom-1.)/denom*d_exp1/exp_sum;
+                            dgamma_local += lpsi2*(d_exp1/gnq-d_exp2/(1.-gnq))/exp_sum;
+                            dl_local += lpsi2*(((Snq/lq+muZhat2_denom)/denom+dZ*dZ/(4.*lq*lq))*d_exp1+Z2/(2.*lq*lq)*d_exp2)/exp_sum;
+                            g_local[threadIdx.x] += 2.*lpsi2*((muZhat/denom-dZ/(2*lq))*d_exp1-Zm1q/lq*d_exp2)/exp_sum;
+                        }
+                    }
+                    __syncthreads();
+                    reduce_sum(g_local, p<P-1?THREADNUM:N-(P-1)*THREADNUM);
+                    if(threadIdx.x==0) {dZ[IDX_MQ(m1,q)] += g_local[0];}
+                }
+                if(n<N) {
+                    dmu[IDX_NQB(n,q,blockIdx.x)] += -2.*dmu_local;
+                    dS[IDX_NQB(n,q,blockIdx.x)] += dS_local;
+                    dgamma[IDX_NQB(n,q,blockIdx.x)] += dgamma_local;
+                }
+                __threadfence_block();
+            }
+            g_local[threadIdx.x] = dl_local*2.*lq_sqrt;
+            __syncthreads();
+            reduce_sum(g_local, THREADNUM);
+            if(threadIdx.x==0) {dl[IDX_QB(q,blockIdx.x)] += g_local[0];}
+        }
+        g_local[threadIdx.x] = dvar_local;
+        __syncthreads();
+        reduce_sum(g_local, THREADNUM);
+        if(threadIdx.x==0) {dvar[blockIdx.x] += g_local[0]*2/var;}
+    }
+    """
+
+class PSICOMP_SSRBF_GPU(PSICOMP_RBF):
+
[docs] + def __init__(self, threadnum=128, blocknum=15, GPU_direct=False): + self.GPU_direct = GPU_direct + self.gpuCache = None + + self.threadnum = threadnum + self.blocknum = blocknum + module = SourceModule("#define THREADNUM "+str(self.threadnum)+"\n"+gpu_code) + self.g_psi1computations = module.get_function('psi1computations') + self.g_psi1computations.prepare('PPPPdPPPPiii') + self.g_psi2computations = module.get_function('psi2computations') + self.g_psi2computations.prepare('PPPPPdPPPPiii') + self.g_psi1compDer = module.get_function('psi1compDer') + self.g_psi1compDer.prepare('PPPPPPPPPPPdPPPPPiii') + self.g_psi2compDer = module.get_function('psi2compDer') + self.g_psi2compDer.prepare('PPPPPPPPPPPdPPPPPiii') + self.g_compDenom = module.get_function('compDenom') + self.g_compDenom.prepare('PPPPPPPii') + + def __deepcopy__(self, memo): + s = PSICOMP_SSRBF_GPU(threadnum=self.threadnum, blocknum=self.blocknum, GPU_direct=self.GPU_direct) + memo[id(self)] = s + return s + + def _initGPUCache(self, N, M, Q): + if self.gpuCache == None: + self.gpuCache = { + 'l_gpu' :gpuarray.empty((Q,),np.float64,order='F'), + 'Z_gpu' :gpuarray.empty((M,Q),np.float64,order='F'), + 'mu_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + 'S_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + 'gamma_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + 'psi1_gpu' :gpuarray.empty((N,M),np.float64,order='F'), + 'psi2_gpu' :gpuarray.empty((M,M),np.float64,order='F'), + 'psi2n_gpu' :gpuarray.empty((N,M,M),np.float64,order='F'), + 'dL_dpsi1_gpu' :gpuarray.empty((N,M),np.float64,order='F'), + 'dL_dpsi2_gpu' :gpuarray.empty((M,M),np.float64,order='F'), + 'log_denom1_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + 'log_denom2_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + 'log_gamma_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + 'log_gamma1_gpu' :gpuarray.empty((N,Q),np.float64,order='F'), + # derivatives + 'dvar_gpu' :gpuarray.empty((self.blocknum,),np.float64, order='F'), + 'dl_gpu' :gpuarray.empty((Q,self.blocknum),np.float64, order='F'), + 'dZ_gpu' :gpuarray.empty((M,Q),np.float64, order='F'), + 'dmu_gpu' :gpuarray.empty((N,Q,self.blocknum),np.float64, order='F'), + 'dS_gpu' :gpuarray.empty((N,Q,self.blocknum),np.float64, order='F'), + 'dgamma_gpu' :gpuarray.empty((N,Q,self.blocknum),np.float64, order='F'), + # grad + 'grad_l_gpu' :gpuarray.empty((Q,),np.float64, order='F'), + 'grad_mu_gpu' :gpuarray.empty((N,Q,),np.float64, order='F'), + 'grad_S_gpu' :gpuarray.empty((N,Q,),np.float64, order='F'), + 'grad_gamma_gpu' :gpuarray.empty((N,Q,),np.float64, order='F'), + } + else: + assert N==self.gpuCache['mu_gpu'].shape[0] + assert M==self.gpuCache['Z_gpu'].shape[0] + assert Q==self.gpuCache['l_gpu'].shape[0] + + def sync_params(self, lengthscale, Z, mu, S, gamma): +
[docs] if len(lengthscale)==1: + self.gpuCache['l_gpu'].fill(lengthscale) + else: + self.gpuCache['l_gpu'].set(np.asfortranarray(lengthscale)) + self.gpuCache['Z_gpu'].set(np.asfortranarray(Z)) + self.gpuCache['mu_gpu'].set(np.asfortranarray(mu)) + self.gpuCache['S_gpu'].set(np.asfortranarray(S)) + self.gpuCache['gamma_gpu'].set(np.asfortranarray(gamma)) + N,Q = self.gpuCache['S_gpu'].shape + self.g_compDenom.prepared_call((self.blocknum,1),(self.threadnum,1,1), self.gpuCache['log_denom1_gpu'].gpudata,self.gpuCache['log_denom2_gpu'].gpudata,self.gpuCache['log_gamma_gpu'].gpudata,self.gpuCache['log_gamma1_gpu'].gpudata,self.gpuCache['gamma_gpu'].gpudata,self.gpuCache['l_gpu'].gpudata,self.gpuCache['S_gpu'].gpudata, np.int32(N), np.int32(Q)) + + def reset_derivative(self):
+
[docs] self.gpuCache['dvar_gpu'].fill(0.) + self.gpuCache['dl_gpu'].fill(0.) + self.gpuCache['dZ_gpu'].fill(0.) + self.gpuCache['dmu_gpu'].fill(0.) + self.gpuCache['dS_gpu'].fill(0.) + self.gpuCache['dgamma_gpu'].fill(0.) + self.gpuCache['grad_l_gpu'].fill(0.) + self.gpuCache['grad_mu_gpu'].fill(0.) + self.gpuCache['grad_S_gpu'].fill(0.) + self.gpuCache['grad_gamma_gpu'].fill(0.) + + def get_dimensions(self, Z, variational_posterior):
+
[docs] return variational_posterior.mean.shape[0], Z.shape[0], Z.shape[1] + + @Cache_this(limit=1, ignore_args=(0,))
+ def psicomputations(self, variance, lengthscale, Z, variational_posterior): + """ + Z - MxQ + mu - NxQ + S - NxQ + """ + N,M,Q = self.get_dimensions(Z, variational_posterior) + self._initGPUCache(N,M,Q) + self.sync_params(lengthscale, Z, variational_posterior.mean, variational_posterior.variance, variational_posterior.binary_prob) + + psi1_gpu = self.gpuCache['psi1_gpu'] + psi2_gpu = self.gpuCache['psi2_gpu'] + psi2n_gpu = self.gpuCache['psi2n_gpu'] + l_gpu = self.gpuCache['l_gpu'] + Z_gpu = self.gpuCache['Z_gpu'] + mu_gpu = self.gpuCache['mu_gpu'] + S_gpu = self.gpuCache['S_gpu'] + log_denom1_gpu = self.gpuCache['log_denom1_gpu'] + log_denom2_gpu = self.gpuCache['log_denom2_gpu'] + log_gamma_gpu = self.gpuCache['log_gamma_gpu'] + log_gamma1_gpu = self.gpuCache['log_gamma1_gpu'] + + psi0 = np.empty((N,)) + psi0[:] = variance + self.g_psi1computations.prepared_call((self.blocknum,1),(self.threadnum,1,1),psi1_gpu.gpudata, log_denom1_gpu.gpudata, log_gamma_gpu.gpudata, log_gamma1_gpu.gpudata, np.float64(variance),l_gpu.gpudata,Z_gpu.gpudata,mu_gpu.gpudata,S_gpu.gpudata, np.int32(N), np.int32(M), np.int32(Q)) + self.g_psi2computations.prepared_call((self.blocknum,1),(self.threadnum,1,1),psi2_gpu.gpudata, psi2n_gpu.gpudata, log_denom2_gpu.gpudata, log_gamma_gpu.gpudata, log_gamma1_gpu.gpudata, np.float64(variance),l_gpu.gpudata,Z_gpu.gpudata,mu_gpu.gpudata,S_gpu.gpudata, np.int32(N), np.int32(M), np.int32(Q)) + + if self.GPU_direct: + return psi0, psi1_gpu, psi2_gpu + else: + return psi0, psi1_gpu.get(), psi2_gpu.get() + + @Cache_this(limit=1, ignore_args=(0,1,2,3)) + def psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior): + ARD = (len(lengthscale)!=1) + + N,M,Q = self.get_dimensions(Z, variational_posterior) + psi1_gpu = self.gpuCache['psi1_gpu'] + psi2n_gpu = self.gpuCache['psi2n_gpu'] + l_gpu = self.gpuCache['l_gpu'] + Z_gpu = self.gpuCache['Z_gpu'] + mu_gpu = self.gpuCache['mu_gpu'] + S_gpu = self.gpuCache['S_gpu'] + gamma_gpu = self.gpuCache['gamma_gpu'] + dvar_gpu = self.gpuCache['dvar_gpu'] + dl_gpu = self.gpuCache['dl_gpu'] + dZ_gpu = self.gpuCache['dZ_gpu'] + dmu_gpu = self.gpuCache['dmu_gpu'] + dS_gpu = self.gpuCache['dS_gpu'] + dgamma_gpu = self.gpuCache['dgamma_gpu'] + grad_l_gpu = self.gpuCache['grad_l_gpu'] + grad_mu_gpu = self.gpuCache['grad_mu_gpu'] + grad_S_gpu = self.gpuCache['grad_S_gpu'] + grad_gamma_gpu = self.gpuCache['grad_gamma_gpu'] + log_denom1_gpu = self.gpuCache['log_denom1_gpu'] + log_denom2_gpu = self.gpuCache['log_denom2_gpu'] + log_gamma_gpu = self.gpuCache['log_gamma_gpu'] + log_gamma1_gpu = self.gpuCache['log_gamma1_gpu'] + + if self.GPU_direct: + dL_dpsi1_gpu = dL_dpsi1 + dL_dpsi2_gpu = dL_dpsi2 + dL_dpsi0_sum = gpuarray.sum(dL_dpsi0).get() + else: + dL_dpsi1_gpu = self.gpuCache['dL_dpsi1_gpu'] + dL_dpsi2_gpu = self.gpuCache['dL_dpsi2_gpu'] + dL_dpsi1_gpu.set(np.asfortranarray(dL_dpsi1)) + dL_dpsi2_gpu.set(np.asfortranarray(dL_dpsi2)) + dL_dpsi0_sum = dL_dpsi0.sum() + + self.reset_derivative() + # t=self.g_psi1compDer(dvar_gpu,dl_gpu,dZ_gpu,dmu_gpu,dS_gpu,dL_dpsi1_gpu,psi1_gpu, np.float64(variance),l_gpu,Z_gpu,mu_gpu,S_gpu, np.int32(N), np.int32(M), np.int32(Q), block=(self.threadnum,1,1), grid=(self.blocknum,1),time_kernel=True) + # print 'g_psi1compDer '+str(t) + # t=self.g_psi2compDer(dvar_gpu,dl_gpu,dZ_gpu,dmu_gpu,dS_gpu,dL_dpsi2_gpu,psi2n_gpu, np.float64(variance),l_gpu,Z_gpu,mu_gpu,S_gpu, np.int32(N), np.int32(M), np.int32(Q), block=(self.threadnum,1,1), grid=(self.blocknum,1),time_kernel=True) + # print 'g_psi2compDer '+str(t) + self.g_psi1compDer.prepared_call((self.blocknum,1),(self.threadnum,1,1),dvar_gpu.gpudata,dl_gpu.gpudata,dZ_gpu.gpudata,dmu_gpu.gpudata,dS_gpu.gpudata,dgamma_gpu.gpudata,dL_dpsi1_gpu.gpudata,psi1_gpu.gpudata, log_denom1_gpu.gpudata, log_gamma_gpu.gpudata, log_gamma1_gpu.gpudata, np.float64(variance),l_gpu.gpudata,Z_gpu.gpudata,mu_gpu.gpudata,S_gpu.gpudata,gamma_gpu.gpudata,np.int32(N), np.int32(M), np.int32(Q)) + self.g_psi2compDer.prepared_call((self.blocknum,1),(self.threadnum,1,1),dvar_gpu.gpudata,dl_gpu.gpudata,dZ_gpu.gpudata,dmu_gpu.gpudata,dS_gpu.gpudata,dgamma_gpu.gpudata,dL_dpsi2_gpu.gpudata,psi2n_gpu.gpudata, log_denom2_gpu.gpudata, log_gamma_gpu.gpudata, log_gamma1_gpu.gpudata, np.float64(variance),l_gpu.gpudata,Z_gpu.gpudata,mu_gpu.gpudata,S_gpu.gpudata,gamma_gpu.gpudata,np.int32(N), np.int32(M), np.int32(Q)) + + dL_dvar = dL_dpsi0_sum + gpuarray.sum(dvar_gpu).get() + sum_axis(grad_mu_gpu,dmu_gpu,N*Q,self.blocknum) + dL_dmu = grad_mu_gpu.get() + sum_axis(grad_S_gpu,dS_gpu,N*Q,self.blocknum) + dL_dS = grad_S_gpu.get() + sum_axis(grad_gamma_gpu,dgamma_gpu,N*Q,self.blocknum) + dL_dgamma = grad_gamma_gpu.get() + dL_dZ = dZ_gpu.get() + if ARD: + sum_axis(grad_l_gpu,dl_gpu,Q,self.blocknum) + dL_dlengscale = grad_l_gpu.get() + else: + dL_dlengscale = gpuarray.sum(dl_gpu).get() + + return dL_dvar, dL_dlengscale, dL_dZ, dL_dmu, dL_dS, dL_dgamma + +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/rbf.html b/doc/_build/html/_modules/GPy/kern/_src/rbf.html new file mode 100644 index 00000000..67c0212a --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/rbf.html @@ -0,0 +1,164 @@ + + + + + + + + GPy.kern._src.rbf — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.rbf

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from stationary import Stationary
+from psi_comp import PSICOMP_RBF
+from psi_comp.rbf_psi_gpucomp import PSICOMP_RBF_GPU
+from ...util.config import *
+
+
[docs]class RBF(Stationary): + """ + Radial Basis Function kernel, aka squared-exponential, exponentiated quadratic or Gaussian kernel: + + .. math:: + + k(r) = \sigma^2 \exp \\bigg(- \\frac{1}{2} r^2 \\bigg) + + """ + _support_GPU = True + def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='rbf', useGPU=False): + super(RBF, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name, useGPU=useGPU) + self.psicomp = PSICOMP_RBF() + if self.useGPU: + self.psicomp = PSICOMP_RBF_GPU() + else: + self.psicomp = PSICOMP_RBF() + +
[docs] def K_of_r(self, r): + return self.variance * np.exp(-0.5 * r**2) +
+
[docs] def dK_dr(self, r): + return -r*self.K_of_r(r) +
+ def __getstate__(self): + dc = super(RBF, self).__getstate__() + if self.useGPU: + dc['psicomp'] = PSICOMP_RBF() + return dc + + def __setstate__(self, state): + return super(RBF, self).__setstate__(state) + +
[docs] def spectrum(self, omega): + assert self.input_dim == 1 #TODO: higher dim spectra? + return self.variance*np.sqrt(2*np.pi)*self.lengthscale*np.exp(-self.lengthscale*2*omega**2/2) + + #---------------------------------------# + # PSI statistics # + #---------------------------------------# +
+
[docs] def psi0(self, Z, variational_posterior): + return self.psicomp.psicomputations(self.variance, self.lengthscale, Z, variational_posterior)[0] +
+
[docs] def psi1(self, Z, variational_posterior): + return self.psicomp.psicomputations(self.variance, self.lengthscale, Z, variational_posterior)[1] +
+
[docs] def psi2(self, Z, variational_posterior): + return self.psicomp.psicomputations(self.variance, self.lengthscale, Z, variational_posterior)[2] +
+
[docs] def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + dL_dvar, dL_dlengscale = self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variance, self.lengthscale, Z, variational_posterior)[:2] + self.variance.gradient = dL_dvar + self.lengthscale.gradient = dL_dlengscale +
+
[docs] def gradients_Z_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + return self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variance, self.lengthscale, Z, variational_posterior)[2] +
+
[docs] def gradients_qX_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + return self.psicomp.psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, self.variance, self.lengthscale, Z, variational_posterior)[3:] +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/splitKern.html b/doc/_build/html/_modules/GPy/kern/_src/splitKern.html new file mode 100644 index 00000000..33937492 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/splitKern.html @@ -0,0 +1,297 @@ + + + + + + + + GPy.kern._src.splitKern — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.splitKern

+"""
+A new kernel
+"""
+
+import numpy as np
+from kern import Kern,CombinationKernel
+from .independent_outputs import index_to_slices
+import itertools
+
+
[docs]class DiffGenomeKern(Kern): + + def __init__(self, kernel, idx_p, Xp, index_dim=-1, name='DiffGenomeKern'): + self.idx_p = idx_p + self.index_dim=index_dim + self.kern = SplitKern(kernel,Xp, index_dim=index_dim) + super(DiffGenomeKern, self).__init__(input_dim=kernel.input_dim+1, active_dims=None, name=name) + self.add_parameter(self.kern) + +
[docs] def K(self, X, X2=None): + assert X2==None + K = self.kern.K(X,X2) + + if self.idx_p<=0 or self.idx_p>X.shape[0]/2: + return K + + slices = index_to_slices(X[:,self.index_dim]) + idx_start = slices[1][0].start + idx_end = idx_start+self.idx_p + K_c = K[idx_start:idx_end,idx_start:idx_end].copy() + K[idx_start:idx_end,:] = K[:self.idx_p,:] + K[:,idx_start:idx_end] = K[:,:self.idx_p] + K[idx_start:idx_end,idx_start:idx_end] = K_c + + return K +
+
[docs] def Kdiag(self,X): + Kdiag = self.kern.Kdiag(X) + + if self.idx_p<=0 or self.idx_p>X.shape[0]/2: + return Kdiag + + slices = index_to_slices(X[:,self.index_dim]) + idx_start = slices[1][0].start + idx_end = idx_start+self.idx_p + Kdiag[idx_start:idx_end] = Kdiag[:self.idx_p] + + return Kdiag +
+
[docs] def update_gradients_full(self,dL_dK,X,X2=None): + assert X2==None + if self.idx_p<=0 or self.idx_p>X.shape[0]/2: + self.kern.update_gradients_full(dL_dK, X) + return + + slices = index_to_slices(X[:,self.index_dim]) + idx_start = slices[1][0].start + idx_end = idx_start+self.idx_p + + self.kern.update_gradients_full(dL_dK[idx_start:idx_end,:], X[:self.idx_p],X) + grad_p1 = self.kern.gradient.copy() + self.kern.update_gradients_full(dL_dK[:,idx_start:idx_end], X, X[:self.idx_p]) + grad_p2 = self.kern.gradient.copy() + self.kern.update_gradients_full(dL_dK[idx_start:idx_end,idx_start:idx_end], X[:self.idx_p],X[idx_start:idx_end]) + grad_p3 = self.kern.gradient.copy() + self.kern.update_gradients_full(dL_dK[idx_start:idx_end,idx_start:idx_end], X[idx_start:idx_end], X[:self.idx_p]) + grad_p4 = self.kern.gradient.copy() + + self.kern.update_gradients_full(dL_dK[idx_start:idx_end,:], X[idx_start:idx_end],X) + grad_n1 = self.kern.gradient.copy() + self.kern.update_gradients_full(dL_dK[:,idx_start:idx_end], X, X[idx_start:idx_end]) + grad_n2 = self.kern.gradient.copy() + self.kern.update_gradients_full(dL_dK[idx_start:idx_end,idx_start:idx_end], X[idx_start:idx_end], X[idx_start:idx_end]) + grad_n3 = self.kern.gradient.copy() + + self.kern.update_gradients_full(dL_dK, X) + self.kern.gradient += grad_p1+grad_p2-grad_p3-grad_p4-grad_n1-grad_n2+2*grad_n3 +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + pass +
+
[docs]class SplitKern(CombinationKernel): + + def __init__(self, kernel, Xp, index_dim=-1, name='SplitKern'): + assert isinstance(index_dim, int), "The index dimension must be an integer!" + self.kern = kernel + self.kern_cross = SplitKern_cross(kernel,Xp) + super(SplitKern, self).__init__(kernels=[self.kern, self.kern_cross], extra_dims=[index_dim], name=name) + self.index_dim = index_dim + +
[docs] def K(self,X ,X2=None): + slices = index_to_slices(X[:,self.index_dim]) + assert len(slices)<=2, 'The Split kernel only support two different indices' + if X2 is None: + target = np.zeros((X.shape[0], X.shape[0])) + # diagonal blocks + [[target.__setitem__((s,ss), self.kern.K(X[s,:], X[ss,:])) for s,ss in itertools.product(slices_i, slices_i)] for slices_i in slices] + if len(slices)>1: + # cross blocks + [target.__setitem__((s,ss), self.kern_cross.K(X[s,:], X[ss,:])) for s,ss in itertools.product(slices[0], slices[1])] + # cross blocks + [target.__setitem__((s,ss), self.kern_cross.K(X[s,:], X[ss,:])) for s,ss in itertools.product(slices[1], slices[0])] + else: + slices2 = index_to_slices(X2[:,self.index_dim]) + assert len(slices2)<=2, 'The Split kernel only support two different indices' + target = np.zeros((X.shape[0], X2.shape[0])) + # diagonal blocks + [[target.__setitem__((s,s2), self.kern.K(X[s,:],X2[s2,:])) for s,s2 in itertools.product(slices[i], slices2[i])] for i in xrange(min(len(slices),len(slices2)))] + if len(slices)>1: + [target.__setitem__((s,s2), self.kern_cross.K(X[s,:],X2[s2,:])) for s,s2 in itertools.product(slices[1], slices2[0])] + if len(slices2)>1: + [target.__setitem__((s,s2), self.kern_cross.K(X[s,:],X2[s2,:])) for s,s2 in itertools.product(slices[0], slices2[1])] + return target +
+
[docs] def Kdiag(self,X): + return self.kern.Kdiag(X) +
+
[docs] def update_gradients_full(self,dL_dK,X,X2=None): + slices = index_to_slices(X[:,self.index_dim]) + target = np.zeros(self.kern.size) + + def collate_grads(dL, X, X2, cross=False): + if cross: + self.kern_cross.update_gradients_full(dL,X,X2) + target[:] += self.kern_cross.kern.gradient + else: + self.kern.update_gradients_full(dL,X,X2) + target[:] += self.kern.gradient + + if X2 is None: + assert dL_dK.shape==(X.shape[0],X.shape[0]) + [[collate_grads(dL_dK[s,ss], X[s], X[ss]) for s,ss in itertools.product(slices_i, slices_i)] for slices_i in slices] + if len(slices)>1: + [collate_grads(dL_dK[s,ss], X[s], X[ss], True) for s,ss in itertools.product(slices[0], slices[1])] + [collate_grads(dL_dK[s,ss], X[s], X[ss], True) for s,ss in itertools.product(slices[1], slices[0])] + else: + assert dL_dK.shape==(X.shape[0],X2.shape[0]) + slices2 = index_to_slices(X2[:,self.index_dim]) + [[collate_grads(dL_dK[s,s2],X[s],X2[s2]) for s,s2 in itertools.product(slices[i], slices2[i])] for i in xrange(min(len(slices),len(slices2)))] + if len(slices)>1: + [collate_grads(dL_dK[s,s2], X[s], X2[s2], True) for s,s2 in itertools.product(slices[1], slices2[0])] + if len(slices2)>1: + [collate_grads(dL_dK[s,s2], X[s], X2[s2], True) for s,s2 in itertools.product(slices[0], slices2[1])] + self.kern.gradient = target +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + self.kern.update_gradients_diag(self, dL_dKdiag, X) +
+
[docs]class SplitKern_cross(Kern): + + def __init__(self, kernel, Xp, name='SplitKern_cross'): + assert isinstance(kernel, Kern) + self.kern = kernel + if not isinstance(Xp,np.ndarray): + Xp = np.array([[Xp]]) + self.Xp = Xp + super(SplitKern_cross, self).__init__(input_dim=kernel.input_dim, active_dims=None, name=name) + +
[docs] def K(self, X, X2=None): + if X2 is None: + return np.dot(self.kern.K(X,self.Xp),self.kern.K(self.Xp,X))/self.kern.K(self.Xp,self.Xp) + else: + return np.dot(self.kern.K(X,self.Xp),self.kern.K(self.Xp,X2))/self.kern.K(self.Xp,self.Xp) +
+
[docs] def Kdiag(self, X): + return np.inner(self.kern.K(X,self.Xp),self.kern.K(self.Xp,X).T)/self.kern.K(self.Xp,self.Xp) +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + if X2 is None: + X2 = X + + k1 = self.kern.K(X,self.Xp) + k2 = self.kern.K(self.Xp,X2) + k3 = self.kern.K(self.Xp,self.Xp) + dL_dk1 = np.einsum('ij,j->i',dL_dK,k2[0])/k3[0,0] + dL_dk2 = np.einsum('ij,i->j',dL_dK,k1[:,0])/k3[0,0] + dL_dk3 = np.einsum('ij,ij->',dL_dK,-np.dot(k1,k2)/(k3[0,0]*k3[0,0])) + + self.kern.update_gradients_full(dL_dk1[:,None],X,self.Xp) + grad = self.kern.gradient.copy() + self.kern.update_gradients_full(dL_dk2[None,:],self.Xp,X2) + grad += self.kern.gradient.copy() + self.kern.update_gradients_full(np.array([[dL_dk3]]),self.Xp,self.Xp) + grad += self.kern.gradient.copy() + + self.kern.gradient = grad +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + k1 = self.kern.K(X,self.Xp) + k2 = self.kern.K(self.Xp,X) + k3 = self.kern.K(self.Xp,self.Xp) + dL_dk1 = dL_dKdiag*k2[0]/k3 + dL_dk2 = dL_dKdiag*k1[:,0]/k3 + dL_dk3 = -dL_dKdiag*(k1[:,0]*k2[0]).sum()/(k3*k3) + + self.kern.update_gradients_full(dL_dk1[:,None],X,self.Xp) + grad1 = self.kern.gradient.copy() + self.kern.update_gradients_full(dL_dk2[None,:],self.Xp,X) + grad2 = self.kern.gradient.copy() + self.kern.update_gradients_full(np.array([[dL_dk3]]),self.Xp,self.Xp) + grad3 = self.kern.gradient.copy() + + self.kern.gradient = grad1+grad2+grad3 + +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/static.html b/doc/_build/html/_modules/GPy/kern/_src/static.html new file mode 100644 index 00000000..a2cefe60 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/static.html @@ -0,0 +1,215 @@ + + + + + + + + GPy.kern._src.static — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.static

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+from kern import Kern
+import numpy as np
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+
+
[docs]class Static(Kern): + def __init__(self, input_dim, variance, active_dims, name): + super(Static, self).__init__(input_dim, active_dims, name) + self.variance = Param('variance', variance, Logexp()) + self.link_parameters(self.variance) + +
[docs] def Kdiag(self, X): + ret = np.empty((X.shape[0],), dtype=np.float64) + ret[:] = self.variance + return ret +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + return np.zeros(X.shape) +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + return np.zeros(X.shape) +
+
[docs] def gradients_Z_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + return np.zeros(Z.shape) +
+
[docs] def gradients_qX_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + return np.zeros(variational_posterior.shape), np.zeros(variational_posterior.shape) +
+
[docs] def psi0(self, Z, variational_posterior): + return self.Kdiag(variational_posterior.mean) +
+
[docs] def psi1(self, Z, variational_posterior): + return self.K(variational_posterior.mean, Z) +
+
[docs] def psi2(self, Z, variational_posterior): + K = self.K(variational_posterior.mean, Z) + return np.einsum('ij,ik->jk',K,K) #K[:,:,None]*K[:,None,:] # NB. more efficient implementations on inherriting classes +
+
[docs] def input_sensitivity(self, summarize=True): + if summarize: + return super(Static, self).input_sensitivity(summarize=summarize) + else: + return np.ones(self.input_dim) * self.variance +
+
[docs]class White(Static): + def __init__(self, input_dim, variance=1., active_dims=None, name='white'): + super(White, self).__init__(input_dim, variance, active_dims, name) + +
[docs] def K(self, X, X2=None): + if X2 is None: + return np.eye(X.shape[0])*self.variance + else: + return np.zeros((X.shape[0], X2.shape[0])) +
+
[docs] def psi2(self, Z, variational_posterior): + return np.zeros((Z.shape[0], Z.shape[0]), dtype=np.float64) +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + self.variance.gradient = np.trace(dL_dK) +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + self.variance.gradient = dL_dKdiag.sum() +
+
[docs] def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + self.variance.gradient = dL_dpsi0.sum() +
+
[docs]class Bias(Static): + def __init__(self, input_dim, variance=1., active_dims=None, name='bias'): + super(Bias, self).__init__(input_dim, variance, active_dims, name) + +
[docs] def K(self, X, X2=None): + shape = (X.shape[0], X.shape[0] if X2 is None else X2.shape[0]) + ret = np.empty(shape, dtype=np.float64) + ret[:] = self.variance + return ret +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + self.variance.gradient = dL_dK.sum() +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + self.variance.gradient = dL_dKdiag.sum() +
+
[docs] def psi2(self, Z, variational_posterior): + ret = np.empty((Z.shape[0], Z.shape[0]), dtype=np.float64) + ret[:] = self.variance*self.variance*variational_posterior.shape[0] + return ret +
+
[docs] def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + self.variance.gradient = dL_dpsi0.sum() + dL_dpsi1.sum() + 2.*self.variance*dL_dpsi2.sum()*variational_posterior.shape[0] +
+
[docs]class Fixed(Static): + def __init__(self, input_dim, covariance_matrix, variance=1., active_dims=None, name='fixed'): + """ + :param input_dim: the number of input dimensions + :type input_dim: int + :param variance: the variance of the kernel + :type variance: float + """ + super(Fixed, self).__init__(input_dim, variance, active_dims, name) + self.fixed_K = covariance_matrix +
[docs] def K(self, X, X2): + return self.variance * self.fixed_K +
+
[docs] def Kdiag(self, X): + return self.variance * self.fixed_K.diag() +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + self.variance.gradient = np.einsum('ij,ij', dL_dK, self.fixed_K) +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + self.variance.gradient = np.einsum('i,i', dL_dKdiag, self.fixed_K) +
+
[docs] def psi2(self, Z, variational_posterior): + return np.zeros((Z.shape[0], Z.shape[0]), dtype=np.float64) +
+
[docs] def update_gradients_expectations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + self.variance.gradient = dL_dpsi0.sum() +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/stationary.html b/doc/_build/html/_modules/GPy/kern/_src/stationary.html new file mode 100644 index 00000000..a86b8e93 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/stationary.html @@ -0,0 +1,576 @@ + + + + + + + + GPy.kern._src.stationary — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.stationary

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+from kern import Kern
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+from ...util.linalg import tdot
+from ... import util
+import numpy as np
+from scipy import integrate, weave
+from ...util.config import config # for assesing whether to use weave
+from ...util.caching import Cache_this
+
+
[docs]class Stationary(Kern): + """ + Stationary kernels (covariance functions). + + Stationary covariance fucntion depend only on r, where r is defined as + + r = \sqrt{ \sum_{q=1}^Q (x_q - x'_q)^2 } + + The covariance function k(x, x' can then be written k(r). + + In this implementation, r is scaled by the lengthscales parameter(s): + + r = \sqrt{ \sum_{q=1}^Q \frac{(x_q - x'_q)^2}{\ell_q^2} }. + + By default, there's only one lengthscale: seaprate lengthscales for each + dimension can be enables by setting ARD=True. + + To implement a stationary covariance function using this class, one need + only define the covariance function k(r), and it derivative. + + ... + def K_of_r(self, r): + return foo + def dK_dr(self, r): + return bar + + The lengthscale(s) and variance parameters are added to the structure automatically. + + """ + + def __init__(self, input_dim, variance, lengthscale, ARD, active_dims, name, useGPU=False): + super(Stationary, self).__init__(input_dim, active_dims, name,useGPU=useGPU) + self.ARD = ARD + if not ARD: + if lengthscale is None: + lengthscale = np.ones(1) + else: + lengthscale = np.asarray(lengthscale) + assert lengthscale.size == 1, "Only 1 lengthscale needed for non-ARD kernel" + else: + if lengthscale is not None: + lengthscale = np.asarray(lengthscale) + assert lengthscale.size in [1, input_dim], "Bad number of lengthscales" + if lengthscale.size != input_dim: + lengthscale = np.ones(input_dim)*lengthscale + else: + lengthscale = np.ones(self.input_dim) + self.lengthscale = Param('lengthscale', lengthscale, Logexp()) + self.variance = Param('variance', variance, Logexp()) + assert self.variance.size==1 + self.link_parameters(self.variance, self.lengthscale) + +
[docs] def K_of_r(self, r): + raise NotImplementedError, "implement the covariance function as a fn of r to use this class" +
+
[docs] def dK_dr(self, r): + raise NotImplementedError, "implement derivative of the covariance function wrt r to use this class" +
+ @Cache_this(limit=5, ignore_args=()) +
[docs] def K(self, X, X2=None): + """ + Kernel function applied on inputs X and X2. + In the stationary case there is an inner function depending on the + distances from X to X2, called r. + + K(X, X2) = K_of_r((X-X2)**2) + """ + r = self._scaled_dist(X, X2) + return self.K_of_r(r) +
+ @Cache_this(limit=3, ignore_args=()) + def dK_dr_via_X(self, X, X2): + #a convenience function, so we can cache dK_dr + return self.dK_dr(self._scaled_dist(X, X2)) + + def _unscaled_dist(self, X, X2=None): + """ + Compute the Euclidean distance between each row of X and X2, or between + each pair of rows of X if X2 is None. + """ + #X, = self._slice_X(X) + if X2 is None: + Xsq = np.sum(np.square(X),1) + r2 = -2.*tdot(X) + (Xsq[:,None] + Xsq[None,:]) + util.diag.view(r2)[:,]= 0. # force diagnoal to be zero: sometime numerically a little negative + r2 = np.clip(r2, 0, np.inf) + return np.sqrt(r2) + else: + #X2, = self._slice_X(X2) + X1sq = np.sum(np.square(X),1) + X2sq = np.sum(np.square(X2),1) + r2 = -2.*np.dot(X, X2.T) + X1sq[:,None] + X2sq[None,:] + r2 = np.clip(r2, 0, np.inf) + return np.sqrt(r2) + + @Cache_this(limit=5, ignore_args=()) + def _scaled_dist(self, X, X2=None): + """ + Efficiently compute the scaled distance, r. + + r = \sqrt( \sum_{q=1}^Q (x_q - x'q)^2/l_q^2 ) + + Note that if thre is only one lengthscale, l comes outside the sum. In + this case we compute the unscaled distance first (in a separate + function for caching) and divide by lengthscale afterwards + + """ + if self.ARD: + if X2 is not None: + X2 = X2 / self.lengthscale + return self._unscaled_dist(X/self.lengthscale, X2) + else: + return self._unscaled_dist(X, X2)/self.lengthscale + +
[docs] def Kdiag(self, X): + ret = np.empty(X.shape[0]) + ret[:] = self.variance + return ret +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + """ + Given the derivative of the objective with respect to the diagonal of + the covariance matrix, compute the derivative wrt the parameters of + this kernel and stor in the <parameter>.gradient field. + + See also update_gradients_full + """ + self.variance.gradient = np.sum(dL_dKdiag) + self.lengthscale.gradient = 0. +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + """ + Given the derivative of the objective wrt the covariance matrix + (dL_dK), compute the gradient wrt the parameters of this kernel, + and store in the parameters object as e.g. self.variance.gradient + """ + self.variance.gradient = np.einsum('ij,ij,i', self.K(X, X2), dL_dK, 1./self.variance) + + #now the lengthscale gradient(s) + dL_dr = self.dK_dr_via_X(X, X2) * dL_dK + if self.ARD: + #rinv = self._inv_dis# this is rather high memory? Should we loop instead?t(X, X2) + #d = X[:, None, :] - X2[None, :, :] + #x_xl3 = np.square(d) + #self.lengthscale.gradient = -((dL_dr*rinv)[:,:,None]*x_xl3).sum(0).sum(0)/self.lengthscale**3 + tmp = dL_dr*self._inv_dist(X, X2) + if X2 is None: X2 = X + + + if config.getboolean('weave', 'working'): + try: + self.lengthscale.gradient = self.weave_lengthscale_grads(tmp, X, X2) + except: + print "\n Weave compilation failed. Falling back to (slower) numpy implementation\n" + config.set('weave', 'working', 'False') + self.lengthscale.gradient = np.array([np.einsum('ij,ij,...', tmp, np.square(X[:,q:q+1] - X2[:,q:q+1].T), -1./self.lengthscale[q]**3) for q in xrange(self.input_dim)]) + else: + self.lengthscale.gradient = np.array([np.einsum('ij,ij,...', tmp, np.square(X[:,q:q+1] - X2[:,q:q+1].T), -1./self.lengthscale[q]**3) for q in xrange(self.input_dim)]) + else: + r = self._scaled_dist(X, X2) + self.lengthscale.gradient = -np.sum(dL_dr*r)/self.lengthscale + +
+ def _inv_dist(self, X, X2=None): + """ + Compute the elementwise inverse of the distance matrix, expecpt on the + diagonal, where we return zero (the distance on the diagonal is zero). + This term appears in derviatives. + """ + dist = self._scaled_dist(X, X2).copy() + return 1./np.where(dist != 0., dist, np.inf) + +
[docs] def weave_lengthscale_grads(self, tmp, X, X2): + """Use scipy.weave to compute derivatives wrt the lengthscales""" + N,M = tmp.shape + Q = X.shape[1] + if hasattr(X, 'values'):X = X.values + if hasattr(X2, 'values'):X2 = X2.values + grads = np.zeros(self.input_dim) + code = """ + double gradq; + for(int q=0; q<Q; q++){ + gradq = 0; + for(int n=0; n<N; n++){ + for(int m=0; m<M; m++){ + gradq += tmp(n,m)*(X(n,q)-X2(m,q))*(X(n,q)-X2(m,q)); + } + } + grads(q) = gradq; + } + """ + weave.inline(code, ['tmp', 'X', 'X2', 'grads', 'N', 'M', 'Q'], type_converters=weave.converters.blitz, support_code="#include <math.h>") + return -grads/self.lengthscale**3 +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + """ + Given the derivative of the objective wrt K (dL_dK), compute the derivative wrt X + """ + if config.getboolean('weave', 'working'): + try: + return self.gradients_X_weave(dL_dK, X, X2) + except: + print "\n Weave compilation failed. Falling back to (slower) numpy implementation\n" + config.set('weave', 'working', 'False') + return self.gradients_X_(dL_dK, X, X2) + else: + return self.gradients_X_(dL_dK, X, X2) +
+
[docs] def gradients_X_(self, dL_dK, X, X2=None): + invdist = self._inv_dist(X, X2) + dL_dr = self.dK_dr_via_X(X, X2) * dL_dK + tmp = invdist*dL_dr + if X2 is None: + tmp = tmp + tmp.T + X2 = X + + #The high-memory numpy way: + #d = X[:, None, :] - X2[None, :, :] + #ret = np.sum(tmp[:,:,None]*d,1)/self.lengthscale**2 + + #the lower memory way with a loop + ret = np.empty(X.shape, dtype=np.float64) + for q in xrange(self.input_dim): + np.sum(tmp*(X[:,q][:,None]-X2[:,q][None,:]), axis=1, out=ret[:,q]) + ret /= self.lengthscale**2 + + return ret +
+
[docs] def gradients_X_weave(self, dL_dK, X, X2=None): + invdist = self._inv_dist(X, X2) + dL_dr = self.dK_dr_via_X(X, X2) * dL_dK + tmp = invdist*dL_dr + if X2 is None: + tmp = tmp + tmp.T + X2 = X + + code = """ + int n,m,d; + double retnd; + #pragma omp parallel for private(n,d, retnd, m) + for(d=0;d<D;d++){ + for(n=0;n<N;n++){ + retnd = 0.0; + for(m=0;m<M;m++){ + retnd += tmp(n,m)*(X(n,d)-X2(m,d)); + } + ret(n,d) = retnd; + } + } + + """ + if hasattr(X, 'values'):X = X.values #remove the GPy wrapping to make passing into weave safe + if hasattr(X2, 'values'):X2 = X2.values + ret = np.zeros(X.shape) + N,D = X.shape + N,M = tmp.shape + from scipy import weave + support_code = """ + #include <omp.h> + #include <stdio.h> + """ + weave_options = {'headers' : ['<omp.h>'], + 'extra_compile_args': ['-fopenmp -O3'], # -march=native'], + 'extra_link_args' : ['-lgomp']} + weave.inline(code, ['ret', 'N', 'D', 'M', 'tmp', 'X', 'X2'], type_converters=weave.converters.blitz, support_code=support_code, **weave_options) + return ret/self.lengthscale**2 +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + return np.zeros(X.shape) +
+
[docs] def input_sensitivity(self, summarize=True): + return np.ones(self.input_dim)/self.lengthscale**2 +
+
[docs]class Exponential(Stationary): + def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='Exponential'): + super(Exponential, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name) + +
[docs] def K_of_r(self, r): + return self.variance * np.exp(-0.5 * r) +
+
[docs] def dK_dr(self, r): + return -0.5*self.K_of_r(r) + +
+
[docs]class OU(Stationary): + """ + OU kernel: + + .. math:: + + k(r) = \\sigma^2 \exp(- r) \\ \\ \\ \\ \\text{ where } r = \sqrt{\sum_{i=1}^input_dim \\frac{(x_i-y_i)^2}{\ell_i^2} } + + """ + + def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='OU'): + super(OU, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name) + +
[docs] def K_of_r(self, r): + return self.variance * np.exp(-r) +
+
[docs] def dK_dr(self,r): + return -1.*self.variance*np.exp(-r) + +
+
[docs]class Matern32(Stationary): + """ + Matern 3/2 kernel: + + .. math:: + + k(r) = \\sigma^2 (1 + \\sqrt{3} r) \exp(- \sqrt{3} r) \\ \\ \\ \\ \\text{ where } r = \sqrt{\sum_{i=1}^input_dim \\frac{(x_i-y_i)^2}{\ell_i^2} } + + """ + + def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='Mat32'): + super(Matern32, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name) + +
[docs] def K_of_r(self, r): + return self.variance * (1. + np.sqrt(3.) * r) * np.exp(-np.sqrt(3.) * r) +
+
[docs] def dK_dr(self,r): + return -3.*self.variance*r*np.exp(-np.sqrt(3.)*r) +
+
[docs] def Gram_matrix(self, F, F1, F2, lower, upper): + """ + Return the Gram matrix of the vector of functions F with respect to the + RKHS norm. The use of this function is limited to input_dim=1. + + :param F: vector of functions + :type F: np.array + :param F1: vector of derivatives of F + :type F1: np.array + :param F2: vector of second derivatives of F + :type F2: np.array + :param lower,upper: boundaries of the input domain + :type lower,upper: floats + """ + assert self.input_dim == 1 + def L(x, i): + return(3. / self.lengthscale ** 2 * F[i](x) + 2 * np.sqrt(3) / self.lengthscale * F1[i](x) + F2[i](x)) + n = F.shape[0] + G = np.zeros((n, n)) + for i in range(n): + for j in range(i, n): + G[i, j] = G[j, i] = integrate.quad(lambda x : L(x, i) * L(x, j), lower, upper)[0] + Flower = np.array([f(lower) for f in F])[:, None] + F1lower = np.array([f(lower) for f in F1])[:, None] + return(self.lengthscale ** 3 / (12.*np.sqrt(3) * self.variance) * G + 1. / self.variance * np.dot(Flower, Flower.T) + self.lengthscale ** 2 / (3.*self.variance) * np.dot(F1lower, F1lower.T)) + +
+
[docs]class Matern52(Stationary): + """ + Matern 5/2 kernel: + + .. math:: + + k(r) = \sigma^2 (1 + \sqrt{5} r + \\frac53 r^2) \exp(- \sqrt{5} r) + """ + def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='Mat52'): + super(Matern52, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name) + +
[docs] def K_of_r(self, r): + return self.variance*(1+np.sqrt(5.)*r+5./3*r**2)*np.exp(-np.sqrt(5.)*r) +
+
[docs] def dK_dr(self, r): + return self.variance*(10./3*r -5.*r -5.*np.sqrt(5.)/3*r**2)*np.exp(-np.sqrt(5.)*r) +
+
[docs] def Gram_matrix(self, F, F1, F2, F3, lower, upper): + """ + Return the Gram matrix of the vector of functions F with respect to the RKHS norm. The use of this function is limited to input_dim=1. + + :param F: vector of functions + :type F: np.array + :param F1: vector of derivatives of F + :type F1: np.array + :param F2: vector of second derivatives of F + :type F2: np.array + :param F3: vector of third derivatives of F + :type F3: np.array + :param lower,upper: boundaries of the input domain + :type lower,upper: floats + """ + assert self.input_dim == 1 + def L(x,i): + return(5*np.sqrt(5)/self.lengthscale**3*F[i](x) + 15./self.lengthscale**2*F1[i](x)+ 3*np.sqrt(5)/self.lengthscale*F2[i](x) + F3[i](x)) + n = F.shape[0] + G = np.zeros((n,n)) + for i in range(n): + for j in range(i,n): + G[i,j] = G[j,i] = integrate.quad(lambda x : L(x,i)*L(x,j),lower,upper)[0] + G_coef = 3.*self.lengthscale**5/(400*np.sqrt(5)) + Flower = np.array([f(lower) for f in F])[:,None] + F1lower = np.array([f(lower) for f in F1])[:,None] + F2lower = np.array([f(lower) for f in F2])[:,None] + orig = 9./8*np.dot(Flower,Flower.T) + 9.*self.lengthscale**4/200*np.dot(F2lower,F2lower.T) + orig2 = 3./5*self.lengthscale**2 * ( np.dot(F1lower,F1lower.T) + 1./8*np.dot(Flower,F2lower.T) + 1./8*np.dot(F2lower,Flower.T)) + return(1./self.variance* (G_coef*G + orig + orig2)) + +
+
[docs]class ExpQuad(Stationary): + """ + The Exponentiated quadratic covariance function. + + .. math:: + + k(r) = \sigma^2 (1 + \sqrt{5} r + \\frac53 r^2) \exp(- \sqrt{5} r) + + notes:: + - Yes, this is exactly the same as the RBF covariance function, but the + RBF implementation also has some features for doing variational kernels + (the psi-statistics). + + """ + def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='ExpQuad'): + super(ExpQuad, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name) + +
[docs] def K_of_r(self, r): + return self.variance * np.exp(-0.5 * r**2) +
+
[docs] def dK_dr(self, r): + return -r*self.K_of_r(r) +
+
[docs]class Cosine(Stationary): + def __init__(self, input_dim, variance=1., lengthscale=None, ARD=False, active_dims=None, name='Cosine'): + super(Cosine, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name) + +
[docs] def K_of_r(self, r): + return self.variance * np.cos(r) +
+
[docs] def dK_dr(self, r): + return -self.variance * np.sin(r) + +
+
[docs]class RatQuad(Stationary): + """ + Rational Quadratic Kernel + + .. math:: + + k(r) = \sigma^2 \\bigg( 1 + \\frac{r^2}{2} \\bigg)^{- \\alpha} + + """ + + + def __init__(self, input_dim, variance=1., lengthscale=None, power=2., ARD=False, active_dims=None, name='RatQuad'): + super(RatQuad, self).__init__(input_dim, variance, lengthscale, ARD, active_dims, name) + self.power = Param('power', power, Logexp()) + self.link_parameters(self.power) + +
[docs] def K_of_r(self, r): + r2 = np.power(r, 2.) + return self.variance*np.power(1. + r2/2., -self.power) +
+
[docs] def dK_dr(self, r): + r2 = np.power(r, 2.) + return -self.variance*self.power*r*np.power(1. + r2/2., - self.power - 1.) +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + super(RatQuad, self).update_gradients_full(dL_dK, X, X2) + r = self._scaled_dist(X, X2) + r2 = np.power(r, 2.) + dK_dpow = -self.variance * np.power(2., self.power) * np.power(r2 + 2., -self.power) * np.log(0.5*(r2+2.)) + grad = np.sum(dL_dK*dK_dpow) + self.power.gradient = grad +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + super(RatQuad, self).update_gradients_diag(dL_dKdiag, X) + self.power.gradient = 0. +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/kern/_src/trunclinear.html b/doc/_build/html/_modules/GPy/kern/_src/trunclinear.html new file mode 100644 index 00000000..fed71196 --- /dev/null +++ b/doc/_build/html/_modules/GPy/kern/_src/trunclinear.html @@ -0,0 +1,296 @@ + + + + + + + + GPy.kern._src.trunclinear — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.kern._src.trunclinear

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from kern import Kern
+from ...core.parameterization import Param
+from ...core.parameterization.transformations import Logexp
+from ...util.caching import Cache_this
+from ...util.config import *
+
+
[docs]class TruncLinear(Kern): + """ + Truncated Linear kernel + + .. math:: + + k(x,y) = \sum_{i=1}^input_dim \sigma^2_i \max(0, x_iy_i - \simga_q) + + :param input_dim: the number of input dimensions + :type input_dim: int + :param variances: the vector of variances :math:`\sigma^2_i` + :type variances: array or list of the appropriate size (or float if there + is only one variance parameter) + :param ARD: Auto Relevance Determination. If False, the kernel has only one + variance parameter \sigma^2, otherwise there is one variance + parameter per dimension. + :type ARD: Boolean + :rtype: kernel object + + """ + + def __init__(self, input_dim, variances=None, delta=None, ARD=False, active_dims=None, name='linear'): + super(TruncLinear, self).__init__(input_dim, active_dims, name) + self.ARD = ARD + if not ARD: + if variances is not None: + variances = np.asarray(variances) + delta = np.asarray(delta) + assert variances.size == 1, "Only one variance needed for non-ARD kernel" + else: + variances = np.ones(1) + delta = np.zeros(1) + else: + if variances is not None: + variances = np.asarray(variances) + delta = np.asarray(delta) + assert variances.size == self.input_dim, "bad number of variances, need one ARD variance per input_dim" + else: + variances = np.ones(self.input_dim) + delta = np.zeros(self.input_dim) + + self.variances = Param('variances', variances, Logexp()) + self.delta = Param('delta', delta) + self.add_parameter(self.variances) + self.add_parameter(self.delta) + + @Cache_this(limit=2) +
[docs] def K(self, X, X2=None): + XX = self.variances*self._product(X, X2) + return XX.sum(axis=-1) +
+ @Cache_this(limit=2) + def _product(self, X, X2=None): + if X2 is None: + X2 = X + XX = np.einsum('nq,mq->nmq',X-self.delta,X2-self.delta) + XX[XX<0] = 0 + return XX + +
[docs] def Kdiag(self, X): + return (self.variances*np.square(X-self.delta)).sum(axis=-1) +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + dK_dvar = self._product(X, X2) + if X2 is None: + X2=X + dK_ddelta = self.variances*(2*self.delta-X[:,None,:]-X2[None,:,:])*(dK_dvar>0) + if self.ARD: + self.variances.gradient[:] = np.einsum('nmq,nm->q',dK_dvar,dL_dK) + self.delta.gradient[:] = np.einsum('nmq,nm->q',dK_ddelta,dL_dK) + else: + self.variances.gradient[:] = np.einsum('nmq,nm->',dK_dvar,dL_dK) + self.delta.gradient[:] = np.einsum('nmq,nm->',dK_ddelta,dL_dK) +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + if self.ARD: + self.variances.gradient[:] = np.einsum('nq,n->q',np.square(X-self.delta),dL_dKdiag) + self.delta.gradient[:] = np.einsum('nq,n->q',2*self.variances*(self.delta-X),dL_dKdiag) + else: + self.variances.gradient[:] = np.einsum('nq,n->',np.square(X-self.delta),dL_dKdiag) + self.delta.gradient[:] = np.einsum('nq,n->',2*self.variances*(self.delta-X),dL_dKdiag) +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + XX = self._product(X, X2) + if X2 is None: + Xp = (self.variances*(X-self.delta))*(XX>0) + else: + Xp = (self.variances*(X2-self.delta))*(XX>0) + if X2 is None: + return np.einsum('nmq,nm->nq',Xp,dL_dK)+np.einsum('mnq,nm->mq',Xp,dL_dK) + else: + return np.einsum('nmq,nm->nq',Xp,dL_dK) +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + return 2.*self.variances*dL_dKdiag[:,None]*(X-self.delta) +
+
[docs] def input_sensitivity(self): + return np.ones(self.input_dim) * self.variances +
+
[docs]class TruncLinear_inf(Kern): + """ + Truncated Linear kernel + + .. math:: + + k(x,y) = \sum_{i=1}^input_dim \sigma^2_i \max(0, x_iy_i - \simga_q) + + :param input_dim: the number of input dimensions + :type input_dim: int + :param variances: the vector of variances :math:`\sigma^2_i` + :type variances: array or list of the appropriate size (or float if there + is only one variance parameter) + :param ARD: Auto Relevance Determination. If False, the kernel has only one + variance parameter \sigma^2, otherwise there is one variance + parameter per dimension. + :type ARD: Boolean + :rtype: kernel object + + """ + + def __init__(self, input_dim, interval, variances=None, ARD=False, active_dims=None, name='linear'): + super(TruncLinear_inf, self).__init__(input_dim, active_dims, name) + self.interval = interval + self.ARD = ARD + if not ARD: + if variances is not None: + variances = np.asarray(variances) + assert variances.size == 1, "Only one variance needed for non-ARD kernel" + else: + variances = np.ones(1) + else: + if variances is not None: + variances = np.asarray(variances) + assert variances.size == self.input_dim, "bad number of variances, need one ARD variance per input_dim" + else: + variances = np.ones(self.input_dim) + + self.variances = Param('variances', variances, Logexp()) + self.add_parameter(self.variances) + + +# @Cache_this(limit=2) +
[docs] def K(self, X, X2=None): + tmp = self._product(X, X2) + return (self.variances*tmp).sum(axis=-1) + +# @Cache_this(limit=2)
+ def _product(self, X, X2=None): + if X2 is None: + X2 = X + X_X2 = X[:,None,:]-X2[None,:,:] + tmp = np.abs(X_X2**3)/6+np.einsum('nq,mq->nmq',X,X2)*(self.interval[1]-self.interval[0]) \ + -(X[:,None,:]+X2[None,:,:])*(self.interval[1]*self.interval[1]-self.interval[0]*self.interval[0])/2+(self.interval[1]**3-self.interval[0]**3)/3. + return tmp + +
[docs] def Kdiag(self, X): + tmp = np.square(X)*(self.interval[1]-self.interval[0]) \ + -X*(self.interval[1]*self.interval[1]-self.interval[0]*self.interval[0])+(self.interval[1]**3-self.interval[0]**3)/3 + return (self.variances*tmp).sum(axis=-1) +
+
[docs] def update_gradients_full(self, dL_dK, X, X2=None): + dK_dvar = self._product(X, X2) + if self.ARD: + self.variances.gradient[:] = np.einsum('nmq,nm->q',dK_dvar,dL_dK) + else: + self.variances.gradient[:] = np.einsum('nmq,nm->',dK_dvar,dL_dK) +
+
[docs] def update_gradients_diag(self, dL_dKdiag, X): + tmp = np.square(X)*(self.interval[1]-self.interval[0]) \ + -X*(self.interval[1]*self.interval[1]-self.interval[0]*self.interval[0])+(self.interval[1]**3-self.interval[0]**3)/3 + if self.ARD: + self.variances.gradient[:] = np.einsum('nq,n->q',tmp,dL_dKdiag) + else: + self.variances.gradient[:] = np.einsum('nq,n->',tmp,dL_dKdiag) +
+
[docs] def gradients_X(self, dL_dK, X, X2=None): + XX = self._product(X, X2) + if X2 is None: + Xp = (self.variances*(X-self.delta))*(XX>0) + else: + Xp = (self.variances*(X2-self.delta))*(XX>0) + if X2 is None: + return np.einsum('nmq,nm->nq',Xp,dL_dK)+np.einsum('mnq,nm->mq',Xp,dL_dK) + else: + return np.einsum('nmq,nm->nq',Xp,dL_dK) +
+
[docs] def gradients_X_diag(self, dL_dKdiag, X): + return 2.*self.variances*dL_dKdiag[:,None]*(X-self.delta) +
+
[docs] def input_sensitivity(self): + return np.ones(self.input_dim) * self.variances +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/likelihoods/bernoulli.html b/doc/_build/html/_modules/GPy/likelihoods/bernoulli.html new file mode 100644 index 00000000..c3d7cbfd --- /dev/null +++ b/doc/_build/html/_modules/GPy/likelihoods/bernoulli.html @@ -0,0 +1,318 @@ + + + + + + + + GPy.likelihoods.bernoulli — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.likelihoods.bernoulli

+# Copyright (c) 2012-2014 The GPy authors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ..util.univariate_Gaussian import std_norm_pdf, std_norm_cdf
+import link_functions
+from likelihood import Likelihood
+from scipy import stats
+
+
[docs]class Bernoulli(Likelihood): + """ + Bernoulli likelihood + + .. math:: + p(y_{i}|\\lambda(f_{i})) = \\lambda(f_{i})^{y_{i}}(1-f_{i})^{1-y_{i}} + + .. Note:: + Y takes values in either {-1, 1} or {0, 1}. + link function should have the domain [0, 1], e.g. probit (default) or Heaviside + + .. See also:: + likelihood.py, for the parent class + """ + def __init__(self, gp_link=None): + if gp_link is None: + gp_link = link_functions.Probit() + + super(Bernoulli, self).__init__(gp_link, 'Bernoulli') + + if isinstance(gp_link , (link_functions.Heaviside, link_functions.Probit)): + self.log_concave = True + + def _preprocess_values(self, Y): + """ + Check if the values of the observations correspond to the values + assumed by the likelihood function. + + ..Note:: Binary classification algorithm works better with classes {-1, 1} + """ + Y_prep = Y.copy() + Y1 = Y[Y.flatten()==1].size + Y2 = Y[Y.flatten()==0].size + assert Y1 + Y2 == Y.size, 'Bernoulli likelihood is meant to be used only with outputs in {0, 1}.' + Y_prep[Y.flatten() == 0] = -1 + return Y_prep + +
[docs] def moments_match_ep(self, Y_i, tau_i, v_i): + """ + Moments match of the marginal approximation in EP algorithm + + :param i: number of observation (int) + :param tau_i: precision of the cavity distribution (float) + :param v_i: mean/variance of the cavity distribution (float) + """ + if Y_i == 1: + sign = 1. + elif Y_i == 0 or Y_i == -1: + sign = -1 + else: + raise ValueError("bad value for Bernoulli observation (0, 1)") + if isinstance(self.gp_link, link_functions.Probit): + z = sign*v_i/np.sqrt(tau_i**2 + tau_i) + Z_hat = std_norm_cdf(z) + phi = std_norm_pdf(z) + mu_hat = v_i/tau_i + sign*phi/(Z_hat*np.sqrt(tau_i**2 + tau_i)) + sigma2_hat = 1./tau_i - (phi/((tau_i**2+tau_i)*Z_hat))*(z+phi/Z_hat) + + elif isinstance(self.gp_link, link_functions.Heaviside): + a = sign*v_i/np.sqrt(tau_i) + Z_hat = std_norm_cdf(a) + N = std_norm_pdf(a) + mu_hat = v_i/tau_i + sign*N/Z_hat/np.sqrt(tau_i) + sigma2_hat = (1. - a*N/Z_hat - np.square(N/Z_hat))/tau_i + else: + #TODO: do we want to revert to numerical quadrature here? + raise ValueError("Exact moment matching not available for link {}".format(self.gp_link.__name__)) + + return Z_hat, mu_hat, sigma2_hat +
+
[docs] def predictive_mean(self, mu, variance, Y_metadata=None): + + if isinstance(self.gp_link, link_functions.Probit): + return stats.norm.cdf(mu/np.sqrt(1+variance)) + + elif isinstance(self.gp_link, link_functions.Heaviside): + return stats.norm.cdf(mu/np.sqrt(variance)) + + else: + raise NotImplementedError +
+
[docs] def predictive_variance(self, mu, variance, pred_mean, Y_metadata=None): + + if isinstance(self.gp_link, link_functions.Heaviside): + return 0. + else: + return np.nan +
+ + + +
[docs] def d2logpdf_dlink2(self, inv_link_f, y, Y_metadata=None): + """ + Hessian at y, given inv_link_f, w.r.t inv_link_f the hessian will be 0 unless i == j + i.e. second derivative logpdf at y given inverse link of f_i and inverse link of f_j w.r.t inverse link of f_i and inverse link of f_j. + + + .. math:: + \\frac{d^{2}\\ln p(y_{i}|\\lambda(f_{i}))}{d\\lambda(f)^{2}} = \\frac{-y_{i}}{\\lambda(f)^{2}} - \\frac{(1-y_{i})}{(1-\\lambda(f))^{2}} + + :param inv_link_f: latent variables inverse link of f. + :type inv_link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata not used in bernoulli + :returns: Diagonal of log hessian matrix (second derivative of log likelihood evaluated at points inverse link of f. + :rtype: Nx1 array + + .. Note:: + Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases + (the distribution for y_i depends only on inverse link of f_i not on inverse link of f_(j!=i) + """ + #d2logpdf_dlink2 = -y/(inv_link_f**2) - (1-y)/((1-inv_link_f)**2) + #d2logpdf_dlink2 = np.where(y, -1./np.square(inv_link_f), -1./np.square(1.-inv_link_f)) + arg = np.where(y, inv_link_f, 1.-inv_link_f) + ret = -1./np.square(np.clip(arg, 1e-3, np.inf)) + if np.any(np.isinf(ret)): + stop + return ret +
+
[docs] def d3logpdf_dlink3(self, inv_link_f, y, Y_metadata=None): + """ + Third order derivative log-likelihood function at y given inverse link of f w.r.t inverse link of f + + .. math:: + \\frac{d^{3} \\ln p(y_{i}|\\lambda(f_{i}))}{d^{3}\\lambda(f)} = \\frac{2y_{i}}{\\lambda(f)^{3}} - \\frac{2(1-y_{i}}{(1-\\lambda(f))^{3}} + + :param inv_link_f: latent variables passed through inverse link of f. + :type inv_link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata not used in bernoulli + :returns: third derivative of log likelihood evaluated at points inverse_link(f) + :rtype: Nx1 array + """ + assert np.atleast_1d(inv_link_f).shape == np.atleast_1d(y).shape + #d3logpdf_dlink3 = 2*(y/(inv_link_f**3) - (1-y)/((1-inv_link_f)**3)) + state = np.seterr(divide='ignore') + # TODO check y \in {0, 1} or {-1, 1} + d3logpdf_dlink3 = np.where(y, 2./(inv_link_f**3), -2./((1.-inv_link_f)**3)) + np.seterr(**state) + return d3logpdf_dlink3 +
+
[docs] def samples(self, gp, Y_metadata=None): + """ + Returns a set of samples of observations based on a given value of the latent variable. + + :param gp: latent variable + """ + orig_shape = gp.shape + gp = gp.flatten() + ns = np.ones_like(gp, dtype=int) + Ysim = np.random.binomial(ns, self.gp_link.transf(gp)) + return Ysim.reshape(orig_shape) +
+
[docs] def exact_inference_gradients(self, dL_dKdiag,Y_metadata=None): + pass
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/likelihoods/exponential.html b/doc/_build/html/_modules/GPy/likelihoods/exponential.html new file mode 100644 index 00000000..d4cc87b2 --- /dev/null +++ b/doc/_build/html/_modules/GPy/likelihoods/exponential.html @@ -0,0 +1,234 @@ + + + + + + + + GPy.likelihoods.exponential — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.likelihoods.exponential

+# Copyright (c) 2012-2014 GPy Authors
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from scipy import stats,special
+import scipy as sp
+import link_functions
+from likelihood import Likelihood
+
+
[docs]class Exponential(Likelihood): + """ + Expoential likelihood + Y is expected to take values in {0,1,2,...} + ----- + $$ + L(x) = \exp(\lambda) * \lambda**Y_i / Y_i! + $$ + """ + def __init__(self,gp_link=None): + if gp_link is None: + gp_link = link_functions.Log() + super(Exponential, self).__init__(gp_link, 'ExpLikelihood') + + + + +
[docs] def d2logpdf_dlink2(self, link_f, y, Y_metadata=None): + """ + Hessian at y, given link(f), w.r.t link(f) + i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j) + The hessian will be 0 unless i == j + + .. math:: + \\frac{d^{2} \\ln p(y_{i}|\lambda(f_{i}))}{d^{2}\\lambda(f)} = -\\frac{1}{\\lambda(f_{i})^{2}} + + :param link_f: latent variables link(f) + :type link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in exponential distribution + :returns: Diagonal of hessian matrix (second derivative of likelihood evaluated at points f) + :rtype: Nx1 array + + .. Note:: + Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases + (the distribution for y_i depends only on link(f_i) not on link(f_(j!=i)) + """ + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape + hess = -1./(link_f**2) + #hess = -2*y/(link_f**3) + 1/(link_f**2) + return hess +
+
[docs] def d3logpdf_dlink3(self, link_f, y, Y_metadata=None): + """ + Third order derivative log-likelihood function at y given link(f) w.r.t link(f) + + .. math:: + \\frac{d^{3} \\ln p(y_{i}|\lambda(f_{i}))}{d^{3}\\lambda(f)} = \\frac{2}{\\lambda(f_{i})^{3}} + + :param link_f: latent variables link(f) + :type link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in exponential distribution + :returns: third derivative of likelihood evaluated at points f + :rtype: Nx1 array + """ + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape + d3lik_dlink3 = 2./(link_f**3) + #d3lik_dlink3 = 6*y/(link_f**4) - 2./(link_f**3) + return d3lik_dlink3 +
+
[docs] def samples(self, gp): + """ + Returns a set of samples of observations based on a given value of the latent variable. + + :param gp: latent variable + """ + orig_shape = gp.shape + gp = gp.flatten() + Ysim = np.random.exponential(1.0/self.gp_link.transf(gp)) + return Ysim.reshape(orig_shape)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/likelihoods/gamma.html b/doc/_build/html/_modules/GPy/likelihoods/gamma.html new file mode 100644 index 00000000..92d98b88 --- /dev/null +++ b/doc/_build/html/_modules/GPy/likelihoods/gamma.html @@ -0,0 +1,239 @@ + + + + + + + + GPy.likelihoods.gamma — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.likelihoods.gamma

+# Copyright (c) 2012 - 2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from scipy import stats,special
+import scipy as sp
+from ..core.parameterization import Param
+import link_functions
+from likelihood import Likelihood
+
+
[docs]class Gamma(Likelihood): + """ + Gamma likelihood + + .. math:: + p(y_{i}|\\lambda(f_{i})) = \\frac{\\beta^{\\alpha_{i}}}{\\Gamma(\\alpha_{i})}y_{i}^{\\alpha_{i}-1}e^{-\\beta y_{i}}\\\\ + \\alpha_{i} = \\beta y_{i} + + """ + def __init__(self,gp_link=None,beta=1.): + if gp_link is None: + gp_link = link_functions.Log() + super(Gamma, self).__init__(gp_link, 'Gamma') + + self.beta = Param('beta', beta) + self.link_parameter(self.beta) + self.beta.fix()#TODO: gradients! + + + + +
[docs] def d2logpdf_dlink2(self, link_f, y, Y_metadata=None): + """ + Hessian at y, given link(f), w.r.t link(f) + i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j) + The hessian will be 0 unless i == j + + .. math:: + \\frac{d^{2} \\ln p(y_{i}|\lambda(f_{i}))}{d^{2}\\lambda(f)} = -\\beta^{2}\\frac{d\\Psi(\\alpha_{i})}{d\\alpha_{i}}\\\\ + \\alpha_{i} = \\beta y_{i} + + :param link_f: latent variables link(f) + :type link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in gamma distribution + :returns: Diagonal of hessian matrix (second derivative of likelihood evaluated at points f) + :rtype: Nx1 array + + .. Note:: + Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases + (the distribution for y_i depends only on link(f_i) not on link(f_(j!=i)) + """ + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape + hess = -special.polygamma(1, self.beta*link_f)*(self.beta**2) + #old + #return -self.gp_link.d2transf_df2(gp)*self.beta*np.log(obs) + special.polygamma(1,self.gp_link.transf(gp)*self.beta)*(self.gp_link.dtransf_df(gp)*self.beta)**2 + special.psi(self.gp_link.transf(gp)*self.beta)*self.gp_link.d2transf_df2(gp)*self.beta + return hess +
+
[docs] def d3logpdf_dlink3(self, link_f, y, Y_metadata=None): + """ + Third order derivative log-likelihood function at y given link(f) w.r.t link(f) + + .. math:: + \\frac{d^{3} \\ln p(y_{i}|\lambda(f_{i}))}{d^{3}\\lambda(f)} = -\\beta^{3}\\frac{d^{2}\\Psi(\\alpha_{i})}{d\\alpha_{i}}\\\\ + \\alpha_{i} = \\beta y_{i} + + :param link_f: latent variables link(f) + :type link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in gamma distribution + :returns: third derivative of likelihood evaluated at points f + :rtype: Nx1 array + """ + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape + d3lik_dlink3 = -special.polygamma(2, self.beta*link_f)*(self.beta**3) + return d3lik_dlink3
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/likelihoods/gaussian.html b/doc/_build/html/_modules/GPy/likelihoods/gaussian.html new file mode 100644 index 00000000..88ba9f6e --- /dev/null +++ b/doc/_build/html/_modules/GPy/likelihoods/gaussian.html @@ -0,0 +1,411 @@ + + + + + + + + GPy.likelihoods.gaussian — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.likelihoods.gaussian

+# Copyright (c) 2012-2014 The GPy authors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+#TODO
+"""
+A lot of this code assumes that the link function is the identity.
+
+I think laplace code is okay, but I'm quite sure that the EP moments will only work if the link is identity.
+
+Furthermore, exact Guassian inference can only be done for the identity link, so we should be asserting so for all calls which relate to that.
+
+James 11/12/13
+"""
+
+import numpy as np
+from scipy import stats, special
+import link_functions
+from likelihood import Likelihood
+from ..core.parameterization import Param
+from ..core.parameterization.transformations import Logexp
+from scipy import stats
+
+
[docs]class Gaussian(Likelihood): + """ + Gaussian likelihood + + .. math:: + \\ln p(y_{i}|\\lambda(f_{i})) = -\\frac{N \\ln 2\\pi}{2} - \\frac{\\ln |K|}{2} - \\frac{(y_{i} - \\lambda(f_{i}))^{T}\\sigma^{-2}(y_{i} - \\lambda(f_{i}))}{2} + + :param variance: variance value of the Gaussian distribution + :param N: Number of data points + :type N: int + """ + def __init__(self, gp_link=None, variance=1., name='Gaussian_noise'): + if gp_link is None: + gp_link = link_functions.Identity() + + assert isinstance(gp_link, link_functions.Identity), "the likelihood only implemented for the identity link" + + super(Gaussian, self).__init__(gp_link, name=name) + + self.variance = Param('variance', variance, Logexp()) + self.link_parameter(self.variance) + + if isinstance(gp_link, link_functions.Identity): + self.log_concave = True + +
[docs] def betaY(self,Y,Y_metadata=None): + #TODO: ~Ricardo this does not live here + return Y/self.gaussian_variance(Y_metadata) +
+
[docs] def gaussian_variance(self, Y_metadata=None): + return self.variance +
+
[docs] def update_gradients(self, grad): + self.variance.gradient = grad +
+
[docs] def exact_inference_gradients(self, dL_dKdiag,Y_metadata=None): + return dL_dKdiag.sum() +
+ def _preprocess_values(self, Y): + """ + Check if the values of the observations correspond to the values + assumed by the likelihood function. + """ + return Y + + def _moments_match_ep(self, data_i, tau_i, v_i): + """ + Moments match of the marginal approximation in EP algorithm + + :param i: number of observation (int) + :param tau_i: precision of the cavity distribution (float) + :param v_i: mean/variance of the cavity distribution (float) + """ + sigma2_hat = 1./(1./self.variance + tau_i) + mu_hat = sigma2_hat*(data_i/self.variance + v_i) + sum_var = self.variance + 1./tau_i + Z_hat = 1./np.sqrt(2.*np.pi*sum_var)*np.exp(-.5*(data_i - v_i/tau_i)**2./sum_var) + return Z_hat, mu_hat, sigma2_hat + +
[docs] def predictive_values(self, mu, var, full_cov=False, Y_metadata=None): + if full_cov: + if var.ndim == 2: + var += np.eye(var.shape[0])*self.variance + if var.ndim == 3: + var += np.atleast_3d(np.eye(var.shape[0])*self.variance) + else: + var += self.variance + return mu, var +
+
[docs] def predictive_mean(self, mu, sigma): + return mu +
+
[docs] def predictive_variance(self, mu, sigma, predictive_mean=None): + return self.variance + sigma**2 +
+
[docs] def predictive_quantiles(self, mu, var, quantiles, Y_metadata=None): + return [stats.norm.ppf(q/100.)*np.sqrt(var + self.variance) + mu for q in quantiles] +
+ + + +
[docs] def d2logpdf_dlink2(self, link_f, y, Y_metadata=None): + """ + Hessian at y, given link_f, w.r.t link_f. + i.e. second derivative logpdf at y given link(f_i) link(f_j) w.r.t link(f_i) and link(f_j) + + The hessian will be 0 unless i == j + + .. math:: + \\frac{d^{2} \\ln p(y_{i}|\\lambda(f_{i}))}{d^{2}f} = -\\frac{1}{\\sigma^{2}} + + :param link_f: latent variables link(f) + :type link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata not used in gaussian + :returns: Diagonal of log hessian matrix (second derivative of log likelihood evaluated at points link(f)) + :rtype: Nx1 array + + .. Note:: + Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases + (the distribution for y_i depends only on link(f_i) not on link(f_(j!=i)) + """ + assert np.asarray(link_f).shape == np.asarray(y).shape + N = y.shape[0] + hess = -(1.0/self.variance)*np.ones((N, 1)) + return hess +
+
[docs] def d3logpdf_dlink3(self, link_f, y, Y_metadata=None): + """ + Third order derivative log-likelihood function at y given link(f) w.r.t link(f) + + .. math:: + \\frac{d^{3} \\ln p(y_{i}|\\lambda(f_{i}))}{d^{3}\\lambda(f)} = 0 + + :param link_f: latent variables link(f) + :type link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata not used in gaussian + :returns: third derivative of log likelihood evaluated at points link(f) + :rtype: Nx1 array + """ + assert np.asarray(link_f).shape == np.asarray(y).shape + N = y.shape[0] + d3logpdf_dlink3 = np.zeros((N,1)) + return d3logpdf_dlink3 +
+ + +
[docs] def d2logpdf_dlink2_dvar(self, link_f, y, Y_metadata=None): + """ + Gradient of the hessian (d2logpdf_dlink2) w.r.t variance parameter (noise_variance) + + .. math:: + \\frac{d}{d\\sigma^{2}}(\\frac{d^{2} \\ln p(y_{i}|\\lambda(f_{i}))}{d^{2}\\lambda(f)}) = \\frac{1}{\\sigma^{4}} + + :param link_f: latent variables link(f) + :type link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata not used in gaussian + :returns: derivative of log hessian evaluated at points link(f_i) and link(f_j) w.r.t variance parameter + :rtype: Nx1 array + """ + assert np.asarray(link_f).shape == np.asarray(y).shape + s_4 = 1.0/(self.variance**2) + N = y.shape[0] + d2logpdf_dlink2_dvar = np.ones((N,1))*s_4 + return d2logpdf_dlink2_dvar +
+ + +
[docs] def d2logpdf_dlink2_dtheta(self, f, y, Y_metadata=None): + d2logpdf_dlink2_dvar = self.d2logpdf_dlink2_dvar(f, y, Y_metadata=Y_metadata) + return d2logpdf_dlink2_dvar +
+ def _mean(self, gp): + """ + Expected value of y under the Mass (or density) function p(y|f) + + .. math:: + E_{p(y|f)}[y] + """ + return self.gp_link.transf(gp) + + def _variance(self, gp): + """ + Variance of y under the Mass (or density) function p(y|f) + + .. math:: + Var_{p(y|f)}[y] + """ + return self.variance + +
[docs] def samples(self, gp, Y_metadata=None): + """ + Returns a set of samples of observations based on a given value of the latent variable. + + :param gp: latent variable + """ + orig_shape = gp.shape + gp = gp.flatten() + #orig_shape = gp.shape + gp = gp.flatten() + Ysim = np.array([np.random.normal(self.gp_link.transf(gpj), scale=np.sqrt(self.variance), size=1) for gpj in gp]) + return Ysim.reshape(orig_shape) +
+
[docs] def log_predictive_density(self, y_test, mu_star, var_star): + """ + assumes independence + """ + v = var_star + self.variance + return -0.5*np.log(2*np.pi) -0.5*np.log(v) - 0.5*np.square(y_test - mu_star)/v +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/likelihoods/likelihood.html b/doc/_build/html/_modules/GPy/likelihoods/likelihood.html new file mode 100644 index 00000000..78df0385 --- /dev/null +++ b/doc/_build/html/_modules/GPy/likelihoods/likelihood.html @@ -0,0 +1,567 @@ + + + + + + + + GPy.likelihoods.likelihood — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.likelihoods.likelihood

+# Copyright (c) 2012-2014 The GPy authors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from scipy import stats,special
+import scipy as sp
+import link_functions
+from ..util.misc import chain_1, chain_2, chain_3
+from scipy.integrate import quad
+import warnings
+from ..core.parameterization import Parameterized
+
+
[docs]class Likelihood(Parameterized): + """ + Likelihood base class, used to defing p(y|f). + + All instances use _inverse_ link functions, which can be swapped out. It is + expected that inheriting classes define a default inverse link function + + To use this class, inherit and define missing functionality. + + Inheriting classes *must* implement: + pdf_link : a bound method which turns the output of the link function into the pdf + logpdf_link : the logarithm of the above + + To enable use with EP, inheriting classes *must* define: + TODO: a suitable derivative function for any parameters of the class + It is also desirable to define: + moments_match_ep : a function to compute the EP moments If this isn't defined, the moments will be computed using 1D quadrature. + + To enable use with Laplace approximation, inheriting classes *must* define: + Some derivative functions *AS TODO* + + For exact Gaussian inference, define *JH TODO* + + """ + def __init__(self, gp_link, name): + super(Likelihood, self).__init__(name) + assert isinstance(gp_link,link_functions.GPTransformation), "gp_link is not a valid GPTransformation." + self.gp_link = gp_link + self.log_concave = False + + def _gradients(self,partial): + return np.zeros(0) + +
[docs] def update_gradients(self, partial): + if self.size > 0: + raise NotImplementedError('Must be implemented for likelihoods with parameters to be optimized') +
+ def _preprocess_values(self,Y): + """ + In case it is needed, this function assess the output values or makes any pertinent transformation on them. + + :param Y: observed output + :type Y: Nx1 numpy.darray + + """ + return Y + +
[docs] def conditional_mean(self, gp): + """ + The mean of the random variable conditioned on one value of the GP + """ + raise NotImplementedError +
+
[docs] def conditional_variance(self, gp): + """ + The variance of the random variable conditioned on one value of the GP + """ + raise NotImplementedError +
+
[docs] def log_predictive_density(self, y_test, mu_star, var_star): + """ + Calculation of the log predictive density + + .. math: + p(y_{*}|D) = p(y_{*}|f_{*})p(f_{*}|\mu_{*}\\sigma^{2}_{*}) + + :param y_test: test observations (y_{*}) + :type y_test: (Nx1) array + :param mu_star: predictive mean of gaussian p(f_{*}|mu_{*}, var_{*}) + :type mu_star: (Nx1) array + :param var_star: predictive variance of gaussian p(f_{*}|mu_{*}, var_{*}) + :type var_star: (Nx1) array + """ + assert y_test.shape==mu_star.shape + assert y_test.shape==var_star.shape + assert y_test.shape[1] == 1 + def integral_generator(y, m, v): + """Generate a function which can be integrated to give p(Y*|Y) = int p(Y*|f*)p(f*|Y) df*""" + def f(f_star): + return self.pdf(f_star, y)*np.exp(-(1./(2*v))*np.square(m-f_star)) + return f + + scaled_p_ystar, accuracy = zip(*[quad(integral_generator(y, m, v), -np.inf, np.inf) for y, m, v in zip(y_test.flatten(), mu_star.flatten(), var_star.flatten())]) + scaled_p_ystar = np.array(scaled_p_ystar).reshape(-1,1) + p_ystar = scaled_p_ystar/np.sqrt(2*np.pi*var_star) + return np.log(p_ystar) +
+ def _moments_match_ep(self,obs,tau,v): + """ + Calculation of moments using quadrature + + :param obs: observed output + :param tau: cavity distribution 1st natural parameter (precision) + :param v: cavity distribution 2nd natural paramenter (mu*precision) + """ + #Compute first integral for zeroth moment. + #NOTE constant np.sqrt(2*pi/tau) added at the end of the function + mu = v/tau + def int_1(f): + return self.pdf(f, obs)*np.exp(-0.5*tau*np.square(mu-f)) + z_scaled, accuracy = quad(int_1, -np.inf, np.inf) + + #Compute second integral for first moment + def int_2(f): + return f*self.pdf(f, obs)*np.exp(-0.5*tau*np.square(mu-f)) + mean, accuracy = quad(int_2, -np.inf, np.inf) + mean /= z_scaled + + #Compute integral for variance + def int_3(f): + return (f**2)*self.pdf(f, obs)*np.exp(-0.5*tau*np.square(mu-f)) + Ef2, accuracy = quad(int_3, -np.inf, np.inf) + Ef2 /= z_scaled + variance = Ef2 - mean**2 + + #Add constant to the zeroth moment + #NOTE: this constant is not needed in the other moments because it cancells out. + z = z_scaled/np.sqrt(2*np.pi/tau) + + return z, mean, variance + +
[docs] def variational_expectations(self, Y, m, v, gh_points=None): + """ + Use Gauss-Hermite Quadrature to compute + + E_p(f) [ log p(y|f) ] + d/dm E_p(f) [ log p(y|f) ] + d/dv E_p(f) [ log p(y|f) ] + + where p(f) is a Gaussian with mean m and variance v. The shapes of Y, m and v should match. + + if no gh_points are passed, we construct them using defualt options + """ + + if gh_points is None: + gh_x, gh_w = np.polynomial.hermite.hermgauss(12) + else: + gh_x, gh_w = gh_points + + shape = m.shape + m,v,Y = m.flatten(), v.flatten(), Y.flatten() + + #make a grid of points + X = gh_x[None,:]*np.sqrt(2.*v[:,None]) + m[:,None] + + #evaluate the likelhood for the grid. First ax indexes the data (and mu, var) and the second indexes the grid. + # broadcast needs to be handled carefully. + logp = self.logpdf(X,Y[:,None]) + dlogp_dx = self.dlogpdf_df(X, Y[:,None]) + d2logp_dx2 = self.d2logpdf_df2(X, Y[:,None]) + + #clipping for numerical stability + logp = np.clip(logp,-1e6,1e6) + dlogp_dx = np.clip(dlogp_dx,-1e6,1e6) + d2logp_dx2 = np.clip(d2logp_dx2,-1e6,1e6) + + #average over the gird to get derivatives of the Gaussian's parameters + F = np.dot(logp, gh_w) + dF_dm = np.dot(dlogp_dx, gh_w) + dF_dv = np.dot(d2logp_dx2, gh_w)/2. + + if np.any(np.isnan(dF_dv)) or np.any(np.isinf(dF_dv)): + stop + if np.any(np.isnan(dF_dm)) or np.any(np.isinf(dF_dm)): + stop + + return F.reshape(*shape), dF_dm.reshape(*shape), dF_dv.reshape(*shape) + + + +
+
[docs] def predictive_mean(self, mu, variance, Y_metadata=None): + """ + Quadrature calculation of the predictive mean: E(Y_star|Y) = E( E(Y_star|f_star, Y) ) + + :param mu: mean of posterior + :param sigma: standard deviation of posterior + + """ + #conditional_mean: the edpected value of y given some f, under this likelihood + def int_mean(f,m,v): + p = np.exp(-(0.5/v)*np.square(f - m)) + #If p is zero then conditional_mean will overflow + if p < 1e-10: + return 0. + else: + return self.conditional_mean(f)*p + scaled_mean = [quad(int_mean, -np.inf, np.inf,args=(mj,s2j))[0] for mj,s2j in zip(mu,variance)] + mean = np.array(scaled_mean)[:,None] / np.sqrt(2*np.pi*(variance)) + + return mean +
+ def _conditional_mean(self, f): + """Quadrature calculation of the conditional mean: E(Y_star|f)""" + raise NotImplementedError, "implement this function to make predictions" + +
[docs] def predictive_variance(self, mu,variance, predictive_mean=None, Y_metadata=None): + """ + Approximation to the predictive variance: V(Y_star) + + The following variance decomposition is used: + V(Y_star) = E( V(Y_star|f_star) ) + V( E(Y_star|f_star) ) + + :param mu: mean of posterior + :param sigma: standard deviation of posterior + :predictive_mean: output's predictive mean, if None _predictive_mean function will be called. + + """ + #sigma2 = sigma**2 + normalizer = np.sqrt(2*np.pi*variance) + + # E( V(Y_star|f_star) ) + def int_var(f,m,v): + p = np.exp(-(0.5/v)*np.square(f - m)) + #If p is zero then conditional_variance will overflow + if p < 1e-10: + return 0. + else: + return self.conditional_variance(f)*p + scaled_exp_variance = [quad(int_var, -np.inf, np.inf,args=(mj,s2j))[0] for mj,s2j in zip(mu,variance)] + exp_var = np.array(scaled_exp_variance)[:,None] / normalizer + + #V( E(Y_star|f_star) ) = E( E(Y_star|f_star)**2 ) - E( E(Y_star|f_star) )**2 + + #E( E(Y_star|f_star) )**2 + if predictive_mean is None: + predictive_mean = self.predictive_mean(mu,variance) + predictive_mean_sq = predictive_mean**2 + + #E( E(Y_star|f_star)**2 ) + def int_pred_mean_sq(f,m,v,predictive_mean_sq): + p = np.exp(-(0.5/v)*np.square(f - m)) + #If p is zero then conditional_mean**2 will overflow + if p < 1e-10: + return 0. + else: + return self.conditional_mean(f)**2*p + + scaled_exp_exp2 = [quad(int_pred_mean_sq, -np.inf, np.inf,args=(mj,s2j,pm2j))[0] for mj,s2j,pm2j in zip(mu,variance,predictive_mean_sq)] + exp_exp2 = np.array(scaled_exp_exp2)[:,None] / normalizer + + var_exp = exp_exp2 - predictive_mean_sq + + # V(Y_star) = E[ V(Y_star|f_star) ] + V[ E(Y_star|f_star) ] + # V(Y_star) = E[ V(Y_star|f_star) ] + E(Y_star**2|f_star) - E[Y_star|f_star]**2 + return exp_var + var_exp +
+ + + +
[docs] def d2logpdf_dlink2(self, inv_link_f, y, Y_metadata=None): + raise NotImplementedError +
+
[docs] def d3logpdf_dlink3(self, inv_link_f, y, Y_metadata=None): + raise NotImplementedError +
+ + +
[docs] def d2logpdf_dlink2_dtheta(self, inv_link_f, y, Y_metadata=None): + raise NotImplementedError +
+
[docs] def pdf(self, f, y, Y_metadata=None): + """ + Evaluates the link function link(f) then computes the likelihood (pdf) using it + + .. math: + p(y|\\lambda(f)) + + :param f: latent variables f + :type f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in student t distribution - not used + :returns: likelihood evaluated for this point + :rtype: float + """ + inv_link_f = self.gp_link.transf(f) + return self.pdf_link(inv_link_f, y, Y_metadata=Y_metadata) +
+
[docs] def logpdf(self, f, y, Y_metadata=None): + """ + Evaluates the link function link(f) then computes the log likelihood (log pdf) using it + + .. math: + \\log p(y|\\lambda(f)) + + :param f: latent variables f + :type f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in student t distribution - not used + :returns: log likelihood evaluated for this point + :rtype: float + """ + inv_link_f = self.gp_link.transf(f) + return self.logpdf_link(inv_link_f, y, Y_metadata=Y_metadata) +
+
[docs] def dlogpdf_df(self, f, y, Y_metadata=None): + """ + Evaluates the link function link(f) then computes the derivative of log likelihood using it + Uses the Faa di Bruno's formula for the chain rule + + .. math:: + \\frac{d\\log p(y|\\lambda(f))}{df} = \\frac{d\\log p(y|\\lambda(f))}{d\\lambda(f)}\\frac{d\\lambda(f)}{df} + + :param f: latent variables f + :type f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in student t distribution - not used + :returns: derivative of log likelihood evaluated for this point + :rtype: 1xN array + """ + inv_link_f = self.gp_link.transf(f) + dlogpdf_dlink = self.dlogpdf_dlink(inv_link_f, y, Y_metadata=Y_metadata) + dlink_df = self.gp_link.dtransf_df(f) + return chain_1(dlogpdf_dlink, dlink_df) +
+
[docs] def d2logpdf_df2(self, f, y, Y_metadata=None): + """ + Evaluates the link function link(f) then computes the second derivative of log likelihood using it + Uses the Faa di Bruno's formula for the chain rule + + .. math:: + \\frac{d^{2}\\log p(y|\\lambda(f))}{df^{2}} = \\frac{d^{2}\\log p(y|\\lambda(f))}{d^{2}\\lambda(f)}\\left(\\frac{d\\lambda(f)}{df}\\right)^{2} + \\frac{d\\log p(y|\\lambda(f))}{d\\lambda(f)}\\frac{d^{2}\\lambda(f)}{df^{2}} + + :param f: latent variables f + :type f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in student t distribution - not used + :returns: second derivative of log likelihood evaluated for this point (diagonal only) + :rtype: 1xN array + """ + inv_link_f = self.gp_link.transf(f) + d2logpdf_dlink2 = self.d2logpdf_dlink2(inv_link_f, y, Y_metadata=Y_metadata) + dlink_df = self.gp_link.dtransf_df(f) + dlogpdf_dlink = self.dlogpdf_dlink(inv_link_f, y, Y_metadata=Y_metadata) + d2link_df2 = self.gp_link.d2transf_df2(f) + return chain_2(d2logpdf_dlink2, dlink_df, dlogpdf_dlink, d2link_df2) +
+
[docs] def d3logpdf_df3(self, f, y, Y_metadata=None): + """ + Evaluates the link function link(f) then computes the third derivative of log likelihood using it + Uses the Faa di Bruno's formula for the chain rule + + .. math:: + \\frac{d^{3}\\log p(y|\\lambda(f))}{df^{3}} = \\frac{d^{3}\\log p(y|\\lambda(f)}{d\\lambda(f)^{3}}\\left(\\frac{d\\lambda(f)}{df}\\right)^{3} + 3\\frac{d^{2}\\log p(y|\\lambda(f)}{d\\lambda(f)^{2}}\\frac{d\\lambda(f)}{df}\\frac{d^{2}\\lambda(f)}{df^{2}} + \\frac{d\\log p(y|\\lambda(f)}{d\\lambda(f)}\\frac{d^{3}\\lambda(f)}{df^{3}} + + :param f: latent variables f + :type f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in student t distribution - not used + :returns: third derivative of log likelihood evaluated for this point + :rtype: float + """ + inv_link_f = self.gp_link.transf(f) + d3logpdf_dlink3 = self.d3logpdf_dlink3(inv_link_f, y, Y_metadata=Y_metadata) + dlink_df = self.gp_link.dtransf_df(f) + d2logpdf_dlink2 = self.d2logpdf_dlink2(inv_link_f, y, Y_metadata=Y_metadata) + d2link_df2 = self.gp_link.d2transf_df2(f) + dlogpdf_dlink = self.dlogpdf_dlink(inv_link_f, y, Y_metadata=Y_metadata) + d3link_df3 = self.gp_link.d3transf_df3(f) + return chain_3(d3logpdf_dlink3, dlink_df, d2logpdf_dlink2, d2link_df2, dlogpdf_dlink, d3link_df3) +
+
[docs] def dlogpdf_dtheta(self, f, y, Y_metadata=None): + """ + TODO: Doc strings + """ + if self.size > 0: + inv_link_f = self.gp_link.transf(f) + return self.dlogpdf_link_dtheta(inv_link_f, y, Y_metadata=Y_metadata) + else: + # There are no parameters so return an empty array for derivatives + return np.zeros([1, 0]) +
+
[docs] def dlogpdf_df_dtheta(self, f, y, Y_metadata=None): + """ + TODO: Doc strings + """ + if self.size > 0: + inv_link_f = self.gp_link.transf(f) + dlink_df = self.gp_link.dtransf_df(f) + dlogpdf_dlink_dtheta = self.dlogpdf_dlink_dtheta(inv_link_f, y, Y_metadata=Y_metadata) + return chain_1(dlogpdf_dlink_dtheta, dlink_df) + else: + # There are no parameters so return an empty array for derivatives + return np.zeros([f.shape[0], 0]) +
+
[docs] def d2logpdf_df2_dtheta(self, f, y, Y_metadata=None): + """ + TODO: Doc strings + """ + if self.size > 0: + inv_link_f = self.gp_link.transf(f) + dlink_df = self.gp_link.dtransf_df(f) + d2link_df2 = self.gp_link.d2transf_df2(f) + d2logpdf_dlink2_dtheta = self.d2logpdf_dlink2_dtheta(inv_link_f, y, Y_metadata=Y_metadata) + dlogpdf_dlink_dtheta = self.dlogpdf_dlink_dtheta(inv_link_f, y, Y_metadata=Y_metadata) + return chain_2(d2logpdf_dlink2_dtheta, dlink_df, dlogpdf_dlink_dtheta, d2link_df2) + else: + # There are no parameters so return an empty array for derivatives + return np.zeros([f.shape[0], 0]) +
+ def _laplace_gradients(self, f, y, Y_metadata=None): + dlogpdf_dtheta = self.dlogpdf_dtheta(f, y, Y_metadata=Y_metadata) + dlogpdf_df_dtheta = self.dlogpdf_df_dtheta(f, y, Y_metadata=Y_metadata) + d2logpdf_df2_dtheta = self.d2logpdf_df2_dtheta(f, y, Y_metadata=Y_metadata) + + #Parameters are stacked vertically. Must be listed in same order as 'get_param_names' + # ensure we have gradients for every parameter we want to optimize + assert len(dlogpdf_dtheta) == self.size #1 x num_param array + assert dlogpdf_df_dtheta.shape[1] == self.size #f x num_param matrix + assert d2logpdf_df2_dtheta.shape[1] == self.size #f x num_param matrix + + return dlogpdf_dtheta, dlogpdf_df_dtheta, d2logpdf_df2_dtheta + +
[docs] def predictive_values(self, mu, var, full_cov=False, Y_metadata=None): + """ + Compute mean, variance of the predictive distibution. + + :param mu: mean of the latent variable, f, of posterior + :param var: variance of the latent variable, f, of posterior + :param full_cov: whether to use the full covariance or just the diagonal + :type full_cov: Boolean + """ + + pred_mean = self.predictive_mean(mu, var, Y_metadata) + pred_var = self.predictive_variance(mu, var, pred_mean, Y_metadata) + + return pred_mean, pred_var +
+
[docs] def predictive_quantiles(self, mu, var, quantiles, Y_metadata=None): + #compute the quantiles by sampling!!! + N_samp = 1000 + s = np.random.randn(mu.shape[0], N_samp)*np.sqrt(var) + mu + #ss_f = s.flatten() + #ss_y = self.samples(ss_f, Y_metadata) + ss_y = self.samples(s, Y_metadata) + #ss_y = ss_y.reshape(mu.shape[0], N_samp) + + return [np.percentile(ss_y ,q, axis=1)[:,None] for q in quantiles] +
+
[docs] def samples(self, gp, Y_metadata=None): + """ + Returns a set of samples of observations based on a given value of the latent variable. + + :param gp: latent variable + """ + raise NotImplementedError
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/likelihoods/link_functions.html b/doc/_build/html/_modules/GPy/likelihoods/link_functions.html new file mode 100644 index 00000000..9b2ab4f2 --- /dev/null +++ b/doc/_build/html/_modules/GPy/likelihoods/link_functions.html @@ -0,0 +1,282 @@ + + + + + + + + GPy.likelihoods.link_functions — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.likelihoods.link_functions

+# Copyright (c) 2012-2014 The GPy authors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from scipy import stats
+import scipy as sp
+from GPy.util.univariate_Gaussian import std_norm_pdf,std_norm_cdf,inv_std_norm_cdf
+
+_exp_lim_val = np.finfo(np.float64).max
+_lim_val = np.log(_exp_lim_val)
+
+
[docs]class GPTransformation(object): + """ + Link function class for doing non-Gaussian likelihoods approximation + + :param Y: observed output (Nx1 numpy.darray) + + .. note:: Y values allowed depend on the likelihood_function used + + """ + def __init__(self): + pass + +
[docs] def transf(self,f): + """ + Gaussian process tranformation function, latent space -> output space + """ + raise NotImplementedError +
+
[docs] def dtransf_df(self,f): + """ + derivative of transf(f) w.r.t. f + """ + raise NotImplementedError +
+
[docs] def d2transf_df2(self,f): + """ + second derivative of transf(f) w.r.t. f + """ + raise NotImplementedError +
+
[docs] def d3transf_df3(self,f): + """ + third derivative of transf(f) w.r.t. f + """ + raise NotImplementedError +
+
[docs]class Identity(GPTransformation): + """ + .. math:: + + g(f) = f + + """ +
[docs] def transf(self,f): + return f +
+
[docs] def dtransf_df(self,f): + return np.ones_like(f) +
+
[docs] def d2transf_df2(self,f): + return np.zeros_like(f) +
+
[docs] def d3transf_df3(self,f): + return np.zeros_like(f) + +
+
[docs]class Probit(GPTransformation): + """ + .. math:: + + g(f) = \\Phi^{-1} (mu) + + """ +
[docs] def transf(self,f): + return std_norm_cdf(f) +
+
[docs] def dtransf_df(self,f): + return std_norm_pdf(f) +
+
[docs] def d2transf_df2(self,f): + #FIXME + return -f * std_norm_pdf(f) +
+
[docs] def d3transf_df3(self,f): + #FIXME + f2 = f**2 + return -(1/(np.sqrt(2*np.pi)))*np.exp(-0.5*(f2))*(1-f2) + +
+
[docs]class Cloglog(GPTransformation): + """ + Complementary log-log link + .. math:: + + p(f) = 1 - e^{-e^f} + + or + + f = \log (-\log(1-p)) + + """ +
[docs] def transf(self,f): + return 1-np.exp(-np.exp(f)) +
+
[docs] def dtransf_df(self,f): + return np.exp(f-np.exp(f)) +
+
[docs] def d2transf_df2(self,f): + ef = np.exp(f) + return -np.exp(f-ef)*(ef-1.) +
+
[docs] def d3transf_df3(self,f): + ef = np.exp(f) + return np.exp(f-ef)*(1.-3*ef + ef**2) + +
+
[docs]class Log(GPTransformation): + """ + .. math:: + + g(f) = \\log(\\mu) + + """ +
[docs] def transf(self,f): + return np.exp(np.clip(f, -_lim_val, _lim_val)) +
+
[docs] def dtransf_df(self,f): + return np.exp(np.clip(f, -_lim_val, _lim_val)) +
+
[docs] def d2transf_df2(self,f): + return np.exp(np.clip(f, -_lim_val, _lim_val)) +
+
[docs] def d3transf_df3(self,f): + return np.exp(np.clip(f, -_lim_val, _lim_val)) +
+
[docs]class Log_ex_1(GPTransformation): + """ + .. math:: + + g(f) = \\log(\\exp(\\mu) - 1) + + """ +
[docs] def transf(self,f): + return np.log(1.+np.exp(f)) +
+
[docs] def dtransf_df(self,f): + return np.exp(f)/(1.+np.exp(f)) +
+
[docs] def d2transf_df2(self,f): + aux = np.exp(f)/(1.+np.exp(f)) + return aux*(1.-aux) +
+
[docs] def d3transf_df3(self,f): + aux = np.exp(f)/(1.+np.exp(f)) + daux_df = aux*(1.-aux) + return daux_df - (2.*aux*daux_df) +
+
[docs]class Reciprocal(GPTransformation): +
[docs] def transf(self,f): + return 1./f +
+
[docs] def dtransf_df(self,f): + return -1./(f**2) +
+
[docs] def d2transf_df2(self,f): + return 2./(f**3) +
+
[docs] def d3transf_df3(self,f): + return -6./(f**4) +
+
[docs]class Heaviside(GPTransformation): + """ + + .. math:: + + g(f) = I_{x \\in A} + + """ +
[docs] def transf(self,f): + #transformation goes here + return np.where(f>0, 1, 0) +
+
[docs] def dtransf_df(self,f): + raise NotImplementedError, "This function is not differentiable!" +
+
[docs] def d2transf_df2(self,f): + raise NotImplementedError, "This function is not differentiable!"
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/likelihoods/mixed_noise.html b/doc/_build/html/_modules/GPy/likelihoods/mixed_noise.html new file mode 100644 index 00000000..808080a7 --- /dev/null +++ b/doc/_build/html/_modules/GPy/likelihoods/mixed_noise.html @@ -0,0 +1,176 @@ + + + + + + + + GPy.likelihoods.mixed_noise — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.likelihoods.mixed_noise

+# Copyright (c) 2012-2014 The GPy authors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from scipy import stats, special
+import link_functions
+from likelihood import Likelihood
+from gaussian import Gaussian
+from ..core.parameterization import Param
+from ..core.parameterization.transformations import Logexp
+from ..core.parameterization import Parameterized
+import itertools
+
+
[docs]class MixedNoise(Likelihood): + def __init__(self, likelihoods_list, name='mixed_noise'): + #NOTE at the moment this likelihood only works for using a list of gaussians + super(Likelihood, self).__init__(name=name) + + self.link_parameters(*likelihoods_list) + self.likelihoods_list = likelihoods_list + self.log_concave = False + +
[docs] def gaussian_variance(self, Y_metadata): + assert all([isinstance(l, Gaussian) for l in self.likelihoods_list]) + ind = Y_metadata['output_index'].flatten() + variance = np.zeros(ind.size) + for lik, j in zip(self.likelihoods_list, range(len(self.likelihoods_list))): + variance[ind==j] = lik.variance + return variance +
+
[docs] def betaY(self,Y,Y_metadata): + #TODO not here. + return Y/self.gaussian_variance(Y_metadata=Y_metadata)[:,None] +
+
[docs] def update_gradients(self, gradients): + self.gradient = gradients +
+
[docs] def exact_inference_gradients(self, dL_dKdiag, Y_metadata): + assert all([isinstance(l, Gaussian) for l in self.likelihoods_list]) + ind = Y_metadata['output_index'].flatten() + return np.array([dL_dKdiag[ind==i].sum() for i in range(len(self.likelihoods_list))]) +
+
[docs] def predictive_values(self, mu, var, full_cov=False, Y_metadata=None): + ind = Y_metadata['output_index'].flatten() + _variance = np.array([self.likelihoods_list[j].variance for j in ind ]) + if full_cov: + var += np.eye(var.shape[0])*_variance + else: + var += _variance + return mu, var +
+
[docs] def predictive_variance(self, mu, sigma, Y_metadata): + _variance = self.gaussian_variance(Y_metadata) + return _variance + sigma**2 +
+
[docs] def predictive_quantiles(self, mu, var, quantiles, Y_metadata): + ind = Y_metadata['output_index'].flatten() + outputs = np.unique(ind) + Q = np.zeros( (mu.size,len(quantiles)) ) + for j in outputs: + q = self.likelihoods_list[j].predictive_quantiles(mu[ind==j,:], + var[ind==j,:],quantiles,Y_metadata=None) + Q[ind==j,:] = np.hstack(q) + return [q[:,None] for q in Q.T] +
+
[docs] def samples(self, gp, Y_metadata): + """ + Returns a set of samples of observations based on a given value of the latent variable. + + :param gp: latent variable + """ + N1, N2 = gp.shape + Ysim = np.zeros((N1,N2)) + ind = Y_metadata['output_index'].flatten() + for j in np.unique(ind): + flt = ind==j + gp_filtered = gp[flt,:] + n1 = gp_filtered.shape[0] + lik = self.likelihoods_list[j] + _ysim = np.array([np.random.normal(lik.gp_link.transf(gpj), scale=np.sqrt(lik.variance), size=1) for gpj in gp_filtered.flatten()]) + Ysim[flt,:] = _ysim.reshape(n1,N2) + return Ysim
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/likelihoods/poisson.html b/doc/_build/html/_modules/GPy/likelihoods/poisson.html new file mode 100644 index 00000000..66907840 --- /dev/null +++ b/doc/_build/html/_modules/GPy/likelihoods/poisson.html @@ -0,0 +1,251 @@ + + + + + + + + GPy.likelihoods.poisson — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.likelihoods.poisson

+from __future__ import division
+# Copyright (c) 2012-2014 Ricardo Andrade, Alan Saul
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from scipy import stats,special
+import scipy as sp
+import link_functions
+from likelihood import Likelihood
+
+
[docs]class Poisson(Likelihood): + """ + Poisson likelihood + + .. math:: + p(y_{i}|\\lambda(f_{i})) = \\frac{\\lambda(f_{i})^{y_{i}}}{y_{i}!}e^{-\\lambda(f_{i})} + + .. Note:: + Y is expected to take values in {0,1,2,...} + """ + def __init__(self, gp_link=None): + if gp_link is None: + gp_link = link_functions.Log() + + super(Poisson, self).__init__(gp_link, name='Poisson') + + def _conditional_mean(self, f): + """ + the expected value of y given a value of f + """ + return self.gp_link.transf(gp) + + + + +
[docs] def d2logpdf_dlink2(self, link_f, y, Y_metadata=None): + """ + Hessian at y, given link(f), w.r.t link(f) + i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j) + The hessian will be 0 unless i == j + + .. math:: + \\frac{d^{2} \\ln p(y_{i}|\lambda(f_{i}))}{d^{2}\\lambda(f)} = \\frac{-y_{i}}{\\lambda(f_{i})^{2}} + + :param link_f: latent variables link(f) + :type link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in poisson distribution + :returns: Diagonal of hessian matrix (second derivative of likelihood evaluated at points f) + :rtype: Nx1 array + + .. Note:: + Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases + (the distribution for y_i depends only on link(f_i) not on link(f_(j!=i)) + """ + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape + hess = -y/(link_f**2) + return hess + #d2_df = self.gp_link.d2transf_df2(gp) + #transf = self.gp_link.transf(gp) + #return obs * ((self.gp_link.dtransf_df(gp)/transf)**2 - d2_df/transf) + d2_df +
+
[docs] def d3logpdf_dlink3(self, link_f, y, Y_metadata=None): + """ + Third order derivative log-likelihood function at y given link(f) w.r.t link(f) + + .. math:: + \\frac{d^{3} \\ln p(y_{i}|\lambda(f_{i}))}{d^{3}\\lambda(f)} = \\frac{2y_{i}}{\\lambda(f_{i})^{3}} + + :param link_f: latent variables link(f) + :type link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in poisson distribution + :returns: third derivative of likelihood evaluated at points f + :rtype: Nx1 array + """ + assert np.atleast_1d(link_f).shape == np.atleast_1d(y).shape + d3lik_dlink3 = 2*y/(link_f)**3 + return d3lik_dlink3 +
+
[docs] def conditional_mean(self,gp): + """ + The mean of the random variable conditioned on one value of the GP + """ + return self.gp_link.transf(gp) +
+
[docs] def conditional_variance(self,gp): + """ + The variance of the random variable conditioned on one value of the GP + """ + return self.gp_link.transf(gp) +
+
[docs] def samples(self, gp, Y_metadata=None): + """ + Returns a set of samples of observations based on a given value of the latent variable. + + :param gp: latent variable + """ + orig_shape = gp.shape + gp = gp.flatten() + Ysim = np.random.poisson(self.gp_link.transf(gp)) + return Ysim.reshape(orig_shape)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/likelihoods/student_t.html b/doc/_build/html/_modules/GPy/likelihoods/student_t.html new file mode 100644 index 00000000..d93e3fa8 --- /dev/null +++ b/doc/_build/html/_modules/GPy/likelihoods/student_t.html @@ -0,0 +1,373 @@ + + + + + + + + GPy.likelihoods.student_t — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.likelihoods.student_t

+# Copyright (c) 2012-2014 Ricardo Andrade, Alan Saul
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from scipy import stats, special
+import scipy as sp
+import link_functions
+from scipy import stats, integrate
+from scipy.special import gammaln, gamma
+from likelihood import Likelihood
+from ..core.parameterization import Param
+from ..core.parameterization.transformations import Logexp
+
+
[docs]class StudentT(Likelihood): + """ + Student T likelihood + + For nomanclature see Bayesian Data Analysis 2003 p576 + + .. math:: + p(y_{i}|\\lambda(f_{i})) = \\frac{\\Gamma\\left(\\frac{v+1}{2}\\right)}{\\Gamma\\left(\\frac{v}{2}\\right)\\sqrt{v\\pi\\sigma^{2}}}\\left(1 + \\frac{1}{v}\\left(\\frac{(y_{i} - f_{i})^{2}}{\\sigma^{2}}\\right)\\right)^{\\frac{-v+1}{2}} + + """ + def __init__(self,gp_link=None, deg_free=5, sigma2=2): + if gp_link is None: + gp_link = link_functions.Identity() + + super(StudentT, self).__init__(gp_link, name='Student_T') + # sigma2 is not a noise parameter, it is a squared scale. + self.sigma2 = Param('t_scale2', float(sigma2), Logexp()) + self.v = Param('deg_free', float(deg_free)) + self.link_parameter(self.sigma2) + self.link_parameter(self.v) + self.v.constrain_fixed() + + self.log_concave = False + +
[docs] def parameters_changed(self): + self.variance = (self.v / float(self.v - 2)) * self.sigma2 +
+
[docs] def update_gradients(self, grads): + """ + Pull out the gradients, be careful as the order must match the order + in which the parameters are added + """ + self.sigma2.gradient = grads[0] + self.v.gradient = grads[1] +
+ + + +
[docs] def d2logpdf_dlink2(self, inv_link_f, y, Y_metadata=None): + """ + Hessian at y, given link(f), w.r.t link(f) + i.e. second derivative logpdf at y given link(f_i) and link(f_j) w.r.t link(f_i) and link(f_j) + The hessian will be 0 unless i == j + + .. math:: + \\frac{d^{2} \\ln p(y_{i}|\lambda(f_{i}))}{d^{2}\\lambda(f)} = \\frac{(v+1)((y_{i}-\lambda(f_{i}))^{2} - \\sigma^{2}v)}{((y_{i}-\lambda(f_{i}))^{2} + \\sigma^{2}v)^{2}} + + :param inv_link_f: latent variables inv_link(f) + :type inv_link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in student t distribution + :returns: Diagonal of hessian matrix (second derivative of likelihood evaluated at points f) + :rtype: Nx1 array + + .. Note:: + Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases + (the distribution for y_i depends only on link(f_i) not on link(f_(j!=i)) + """ + assert np.atleast_1d(inv_link_f).shape == np.atleast_1d(y).shape + e = y - inv_link_f + hess = ((self.v + 1)*(e**2 - self.v*self.sigma2)) / ((self.sigma2*self.v + e**2)**2) + return hess +
+
[docs] def d3logpdf_dlink3(self, inv_link_f, y, Y_metadata=None): + """ + Third order derivative log-likelihood function at y given link(f) w.r.t link(f) + + .. math:: + \\frac{d^{3} \\ln p(y_{i}|\lambda(f_{i}))}{d^{3}\\lambda(f)} = \\frac{-2(v+1)((y_{i} - \lambda(f_{i}))^3 - 3(y_{i} - \lambda(f_{i})) \\sigma^{2} v))}{((y_{i} - \lambda(f_{i})) + \\sigma^{2} v)^3} + + :param inv_link_f: latent variables link(f) + :type inv_link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in student t distribution + :returns: third derivative of likelihood evaluated at points f + :rtype: Nx1 array + """ + assert np.atleast_1d(inv_link_f).shape == np.atleast_1d(y).shape + e = y - inv_link_f + d3lik_dlink3 = ( -(2*(self.v + 1)*(-e)*(e**2 - 3*self.v*self.sigma2)) / + ((e**2 + self.sigma2*self.v)**3) + ) + return d3lik_dlink3 +
+ + +
[docs] def d2logpdf_dlink2_dvar(self, inv_link_f, y, Y_metadata=None): + """ + Gradient of the hessian (d2logpdf_dlink2) w.r.t variance parameter (t_noise) + + .. math:: + \\frac{d}{d\\sigma^{2}}(\\frac{d^{2} \\ln p(y_{i}|\lambda(f_{i}))}{d^{2}f}) = \\frac{v(v+1)(\\sigma^{2}v - 3(y_{i} - \lambda(f_{i}))^{2})}{(\\sigma^{2}v + (y_{i} - \lambda(f_{i}))^{2})^{3}} + + :param inv_link_f: latent variables link(f) + :type inv_link_f: Nx1 array + :param y: data + :type y: Nx1 array + :param Y_metadata: Y_metadata which is not used in student t distribution + :returns: derivative of hessian evaluated at points f and f_j w.r.t variance parameter + :rtype: Nx1 array + """ + assert np.atleast_1d(inv_link_f).shape == np.atleast_1d(y).shape + e = y - inv_link_f + d2logpdf_dlink2_dvar = ( (self.v*(self.v+1)*(self.sigma2*self.v - 3*(e**2))) + / ((self.sigma2*self.v + (e**2))**3) + ) + return d2logpdf_dlink2_dvar +
+ + +
[docs] def d2logpdf_dlink2_dtheta(self, f, y, Y_metadata=None): + d2logpdf_dlink2_dvar = self.d2logpdf_dlink2_dvar(f, y, Y_metadata=Y_metadata) + d2logpdf_dlink2_dv = np.zeros_like(d2logpdf_dlink2_dvar) #FIXME: Not done yet + return np.hstack((d2logpdf_dlink2_dvar, d2logpdf_dlink2_dv)) +
+
[docs] def predictive_mean(self, mu, sigma, Y_metadata=None): + # The comment here confuses mean and median. + return self.gp_link.transf(mu) # only true if link is monotonic, which it is. +
+
[docs] def predictive_variance(self, mu,variance, predictive_mean=None, Y_metadata=None): + if self.deg_free<=2.: + return np.empty(mu.shape)*np.nan # does not exist for degrees of freedom <= 2. + else: + return super(StudentT, self).predictive_variance(mu, variance, predictive_mean, Y_metadata) +
+
[docs] def conditional_mean(self, gp): + return self.gp_link.transf(gp) +
+
[docs] def conditional_variance(self, gp): + return self.deg_free/(self.deg_free - 2.) +
+
[docs] def samples(self, gp, Y_metadata=None): + """ + Returns a set of samples of observations based on a given value of the latent variable. + + :param gp: latent variable + """ + orig_shape = gp.shape + gp = gp.flatten() + #FIXME: Very slow as we are computing a new random variable per input! + #Can't get it to sample all at the same time + #student_t_samples = np.array([stats.t.rvs(self.v, self.gp_link.transf(gpj),scale=np.sqrt(self.sigma2), size=1) for gpj in gp]) + dfs = np.ones_like(gp)*self.v + scales = np.ones_like(gp)*np.sqrt(self.sigma2) + student_t_samples = stats.t.rvs(dfs, loc=self.gp_link.transf(gp), + scale=scales) + return student_t_samples.reshape(orig_shape)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/mappings/additive.html b/doc/_build/html/_modules/GPy/mappings/additive.html new file mode 100644 index 00000000..f0f2455e --- /dev/null +++ b/doc/_build/html/_modules/GPy/mappings/additive.html @@ -0,0 +1,155 @@ + + + + + + + + GPy.mappings.additive — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.mappings.additive

+# Copyright (c) 2013, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ..core.mapping import Mapping
+import GPy
+
+
[docs]class Additive(Mapping): + """ + Mapping based on adding two existing mappings together. + + .. math:: + + f(\mathbf{x}*) = f_1(\mathbf{x}*) + f_2(\mathbf(x)*) + + :param mapping1: first mapping to add together. + :type mapping1: GPy.mappings.Mapping + :param mapping2: second mapping to add together. + :type mapping2: GPy.mappings.Mapping + :param tensor: whether or not to use the tensor product of input spaces + :type tensor: bool + + """ + + def __init__(self, mapping1, mapping2, tensor=False): + if tensor: + input_dim = mapping1.input_dim + mapping2.input_dim + else: + input_dim = mapping1.input_dim + assert(mapping1.input_dim==mapping2.input_dim) + assert(mapping1.output_dim==mapping2.output_dim) + output_dim = mapping1.output_dim + Mapping.__init__(self, input_dim=input_dim, output_dim=output_dim) + self.mapping1 = mapping1 + self.mapping2 = mapping2 + self.num_params = self.mapping1.num_params + self.mapping2.num_params + self.name = self.mapping1.name + '+' + self.mapping2.name + def _get_param_names(self): + return self.mapping1._get_param_names + self.mapping2._get_param_names + + def _get_params(self): + return np.hstack((self.mapping1._get_params(), self.mapping2._get_params())) + + def _set_params(self, x): + self.mapping1._set_params(x[:self.mapping1.num_params]) + self.mapping2._set_params(x[self.mapping1.num_params:]) + +
[docs] def randomize(self): + self.mapping1._randomize() + self.mapping2._randomize() +
+
[docs] def f(self, X): + return self.mapping1.f(X) + self.mapping2.f(X) +
+
[docs] def df_dtheta(self, dL_df, X): + self._df_dA = (dL_df[:, :, None]*self.kern.K(X, self.X)[:, None, :]).sum(0).T + self._df_dbias = (dL_df.sum(0)) + return np.hstack((self._df_dA.flatten(), self._df_dbias)) +
+
[docs] def df_dX(self, dL_df, X): + return self.kern.dK_dX((dL_df[:, None, :]*self.A[None, :, :]).sum(2), X, self.X)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/mappings/kernel.html b/doc/_build/html/_modules/GPy/mappings/kernel.html new file mode 100644 index 00000000..b15962f6 --- /dev/null +++ b/doc/_build/html/_modules/GPy/mappings/kernel.html @@ -0,0 +1,154 @@ + + + + + + + + GPy.mappings.kernel — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.mappings.kernel

+# Copyright (c) 2013, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ..core.mapping import Mapping
+import GPy
+
+
[docs]class Kernel(Mapping): + """ + Mapping based on a kernel/covariance function. + + .. math:: + + f(\mathbf{x}*) = \mathbf{A}\mathbf{k}(\mathbf{X}, \mathbf{x}^*) + \mathbf{b} + + :param X: input observations containing :math:`\mathbf{X}` + :type X: ndarray + :param output_dim: dimension of output. + :type output_dim: int + :param kernel: a GPy kernel, defaults to GPy.kern.RBF + :type kernel: GPy.kern.kern + + """ + + def __init__(self, X, output_dim=1, kernel=None): + Mapping.__init__(self, input_dim=X.shape[1], output_dim=output_dim) + if kernel is None: + kernel = GPy.kern.RBF(self.input_dim) + self.kern = kernel + self.X = X + self.num_data = X.shape[0] + self.num_params = self.output_dim*(self.num_data + 1) + self.A = np.array((self.num_data, self.output_dim)) + self.bias = np.array(self.output_dim) + self.randomize() + self.name = 'kernel' + def _get_param_names(self): + return sum([['A_%i_%i' % (n, d) for d in range(self.output_dim)] for n in range(self.num_data)], []) + ['bias_%i' % d for d in range(self.output_dim)] + + def _get_params(self): + return np.hstack((self.A.flatten(), self.bias)) + + def _set_params(self, x): + self.A = x[:self.num_data * self.output_dim].reshape(self.num_data, self.output_dim).copy() + self.bias = x[self.num_data*self.output_dim:].copy() + +
[docs] def randomize(self): + self.A = np.random.randn(self.num_data, self.output_dim)/np.sqrt(self.num_data+1) + self.bias = np.random.randn(self.output_dim)/np.sqrt(self.num_data+1) +
+
[docs] def f(self, X): + return np.dot(self.kern.K(X, self.X),self.A) + self.bias +
+
[docs] def df_dtheta(self, dL_df, X): + self._df_dA = (dL_df[:, :, None]*self.kern.K(X, self.X)[:, None, :]).sum(0).T + self._df_dbias = (dL_df.sum(0)) + return np.hstack((self._df_dA.flatten(), self._df_dbias)) +
+
[docs] def df_dX(self, dL_df, X): + return self.kern.gradients_X((dL_df[:, None, :]*self.A[None, :, :]).sum(2), X, self.X)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/mappings/linear.html b/doc/_build/html/_modules/GPy/mappings/linear.html new file mode 100644 index 00000000..e2af2bde --- /dev/null +++ b/doc/_build/html/_modules/GPy/mappings/linear.html @@ -0,0 +1,137 @@ + + + + + + + + GPy.mappings.linear — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.mappings.linear

+# Copyright (c) 2013, 2014 GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ..core.mapping import Bijective_mapping
+from ..core.parameterization import Param
+
+
[docs]class Linear(Bijective_mapping): + """ + Mapping based on a linear model. + + .. math:: + + f(\mathbf{x}*) = \mathbf{W}\mathbf{x}^* + \mathbf{b} + + :param X: input observations + :type X: ndarray + :param output_dim: dimension of output. + :type output_dim: int + + """ + + def __init__(self, input_dim=1, output_dim=1, name='linear'): + Bijective_mapping.__init__(self, input_dim=input_dim, output_dim=output_dim, name=name) + self.W = Param('W',np.array((self.input_dim, self.output_dim))) + self.bias = Param('bias',np.array(self.output_dim)) + self.link_parameters(self.W, self.bias) + +
[docs] def f(self, X): + return np.dot(X,self.W) + self.bias +
+
[docs] def g(self, f): + V = np.linalg.solve(np.dot(self.W.T, self.W), W.T) + return np.dot(f-self.bias, V) +
+
[docs] def df_dtheta(self, dL_df, X): + df_dW = (dL_df[:, :, None]*X[:, None, :]).sum(0).T + df_dbias = (dL_df.sum(0)) + return np.hstack((df_dW.flatten(), df_dbias)) +
+
[docs] def dL_dX(self, partial, X): + """The gradient of L with respect to the inputs to the mapping, where L is a function that is dependent on the output of the mapping, f.""" + return (partial[:, None, :]*self.W[None, :, :]).sum(2)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/mappings/mlp.html b/doc/_build/html/_modules/GPy/mappings/mlp.html new file mode 100644 index 00000000..6bd51a3f --- /dev/null +++ b/doc/_build/html/_modules/GPy/mappings/mlp.html @@ -0,0 +1,224 @@ + + + + + + + + GPy.mappings.mlp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.mappings.mlp

+# Copyright (c) 2013, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ..core.mapping import Mapping
+
+
[docs]class MLP(Mapping): + """ + Mapping based on a multi-layer perceptron neural network model. + + .. math:: + + f(\\mathbf{x}*) = \\mathbf{W}^0\\boldsymbol{\\phi}(\\mathbf{W}^1\\mathbf{x}+\\mathbf{b}^1)^* + \\mathbf{b}^0 + + where + + .. math:: + + \\phi(\\cdot) = \\text{tanh}(\\cdot) + + :param X: input observations + :type X: ndarray + :param output_dim: dimension of output. + :type output_dim: int + :param hidden_dim: dimension of hidden layer. If it is an int, there is one hidden layer of the given dimension. If it is a list of ints there are as manny hidden layers as the length of the list, each with the given number of hidden nodes in it. + :type hidden_dim: int or list of ints. + + """ + + def __init__(self, input_dim=1, output_dim=1, hidden_dim=3): + Mapping.__init__(self, input_dim=input_dim, output_dim=output_dim) + self.name = 'mlp' + if isinstance(hidden_dim, int): + hidden_dim = [hidden_dim] + self.hidden_dim = hidden_dim + self.activation = [None]*len(self.hidden_dim) + self.W = [] + self._dL_dW = [] + self.bias = [] + self._dL_dbias = [] + self.W.append(np.zeros((self.input_dim, self.hidden_dim[0]))) + self._dL_dW.append(np.zeros((self.input_dim, self.hidden_dim[0]))) + self.bias.append(np.zeros(self.hidden_dim[0])) + self._dL_dbias.append(np.zeros(self.hidden_dim[0])) + self.num_params = self.hidden_dim[0]*(self.input_dim+1) + for h1, h0 in zip(hidden_dim[1:], hidden_dim[0:-1]): + self.W.append(np.zeros((h0, h1))) + self._dL_dW.append(np.zeros((h0, h1))) + self.bias.append(np.zeros(h1)) + self._dL_dbias.append(np.zeros(h1)) + self.num_params += h1*(h0+1) + self.W.append(np.zeros((self.hidden_dim[-1], self.output_dim))) + self._dL_dW.append(np.zeros((self.hidden_dim[-1], self.output_dim))) + self.bias.append(np.zeros(self.output_dim)) + self._dL_dbias.append(np.zeros(self.output_dim)) + self.num_params += self.output_dim*(self.hidden_dim[-1]+1) + self.randomize() + + def _get_param_names(self): + return sum([['W%i_%i_%i' % (i, n, d) for n in range(self.W[i].shape[0]) for d in range(self.W[i].shape[1])] + ['bias%i_%i' % (i, d) for d in range(self.W[i].shape[1])] for i in range(len(self.W))], []) + + def _get_params(self): + param = np.array([]) + for W, bias in zip(self.W, self.bias): + param = np.hstack((param, W.flatten(), bias)) + return param + + def _set_params(self, x): + start = 0 + for W, bias in zip(self.W, self.bias): + end = W.shape[0]*W.shape[1]+start + W[:] = x[start:end].reshape(W.shape[0], W.shape[1]).copy() + start = end + end = W.shape[1]+end + bias[:] = x[start:end].copy() + start = end + +
[docs] def randomize(self): + for W, bias in zip(self.W, self.bias): + W[:] = np.random.randn(W.shape[0], W.shape[1])/np.sqrt(W.shape[0]+1) + bias[:] = np.random.randn(W.shape[1])/np.sqrt(W.shape[0]+1) +
+
[docs] def f(self, X): + self._f_computations(X) + return np.dot(np.tanh(self.activation[-1]), self.W[-1]) + self.bias[-1] +
+ def _f_computations(self, X): + W = self.W[0] + bias = self.bias[0] + self.activation[0] = np.dot(X,W) + bias + for W, bias, index in zip(self.W[1:-1], self.bias[1:-1], range(1, len(self.activation))): + self.activation[index] = np.dot(np.tanh(self.activation[index-1]), W)+bias + +
[docs] def df_dtheta(self, dL_df, X): + self._df_computations(dL_df, X) + g = np.array([]) + for gW, gbias in zip(self._dL_dW, self._dL_dbias): + g = np.hstack((g, gW.flatten(), gbias)) + return g +
+ def _df_computations(self, dL_df, X): + self._f_computations(X) + a0 = self.activation[-1] + W = self.W[-1] + self._dL_dW[-1] = (dL_df[:, :, None]*np.tanh(a0[:, None, :])).sum(0).T + dL_dta=(dL_df[:, None, :]*W[None, :, :]).sum(2) + self._dL_dbias[-1] = (dL_df.sum(0)) + for dL_dW, dL_dbias, W, bias, a0, a1 in zip(self._dL_dW[-2:0:-1], + self._dL_dbias[-2:0:-1], + self.W[-2:0:-1], + self.bias[-2:0:-1], + self.activation[-2::-1], + self.activation[-1:0:-1]): + ta = np.tanh(a1) + dL_da = dL_dta*(1-ta*ta) + dL_dW[:] = (dL_da[:, :, None]*np.tanh(a0[:, None, :])).sum(0).T + dL_dbias[:] = (dL_da.sum(0)) + dL_dta = (dL_da[:, None, :]*W[None, :, :]).sum(2) + ta = np.tanh(self.activation[0]) + dL_da = dL_dta*(1-ta*ta) + W = self.W[0] + self._dL_dW[0] = (dL_da[:, :, None]*X[:, None, :]).sum(0).T + self._dL_dbias[0] = (dL_da.sum(0)) + self._dL_dX = (dL_da[:, None, :]*W[None, :, :]).sum(2) + + +
[docs] def df_dX(self, dL_df, X): + self._df_computations(dL_df, X) + return self._dL_dX +
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/bayesian_gplvm.html b/doc/_build/html/_modules/GPy/models/bayesian_gplvm.html new file mode 100644 index 00000000..5d67129c --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/bayesian_gplvm.html @@ -0,0 +1,328 @@ + + + + + + + + GPy.models.bayesian_gplvm — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.bayesian_gplvm

+# Copyright (c) 2012 - 2014 the GPy Austhors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from .. import kern
+from ..core.sparse_gp_mpi import SparseGP_MPI
+from ..likelihoods import Gaussian
+from ..core.parameterization.variational import NormalPosterior, NormalPrior
+from ..inference.latent_function_inference.var_dtc_parallel import VarDTC_minibatch
+import logging
+
+
[docs]class BayesianGPLVM(SparseGP_MPI): + """ + Bayesian Gaussian Process Latent Variable Model + + :param Y: observed data (np.ndarray) or GPy.likelihood + :type Y: np.ndarray| GPy.likelihood instance + :param input_dim: latent dimensionality + :type input_dim: int + :param init: initialisation method for the latent space + :type init: 'PCA'|'random' + + """ + def __init__(self, Y, input_dim, X=None, X_variance=None, init='PCA', num_inducing=10, + Z=None, kernel=None, inference_method=None, likelihood=None, + name='bayesian gplvm', mpi_comm=None, normalizer=None, + missing_data=False, stochastic=False, batchsize=1): + + self.logger = logging.getLogger(self.__class__.__name__) + if X is None: + from ..util.initialization import initialize_latent + self.logger.info("initializing latent space X with method {}".format(init)) + X, fracs = initialize_latent(init, input_dim, Y) + else: + fracs = np.ones(input_dim) + + self.init = init + + if X_variance is None: + self.logger.info("initializing latent space variance ~ uniform(0,.1)") + X_variance = np.random.uniform(0,.1,X.shape) + + if Z is None: + self.logger.info("initializing inducing inputs") + Z = np.random.permutation(X.copy())[:num_inducing] + assert Z.shape[1] == X.shape[1] + + if kernel is None: + self.logger.info("initializing kernel RBF") + kernel = kern.RBF(input_dim, lengthscale=1./fracs, ARD=True) #+ kern.Bias(input_dim) + kern.White(input_dim) + + if likelihood is None: + likelihood = Gaussian() + + self.variational_prior = NormalPrior() + X = NormalPosterior(X, X_variance) + + if inference_method is None: + if mpi_comm is not None: + inference_method = VarDTC_minibatch(mpi_comm=mpi_comm) + else: + from ..inference.latent_function_inference.var_dtc import VarDTC + self.logger.debug("creating inference_method var_dtc") + inference_method = VarDTC(limit=1 if not missing_data else Y.shape[1]) + if isinstance(inference_method,VarDTC_minibatch): + inference_method.mpi_comm = mpi_comm + + super(BayesianGPLVM,self).__init__(X, Y, Z, kernel, likelihood=likelihood, + name=name, inference_method=inference_method, + normalizer=normalizer, mpi_comm=mpi_comm, + variational_prior=self.variational_prior, + ) + self.link_parameter(self.X, index=0) + +
[docs] def set_X_gradients(self, X, X_grad): + """Set the gradients of the posterior distribution of X in its specific form.""" + X.mean.gradient, X.variance.gradient = X_grad +
+
[docs] def get_X_gradients(self, X): + """Get the gradients of the posterior distribution of X in its specific form.""" + return X.mean.gradient, X.variance.gradient +
+
[docs] def parameters_changed(self): + super(BayesianGPLVM,self).parameters_changed() + if isinstance(self.inference_method, VarDTC_minibatch): + return + + kl_fctr = 1. + self._log_marginal_likelihood -= kl_fctr*self.variational_prior.KL_divergence(self.X) + + self.X.mean.gradient, self.X.variance.gradient = self.kern.gradients_qX_expectations( + variational_posterior=self.X, + Z=self.Z, + dL_dpsi0=self.grad_dict['dL_dpsi0'], + dL_dpsi1=self.grad_dict['dL_dpsi1'], + dL_dpsi2=self.grad_dict['dL_dpsi2']) + + self.variational_prior.update_gradients_KL(self.X) + + + #super(BayesianGPLVM, self).parameters_changed() + #self._log_marginal_likelihood -= self.variational_prior.KL_divergence(self.X) + + #self.X.mean.gradient, self.X.variance.gradient = self.kern.gradients_qX_expectations(variational_posterior=self.X, Z=self.Z, dL_dpsi0=self.grad_dict['dL_dpsi0'], dL_dpsi1=self.grad_dict['dL_dpsi1'], dL_dpsi2=self.grad_dict['dL_dpsi2']) + + # This is testing code ------------------------- +# i = np.random.randint(self.X.shape[0]) +# X_ = self.X.mean +# which = np.sqrt(((X_ - X_[i:i+1])**2).sum(1)).argsort()>(max(0, self.X.shape[0]-51)) +# _, _, grad_dict = self.inference_method.inference(self.kern, self.X[which], self.Z, self.likelihood, self.Y[which], self.Y_metadata) +# grad = self.kern.gradients_qX_expectations(variational_posterior=self.X[which], Z=self.Z, dL_dpsi0=grad_dict['dL_dpsi0'], dL_dpsi1=grad_dict['dL_dpsi1'], dL_dpsi2=grad_dict['dL_dpsi2']) +# +# self.X.mean.gradient[:] = 0 +# self.X.variance.gradient[:] = 0 +# self.X.mean.gradient[which] = grad[0] +# self.X.variance.gradient[which] = grad[1] + + # update for the KL divergence +# self.variational_prior.update_gradients_KL(self.X, which) + # ----------------------------------------------- + + # update for the KL divergence + #self.variational_prior.update_gradients_KL(self.X) +
+
[docs] def plot_latent(self, labels=None, which_indices=None, + resolution=50, ax=None, marker='o', s=40, + fignum=None, plot_inducing=True, legend=True, + plot_limits=None, + aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={}): + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import dim_reduction_plots + + return dim_reduction_plots.plot_latent(self, labels, which_indices, + resolution, ax, marker, s, + fignum, plot_inducing, legend, + plot_limits, aspect, updates, predict_kwargs, imshow_kwargs) +
+
[docs] def do_test_latents(self, Y): + """ + Compute the latent representation for a set of new points Y + + Notes: + This will only work with a univariate Gaussian likelihood (for now) + """ + N_test = Y.shape[0] + input_dim = self.Z.shape[1] + + means = np.zeros((N_test, input_dim)) + covars = np.zeros((N_test, input_dim)) + + dpsi0 = -0.5 * self.input_dim / self.likelihood.variance + dpsi2 = self.grad_dict['dL_dpsi2'][0][None, :, :] # TODO: this may change if we ignore het. likelihoods + V = Y/self.likelihood.variance + + #compute CPsi1V + #if self.Cpsi1V is None: + # psi1V = np.dot(self.psi1.T, self.likelihood.V) + # tmp, _ = linalg.dtrtrs(self._Lm, np.asfortranarray(psi1V), lower=1, trans=0) + # tmp, _ = linalg.dpotrs(self.LB, tmp, lower=1) + # self.Cpsi1V, _ = linalg.dtrtrs(self._Lm, tmp, lower=1, trans=1) + + dpsi1 = np.dot(self.posterior.woodbury_vector, V.T) + + #start = np.zeros(self.input_dim * 2) + + + from scipy.optimize import minimize + + for n, dpsi1_n in enumerate(dpsi1.T[:, :, None]): + args = (input_dim, self.kern.copy(), self.Z, dpsi0, dpsi1_n.T, dpsi2) + res = minimize(latent_cost_and_grad, jac=True, x0=np.hstack((means[n], covars[n])), args=args, method='BFGS') + xopt = res.x + mu, log_S = xopt.reshape(2, 1, -1) + means[n] = mu[0].copy() + covars[n] = np.exp(log_S[0]).copy() + + X = NormalPosterior(means, covars) + + return X +
+
[docs] def dmu_dX(self, Xnew): + """ + Calculate the gradient of the prediction at Xnew w.r.t Xnew. + """ + dmu_dX = np.zeros_like(Xnew) + for i in range(self.Z.shape[0]): + dmu_dX += self.kern.gradients_X(self.grad_dict['dL_dpsi1'][i:i + 1, :], Xnew, self.Z[i:i + 1, :]) + return dmu_dX +
+
[docs] def dmu_dXnew(self, Xnew): + """ + Individual gradient of prediction at Xnew w.r.t. each sample in Xnew + """ + gradients_X = np.zeros((Xnew.shape[0], self.num_inducing)) + ones = np.ones((1, 1)) + for i in range(self.Z.shape[0]): + gradients_X[:, i] = self.kern.gradients_X(ones, Xnew, self.Z[i:i + 1, :]).sum(-1) + return np.dot(gradients_X, self.grad_dict['dL_dpsi1']) +
+
[docs] def plot_steepest_gradient_map(self, *args, ** kwargs): + """ + See GPy.plotting.matplot_dep.dim_reduction_plots.plot_steepest_gradient_map + """ + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import dim_reduction_plots + + return dim_reduction_plots.plot_steepest_gradient_map(self,*args,**kwargs) + +
+
[docs]def latent_cost_and_grad(mu_S, input_dim, kern, Z, dL_dpsi0, dL_dpsi1, dL_dpsi2): + """ + objective function for fitting the latent variables for test points + (negative log-likelihood: should be minimised!) + """ + mu = mu_S[:input_dim][None] + log_S = mu_S[input_dim:][None] + S = np.exp(log_S) + + X = NormalPosterior(mu, S) + + psi0 = kern.psi0(Z, X) + psi1 = kern.psi1(Z, X) + psi2 = kern.psi2(Z, X) + + lik = dL_dpsi0 * psi0.sum() + np.einsum('ij,kj->...', dL_dpsi1, psi1) + np.einsum('ijk,lkj->...', dL_dpsi2, psi2) - 0.5 * np.sum(np.square(mu) + S) + 0.5 * np.sum(log_S) + + dLdmu, dLdS = kern.gradients_qX_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, X) + dmu = dLdmu - mu + # dS = S0 + S1 + S2 -0.5 + .5/S + dlnS = S * (dLdS - 0.5) + .5 + + return -lik, -np.hstack((dmu.flatten(), dlnS.flatten()))
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/bayesian_gplvm_minibatch.html b/doc/_build/html/_modules/GPy/models/bayesian_gplvm_minibatch.html new file mode 100644 index 00000000..2a681622 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/bayesian_gplvm_minibatch.html @@ -0,0 +1,363 @@ + + + + + + + + GPy.models.bayesian_gplvm_minibatch — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.bayesian_gplvm_minibatch

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from .. import kern
+from ..likelihoods import Gaussian
+from ..core.parameterization.variational import NormalPosterior, NormalPrior
+from ..inference.latent_function_inference.var_dtc_parallel import VarDTC_minibatch
+import logging
+from GPy.models.sparse_gp_minibatch import SparseGPMiniBatch
+
+
[docs]class BayesianGPLVMMiniBatch(SparseGPMiniBatch): + """ + Bayesian Gaussian Process Latent Variable Model + + :param Y: observed data (np.ndarray) or GPy.likelihood + :type Y: np.ndarray| GPy.likelihood instance + :param input_dim: latent dimensionality + :type input_dim: int + :param init: initialisation method for the latent space + :type init: 'PCA'|'random' + + """ + def __init__(self, Y, input_dim, X=None, X_variance=None, init='PCA', num_inducing=10, + Z=None, kernel=None, inference_method=None, likelihood=None, + name='bayesian gplvm', normalizer=None, + missing_data=False, stochastic=False, batchsize=1): + self.logger = logging.getLogger(self.__class__.__name__) + if X is None: + from ..util.initialization import initialize_latent + self.logger.info("initializing latent space X with method {}".format(init)) + X, fracs = initialize_latent(init, input_dim, Y) + else: + fracs = np.ones(input_dim) + + self.init = init + + if X_variance is None: + self.logger.info("initializing latent space variance ~ uniform(0,.1)") + X_variance = np.random.uniform(0,.1,X.shape) + + if Z is None: + self.logger.info("initializing inducing inputs") + Z = np.random.permutation(X.copy())[:num_inducing] + assert Z.shape[1] == X.shape[1] + + if kernel is None: + self.logger.info("initializing kernel RBF") + kernel = kern.RBF(input_dim, lengthscale=1./fracs, ARD=True) #+ kern.Bias(input_dim) + kern.White(input_dim) + + if likelihood is None: + likelihood = Gaussian() + + self.variational_prior = NormalPrior() + X = NormalPosterior(X, X_variance) + + self.kl_factr = 1. + + if inference_method is None: + from ..inference.latent_function_inference.var_dtc import VarDTC + self.logger.debug("creating inference_method var_dtc") + inference_method = VarDTC(limit=1 if not missing_data else Y.shape[1]) + + if kernel.useGPU and isinstance(inference_method, VarDTC_GPU): + kernel.psicomp.GPU_direct = True + + super(BayesianGPLVMMiniBatch,self).__init__(X, Y, Z, kernel, likelihood=likelihood, + name=name, inference_method=inference_method, + normalizer=normalizer, + missing_data=missing_data, stochastic=stochastic, + batchsize=batchsize) + self.X = X + self.link_parameter(self.X, 0) + +
[docs] def set_X_gradients(self, X, X_grad): + """Set the gradients of the posterior distribution of X in its specific form.""" + X.mean.gradient, X.variance.gradient = X_grad +
+
[docs] def get_X_gradients(self, X): + """Get the gradients of the posterior distribution of X in its specific form.""" + return X.mean.gradient, X.variance.gradient +
+ def _inner_parameters_changed(self, kern, X, Z, likelihood, Y, Y_metadata, Lm=None, dL_dKmm=None, subset_indices=None): + posterior, log_marginal_likelihood, grad_dict, current_values, value_indices = super(BayesianGPLVMMiniBatch, self)._inner_parameters_changed(kern, X, Z, likelihood, Y, Y_metadata, Lm=Lm, dL_dKmm=dL_dKmm, subset_indices=subset_indices) + + current_values['meangrad'], current_values['vargrad'] = self.kern.gradients_qX_expectations( + variational_posterior=X, + Z=Z, dL_dpsi0=grad_dict['dL_dpsi0'], + dL_dpsi1=grad_dict['dL_dpsi1'], + dL_dpsi2=grad_dict['dL_dpsi2']) + + kl_fctr = self.kl_factr + if self.missing_data: + d = self.output_dim + log_marginal_likelihood -= kl_fctr*self.variational_prior.KL_divergence(X)/d + else: + log_marginal_likelihood -= kl_fctr*self.variational_prior.KL_divergence(X) + + + # Subsetting Variational Posterior objects, makes the gradients + # empty. We need them to be 0 though: + X.mean.gradient[:] = 0 + X.variance.gradient[:] = 0 + + self.variational_prior.update_gradients_KL(X) + if self.missing_data: + current_values['meangrad'] += kl_fctr*X.mean.gradient/d + current_values['vargrad'] += kl_fctr*X.variance.gradient/d + else: + current_values['meangrad'] += kl_fctr*X.mean.gradient + current_values['vargrad'] += kl_fctr*X.variance.gradient + + if subset_indices is not None: + value_indices['meangrad'] = subset_indices['samples'] + value_indices['vargrad'] = subset_indices['samples'] + return posterior, log_marginal_likelihood, grad_dict, current_values, value_indices + + def _outer_values_update(self, full_values): + """ + Here you put the values, which were collected before in the right places. + E.g. set the gradients of parameters, etc. + """ + super(BayesianGPLVMMiniBatch, self)._outer_values_update(full_values) + self.X.mean.gradient = full_values['meangrad'] + self.X.variance.gradient = full_values['vargrad'] + + def _outer_init_full_values(self): + return dict(meangrad=np.zeros(self.X.mean.shape), + vargrad=np.zeros(self.X.variance.shape)) + +
[docs] def parameters_changed(self): + super(BayesianGPLVMMiniBatch,self).parameters_changed() + if isinstance(self.inference_method, VarDTC_minibatch): + return + + #super(BayesianGPLVM, self).parameters_changed() + #self._log_marginal_likelihood -= self.variational_prior.KL_divergence(self.X) + + #self.X.mean.gradient, self.X.variance.gradient = self.kern.gradients_qX_expectations(variational_posterior=self.X, Z=self.Z, dL_dpsi0=self.grad_dict['dL_dpsi0'], dL_dpsi1=self.grad_dict['dL_dpsi1'], dL_dpsi2=self.grad_dict['dL_dpsi2']) + + # This is testing code ------------------------- +# i = np.random.randint(self.X.shape[0]) +# X_ = self.X.mean +# which = np.sqrt(((X_ - X_[i:i+1])**2).sum(1)).argsort()>(max(0, self.X.shape[0]-51)) +# _, _, grad_dict = self.inference_method.inference(self.kern, self.X[which], self.Z, self.likelihood, self.Y[which], self.Y_metadata) +# grad = self.kern.gradients_qX_expectations(variational_posterior=self.X[which], Z=self.Z, dL_dpsi0=grad_dict['dL_dpsi0'], dL_dpsi1=grad_dict['dL_dpsi1'], dL_dpsi2=grad_dict['dL_dpsi2']) +# +# self.X.mean.gradient[:] = 0 +# self.X.variance.gradient[:] = 0 +# self.X.mean.gradient[which] = grad[0] +# self.X.variance.gradient[which] = grad[1] + + # update for the KL divergence +# self.variational_prior.update_gradients_KL(self.X, which) + # ----------------------------------------------- + + # update for the KL divergence + #self.variational_prior.update_gradients_KL(self.X) +
+
[docs] def plot_latent(self, labels=None, which_indices=None, + resolution=50, ax=None, marker='o', s=40, + fignum=None, plot_inducing=True, legend=True, + plot_limits=None, + aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={}): + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import dim_reduction_plots + + return dim_reduction_plots.plot_latent(self, labels, which_indices, + resolution, ax, marker, s, + fignum, plot_inducing, legend, + plot_limits, aspect, updates, predict_kwargs, imshow_kwargs) +
+
[docs] def do_test_latents(self, Y): + """ + Compute the latent representation for a set of new points Y + + Notes: + This will only work with a univariate Gaussian likelihood (for now) + """ + N_test = Y.shape[0] + input_dim = self.Z.shape[1] + + means = np.zeros((N_test, input_dim)) + covars = np.zeros((N_test, input_dim)) + + dpsi0 = -0.5 * self.input_dim / self.likelihood.variance + dpsi2 = self.grad_dict['dL_dpsi2'][0][None, :, :] # TODO: this may change if we ignore het. likelihoods + V = Y/self.likelihood.variance + + #compute CPsi1V + #if self.Cpsi1V is None: + # psi1V = np.dot(self.psi1.T, self.likelihood.V) + # tmp, _ = linalg.dtrtrs(self._Lm, np.asfortranarray(psi1V), lower=1, trans=0) + # tmp, _ = linalg.dpotrs(self.LB, tmp, lower=1) + # self.Cpsi1V, _ = linalg.dtrtrs(self._Lm, tmp, lower=1, trans=1) + + dpsi1 = np.dot(self.posterior.woodbury_vector, V.T) + + #start = np.zeros(self.input_dim * 2) + + + from scipy.optimize import minimize + + for n, dpsi1_n in enumerate(dpsi1.T[:, :, None]): + args = (input_dim, self.kern.copy(), self.Z, dpsi0, dpsi1_n.T, dpsi2) + res = minimize(latent_cost_and_grad, jac=True, x0=np.hstack((means[n], covars[n])), args=args, method='BFGS') + xopt = res.x + mu, log_S = xopt.reshape(2, 1, -1) + means[n] = mu[0].copy() + covars[n] = np.exp(log_S[0]).copy() + + X = NormalPosterior(means, covars) + + return X +
+
[docs] def dmu_dX(self, Xnew): + """ + Calculate the gradient of the prediction at Xnew w.r.t Xnew. + """ + dmu_dX = np.zeros_like(Xnew) + for i in range(self.Z.shape[0]): + dmu_dX += self.kern.gradients_X(self.grad_dict['dL_dpsi1'][i:i + 1, :], Xnew, self.Z[i:i + 1, :]) + return dmu_dX +
+
[docs] def dmu_dXnew(self, Xnew): + """ + Individual gradient of prediction at Xnew w.r.t. each sample in Xnew + """ + gradients_X = np.zeros((Xnew.shape[0], self.num_inducing)) + ones = np.ones((1, 1)) + for i in range(self.Z.shape[0]): + gradients_X[:, i] = self.kern.gradients_X(ones, Xnew, self.Z[i:i + 1, :]).sum(-1) + return np.dot(gradients_X, self.grad_dict['dL_dpsi1']) +
+
[docs] def plot_steepest_gradient_map(self, *args, ** kwargs): + """ + See GPy.plotting.matplot_dep.dim_reduction_plots.plot_steepest_gradient_map + """ + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import dim_reduction_plots + + return dim_reduction_plots.plot_steepest_gradient_map(self,*args,**kwargs) + +
+
[docs]def latent_cost_and_grad(mu_S, input_dim, kern, Z, dL_dpsi0, dL_dpsi1, dL_dpsi2): + """ + objective function for fitting the latent variables for test points + (negative log-likelihood: should be minimised!) + """ + mu = mu_S[:input_dim][None] + log_S = mu_S[input_dim:][None] + S = np.exp(log_S) + + X = NormalPosterior(mu, S) + + psi0 = kern.psi0(Z, X) + psi1 = kern.psi1(Z, X) + psi2 = kern.psi2(Z, X) + + lik = dL_dpsi0 * psi0.sum() + np.einsum('ij,kj->...', dL_dpsi1, psi1) + np.einsum('ijk,lkj->...', dL_dpsi2, psi2) - 0.5 * np.sum(np.square(mu) + S) + 0.5 * np.sum(log_S) + + dLdmu, dLdS = kern.gradients_qX_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, X) + dmu = dLdmu - mu + # dS = S0 + S1 + S2 -0.5 + .5/S + dlnS = S * (dLdS - 0.5) + .5 + + return -lik, -np.hstack((dmu.flatten(), dlnS.flatten()))
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/bcgplvm.html b/doc/_build/html/_modules/GPy/models/bcgplvm.html new file mode 100644 index 00000000..ebd48c80 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/bcgplvm.html @@ -0,0 +1,141 @@ + + + + + + + + GPy.models.bcgplvm — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.bcgplvm

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from ..core import GP
+from ..models import GPLVM
+from ..mappings import *
+
+
+
[docs]class BCGPLVM(GPLVM): + """ + Back constrained Gaussian Process Latent Variable Model + + :param Y: observed data + :type Y: np.ndarray + :param input_dim: latent dimensionality + :type input_dim: int + :param init: initialisation method for the latent space + :type init: 'PCA'|'random' + :param mapping: mapping for back constraint + :type mapping: GPy.core.Mapping object + + """ + def __init__(self, Y, input_dim, init='PCA', X=None, kernel=None, normalize_Y=False, mapping=None): + + if mapping is None: + mapping = Kernel(X=Y, output_dim=input_dim) + self.mapping = mapping + GPLVM.__init__(self, Y, input_dim, init, X, kernel, normalize_Y) + self.X = self.mapping.f(self.likelihood.Y) + + def _get_param_names(self): + return self.mapping._get_param_names() + GP._get_param_names(self) + + def _get_params(self): + return np.hstack((self.mapping._get_params(), GP._get_params(self))) + + def _set_params(self, x): + self.mapping._set_params(x[:self.mapping.num_params]) + self.X = self.mapping.f(self.likelihood.Y) + GP._set_params(self, x[self.mapping.num_params:]) + + def _log_likelihood_gradients(self): + dL_df = self.kern.gradients_X(self.dL_dK, self.X) + dL_dtheta = self.mapping.df_dtheta(dL_df, self.likelihood.Y) + return np.hstack((dL_dtheta.flatten(), GP._log_likelihood_gradients(self))) +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/gp_classification.html b/doc/_build/html/_modules/GPy/models/gp_classification.html new file mode 100644 index 00000000..54e6c5b3 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/gp_classification.html @@ -0,0 +1,123 @@ + + + + + + + + GPy.models.gp_classification — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.gp_classification

+# Copyright (c) 2013, the GPy Authors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from ..core import GP
+from .. import likelihoods
+from .. import kern
+from ..inference.latent_function_inference.expectation_propagation import EP
+
+
[docs]class GPClassification(GP): + """ + Gaussian Process classification + + This is a thin wrapper around the models.GP class, with a set of sensible defaults + + :param X: input observations + :param Y: observed values, can be None if likelihood is not None + :param kernel: a GPy kernel, defaults to rbf + + .. Note:: Multiple independent outputs are allowed using columns of Y + + """ + + def __init__(self, X, Y, kernel=None,Y_metadata=None): + if kernel is None: + kernel = kern.RBF(X.shape[1]) + + likelihood = likelihoods.Bernoulli() + + GP.__init__(self, X=X, Y=Y, kernel=kernel, likelihood=likelihood, inference_method=EP(), name='gp_classification')
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/gp_coregionalized_regression.html b/doc/_build/html/_modules/GPy/models/gp_coregionalized_regression.html new file mode 100644 index 00000000..0762b10b --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/gp_coregionalized_regression.html @@ -0,0 +1,138 @@ + + + + + + + + GPy.models.gp_coregionalized_regression — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.gp_coregionalized_regression

+# Copyright (c) 2012 - 2014 the GPy Austhors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ..core import GP
+from .. import likelihoods
+from .. import kern
+from .. import util
+
+
[docs]class GPCoregionalizedRegression(GP): + """ + Gaussian Process model for heteroscedastic multioutput regression + + This is a thin wrapper around the models.GP class, with a set of sensible defaults + + :param X_list: list of input observations corresponding to each output + :type X_list: list of numpy arrays + :param Y_list: list of observed values related to the different noise models + :type Y_list: list of numpy arrays + :param kernel: a GPy kernel, defaults to RBF ** Coregionalized + :type kernel: None | GPy.kernel defaults + :likelihoods_list: a list of likelihoods, defaults to list of Gaussian likelihoods + :type likelihoods_list: None | a list GPy.likelihoods + :param name: model name + :type name: string + :param W_rank: number tuples of the corregionalization parameters 'W' (see coregionalize kernel documentation) + :type W_rank: integer + :param kernel_name: name of the kernel + :type kernel_name: string + """ + def __init__(self, X_list, Y_list, kernel=None, likelihoods_list=None, name='GPCR',W_rank=1,kernel_name='coreg'): + + #Input and Output + X,Y,self.output_index = util.multioutput.build_XY(X_list,Y_list) + Ny = len(Y_list) + + #Kernel + if kernel is None: + kernel = util.multioutput.ICM(input_dim=X.shape[1]-1, num_outputs=Ny, kernel=kern.RBF(X.shape[1]-1), W_rank=1,name=kernel_name) + + #Likelihood + likelihood = util.multioutput.build_likelihood(Y_list,self.output_index,likelihoods_list) + + super(GPCoregionalizedRegression, self).__init__(X,Y,kernel,likelihood, Y_metadata={'output_index':self.output_index})
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/gp_heteroscedastic_regression.html b/doc/_build/html/_modules/GPy/models/gp_heteroscedastic_regression.html new file mode 100644 index 00000000..8f305101 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/gp_heteroscedastic_regression.html @@ -0,0 +1,135 @@ + + + + + + + + GPy.models.gp_heteroscedastic_regression — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.gp_heteroscedastic_regression

+# Copyright (c) 2012 - 2014 the GPy Austhors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ..core import GP
+from .. import likelihoods
+from .. import kern
+from .. import util
+
+
[docs]class GPHeteroscedasticRegression(GP): + """ + Gaussian Process model for heteroscedastic regression + + This is a thin wrapper around the models.GP class, with a set of sensible defaults + + :param X: input observations + :param Y: observed values + :param kernel: a GPy kernel, defaults to rbf + """ + def __init__(self, X, Y, kernel=None, Y_metadata=None): + + Ny = Y.shape[0] + + if Y_metadata is None: + Y_metadata = {'output_index':np.arange(Ny)[:,None]} + else: + assert Y_metadata['output_index'].shape[0] == Ny + + if kernel is None: + kernel = kern.RBF(X.shape[1]) + + #Likelihood + #likelihoods_list = [likelihoods.Gaussian(name="Gaussian_noise_%s" %j) for j in range(Ny)] + noise_terms = np.unique(Y_metadata['output_index'].flatten()) + likelihoods_list = [likelihoods.Gaussian(name="Gaussian_noise_%s" %j) for j in noise_terms] + likelihood = likelihoods.MixedNoise(likelihoods_list=likelihoods_list) + + super(GPHeteroscedasticRegression, self).__init__(X,Y,kernel,likelihood, Y_metadata=Y_metadata) + +
[docs] def plot(self,*args): + return NotImplementedError
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/gp_kronecker_gaussian_regression.html b/doc/_build/html/_modules/GPy/models/gp_kronecker_gaussian_regression.html new file mode 100644 index 00000000..be4a2691 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/gp_kronecker_gaussian_regression.html @@ -0,0 +1,213 @@ + + + + + + + + GPy.models.gp_kronecker_gaussian_regression — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.gp_kronecker_gaussian_regression

+# Copyright (c) 2014, James Hensman, Alan Saul
+# Distributed under the terms of the GNU General public License, see LICENSE.txt
+
+import numpy as np
+from ..core.model import Model
+from ..core.parameterization import ObsAr
+from .. import likelihoods
+
+
[docs]class GPKroneckerGaussianRegression(Model): + """ + Kronecker GP regression + + Take two kernels computed on separate spaces K1(X1), K2(X2), and a data + matrix Y which is f size (N1, N2). + + The effective covaraince is np.kron(K2, K1) + The effective data is vec(Y) = Y.flatten(order='F') + + The noise must be iid Gaussian. + + See Stegle et al. + @inproceedings{stegle2011efficient, + title={Efficient inference in matrix-variate gaussian models with $\\backslash$ iid observation noise}, + author={Stegle, Oliver and Lippert, Christoph and Mooij, Joris M and Lawrence, Neil D and Borgwardt, Karsten M}, + booktitle={Advances in Neural Information Processing Systems}, + pages={630--638}, + year={2011} + } + + """ + def __init__(self, X1, X2, Y, kern1, kern2, noise_var=1., name='KGPR'): + Model.__init__(self, name=name) + # accept the construction arguments + self.X1 = ObsAr(X1) + self.X2 = ObsAr(X2) + self.Y = Y + self.kern1, self.kern2 = kern1, kern2 + self.link_parameter(self.kern1) + self.link_parameter(self.kern2) + + self.likelihood = likelihoods.Gaussian() + self.likelihood.variance = noise_var + self.link_parameter(self.likelihood) + + self.num_data1, self.input_dim1 = self.X1.shape + self.num_data2, self.input_dim2 = self.X2.shape + + assert kern1.input_dim == self.input_dim1 + assert kern2.input_dim == self.input_dim2 + assert Y.shape == (self.num_data1, self.num_data2) + +
[docs] def log_likelihood(self): + return self._log_marginal_likelihood +
+
[docs] def parameters_changed(self): + (N1, D1), (N2, D2) = self.X1.shape, self.X2.shape + K1, K2 = self.kern1.K(self.X1), self.kern2.K(self.X2) + + # eigendecompositon + S1, U1 = np.linalg.eigh(K1) + S2, U2 = np.linalg.eigh(K2) + W = np.kron(S2, S1) + self.likelihood.variance + + Y_ = U1.T.dot(self.Y).dot(U2) + + # store these quantities: needed for prediction + Wi = 1./W + Ytilde = Y_.flatten(order='F')*Wi + + self._log_marginal_likelihood = -0.5*self.num_data1*self.num_data2*np.log(2*np.pi)\ + -0.5*np.sum(np.log(W))\ + -0.5*np.dot(Y_.flatten(order='F'), Ytilde) + + # gradients for data fit part + Yt_reshaped = Ytilde.reshape(N1, N2, order='F') + tmp = U1.dot(Yt_reshaped) + dL_dK1 = .5*(tmp*S2).dot(tmp.T) + tmp = U2.dot(Yt_reshaped.T) + dL_dK2 = .5*(tmp*S1).dot(tmp.T) + + # gradients for logdet + Wi_reshaped = Wi.reshape(N1, N2, order='F') + tmp = np.dot(Wi_reshaped, S2) + dL_dK1 += -0.5*(U1*tmp).dot(U1.T) + tmp = np.dot(Wi_reshaped.T, S1) + dL_dK2 += -0.5*(U2*tmp).dot(U2.T) + + self.kern1.update_gradients_full(dL_dK1, self.X1) + self.kern2.update_gradients_full(dL_dK2, self.X2) + + # gradients for noise variance + dL_dsigma2 = -0.5*Wi.sum() + 0.5*np.sum(np.square(Ytilde)) + self.likelihood.variance.gradient = dL_dsigma2 + + # store these quantities for prediction: + self.Wi, self.Ytilde, self.U1, self.U2 = Wi, Ytilde, U1, U2 +
+
[docs] def predict(self, X1new, X2new): + """ + Return the predictive mean and variance at a series of new points X1new, X2new + Only returns the diagonal of the predictive variance, for now. + + :param X1new: The points at which to make a prediction + :type X1new: np.ndarray, Nnew x self.input_dim1 + :param X2new: The points at which to make a prediction + :type X2new: np.ndarray, Nnew x self.input_dim2 + + """ + k1xf = self.kern1.K(X1new, self.X1) + k2xf = self.kern2.K(X2new, self.X2) + A = k1xf.dot(self.U1) + B = k2xf.dot(self.U2) + mu = A.dot(self.Ytilde.reshape(self.num_data1, self.num_data2, order='F')).dot(B.T).flatten(order='F') + k1xx = self.kern1.Kdiag(X1new) + k2xx = self.kern2.Kdiag(X2new) + BA = np.kron(B, A) + var = np.kron(k2xx, k1xx) - np.sum(BA**2*self.Wi, 1) + self.likelihood.variance + + return mu[:, None], var[:, None]
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/gp_regression.html b/doc/_build/html/_modules/GPy/models/gp_regression.html new file mode 100644 index 00000000..29cb9e83 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/gp_regression.html @@ -0,0 +1,129 @@ + + + + + + + + GPy.models.gp_regression — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.gp_regression

+# Copyright (c) 2012 - 2014 the GPy Austhors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ..core import GP
+from .. import likelihoods
+from .. import kern
+
+
[docs]class GPRegression(GP): + """ + Gaussian Process model for regression + + This is a thin wrapper around the models.GP class, with a set of sensible defaults + + :param X: input observations + :param Y: observed values + :param kernel: a GPy kernel, defaults to rbf + :param Norm normalizer: [False] + + Normalize Y with the norm given. + If normalizer is False, no normalization will be done + If it is None, we use GaussianNorm(alization) + + .. Note:: Multiple independent outputs are allowed using columns of Y + + """ + + def __init__(self, X, Y, kernel=None, Y_metadata=None, normalizer=None): + + if kernel is None: + kernel = kern.RBF(X.shape[1]) + + likelihood = likelihoods.Gaussian() + + super(GPRegression, self).__init__(X, Y, kernel, likelihood, name='GP regression', Y_metadata=Y_metadata, normalizer=normalizer) +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/gp_var_gauss.html b/doc/_build/html/_modules/GPy/models/gp_var_gauss.html new file mode 100644 index 00000000..ab9df5d7 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/gp_var_gauss.html @@ -0,0 +1,202 @@ + + + + + + + + GPy.models.gp_var_gauss — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.gp_var_gauss

+# Copyright (c) 2014, James Hensman, Alan Saul
+# Distributed under the terms of the GNU General public License, see LICENSE.txt
+
+import numpy as np
+from scipy import stats
+from scipy.special import erf
+from ..core.model import Model
+from ..core.parameterization import ObsAr
+from .. import kern
+from ..core.parameterization.param import Param
+from ..util.linalg import pdinv
+
+log_2_pi = np.log(2*np.pi)
+
+
+
[docs]class GPVariationalGaussianApproximation(Model): + """ + The Variational Gaussian Approximation revisited implementation for regression + + @article{Opper:2009, + title = {The Variational Gaussian Approximation Revisited}, + author = {Opper, Manfred and Archambeau, C{\'e}dric}, + journal = {Neural Comput.}, + year = {2009}, + pages = {786--792}, + } + """ + def __init__(self, X, Y, kernel=None): + Model.__init__(self,'Variational GP classification') + # accept the construction arguments + self.X = ObsAr(X) + if kernel is None: + kernel = kern.RBF(X.shape[1]) + kern.White(X.shape[1], 0.01) + self.kern = kernel + self.link_parameter(self.kern) + self.num_data, self.input_dim = self.X.shape + + self.alpha = Param('alpha', np.zeros(self.num_data)) + self.beta = Param('beta', np.ones(self.num_data)) + self.link_parameter(self.alpha) + self.link_parameter(self.beta) + + self.gh_x, self.gh_w = np.polynomial.hermite.hermgauss(20) + self.Ysign = np.where(Y==1, 1, -1).flatten() + +
[docs] def log_likelihood(self): + """ + Marginal log likelihood evaluation + """ + return self._log_lik +
+
[docs] def likelihood_quadrature(self, m, v): + """ + Perform Gauss-Hermite quadrature over the log of the likelihood, with a fixed weight + """ + # assume probit for now. + X = self.gh_x[None, :]*np.sqrt(2.*v[:, None]) + (m*self.Ysign)[:, None] + p = stats.norm.cdf(X) + N = stats.norm.pdf(X) + F = np.log(p).dot(self.gh_w) + NoverP = N/p + dF_dm = (NoverP*self.Ysign[:,None]).dot(self.gh_w) + dF_dv = -0.5*(NoverP**2 + NoverP*X).dot(self.gh_w) + return F, dF_dm, dF_dv +
+
[docs] def parameters_changed(self): + K = self.kern.K(self.X) + m = K.dot(self.alpha) + KB = K*self.beta[:, None] + BKB = KB*self.beta[None, :] + A = np.eye(self.num_data) + BKB + Ai, LA, _, Alogdet = pdinv(A) + Sigma = np.diag(self.beta**-2) - Ai/self.beta[:, None]/self.beta[None, :] # posterior coavairance: need full matrix for gradients + var = np.diag(Sigma) + + F, dF_dm, dF_dv = self.likelihood_quadrature(m, var) + dF_da = np.dot(K, dF_dm) + SigmaB = Sigma*self.beta + dF_db = -np.diag(Sigma.dot(np.diag(dF_dv)).dot(SigmaB))*2 + KL = 0.5*(Alogdet + np.trace(Ai) - self.num_data + m.dot(self.alpha)) + dKL_da = m + A_A2 = Ai - Ai.dot(Ai) + dKL_db = np.diag(np.dot(KB.T, A_A2)) + self._log_lik = F.sum() - KL + self.alpha.gradient = dF_da - dKL_da + self.beta.gradient = dF_db - dKL_db + + # K-gradients + dKL_dK = 0.5*(self.alpha[None, :]*self.alpha[:, None] + self.beta[:, None]*self.beta[None, :]*A_A2) + tmp = Ai*self.beta[:, None]/self.beta[None, :] + dF_dK = self.alpha[:, None]*dF_dm[None, :] + np.dot(tmp*dF_dv, tmp.T) + self.kern.update_gradients_full(dF_dK - dKL_dK, self.X) +
+
[docs] def predict(self, Xnew): + """ + Predict the function(s) at the new point(s) Xnew. + + :param Xnew: The points at which to make a prediction + :type Xnew: np.ndarray, Nnew x self.input_dim + """ + Wi, _, _, _ = pdinv(self.kern.K(self.X) + np.diag(self.beta**-2)) + Kux = self.kern.K(self.X, Xnew) + mu = np.dot(Kux.T, self.alpha) + WiKux = np.dot(Wi, Kux) + Kxx = self.kern.Kdiag(Xnew) + var = Kxx - np.sum(WiKux*Kux, 0) + + return 0.5*(1+erf(mu/np.sqrt(2.*(var+1))))
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/gplvm.html b/doc/_build/html/_modules/GPy/models/gplvm.html new file mode 100644 index 00000000..1b75c64f --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/gplvm.html @@ -0,0 +1,177 @@ + + + + + + + + GPy.models.gplvm — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.gplvm

+# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from .. import kern
+from ..core import GP, Param
+from ..likelihoods import Gaussian
+from .. import util
+
+
+
[docs]class GPLVM(GP): + """ + Gaussian Process Latent Variable Model + + + """ + def __init__(self, Y, input_dim, init='PCA', X=None, kernel=None, name="gplvm"): + + """ + :param Y: observed data + :type Y: np.ndarray + :param input_dim: latent dimensionality + :type input_dim: int + :param init: initialisation method for the latent space + :type init: 'PCA'|'random' + """ + if X is None: + from ..util.initialization import initialize_latent + X, fracs = initialize_latent(init, input_dim, Y) + else: + fracs = np.ones(input_dim) + if kernel is None: + kernel = kern.RBF(input_dim, lengthscale=fracs, ARD=input_dim > 1) + kern.Bias(input_dim, np.exp(-2)) + + likelihood = Gaussian() + + super(GPLVM, self).__init__(X, Y, kernel, likelihood, name='GPLVM') + self.X = Param('latent_mean', X) + self.link_parameter(self.X, index=0) + +
[docs] def parameters_changed(self): + super(GPLVM, self).parameters_changed() + self.X.gradient = self.kern.gradients_X(self.grad_dict['dL_dK'], self.X, None) +
+
[docs] def jacobian(self,X): + J = np.zeros((X.shape[0],X.shape[1],self.output_dim)) + for i in range(self.output_dim): + J[:,:,i] = self.kern.gradients_X(self.posterior.woodbury_vector[:,i:i+1], X, self.X) + return J +
+
[docs] def magnification(self,X): + target=np.zeros(X.shape[0]) + #J = np.zeros((X.shape[0],X.shape[1],self.output_dim)) + J = self.jacobian(X) + for i in range(X.shape[0]): + target[i]=np.sqrt(np.linalg.det(np.dot(J[i,:,:],np.transpose(J[i,:,:])))) + return target +
+
[docs] def plot(self): + assert self.likelihood.Y.shape[1] == 2 + pb.scatter(self.likelihood.Y[:, 0], self.likelihood.Y[:, 1], 40, self.X[:, 0].copy(), linewidth=0, cmap=pb.cm.jet) # @UndefinedVariable + Xnew = np.linspace(self.X.min(), self.X.max(), 200)[:, None] + mu, _ = self.predict(Xnew) + import pylab as pb + pb.plot(mu[:, 0], mu[:, 1], 'k', linewidth=1.5) +
+
[docs] def plot_latent(self, labels=None, which_indices=None, + resolution=50, ax=None, marker='o', s=40, + fignum=None, legend=True, + plot_limits=None, + aspect='auto', updates=False, **kwargs): + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import dim_reduction_plots + + return dim_reduction_plots.plot_latent(self, labels, which_indices, + resolution, ax, marker, s, + fignum, False, legend, + plot_limits, aspect, updates, **kwargs) +
+
[docs] def plot_magnification(self, *args, **kwargs): + return util.plot_latent.plot_magnification(self, *args, **kwargs)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/gradient_checker.html b/doc/_build/html/_modules/GPy/models/gradient_checker.html new file mode 100644 index 00000000..e9c85ce9 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/gradient_checker.html @@ -0,0 +1,207 @@ + + + + + + + + GPy.models.gradient_checker — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.gradient_checker

+# ## Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+from ..core.model import Model
+import itertools
+import numpy
+from ..core.parameterization import Param
+
+
[docs]def get_shape(x): + if isinstance(x, numpy.ndarray): + return x.shape + return () +
+
[docs]def at_least_one_element(x): + if isinstance(x, (list, tuple)): + return x + return [x] +
+
[docs]def flatten_if_needed(x): + return numpy.atleast_1d(x).flatten() +
+
[docs]class GradientChecker(Model): + + def __init__(self, f, df, x0, names=None, *args, **kwargs): + """ + :param f: Function to check gradient for + :param df: Gradient of function to check + :param x0: + Initial guess for inputs x (if it has a shape (a,b) this will be reflected in the parameter names). + Can be a list of arrays, if takes a list of arrays. This list will be passed + to f and df in the same order as given here. + If only one argument, make sure not to pass a list!!! + + :type x0: [array-like] | array-like | float | int + :param names: + Names to print, when performing gradcheck. If a list was passed to x0 + a list of names with the same length is expected. + :param args: Arguments passed as f(x, *args, **kwargs) and df(x, *args, **kwargs) + + Examples: + --------- + from GPy.models import GradientChecker + N, M, Q = 10, 5, 3 + + Sinusoid: + + X = numpy.random.rand(N, Q) + grad = GradientChecker(numpy.sin,numpy.cos,X,'x') + grad.checkgrad(verbose=1) + + Using GPy: + + X, Z = numpy.random.randn(N,Q), numpy.random.randn(M,Q) + kern = GPy.kern.linear(Q, ARD=True) + GPy.kern.rbf(Q, ARD=True) + grad = GradientChecker(kern.K, + lambda x: 2*kern.dK_dX(numpy.ones((1,1)), x), + x0 = X.copy(), + names='X') + grad.checkgrad(verbose=1) + grad.randomize() + grad.checkgrad(verbose=1) + """ + Model.__init__(self, 'GradientChecker') + if isinstance(x0, (list, tuple)) and names is None: + self.shapes = [get_shape(xi) for xi in x0] + self.names = ['X{i}'.format(i=i) for i in range(len(x0))] + elif isinstance(x0, (list, tuple)) and names is not None: + self.shapes = [get_shape(xi) for xi in x0] + self.names = names + elif names is None: + self.names = ['X'] + self.shapes = [get_shape(x0)] + else: + self.names = names + self.shapes = [get_shape(x0)] + + for name, xi in zip(self.names, at_least_one_element(x0)): + self.__setattr__(name, Param(name, xi)) + self.link_parameter(self.__getattribute__(name)) +# self._param_names = [] +# for name, shape in zip(self.names, self.shapes): +# self._param_names.extend(map(lambda nameshape: ('_'.join(nameshape)).strip('_'), itertools.izip(itertools.repeat(name), itertools.imap(lambda t: '_'.join(map(str, t)), itertools.product(*map(lambda xi: range(xi), shape)))))) + self.args = args + self.kwargs = kwargs + self.f = f + self.df = df + + def _get_x(self): + if len(self.names) > 1: + return [self.__getattribute__(name) for name in self.names] + list(self.args) + return [self.__getattribute__(self.names[0])] + list(self.args) + +
[docs] def log_likelihood(self): + return float(numpy.sum(self.f(*self._get_x(), **self.kwargs))) +
+ def _log_likelihood_gradients(self): + return numpy.atleast_1d(self.df(*self._get_x(), **self.kwargs)).flatten() + + #def _get_params(self): + #return numpy.atleast_1d(numpy.hstack(map(lambda name: flatten_if_needed(self.__getattribute__(name)), self.names))) + + #def _set_params(self, x): + #current_index = 0 + #for name, shape in zip(self.names, self.shapes): + #current_size = numpy.prod(shape) + #self.__setattr__(name, x[current_index:current_index + current_size].reshape(shape)) + #current_index += current_size + + #def _get_param_names(self): + #_param_names = [] + #for name, shape in zip(self.names, self.shapes): + #_param_names.extend(map(lambda nameshape: ('_'.join(nameshape)).strip('_'), itertools.izip(itertools.repeat(name), itertools.imap(lambda t: '_'.join(map(str, t)), itertools.product(*map(lambda xi: range(xi), shape)))))) + #return _param_names
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/mrd.html b/doc/_build/html/_modules/GPy/models/mrd.html new file mode 100644 index 00000000..85b4ff73 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/mrd.html @@ -0,0 +1,435 @@ + + + + + + + + GPy.models.mrd — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.mrd

+# ## Copyright (c) 2013, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+import itertools, logging
+
+from ..kern import Kern
+from ..core.parameterization.variational import NormalPosterior, NormalPrior
+from ..core.parameterization import Param, Parameterized
+from ..core.parameterization.observable_array import ObsAr
+from ..inference.latent_function_inference.var_dtc import VarDTC
+from ..inference.latent_function_inference import InferenceMethodList
+from ..likelihoods import Gaussian
+from ..util.initialization import initialize_latent
+from ..core.sparse_gp import SparseGP, GP
+from GPy.core.parameterization.variational import VariationalPosterior
+from GPy.models.bayesian_gplvm_minibatch import BayesianGPLVMMiniBatch
+from GPy.models.sparse_gp_minibatch import SparseGPMiniBatch
+
+
[docs]class MRD(BayesianGPLVMMiniBatch): + """ + !WARNING: This is bleeding edge code and still in development. + Functionality may change fundamentally during development! + + Apply MRD to all given datasets Y in Ylist. + + Y_i in [n x p_i] + + If Ylist is a dictionary, the keys of the dictionary are the names, and the + values are the different datasets to compare. + + The samples n in the datasets need + to match up, whereas the dimensionality p_d can differ. + + :param [array-like] Ylist: List of datasets to apply MRD on + :param input_dim: latent dimensionality + :type input_dim: int + :param array-like X: mean of starting latent space q in [n x q] + :param array-like X_variance: variance of starting latent space q in [n x q] + :param initx: initialisation method for the latent space : + + * 'concat' - PCA on concatenation of all datasets + * 'single' - Concatenation of PCA on datasets, respectively + * 'random' - Random draw from a Normal(0,1) + + :type initx: ['concat'|'single'|'random'] + :param initz: initialisation method for inducing inputs + :type initz: 'permute'|'random' + :param num_inducing: number of inducing inputs to use + :param Z: initial inducing inputs + :param kernel: list of kernels or kernel to copy for each output + :type kernel: [GPy.kernels.kernels] | GPy.kernels.kernels | None (default) + :param :class:`~GPy.inference.latent_function_inference inference_method: + InferenceMethodList of inferences, or one inference method for all + :param :class:`~GPy.likelihoodss.likelihoods.likelihoods` likelihoods: the likelihoods to use + :param str name: the name of this model + :param [str] Ynames: the names for the datasets given, must be of equal length as Ylist or None + :param bool|Norm normalizer: How to normalize the data? + :param bool stochastic: Should this model be using stochastic gradient descent over the dimensions? + :param bool|[bool] batchsize: either one batchsize for all, or one batchsize per dataset. + """ + def __init__(self, Ylist, input_dim, X=None, X_variance=None, + initx = 'PCA', initz = 'permute', + num_inducing=10, Z=None, kernel=None, + inference_method=None, likelihoods=None, name='mrd', + Ynames=None, normalizer=False, stochastic=False, batchsize=10): + + self.logger = logging.getLogger(self.__class__.__name__) + self.input_dim = input_dim + self.num_inducing = num_inducing + + if isinstance(Ylist, dict): + Ynames, Ylist = zip(*Ylist.items()) + + self.logger.debug("creating observable arrays") + self.Ylist = [ObsAr(Y) for Y in Ylist] + + if Ynames is None: + self.logger.debug("creating Ynames") + Ynames = ['Y{}'.format(i) for i in range(len(Ylist))] + self.names = Ynames + assert len(self.names) == len(self.Ylist), "one name per dataset, or None if Ylist is a dict" + + if inference_method is None: + self.inference_method = InferenceMethodList([VarDTC() for _ in xrange(len(self.Ylist))]) + else: + assert isinstance(inference_method, InferenceMethodList), "please provide one inference method per Y in the list and provide it as InferenceMethodList, inference_method given: {}".format(inference_method) + self.inference_method = inference_method + + if X is None: + X, fracs = self._init_X(initx, Ylist) + else: + fracs = [X.var(0)]*len(Ylist) + + Z = self._init_Z(initz, X) + self.Z = Param('inducing inputs', Z) + self.num_inducing = self.Z.shape[0] # ensure M==N if M>N + + # sort out the kernels + self.logger.info("building kernels") + if kernel is None: + from ..kern import RBF + kernels = [RBF(input_dim, ARD=1, lengthscale=1./fracs[i]) for i in range(len(Ylist))] + elif isinstance(kernel, Kern): + kernels = [] + for i in range(len(Ylist)): + k = kernel.copy() + kernels.append(k) + else: + assert len(kernel) == len(Ylist), "need one kernel per output" + assert all([isinstance(k, Kern) for k in kernel]), "invalid kernel object detected!" + kernels = kernel + + if X_variance is None: + X_variance = np.random.uniform(0.1, 0.2, X.shape) + + self.variational_prior = NormalPrior() + #self.X = NormalPosterior(X, X_variance) + + if likelihoods is None: + likelihoods = [Gaussian(name='Gaussian_noise'.format(i)) for i in range(len(Ylist))] + else: likelihoods = likelihoods + + self.logger.info("adding X and Z") + super(MRD, self).__init__(Y, input_dim, X=X, X_variance=X_variance, num_inducing=num_inducing, + Z=self.Z, kernel=None, inference_method=self.inference_method, likelihood=Gaussian(), + name='manifold relevance determination', normalizer=None, + missing_data=False, stochastic=False, batchsize=1) + + self._log_marginal_likelihood = 0 + + self.unlink_parameter(self.likelihood) + self.unlink_parameter(self.kern) + del self.kern + del self.likelihood + + self.num_data = Ylist[0].shape[0] + if isinstance(batchsize, int): + batchsize = itertools.repeat(batchsize) + + self.bgplvms = [] + + for i, n, k, l, Y, im, bs in itertools.izip(itertools.count(), Ynames, kernels, likelihoods, Ylist, self.inference_method, batchsize): + assert Y.shape[0] == self.num_data, "All datasets need to share the number of datapoints, and those have to correspond to one another" + md = np.isnan(Y).any() + spgp = BayesianGPLVMMiniBatch(Y, input_dim, X, X_variance, + Z=Z, kernel=k, likelihood=l, + inference_method=im, name=n, + normalizer=normalizer, + missing_data=md, + stochastic=stochastic, + batchsize=bs) + spgp.kl_factr = 1./len(Ynames) + spgp.unlink_parameter(spgp.Z) + spgp.unlink_parameter(spgp.X) + del spgp.Z + del spgp.X + spgp.Z = self.Z + spgp.X = self.X + self.link_parameter(spgp, i+2) + self.bgplvms.append(spgp) + + self.posterior = None + self.logger.info("init done") + +
[docs] def parameters_changed(self): + self._log_marginal_likelihood = 0 + self.Z.gradient[:] = 0. + self.X.gradient[:] = 0. + for b, i in itertools.izip(self.bgplvms, self.inference_method): + self._log_marginal_likelihood += b._log_marginal_likelihood + + self.logger.info('working on im <{}>'.format(hex(id(i)))) + self.Z.gradient[:] += b.full_values['Zgrad'] + grad_dict = b.full_values + + self.X.mean.gradient += grad_dict['meangrad'] + self.X.variance.gradient += grad_dict['vargrad'] + + if isinstance(self.X, VariationalPosterior): + # update for the KL divergence + self.variational_prior.update_gradients_KL(self.X) + self._log_marginal_likelihood -= self.variational_prior.KL_divergence(self.X) + pass +
+
[docs] def log_likelihood(self): + return self._log_marginal_likelihood +
+ def _init_X(self, init='PCA', Ylist=None): + if Ylist is None: + Ylist = self.Ylist + if init in "PCA_concat": + X, fracs = initialize_latent('PCA', self.input_dim, np.hstack(Ylist)) + fracs = [fracs]*len(Ylist) + elif init in "PCA_single": + X = np.zeros((Ylist[0].shape[0], self.input_dim)) + fracs = [] + for qs, Y in itertools.izip(np.array_split(np.arange(self.input_dim), len(Ylist)), Ylist): + x,frcs = initialize_latent('PCA', len(qs), Y) + X[:, qs] = x + fracs.append(frcs) + else: # init == 'random': + X = np.random.randn(Ylist[0].shape[0], self.input_dim) + fracs = X.var(0) + fracs = [fracs]*len(Ylist) + X -= X.mean() + X /= X.std() + return X, fracs + + def _init_Z(self, init="permute", X=None): + if X is None: + X = self.X + if init in "permute": + Z = np.random.permutation(X.copy())[:self.num_inducing] + elif init in "random": + Z = np.random.randn(self.num_inducing, self.input_dim) * X.var() + return Z + + def _handle_plotting(self, fignum, axes, plotf, sharex=False, sharey=False): + import matplotlib.pyplot as plt + if axes is None: + fig = plt.figure(num=fignum) + sharex_ax = None + sharey_ax = None + plots = [] + for i, g in enumerate(self.bgplvms): + try: + if sharex: + sharex_ax = ax # @UndefinedVariable + sharex = False # dont set twice + if sharey: + sharey_ax = ax # @UndefinedVariable + sharey = False # dont set twice + except: + pass + if axes is None: + ax = fig.add_subplot(1, len(self.bgplvms), i + 1, sharex=sharex_ax, sharey=sharey_ax) + elif isinstance(axes, (tuple, list, np.ndarray)): + ax = axes[i] + else: + raise ValueError("Need one axes per latent dimension input_dim") + plots.append(plotf(i, g, ax)) + if sharey_ax is not None: + plt.setp(ax.get_yticklabels(), visible=False) + plt.draw() + if axes is None: + try: + fig.tight_layout() + except: + pass + return plots + +
[docs] def predict(self, Xnew, full_cov=False, Y_metadata=None, kern=None, Yindex=0): + """ + Prediction for data set Yindex[default=0]. + This predicts the output mean and variance for the dataset given in Ylist[Yindex] + """ + b = self.bgplvms[Yindex] + self.posterior = b.posterior + self.kern = b.kern + self.likelihood = b.likelihood + return super(MRD, self).predict(Xnew, full_cov, Y_metadata, kern) + + #=============================================================================== + # TODO: Predict! Maybe even change to several bgplvms, which share an X? + #=============================================================================== + # def plot_predict(self, fignum=None, ax=None, sharex=False, sharey=False, **kwargs): + # fig = self._handle_plotting(fignum, + # ax, + # lambda i, g, ax: ax.imshow(g.predict(g.X)[0], **kwargs), + # sharex=sharex, sharey=sharey) + # return fig +
+
[docs] def plot_scales(self, fignum=None, ax=None, titles=None, sharex=False, sharey=True, *args, **kwargs): + """ + + TODO: Explain other parameters + + :param titles: titles for axes of datasets + + """ + if titles is None: + titles = [r'${}$'.format(name) for name in self.names] + ymax = reduce(max, [np.ceil(max(g.kern.input_sensitivity())) for g in self.bgplvms]) + def plotf(i, g, ax): + #ax.set_ylim([0,ymax]) + return g.kern.plot_ARD(ax=ax, title=titles[i], *args, **kwargs) + fig = self._handle_plotting(fignum, ax, plotf, sharex=sharex, sharey=sharey) + return fig +
+
[docs] def plot_latent(self, labels=None, which_indices=None, + resolution=50, ax=None, marker='o', s=40, + fignum=None, plot_inducing=True, legend=True, + plot_limits=None, + aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={}): + """ + see plotting.matplot_dep.dim_reduction_plots.plot_latent + if predict_kwargs is None, will plot latent spaces for 0th dataset (and kernel), otherwise give + predict_kwargs=dict(Yindex='index') for plotting only the latent space of dataset with 'index'. + """ + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from matplotlib import pyplot as plt + from ..plotting.matplot_dep import dim_reduction_plots + if "Yindex" not in predict_kwargs: + predict_kwargs['Yindex'] = 0 + + Yindex = predict_kwargs['Yindex'] + if ax is None: + fig = plt.figure(num=fignum) + ax = fig.add_subplot(111) + else: + fig = ax.figure + self.kern = self.bgplvms[Yindex].kern + self.likelihood = self.bgplvms[Yindex].likelihood + plot = dim_reduction_plots.plot_latent(self, labels, which_indices, + resolution, ax, marker, s, + fignum, plot_inducing, legend, + plot_limits, aspect, updates, predict_kwargs, imshow_kwargs) + ax.set_title(self.bgplvms[Yindex].name) + try: + fig.tight_layout() + except: + pass + + return plot +
+ def __getstate__(self): + state = super(MRD, self).__getstate__() + if state.has_key('kern'): + del state['kern'] + if state.has_key('likelihood'): + del state['likelihood'] + return state + + def __setstate__(self, state): + # TODO: + super(MRD, self).__setstate__(state) + self.kern = self.bgplvms[0].kern + self.likelihood = self.bgplvms[0].likelihood + self.parameters_changed()
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/sparse_gp_classification.html b/doc/_build/html/_modules/GPy/models/sparse_gp_classification.html new file mode 100644 index 00000000..37262ad5 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/sparse_gp_classification.html @@ -0,0 +1,140 @@ + + + + + + + + GPy.models.sparse_gp_classification — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.sparse_gp_classification

+# Copyright (c) 2013, Ricardo Andrade
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from ..core import SparseGP
+from .. import likelihoods
+from .. import kern
+from ..likelihoods import likelihood
+from ..inference.latent_function_inference import expectation_propagation_dtc
+
+
[docs]class SparseGPClassification(SparseGP): + """ + sparse Gaussian Process model for classification + + This is a thin wrapper around the sparse_GP class, with a set of sensible defaults + + :param X: input observations + :param Y: observed values + :param likelihood: a GPy likelihood, defaults to Binomial with probit link_function + :param kernel: a GPy kernel, defaults to rbf+white + :param normalize_X: whether to normalize the input data before computing (predictions will be in original scales) + :type normalize_X: False|True + :param normalize_Y: whether to normalize the input data before computing (predictions will be in original scales) + :type normalize_Y: False|True + :rtype: model object + + """ + + #def __init__(self, X, Y=None, likelihood=None, kernel=None, normalize_X=False, normalize_Y=False, Z=None, num_inducing=10): + def __init__(self, X, Y=None, likelihood=None, kernel=None, Z=None, num_inducing=10, Y_metadata=None): + + + if kernel is None: + kernel = kern.RBF(X.shape[1]) + + likelihood = likelihoods.Bernoulli() + + if Z is None: + i = np.random.permutation(X.shape[0])[:num_inducing] + Z = X[i].copy() + else: + assert Z.shape[1] == X.shape[1] + + SparseGP.__init__(self, X, Y, Z, kernel, likelihood, inference_method=expectation_propagation_dtc.EPDTC(), name='SparseGPClassification',Y_metadata=Y_metadata) + #def __init__(self, X, Y, Z, kernel, likelihood, inference_method=None, name='sparse gp', Y_metadata=None):
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/sparse_gp_coregionalized_regression.html b/doc/_build/html/_modules/GPy/models/sparse_gp_coregionalized_regression.html new file mode 100644 index 00000000..c7579d41 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/sparse_gp_coregionalized_regression.html @@ -0,0 +1,160 @@ + + + + + + + + GPy.models.sparse_gp_coregionalized_regression — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.sparse_gp_coregionalized_regression

+# Copyright (c) 2012 - 2014 the GPy Austhors (see AUTHORS.txt)
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ..core import SparseGP
+from ..inference.latent_function_inference import VarDTC
+from .. import likelihoods
+from .. import kern
+from .. import util
+
+
[docs]class SparseGPCoregionalizedRegression(SparseGP): + """ + Sparse Gaussian Process model for heteroscedastic multioutput regression + + This is a thin wrapper around the SparseGP class, with a set of sensible defaults + + :param X_list: list of input observations corresponding to each output + :type X_list: list of numpy arrays + :param Y_list: list of observed values related to the different noise models + :type Y_list: list of numpy arrays + :param Z_list: list of inducing inputs (optional) + :type Z_list: empty list | list of numpy arrays + :param kernel: a GPy kernel, defaults to RBF ** Coregionalized + :type kernel: None | GPy.kernel defaults + :likelihoods_list: a list of likelihoods, defaults to list of Gaussian likelihoods + :type likelihoods_list: None | a list GPy.likelihoods + :param num_inducing: number of inducing inputs, defaults to 10 per output (ignored if Z_list is not empty) + :type num_inducing: integer | list of integers + + :param name: model name + :type name: string + :param W_rank: number tuples of the corregionalization parameters 'W' (see coregionalize kernel documentation) + :type W_rank: integer + :param kernel_name: name of the kernel + :type kernel_name: string + """ + + def __init__(self, X_list, Y_list, Z_list=[], kernel=None, likelihoods_list=None, num_inducing=10, X_variance=None, name='SGPCR',W_rank=1,kernel_name='coreg'): + + #Input and Output + X,Y,self.output_index = util.multioutput.build_XY(X_list,Y_list) + Ny = len(Y_list) + + #Kernel + if kernel is None: + kernel = util.multioutput.ICM(input_dim=X.shape[1]-1, num_outputs=Ny, kernel=kern.RBF(X.shape[1]-1), W_rank=1,name=kernel_name) + + #Likelihood + likelihood = util.multioutput.build_likelihood(Y_list,self.output_index,likelihoods_list) + + #Inducing inputs list + if len(Z_list): + assert len(Z_list) == Ny, 'Number of outputs do not match length of inducing inputs list.' + else: + if isinstance(num_inducing,np.int): + num_inducing = [num_inducing] * Ny + num_inducing = np.asarray(num_inducing) + assert num_inducing.size == Ny, 'Number of outputs do not match length of inducing inputs list.' + for ni,Xi in zip(num_inducing,X_list): + i = np.random.permutation(Xi.shape[0])[:ni] + Z_list.append(Xi[i].copy()) + + Z, _, Iz = util.multioutput.build_XY(Z_list) + + super(SparseGPCoregionalizedRegression, self).__init__(X, Y, Z, kernel, likelihood, inference_method=VarDTC(), Y_metadata={'output_index':self.output_index}) + self['.*inducing'][:,-1].fix()
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/sparse_gp_minibatch.html b/doc/_build/html/_modules/GPy/models/sparse_gp_minibatch.html new file mode 100644 index 00000000..46cf520b --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/sparse_gp_minibatch.html @@ -0,0 +1,442 @@ + + + + + + + + GPy.models.sparse_gp_minibatch — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.sparse_gp_minibatch

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from ..core.parameterization.param import Param
+from ..core.gp import GP
+from ..inference.latent_function_inference import var_dtc
+from .. import likelihoods
+from ..core.parameterization.variational import VariationalPosterior
+
+import logging
+from GPy.inference.latent_function_inference.posterior import Posterior
+from GPy.inference.optimization.stochastics import SparseGPStochastics,\
+    SparseGPMissing
+#no stochastics.py file added! from GPy.inference.optimization.stochastics import SparseGPStochastics,\
+    #SparseGPMissing
+logger = logging.getLogger("sparse gp")
+
+
[docs]class SparseGPMiniBatch(GP): + """ + A general purpose Sparse GP model +''' +Created on 3 Nov 2014 + +@author: maxz +''' + + This model allows (approximate) inference using variational DTC or FITC + (Gaussian likelihoods) as well as non-conjugate sparse methods based on + these. + + :param X: inputs + :type X: np.ndarray (num_data x input_dim) + :param likelihood: a likelihood instance, containing the observed data + :type likelihood: GPy.likelihood.(Gaussian | EP | Laplace) + :param kernel: the kernel (covariance function). See link kernels + :type kernel: a GPy.kern.kern instance + :param X_variance: The uncertainty in the measurements of X (Gaussian variance) + :type X_variance: np.ndarray (num_data x input_dim) | None + :param Z: inducing inputs + :type Z: np.ndarray (num_inducing x input_dim) + :param num_inducing: Number of inducing points (optional, default 10. Ignored if Z is not None) + :type num_inducing: int + + """ + + def __init__(self, X, Y, Z, kernel, likelihood, inference_method=None, + name='sparse gp', Y_metadata=None, normalizer=False, + missing_data=False, stochastic=False, batchsize=1): + #pick a sensible inference method + if inference_method is None: + if isinstance(likelihood, likelihoods.Gaussian): + inference_method = var_dtc.VarDTC(limit=1 if not self.missing_data else Y.shape[1]) + else: + #inference_method = ?? + raise NotImplementedError, "what to do what to do?" + print "defaulting to ", inference_method, "for latent function inference" + + self.kl_factr = 1. + self.Z = Param('inducing inputs', Z) + self.num_inducing = Z.shape[0] + + GP.__init__(self, X, Y, kernel, likelihood, inference_method=inference_method, name=name, Y_metadata=Y_metadata, normalizer=normalizer) + self.missing_data = missing_data + + if stochastic and missing_data: + self.missing_data = True + self.ninan = ~np.isnan(Y) + self.stochastics = SparseGPStochastics(self, batchsize) + elif stochastic and not missing_data: + self.missing_data = False + self.stochastics = SparseGPStochastics(self, batchsize) + elif missing_data: + self.missing_data = True + self.ninan = ~np.isnan(Y) + self.stochastics = SparseGPMissing(self) + else: + self.stochastics = False + + logger.info("Adding Z as parameter") + self.link_parameter(self.Z, index=0) + if self.missing_data: + self.Ylist = [] + overall = self.Y_normalized.shape[1] + m_f = lambda i: "Precomputing Y for missing data: {: >7.2%}".format(float(i+1)/overall) + message = m_f(-1) + print message, + for d in xrange(overall): + self.Ylist.append(self.Y_normalized[self.ninan[:, d], d][:, None]) + print ' '*(len(message)+1) + '\r', + message = m_f(d) + print message, + print '' + + self.posterior = None + +
[docs] def has_uncertain_inputs(self): + return isinstance(self.X, VariationalPosterior) +
+ def _inner_parameters_changed(self, kern, X, Z, likelihood, Y, Y_metadata, Lm=None, dL_dKmm=None, subset_indices=None): + """ + This is the standard part, which usually belongs in parameters_changed. + + For automatic handling of subsampling (such as missing_data, stochastics etc.), we need to put this into an inner + loop, in order to ensure a different handling of gradients etc of different + subsets of data. + + The dict in current_values will be passed aroung as current_values for + the rest of the algorithm, so this is the place to store current values, + such as subsets etc, if necessary. + + If Lm and dL_dKmm can be precomputed (or only need to be computed once) + pass them in here, so they will be passed to the inference_method. + + subset_indices is a dictionary of indices. you can put the indices however you + like them into this dictionary for inner use of the indices inside the + algorithm. + """ + try: + posterior, log_marginal_likelihood, grad_dict = self.inference_method.inference(kern, X, Z, likelihood, Y, Y_metadata, Lm=Lm, dL_dKmm=None) + except: + posterior, log_marginal_likelihood, grad_dict = self.inference_method.inference(kern, X, Z, likelihood, Y, Y_metadata) + current_values = {} + likelihood.update_gradients(grad_dict['dL_dthetaL']) + current_values['likgrad'] = likelihood.gradient.copy() + if subset_indices is None: + subset_indices = {} + if isinstance(X, VariationalPosterior): + #gradients wrt kernel + dL_dKmm = grad_dict['dL_dKmm'] + kern.update_gradients_full(dL_dKmm, Z, None) + current_values['kerngrad'] = kern.gradient.copy() + kern.update_gradients_expectations(variational_posterior=X, + Z=Z, + dL_dpsi0=grad_dict['dL_dpsi0'], + dL_dpsi1=grad_dict['dL_dpsi1'], + dL_dpsi2=grad_dict['dL_dpsi2']) + current_values['kerngrad'] += kern.gradient + + #gradients wrt Z + current_values['Zgrad'] = kern.gradients_X(dL_dKmm, Z) + current_values['Zgrad'] += kern.gradients_Z_expectations( + grad_dict['dL_dpsi0'], + grad_dict['dL_dpsi1'], + grad_dict['dL_dpsi2'], + Z=Z, + variational_posterior=X) + else: + #gradients wrt kernel + kern.update_gradients_diag(grad_dict['dL_dKdiag'], X) + current_values['kerngrad'] = kern.gradient.copy() + kern.update_gradients_full(grad_dict['dL_dKnm'], X, Z) + current_values['kerngrad'] += kern.gradient + kern.update_gradients_full(grad_dict['dL_dKmm'], Z, None) + current_values['kerngrad'] += kern.gradient + #gradients wrt Z + current_values['Zgrad'] = kern.gradients_X(grad_dict['dL_dKmm'], Z) + current_values['Zgrad'] += kern.gradients_X(grad_dict['dL_dKnm'].T, Z, X) + return posterior, log_marginal_likelihood, grad_dict, current_values, subset_indices + + def _inner_take_over_or_update(self, full_values=None, current_values=None, value_indices=None): + """ + This is for automatic updates of values in the inner loop of missing + data handling. Both arguments are dictionaries and the values in + full_values will be updated by the current_gradients. + + If a key from current_values does not exist in full_values, it will be + initialized to the value in current_values. + + If there is indices needed for the update, value_indices can be used for + that. If value_indices has the same key, as current_values, the update + in full_values will be indexed by the indices in value_indices. + + grads: + dictionary of standing gradients (you will have to carefully make sure, that + the ordering is right!). The values in here will be updated such that + full_values[key] += current_values[key] forall key in full_gradients.keys() + + gradients: + dictionary of gradients in the current set of parameters. + + value_indices: + dictionary holding indices for the update in full_values. + if the key exists the update rule is:def df(x): + full_values[key][value_indices[key]] += current_values[key] + """ + for key in current_values.keys(): + if value_indices is not None and value_indices.has_key(key): + index = value_indices[key] + else: + index = slice(None) + if full_values.has_key(key): + full_values[key][index] += current_values[key] + else: + full_values[key] = current_values[key] + + def _inner_values_update(self, current_values): + """ + This exists if there is more to do with the current values. + It will be called allways in the inner loop, so that + you can do additional inner updates for the inside of the missing data + loop etc. This can also be used for stochastic updates, when only working on + one dimension of the output. + """ + pass + + def _outer_values_update(self, full_values): + """ + Here you put the values, which were collected before in the right places. + E.g. set the gradients of parameters, etc. + """ + self.likelihood.gradient = full_values['likgrad'] + self.kern.gradient = full_values['kerngrad'] + self.Z.gradient = full_values['Zgrad'] + + def _outer_init_full_values(self): + """ + If full_values has indices in values_indices, we might want to initialize + the full_values differently, so that subsetting is possible. + + Here you can initialize the full_values for the values needed. + + Keep in mind, that if a key does not exist in full_values when updating + values, it will be set (so e.g. for Z there is no need to initialize Zgrad, + as there is no subsetting needed. For X in BGPLVM on the other hand we probably need + to initialize the gradients for the mean and the variance in order to + have the full gradient for indexing) + """ + return {} + + def _outer_loop_for_missing_data(self): + Lm = None + dL_dKmm = None + + self._log_marginal_likelihood = 0 + self.full_values = self._outer_init_full_values() + + if self.posterior is None: + woodbury_inv = np.zeros((self.num_inducing, self.num_inducing, self.output_dim)) + woodbury_vector = np.zeros((self.num_inducing, self.output_dim)) + else: + woodbury_inv = self.posterior._woodbury_inv + woodbury_vector = self.posterior._woodbury_vector + + if not self.stochastics: + m_f = lambda i: "Inference with missing_data: {: >7.2%}".format(float(i+1)/self.output_dim) + message = m_f(-1) + print message, + + for d in self.stochastics.d: + ninan = self.ninan[:, d] + + if not self.stochastics: + print ' '*(len(message)) + '\r', + message = m_f(d) + print message, + + posterior, log_marginal_likelihood, \ + grad_dict, current_values, value_indices = self._inner_parameters_changed( + self.kern, self.X[ninan], + self.Z, self.likelihood, + self.Ylist[d], self.Y_metadata, + Lm, dL_dKmm, + subset_indices=dict(outputs=d, samples=ninan)) + + self._inner_take_over_or_update(self.full_values, current_values, value_indices) + self._inner_values_update(current_values) + + Lm = posterior.K_chol + dL_dKmm = grad_dict['dL_dKmm'] + woodbury_inv[:, :, d] = posterior.woodbury_inv + woodbury_vector[:, d:d+1] = posterior.woodbury_vector + self._log_marginal_likelihood += log_marginal_likelihood + if not self.stochastics: + print '' + + if self.posterior is None: + self.posterior = Posterior(woodbury_inv=woodbury_inv, woodbury_vector=woodbury_vector, + K=posterior._K, mean=None, cov=None, K_chol=posterior.K_chol) + self._outer_values_update(self.full_values) + + def _outer_loop_without_missing_data(self): + self._log_marginal_likelihood = 0 + + if self.posterior is None: + woodbury_inv = np.zeros((self.num_inducing, self.num_inducing, self.output_dim)) + woodbury_vector = np.zeros((self.num_inducing, self.output_dim)) + else: + woodbury_inv = self.posterior._woodbury_inv + woodbury_vector = self.posterior._woodbury_vector + + d = self.stochastics.d + posterior, log_marginal_likelihood, \ + grad_dict, self.full_values, _ = self._inner_parameters_changed( + self.kern, self.X, + self.Z, self.likelihood, + self.Y_normalized[:, d], self.Y_metadata) + self.grad_dict = grad_dict + + self._log_marginal_likelihood += log_marginal_likelihood + + self._outer_values_update(self.full_values) + + woodbury_inv[:, :, d] = posterior.woodbury_inv[:, :, None] + woodbury_vector[:, d] = posterior.woodbury_vector + if self.posterior is None: + self.posterior = Posterior(woodbury_inv=woodbury_inv, woodbury_vector=woodbury_vector, + K=posterior._K, mean=None, cov=None, K_chol=posterior.K_chol) + +
[docs] def parameters_changed(self): + if self.missing_data: + self._outer_loop_for_missing_data() + elif self.stochastics: + self._outer_loop_without_missing_data() + else: + self.posterior, self._log_marginal_likelihood, self.grad_dict, self.full_values, _ = self._inner_parameters_changed(self.kern, self.X, self.Z, self.likelihood, self.Y_normalized, self.Y_metadata) + self._outer_values_update(self.full_values) +
+ def _raw_predict(self, Xnew, full_cov=False, kern=None): + """ + Make a prediction for the latent function values + """ + + if kern is None: kern = self.kern + + if not isinstance(Xnew, VariationalPosterior): + Kx = kern.K(self.Z, Xnew) + mu = np.dot(Kx.T, self.posterior.woodbury_vector) + if full_cov: + Kxx = kern.K(Xnew) + if self.posterior.woodbury_inv.ndim == 2: + var = Kxx - np.dot(Kx.T, np.dot(self.posterior.woodbury_inv, Kx)) + elif self.posterior.woodbury_inv.ndim == 3: + var = Kxx[:,:,None] - np.tensordot(np.dot(np.atleast_3d(self.posterior.woodbury_inv).T, Kx).T, Kx, [1,0]).swapaxes(1,2) + var = var + else: + Kxx = kern.Kdiag(Xnew) + var = (Kxx - np.sum(np.dot(np.atleast_3d(self.posterior.woodbury_inv).T, Kx) * Kx[None,:,:], 1)).T + else: + Kx = kern.psi1(self.Z, Xnew) + mu = np.dot(Kx, self.posterior.woodbury_vector) + if full_cov: + raise NotImplementedError, "TODO" + else: + Kxx = kern.psi0(self.Z, Xnew) + psi2 = kern.psi2(self.Z, Xnew) + var = Kxx - np.sum(np.sum(psi2 * Kmmi_LmiBLmi[None, :, :], 1), 1) + return mu, var
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/sparse_gp_regression.html b/doc/_build/html/_modules/GPy/models/sparse_gp_regression.html new file mode 100644 index 00000000..7d0ad0b1 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/sparse_gp_regression.html @@ -0,0 +1,203 @@ + + + + + + + + GPy.models.sparse_gp_regression — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.sparse_gp_regression

+# Copyright (c) 2012, James Hensman
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from ..core import SparseGP
+from ..core.sparse_gp_mpi import SparseGP_MPI
+from .. import likelihoods
+from .. import kern
+from ..inference.latent_function_inference import VarDTC
+from ..core.parameterization.variational import NormalPosterior
+from GPy.inference.latent_function_inference.var_dtc_parallel import VarDTC_minibatch
+
+
[docs]class SparseGPRegression(SparseGP_MPI): + """ + Gaussian Process model for regression + + This is a thin wrapper around the SparseGP class, with a set of sensible defalts + + :param X: input observations + :param Y: observed values + :param kernel: a GPy kernel, defaults to rbf+white + :param Z: inducing inputs (optional, see note) + :type Z: np.ndarray (num_inducing x input_dim) | None + :param num_inducing: number of inducing points (ignored if Z is passed, see note) + :type num_inducing: int + :rtype: model object + + .. Note:: If no Z array is passed, num_inducing (default 10) points are selected from the data. Other wise num_inducing is ignored + .. Note:: Multiple independent outputs are allowed using columns of Y + + """ + + def __init__(self, X, Y, kernel=None, Z=None, num_inducing=10, X_variance=None, normalizer=None, mpi_comm=None): + num_data, input_dim = X.shape + + # kern defaults to rbf (plus white for stability) + if kernel is None: + kernel = kern.RBF(input_dim)# + kern.white(input_dim, variance=1e-3) + + # Z defaults to a subset of the data + if Z is None: + i = np.random.permutation(num_data)[:min(num_inducing, num_data)] + Z = X.view(np.ndarray)[i].copy() + else: + assert Z.shape[1] == input_dim + + likelihood = likelihoods.Gaussian() + + if not (X_variance is None): + X = NormalPosterior(X,X_variance) + + if mpi_comm is not None: + from ..inference.latent_function_inference.var_dtc_parallel import VarDTC_minibatch + infr = VarDTC_minibatch(mpi_comm=mpi_comm) + else: + infr = VarDTC() + + SparseGP_MPI.__init__(self, X, Y, Z, kernel, likelihood, inference_method=infr, normalizer=normalizer, mpi_comm=mpi_comm) + +
[docs] def parameters_changed(self): + from ..inference.latent_function_inference.var_dtc_parallel import update_gradients_sparsegp,VarDTC_minibatch + if isinstance(self.inference_method,VarDTC_minibatch): + update_gradients_sparsegp(self, mpi_comm=self.mpi_comm) + else: + super(SparseGPRegression, self).parameters_changed() +
+
[docs]class SparseGPRegressionUncertainInput(SparseGP): + """ + Gaussian Process model for regression with Gaussian variance on the inputs (X_variance) + + This is a thin wrapper around the SparseGP class, with a set of sensible defalts + + """ + + def __init__(self, X, X_variance, Y, kernel=None, Z=None, num_inducing=10, normalizer=None): + """ + :param X: input observations + :type X: np.ndarray (num_data x input_dim) + :param X_variance: The uncertainty in the measurements of X (Gaussian variance, optional) + :type X_variance: np.ndarray (num_data x input_dim) + :param Y: observed values + :param kernel: a GPy kernel, defaults to rbf+white + :param Z: inducing inputs (optional, see note) + :type Z: np.ndarray (num_inducing x input_dim) | None + :param num_inducing: number of inducing points (ignored if Z is passed, see note) + :type num_inducing: int + :rtype: model object + + .. Note:: If no Z array is passed, num_inducing (default 10) points are selected from the data. Other wise num_inducing is ignored + .. Note:: Multiple independent outputs are allowed using columns of Y + """ + num_data, input_dim = X.shape + + # kern defaults to rbf (plus white for stability) + if kernel is None: + kernel = kern.RBF(input_dim) + kern.White(input_dim, variance=1e-3) + + # Z defaults to a subset of the data + if Z is None: + i = np.random.permutation(num_data)[:min(num_inducing, num_data)] + Z = X[i].copy() + else: + assert Z.shape[1] == input_dim + + likelihood = likelihoods.Gaussian() + + SparseGP.__init__(self, X, Y, Z, kernel, likelihood, X_variance=X_variance, inference_method=VarDTC(), normalizer=normalizer) + self.ensure_default_constraints()
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/sparse_gplvm.html b/doc/_build/html/_modules/GPy/models/sparse_gplvm.html new file mode 100644 index 00000000..9ff3ab1e --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/sparse_gplvm.html @@ -0,0 +1,137 @@ + + + + + + + + GPy.models.sparse_gplvm — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.sparse_gplvm

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+import sys
+from GPy.models.sparse_gp_regression import SparseGPRegression
+
+
[docs]class SparseGPLVM(SparseGPRegression): + """ + Sparse Gaussian Process Latent Variable Model + + :param Y: observed data + :type Y: np.ndarray + :param input_dim: latent dimensionality + :type input_dim: int + :param init: initialisation method for the latent space + :type init: 'PCA'|'random' + + """ + def __init__(self, Y, input_dim, X=None, kernel=None, init='PCA', num_inducing=10): + if X is None: + from ..util.initialization import initialize_latent + X, fracs = initialize_latent(init, input_dim, Y) + SparseGPRegression.__init__(self, X, Y, kernel=kernel, num_inducing=num_inducing) + +
[docs] def parameters_changed(self): + super(SparseGPLVM, self).parameters_changed() + self.X.gradient = self.kern.gradients_X_diag(self.grad_dict['dL_dKdiag'], self.X) + self.X.gradient += self.kern.gradients_X(self.grad_dict['dL_dKnm'], self.X, self.Z) +
+
[docs] def plot_latent(self, labels=None, which_indices=None, + resolution=50, ax=None, marker='o', s=40, + fignum=None, plot_inducing=True, legend=True, + plot_limits=None, + aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={}): + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import dim_reduction_plots + + return dim_reduction_plots.plot_latent(self, labels, which_indices, + resolution, ax, marker, s, + fignum, plot_inducing, legend, + plot_limits, aspect, updates, predict_kwargs, imshow_kwargs)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/ss_gplvm.html b/doc/_build/html/_modules/GPy/models/ss_gplvm.html new file mode 100644 index 00000000..2786cc30 --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/ss_gplvm.html @@ -0,0 +1,201 @@ + + + + + + + + GPy.models.ss_gplvm — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.ss_gplvm

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+
+from ..core.sparse_gp_mpi import SparseGP_MPI
+from .. import kern
+from ..likelihoods import Gaussian
+from ..core.parameterization.variational import SpikeAndSlabPrior, SpikeAndSlabPosterior
+from ..inference.latent_function_inference.var_dtc_parallel import update_gradients, VarDTC_minibatch
+from ..kern._src.psi_comp.ssrbf_psi_gpucomp import PSICOMP_SSRBF_GPU
+
+
[docs]class SSGPLVM(SparseGP_MPI): + """ + Spike-and-Slab Gaussian Process Latent Variable Model + + :param Y: observed data (np.ndarray) or GPy.likelihood + :type Y: np.ndarray| GPy.likelihood instance + :param input_dim: latent dimensionality + :type input_dim: int + :param init: initialisation method for the latent space + :type init: 'PCA'|'random' + + """ + def __init__(self, Y, input_dim, X=None, X_variance=None, Gamma=None, init='PCA', num_inducing=10, + Z=None, kernel=None, inference_method=None, likelihood=None, name='Spike_and_Slab GPLVM', group_spike=False, mpi_comm=None, pi=None, learnPi=True,normalizer=False, **kwargs): + + self.group_spike = group_spike + + if X == None: + from ..util.initialization import initialize_latent + X, fracs = initialize_latent(init, input_dim, Y) + else: + fracs = np.ones(input_dim) + + self.init = init + + if X_variance is None: # The variance of the variational approximation (S) + X_variance = np.random.uniform(0,.1,X.shape) + + if Gamma is None: + gamma = np.random.randn(X.shape[0], input_dim) + else: + gamma = Gamma.copy() + + if Z is None: + Z = np.random.permutation(X.copy())[:num_inducing] + assert Z.shape[1] == X.shape[1] + + if likelihood is None: + likelihood = Gaussian() + + if kernel is None: + kernel = kern.RBF(input_dim, lengthscale=fracs, ARD=True) # + kern.white(input_dim) + if kernel.useGPU: + kernel.psicomp = PSICOMP_SSRBF_GPU() + + if inference_method is None: + inference_method = VarDTC_minibatch(mpi_comm=mpi_comm) + + if pi is None: + pi = np.empty((input_dim)) + pi[:] = 0.5 + self.variational_prior = SpikeAndSlabPrior(pi=pi,learnPi=learnPi) # the prior probability of the latent binary variable b + + X = SpikeAndSlabPosterior(X, X_variance, gamma) + + super(SSGPLVM,self).__init__(X, Y, Z, kernel, likelihood, variational_prior=self.variational_prior, inference_method=inference_method, name=name, mpi_comm=mpi_comm, normalizer=normalizer, **kwargs) +# self.X.unfix() +# self.X.variance.constrain_positive() + self.link_parameter(self.X, index=0) + + if self.group_spike: + [self.X.gamma[:,i].tie('tieGamma'+str(i)) for i in xrange(self.X.gamma.shape[1])] # Tie columns together + +
[docs] def set_X_gradients(self, X, X_grad): + """Set the gradients of the posterior distribution of X in its specific form.""" + X.mean.gradient, X.variance.gradient, X.binary_prob.gradient = X_grad +
+
[docs] def get_X_gradients(self, X): + """Get the gradients of the posterior distribution of X in its specific form.""" + return X.mean.gradient, X.variance.gradient, X.binary_prob.gradient +
+
[docs] def parameters_changed(self): + super(SSGPLVM,self).parameters_changed() + if isinstance(self.inference_method, VarDTC_minibatch): + return + + self._log_marginal_likelihood -= self.variational_prior.KL_divergence(self.X) + + self.X.mean.gradient, self.X.variance.gradient, self.X.binary_prob.gradient = self.kern.gradients_qX_expectations(variational_posterior=self.X, Z=self.Z, dL_dpsi0=self.grad_dict['dL_dpsi0'], dL_dpsi1=self.grad_dict['dL_dpsi1'], dL_dpsi2=self.grad_dict['dL_dpsi2']) + + # update for the KL divergence + self.variational_prior.update_gradients_KL(self.X) +
+
[docs] def input_sensitivity(self): + if self.kern.ARD: + return self.kern.input_sensitivity() + else: + return self.variational_prior.pi +
+
[docs] def plot_latent(self, plot_inducing=True, *args, **kwargs): + import sys + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import dim_reduction_plots + + return dim_reduction_plots.plot_latent(self, plot_inducing=plot_inducing, *args, **kwargs) +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/ss_mrd.html b/doc/_build/html/_modules/GPy/models/ss_mrd.html new file mode 100644 index 00000000..ba2ea53c --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/ss_mrd.html @@ -0,0 +1,128 @@ + + + + + + + + GPy.models.ss_mrd — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.ss_mrd

+"""
+The Maniforld Relevance Determination model with the spike-and-slab prior
+"""
+
+from ..core import Model
+from .ss_gplvm import SSGPLVM
+
+
[docs]class SSMRD(Model): + + def __init__(self, Ylist, input_dim, X=None, X_variance=None, + initx = 'PCA', initz = 'permute', + num_inducing=10, Z=None, kernel=None, + inference_method=None, likelihoods=None, name='ss_mrd', Ynames=None): + super(SSMRD, self).__init__(name) + + self.updates = False + self.models = [SSGPLVM(y, input_dim, X=X, X_variance=X_variance, num_inducing=num_inducing,Z=Z,init=initx, + kernel=kernel.copy() if kernel else None,inference_method=inference_method,likelihood=likelihoods, + name='model_'+str(i)) for i,y in enumerate(Ylist)] + self.add_parameters(*(self.models)) + + [[[self.models[m].X.mean[i,j:j+1].tie('mean_'+str(i)+'_'+str(j)) for m in xrange(len(self.models))] for j in xrange(self.models[0].X.mean.shape[1])] + for i in xrange(self.models[0].X.mean.shape[0])] + [[[self.models[m].X.variance[i,j:j+1].tie('var_'+str(i)+'_'+str(j)) for m in xrange(len(self.models))] for j in xrange(self.models[0].X.variance.shape[1])] + for i in xrange(self.models[0].X.variance.shape[0])] + + self.updates = True + +
[docs] def parameters_changed(self): + super(SSMRD, self).parameters_changed() + self._log_marginal_likelihood = sum([m._log_marginal_likelihood for m in self.models]) +
+
[docs] def log_likelihood(self): + return self._log_marginal_likelihood
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/models/warped_gp.html b/doc/_build/html/_modules/GPy/models/warped_gp.html new file mode 100644 index 00000000..9bc2d93b --- /dev/null +++ b/doc/_build/html/_modules/GPy/models/warped_gp.html @@ -0,0 +1,193 @@ + + + + + + + + GPy.models.warped_gp — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.models.warped_gp

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+from ..util.warping_functions import *
+from ..core import GP
+from .. import likelihoods
+from GPy.util.warping_functions import TanhWarpingFunction_d
+from GPy import kern
+
+
[docs]class WarpedGP(GP): + def __init__(self, X, Y, kernel=None, warping_function=None, warping_terms=3, normalize_X=False, normalize_Y=False): + + if kernel is None: + kernel = kern.rbf(X.shape[1]) + + if warping_function == None: + self.warping_function = TanhWarpingFunction_d(warping_terms) + self.warping_params = (np.random.randn(self.warping_function.n_terms * 3 + 1,) * 1) + + self.scale_data = False + if self.scale_data: + Y = self._scale_data(Y) + self.has_uncertain_inputs = False + self.Y_untransformed = Y.copy() + self.predict_in_warped_space = False + likelihood = likelihoods.Gaussian(self.transform_data(), normalize=normalize_Y) + + GP.__init__(self, X, likelihood, kernel, normalize_X=normalize_X) + self._set_params(self._get_params()) + + def _scale_data(self, Y): + self._Ymax = Y.max() + self._Ymin = Y.min() + return (Y - self._Ymin) / (self._Ymax - self._Ymin) - 0.5 + + def _unscale_data(self, Y): + return (Y + 0.5) * (self._Ymax - self._Ymin) + self._Ymin + + def _set_params(self, x): + self.warping_params = x[:self.warping_function.num_parameters] + Y = self.transform_data() + self.likelihood.set_data(Y) + GP._set_params(self, x[self.warping_function.num_parameters:].copy()) + + def _get_params(self): + return np.hstack((self.warping_params.flatten().copy(), GP._get_params(self).copy())) + + def _get_param_names(self): + warping_names = self.warping_function._get_param_names() + param_names = GP._get_param_names(self) + return warping_names + param_names + +
[docs] def transform_data(self): + Y = self.warping_function.f(self.Y_untransformed.copy(), self.warping_params).copy() + return Y +
+
[docs] def log_likelihood(self): + ll = GP.log_likelihood(self) + jacobian = self.warping_function.fgrad_y(self.Y_untransformed, self.warping_params) + return ll + np.log(jacobian).sum() +
+ def _log_likelihood_gradients(self): + ll_grads = GP._log_likelihood_gradients(self) + alpha = np.dot(self.Ki, self.likelihood.Y.flatten()) + warping_grads = self.warping_function_gradients(alpha) + + warping_grads = np.append(warping_grads[:, :-1].flatten(), warping_grads[0, -1]) + return np.hstack((warping_grads.flatten(), ll_grads.flatten())) + +
[docs] def warping_function_gradients(self, Kiy): + grad_y = self.warping_function.fgrad_y(self.Y_untransformed, self.warping_params) + grad_y_psi, grad_psi = self.warping_function.fgrad_y_psi(self.Y_untransformed, self.warping_params, + return_covar_chain=True) + djac_dpsi = ((1.0 / grad_y[:, :, None, None]) * grad_y_psi).sum(axis=0).sum(axis=0) + dquad_dpsi = (Kiy[:, None, None, None] * grad_psi).sum(axis=0).sum(axis=0) + + return -dquad_dpsi + djac_dpsi +
+
[docs] def plot_warping(self): + self.warping_function.plot(self.warping_params, self.Y_untransformed.min(), self.Y_untransformed.max()) +
+
[docs] def predict(self, Xnew, which_parts='all', full_cov=False, pred_init=None): + # normalize X values + Xnew = (Xnew.copy() - self._Xoffset) / self._Xscale + mu, var = GP._raw_predict(self, Xnew, full_cov=full_cov, which_parts=which_parts) + + # now push through likelihood + mean, var, _025pm, _975pm = self.likelihood.predictive_values(mu, var, full_cov) + + if self.predict_in_warped_space: + mean = self.warping_function.f_inv(mean, self.warping_params, y=pred_init) + var = self.warping_function.f_inv(var, self.warping_params) + + if self.scale_data: + mean = self._unscale_data(mean) + + return mean, var, _025pm, _975pm
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/Tango.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/Tango.html new file mode 100644 index 00000000..af3463d5 --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/Tango.html @@ -0,0 +1,260 @@ + + + + + + + + GPy.plotting.matplot_dep.Tango — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.Tango

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import matplotlib as mpl
+import pylab as pb
+import sys
+#sys.path.append('/home/james/mlprojects/sitran_cluster/')
+#from switch_pylab_backend import *
+
+
+#this stuff isn;t really Tango related: maybe it could be moved out? TODO
+
[docs]def removeRightTicks(ax=None): + ax = ax or pb.gca() + for i, line in enumerate(ax.get_yticklines()): + if i%2 == 1: # odd indices + line.set_visible(False)
+
[docs]def removeUpperTicks(ax=None): + ax = ax or pb.gca() + for i, line in enumerate(ax.get_xticklines()): + if i%2 == 1: # odd indices + line.set_visible(False)
+
[docs]def fewerXticks(ax=None,divideby=2): + ax = ax or pb.gca() + ax.set_xticks(ax.get_xticks()[::divideby]) + +
+colorsHex = {\ +"Aluminium6":"#2e3436",\ +"Aluminium5":"#555753",\ +"Aluminium4":"#888a85",\ +"Aluminium3":"#babdb6",\ +"Aluminium2":"#d3d7cf",\ +"Aluminium1":"#eeeeec",\ +"lightPurple":"#ad7fa8",\ +"mediumPurple":"#75507b",\ +"darkPurple":"#5c3566",\ +"lightBlue":"#729fcf",\ +"mediumBlue":"#3465a4",\ +"darkBlue": "#204a87",\ +"lightGreen":"#8ae234",\ +"mediumGreen":"#73d216",\ +"darkGreen":"#4e9a06",\ +"lightChocolate":"#e9b96e",\ +"mediumChocolate":"#c17d11",\ +"darkChocolate":"#8f5902",\ +"lightRed":"#ef2929",\ +"mediumRed":"#cc0000",\ +"darkRed":"#a40000",\ +"lightOrange":"#fcaf3e",\ +"mediumOrange":"#f57900",\ +"darkOrange":"#ce5c00",\ +"lightButter":"#fce94f",\ +"mediumButter":"#edd400",\ +"darkButter":"#c4a000"} + +darkList = [colorsHex['darkBlue'],colorsHex['darkRed'],colorsHex['darkGreen'], colorsHex['darkOrange'], colorsHex['darkButter'], colorsHex['darkPurple'], colorsHex['darkChocolate'], colorsHex['Aluminium6']] +mediumList = [colorsHex['mediumBlue'], colorsHex['mediumRed'],colorsHex['mediumGreen'], colorsHex['mediumOrange'], colorsHex['mediumButter'], colorsHex['mediumPurple'], colorsHex['mediumChocolate'], colorsHex['Aluminium5']] +lightList = [colorsHex['lightBlue'], colorsHex['lightRed'],colorsHex['lightGreen'], colorsHex['lightOrange'], colorsHex['lightButter'], colorsHex['lightPurple'], colorsHex['lightChocolate'], colorsHex['Aluminium4']] + +
[docs]def currentDark(): + return darkList[-1]
+
[docs]def currentMedium(): + return mediumList[-1]
+
[docs]def currentLight(): + return lightList[-1] +
+
[docs]def nextDark(): + darkList.append(darkList.pop(0)) + return darkList[-1]
+
[docs]def nextMedium(): + mediumList.append(mediumList.pop(0)) + return mediumList[-1]
+
[docs]def nextLight(): + lightList.append(lightList.pop(0)) + return lightList[-1] +
+
[docs]def reset(): + while not darkList[0]==colorsHex['darkBlue']: + darkList.append(darkList.pop(0)) + while not mediumList[0]==colorsHex['mediumBlue']: + mediumList.append(mediumList.pop(0)) + while not lightList[0]==colorsHex['lightBlue']: + lightList.append(lightList.pop(0)) +
+
[docs]def setLightFigures(): + mpl.rcParams['axes.edgecolor']=colorsHex['Aluminium6'] + mpl.rcParams['axes.facecolor']=colorsHex['Aluminium2'] + mpl.rcParams['axes.labelcolor']=colorsHex['Aluminium6'] + mpl.rcParams['figure.edgecolor']=colorsHex['Aluminium6'] + mpl.rcParams['figure.facecolor']=colorsHex['Aluminium2'] + mpl.rcParams['grid.color']=colorsHex['Aluminium6'] + mpl.rcParams['savefig.edgecolor']=colorsHex['Aluminium2'] + mpl.rcParams['savefig.facecolor']=colorsHex['Aluminium2'] + mpl.rcParams['text.color']=colorsHex['Aluminium6'] + mpl.rcParams['xtick.color']=colorsHex['Aluminium6'] + mpl.rcParams['ytick.color']=colorsHex['Aluminium6'] +
+
[docs]def setDarkFigures(): + mpl.rcParams['axes.edgecolor']=colorsHex['Aluminium2'] + mpl.rcParams['axes.facecolor']=colorsHex['Aluminium6'] + mpl.rcParams['axes.labelcolor']=colorsHex['Aluminium2'] + mpl.rcParams['figure.edgecolor']=colorsHex['Aluminium2'] + mpl.rcParams['figure.facecolor']=colorsHex['Aluminium6'] + mpl.rcParams['grid.color']=colorsHex['Aluminium2'] + mpl.rcParams['savefig.edgecolor']=colorsHex['Aluminium6'] + mpl.rcParams['savefig.facecolor']=colorsHex['Aluminium6'] + mpl.rcParams['text.color']=colorsHex['Aluminium2'] + mpl.rcParams['xtick.color']=colorsHex['Aluminium2'] + mpl.rcParams['ytick.color']=colorsHex['Aluminium2'] +
+
[docs]def hex2rgb(hexcolor): + hexcolor = [hexcolor[1+2*i:1+2*(i+1)] for i in range(3)] + r,g,b = [int(n,16) for n in hexcolor] + return (r,g,b) +
+colorsRGB = dict([(k,hex2rgb(i)) for k,i in colorsHex.items()]) + +cdict_RB = {'red' :((0.,colorsRGB['mediumRed'][0]/256.,colorsRGB['mediumRed'][0]/256.), + (.5,colorsRGB['mediumPurple'][0]/256.,colorsRGB['mediumPurple'][0]/256.), + (1.,colorsRGB['mediumBlue'][0]/256.,colorsRGB['mediumBlue'][0]/256.)), + 'green':((0.,colorsRGB['mediumRed'][1]/256.,colorsRGB['mediumRed'][1]/256.), + (.5,colorsRGB['mediumPurple'][1]/256.,colorsRGB['mediumPurple'][1]/256.), + (1.,colorsRGB['mediumBlue'][1]/256.,colorsRGB['mediumBlue'][1]/256.)), + 'blue':((0.,colorsRGB['mediumRed'][2]/256.,colorsRGB['mediumRed'][2]/256.), + (.5,colorsRGB['mediumPurple'][2]/256.,colorsRGB['mediumPurple'][2]/256.), + (1.,colorsRGB['mediumBlue'][2]/256.,colorsRGB['mediumBlue'][2]/256.))} + +cdict_BGR = {'red' :((0.,colorsRGB['mediumBlue'][0]/256.,colorsRGB['mediumBlue'][0]/256.), + (.5,colorsRGB['mediumGreen'][0]/256.,colorsRGB['mediumGreen'][0]/256.), + (1.,colorsRGB['mediumRed'][0]/256.,colorsRGB['mediumRed'][0]/256.)), + 'green':((0.,colorsRGB['mediumBlue'][1]/256.,colorsRGB['mediumBlue'][1]/256.), + (.5,colorsRGB['mediumGreen'][1]/256.,colorsRGB['mediumGreen'][1]/256.), + (1.,colorsRGB['mediumRed'][1]/256.,colorsRGB['mediumRed'][1]/256.)), + 'blue':((0.,colorsRGB['mediumBlue'][2]/256.,colorsRGB['mediumBlue'][2]/256.), + (.5,colorsRGB['mediumGreen'][2]/256.,colorsRGB['mediumGreen'][2]/256.), + (1.,colorsRGB['mediumRed'][2]/256.,colorsRGB['mediumRed'][2]/256.))} + + +cdict_Alu = {'red' :((0./5,colorsRGB['Aluminium1'][0]/256.,colorsRGB['Aluminium1'][0]/256.), + (1./5,colorsRGB['Aluminium2'][0]/256.,colorsRGB['Aluminium2'][0]/256.), + (2./5,colorsRGB['Aluminium3'][0]/256.,colorsRGB['Aluminium3'][0]/256.), + (3./5,colorsRGB['Aluminium4'][0]/256.,colorsRGB['Aluminium4'][0]/256.), + (4./5,colorsRGB['Aluminium5'][0]/256.,colorsRGB['Aluminium5'][0]/256.), + (5./5,colorsRGB['Aluminium6'][0]/256.,colorsRGB['Aluminium6'][0]/256.)), + 'green' :((0./5,colorsRGB['Aluminium1'][1]/256.,colorsRGB['Aluminium1'][1]/256.), + (1./5,colorsRGB['Aluminium2'][1]/256.,colorsRGB['Aluminium2'][1]/256.), + (2./5,colorsRGB['Aluminium3'][1]/256.,colorsRGB['Aluminium3'][1]/256.), + (3./5,colorsRGB['Aluminium4'][1]/256.,colorsRGB['Aluminium4'][1]/256.), + (4./5,colorsRGB['Aluminium5'][1]/256.,colorsRGB['Aluminium5'][1]/256.), + (5./5,colorsRGB['Aluminium6'][1]/256.,colorsRGB['Aluminium6'][1]/256.)), + 'blue' :((0./5,colorsRGB['Aluminium1'][2]/256.,colorsRGB['Aluminium1'][2]/256.), + (1./5,colorsRGB['Aluminium2'][2]/256.,colorsRGB['Aluminium2'][2]/256.), + (2./5,colorsRGB['Aluminium3'][2]/256.,colorsRGB['Aluminium3'][2]/256.), + (3./5,colorsRGB['Aluminium4'][2]/256.,colorsRGB['Aluminium4'][2]/256.), + (4./5,colorsRGB['Aluminium5'][2]/256.,colorsRGB['Aluminium5'][2]/256.), + (5./5,colorsRGB['Aluminium6'][2]/256.,colorsRGB['Aluminium6'][2]/256.))} +# cmap_Alu = mpl.colors.LinearSegmentedColormap('TangoAluminium',cdict_Alu,256) +# cmap_BGR = mpl.colors.LinearSegmentedColormap('TangoRedBlue',cdict_BGR,256) +# cmap_RB = mpl.colors.LinearSegmentedColormap('TangoRedBlue',cdict_RB,256) +if __name__=='__main__': + import pylab as pb + pb.figure() + pb.pcolor(pb.rand(10,10),cmap=cmap_RB) + pb.colorbar() + pb.show() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/base_plots.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/base_plots.html new file mode 100644 index 00000000..81853a27 --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/base_plots.html @@ -0,0 +1,251 @@ + + + + + + + + GPy.plotting.matplot_dep.base_plots — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.base_plots

+# #Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+try:
+    import Tango
+    import pylab as pb
+except:
+    pass
+import numpy as np
+
+
[docs]def ax_default(fignum, ax): + if ax is None: + fig = pb.figure(fignum) + ax = fig.add_subplot(111) + else: + fig = ax.figure + return fig, ax +
+
[docs]def meanplot(x, mu, color=Tango.colorsHex['darkBlue'], ax=None, fignum=None, linewidth=2,**kw): + _, axes = ax_default(fignum, ax) + return axes.plot(x,mu,color=color,linewidth=linewidth,**kw) +
+
[docs]def gpplot(x, mu, lower, upper, edgecol=Tango.colorsHex['darkBlue'], fillcol=Tango.colorsHex['lightBlue'], ax=None, fignum=None, **kwargs): + _, axes = ax_default(fignum, ax) + + mu = mu.flatten() + x = x.flatten() + lower = lower.flatten() + upper = upper.flatten() + + plots = [] + + #here's the mean + plots.append(meanplot(x, mu, edgecol, axes)) + + #here's the box + kwargs['linewidth']=0.5 + if not 'alpha' in kwargs.keys(): + kwargs['alpha'] = 0.3 + plots.append(axes.fill(np.hstack((x,x[::-1])),np.hstack((upper,lower[::-1])),color=fillcol,**kwargs)) + + #this is the edge: + plots.append(meanplot(x, upper,color=edgecol,linewidth=0.2,ax=axes)) + plots.append(meanplot(x, lower,color=edgecol,linewidth=0.2,ax=axes)) + + return plots + +
+
[docs]def removeRightTicks(ax=None): + ax = ax or pb.gca() + for i, line in enumerate(ax.get_yticklines()): + if i%2 == 1: # odd indices + line.set_visible(False) +
+
[docs]def removeUpperTicks(ax=None): + ax = ax or pb.gca() + for i, line in enumerate(ax.get_xticklines()): + if i%2 == 1: # odd indices + line.set_visible(False) +
+
[docs]def fewerXticks(ax=None,divideby=2): + ax = ax or pb.gca() + ax.set_xticks(ax.get_xticks()[::divideby]) +
+
[docs]def align_subplots(N,M,xlim=None, ylim=None): + """make all of the subplots have the same limits, turn off unnecessary ticks""" + #find sensible xlim,ylim + if xlim is None: + xlim = [np.inf,-np.inf] + for i in range(N*M): + pb.subplot(N,M,i+1) + xlim[0] = min(xlim[0],pb.xlim()[0]) + xlim[1] = max(xlim[1],pb.xlim()[1]) + if ylim is None: + ylim = [np.inf,-np.inf] + for i in range(N*M): + pb.subplot(N,M,i+1) + ylim[0] = min(ylim[0],pb.ylim()[0]) + ylim[1] = max(ylim[1],pb.ylim()[1]) + + for i in range(N*M): + pb.subplot(N,M,i+1) + pb.xlim(xlim) + pb.ylim(ylim) + if (i)%M: + pb.yticks([]) + else: + removeRightTicks() + if i<(M*(N-1)): + pb.xticks([]) + else: + removeUpperTicks() +
+
[docs]def align_subplot_array(axes,xlim=None, ylim=None): + """ + Make all of the axes in the array hae the same limits, turn off unnecessary ticks + use pb.subplots() to get an array of axes + """ + #find sensible xlim,ylim + if xlim is None: + xlim = [np.inf,-np.inf] + for ax in axes.flatten(): + xlim[0] = min(xlim[0],ax.get_xlim()[0]) + xlim[1] = max(xlim[1],ax.get_xlim()[1]) + if ylim is None: + ylim = [np.inf,-np.inf] + for ax in axes.flatten(): + ylim[0] = min(ylim[0],ax.get_ylim()[0]) + ylim[1] = max(ylim[1],ax.get_ylim()[1]) + + N,M = axes.shape + for i,ax in enumerate(axes.flatten()): + ax.set_xlim(xlim) + ax.set_ylim(ylim) + if (i)%M: + ax.set_yticks([]) + else: + removeRightTicks(ax) + if i<(M*(N-1)): + ax.set_xticks([]) + else: + removeUpperTicks(ax) +
+
[docs]def x_frame1D(X,plot_limits=None,resolution=None): + """ + Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits + """ + assert X.shape[1] ==1, "x_frame1D is defined for one-dimensional inputs" + if plot_limits is None: + xmin,xmax = X.min(0),X.max(0) + xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin) + elif len(plot_limits)==2: + xmin, xmax = plot_limits + else: + raise ValueError, "Bad limits for plotting" + + Xnew = np.linspace(xmin,xmax,resolution or 200)[:,None] + return Xnew, xmin, xmax +
+
[docs]def x_frame2D(X,plot_limits=None,resolution=None): + """ + Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits + """ + assert X.shape[1] ==2, "x_frame2D is defined for two-dimensional inputs" + if plot_limits is None: + xmin,xmax = X.min(0),X.max(0) + xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin) + elif len(plot_limits)==2: + xmin, xmax = plot_limits + else: + raise ValueError, "Bad limits for plotting" + + resolution = resolution or 50 + xx,yy = np.mgrid[xmin[0]:xmax[0]:1j*resolution,xmin[1]:xmax[1]:1j*resolution] + Xnew = np.vstack((xx.flatten(),yy.flatten())).T + return Xnew, xx, yy, xmin, xmax
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/dim_reduction_plots.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/dim_reduction_plots.html new file mode 100644 index 00000000..58934bb1 --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/dim_reduction_plots.html @@ -0,0 +1,432 @@ + + + + + + + + GPy.plotting.matplot_dep.dim_reduction_plots — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.dim_reduction_plots

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from latent_space_visualizations.controllers.imshow_controller import ImshowController,ImAnnotateController
+from ...core.parameterization.variational import VariationalPosterior
+from .base_plots import x_frame2D
+import itertools
+try:
+    import Tango
+    from matplotlib.cm import get_cmap
+    import pylab as pb
+except:
+    pass
+
+
[docs]def most_significant_input_dimensions(model, which_indices): + """ + Determine which dimensions should be plotted + """ + if which_indices is None: + if model.input_dim == 1: + input_1 = 0 + input_2 = None + if model.input_dim == 2: + input_1, input_2 = 0, 1 + else: + try: + input_1, input_2 = np.argsort(model.input_sensitivity())[::-1][:2] + except: + raise ValueError, "cannot automatically determine which dimensions to plot, please pass 'which_indices'" + else: + input_1, input_2 = which_indices + return input_1, input_2 +
+
[docs]def plot_latent(model, labels=None, which_indices=None, + resolution=50, ax=None, marker='o', s=40, + fignum=None, plot_inducing=False, legend=True, + plot_limits=None, + aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={}): + """ + :param labels: a np.array of size model.num_data containing labels for the points (can be number, strings, etc) + :param resolution: the resolution of the grid on which to evaluate the predictive variance + """ + if ax is None: + fig = pb.figure(num=fignum) + ax = fig.add_subplot(111) + else: + fig = ax.figure + Tango.reset() + + if labels is None: + labels = np.ones(model.num_data) + + input_1, input_2 = most_significant_input_dimensions(model, which_indices) + + #fethch the data points X that we'd like to plot + X = model.X + if isinstance(X, VariationalPosterior): + X = X.mean + else: + X = X + + + if X.shape[0] > 1000: + print "Warning: subsampling X, as it has more samples then 1000. X.shape={!s}".format(X.shape) + subsample = np.random.choice(X.shape[0], size=1000, replace=False) + X = X[subsample] + labels = labels[subsample] + #======================================================================= + # <<<WORK IN PROGRESS>>> + # <<<DO NOT DELETE>>> + # plt.close('all') + # fig, ax = plt.subplots(1,1) + # from GPy.plotting.matplot_dep.dim_reduction_plots import most_significant_input_dimensions + # import matplotlib.patches as mpatches + # i1, i2 = most_significant_input_dimensions(m, None) + # xmin, xmax = 100, -100 + # ymin, ymax = 100, -100 + # legend_handles = [] + # + # X = m.X.mean[:, [i1, i2]] + # X = m.X.variance[:, [i1, i2]] + # + # xmin = X[:,0].min(); xmax = X[:,0].max() + # ymin = X[:,1].min(); ymax = X[:,1].max() + # range_ = [[xmin, xmax], [ymin, ymax]] + # ul = np.unique(labels) + # + # for i, l in enumerate(ul): + # #cdict = dict(red =[(0., colors[i][0], colors[i][0]), (1., colors[i][0], colors[i][0])], + # # green=[(0., colors[i][0], colors[i][1]), (1., colors[i][1], colors[i][1])], + # # blue =[(0., colors[i][0], colors[i][2]), (1., colors[i][2], colors[i][2])], + # # alpha=[(0., 0., .0), (.5, .5, .5), (1., .5, .5)]) + # #cmap = LinearSegmentedColormap('{}'.format(l), cdict) + # cmap = LinearSegmentedColormap.from_list('cmap_{}'.format(str(l)), [colors[i], colors[i]], 255) + # cmap._init() + # #alphas = .5*(1+scipy.special.erf(np.linspace(-2,2, cmap.N+3)))#np.log(np.linspace(np.exp(0), np.exp(1.), cmap.N+3)) + # alphas = (scipy.special.erf(np.linspace(0,2.4, cmap.N+3)))#np.log(np.linspace(np.exp(0), np.exp(1.), cmap.N+3)) + # cmap._lut[:, -1] = alphas + # print l + # x, y = X[labels==l].T + # + # heatmap, xedges, yedges = np.histogram2d(x, y, bins=300, range=range_) + # #heatmap, xedges, yedges = np.histogram2d(x, y, bins=100) + # + # im = ax.imshow(heatmap, extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]], cmap=cmap, aspect='auto', interpolation='nearest', label=str(l)) + # legend_handles.append(mpatches.Patch(color=colors[i], label=l)) + # ax.set_xlim(xmin, xmax) + # ax.set_ylim(ymin, ymax) + # plt.legend(legend_handles, [l.get_label() for l in legend_handles]) + # plt.draw() + # plt.show() + #======================================================================= + + # create a function which computes the shading of latent space according to the output variance + def plot_function(x): + Xtest_full = np.zeros((x.shape[0], model.X.shape[1])) + Xtest_full[:, [input_1, input_2]] = x + _, var = model.predict(Xtest_full, **predict_kwargs) + var = var[:, :1] + return np.log(var) + + #Create an IMshow controller that can re-plot the latent space shading at a good resolution + if plot_limits is None: + xmin, ymin = X[:, [input_1, input_2]].min(0) + xmax, ymax = X[:, [input_1, input_2]].max(0) + x_r, y_r = xmax-xmin, ymax-ymin + xmin -= .1*x_r + xmax += .1*x_r + ymin -= .1*y_r + ymax += .1*y_r + else: + try: + xmin, xmax, ymin, ymax = plot_limits + except (TypeError, ValueError) as e: + raise e.__class__, "Wrong plot limits: {} given -> need (xmin, xmax, ymin, ymax)".format(plot_limits) + view = ImshowController(ax, plot_function, + (xmin, ymin, xmax, ymax), + resolution, aspect=aspect, interpolation='bilinear', + cmap=pb.cm.binary, **imshow_kwargs) + + # make sure labels are in order of input: + labels = np.asarray(labels) + ulabels = [] + for lab in labels: + if not lab in ulabels: + ulabels.append(lab) + + marker = itertools.cycle(list(marker)) + + for i, ul in enumerate(ulabels): + if type(ul) is np.string_: + this_label = ul + elif type(ul) is np.int64: + this_label = 'class %i' % ul + else: + this_label = unicode(ul) + m = marker.next() + + index = np.nonzero(labels == ul)[0] + if model.input_dim == 1: + x = X[index, input_1] + y = np.zeros(index.size) + else: + x = X[index, input_1] + y = X[index, input_2] + ax.scatter(x, y, marker=m, s=s, c=Tango.nextMedium(), label=this_label, linewidth=.2, edgecolor='k', alpha=.9) + + ax.set_xlabel('latent dimension %i' % input_1) + ax.set_ylabel('latent dimension %i' % input_2) + + if not np.all(labels == 1.) and legend: + ax.legend(loc=0, numpoints=1) + + ax.grid(b=False) # remove the grid if present, it doesn't look good + ax.set_aspect('auto') # set a nice aspect ratio + + if plot_inducing: + Z = model.Z + ax.scatter(Z[:, input_1], Z[:, input_2], c='w', s=14, marker="^", edgecolor='k', linewidth=.3, alpha=.6) + + ax.set_xlim((xmin, xmax)) + ax.set_ylim((ymin, ymax)) + + try: + fig.canvas.draw() + fig.tight_layout() + fig.canvas.draw() + except Exception as e: + print "Could not invoke tight layout: {}".format(e) + pass + + if updates: + try: + ax.figure.canvas.show() + except Exception as e: + print "Could not invoke show: {}".format(e) + raw_input('Enter to continue') + view.deactivate() + return ax +
+
[docs]def plot_magnification(model, labels=None, which_indices=None, + resolution=60, ax=None, marker='o', s=40, + fignum=None, plot_inducing=False, legend=True, + aspect='auto', updates=False): + """ + :param labels: a np.array of size model.num_data containing labels for the points (can be number, strings, etc) + :param resolution: the resolution of the grid on which to evaluate the predictive variance + """ + if ax is None: + fig = pb.figure(num=fignum) + ax = fig.add_subplot(111) + Tango.reset() + + if labels is None: + labels = np.ones(model.num_data) + + input_1, input_2 = most_significant_input_dimensions(model, which_indices) + + # first, plot the output variance as a function of the latent space + Xtest, xx, yy, xmin, xmax = x_frame2D(model.X[:, [input_1, input_2]], resolution=resolution) + Xtest_full = np.zeros((Xtest.shape[0], model.X.shape[1])) + + def plot_function(x): + Xtest_full[:, [input_1, input_2]] = x + mf=model.magnification(Xtest_full) + return mf + + view = ImshowController(ax, plot_function, + tuple(model.X.min(0)[:, [input_1, input_2]]) + tuple(model.X.max(0)[:, [input_1, input_2]]), + resolution, aspect=aspect, interpolation='bilinear', + cmap=pb.cm.gray) + + # make sure labels are in order of input: + ulabels = [] + for lab in labels: + if not lab in ulabels: + ulabels.append(lab) + + marker = itertools.cycle(list(marker)) + + for i, ul in enumerate(ulabels): + if type(ul) is np.string_: + this_label = ul + elif type(ul) is np.int64: + this_label = 'class %i' % ul + else: + this_label = 'class %i' % i + m = marker.next() + + index = np.nonzero(labels == ul)[0] + if model.input_dim == 1: + x = model.X[index, input_1] + y = np.zeros(index.size) + else: + x = model.X[index, input_1] + y = model.X[index, input_2] + ax.scatter(x, y, marker=m, s=s, color=Tango.nextMedium(), label=this_label) + + ax.set_xlabel('latent dimension %i' % input_1) + ax.set_ylabel('latent dimension %i' % input_2) + + if not np.all(labels == 1.) and legend: + ax.legend(loc=0, numpoints=1) + + ax.set_xlim(xmin[0], xmax[0]) + ax.set_ylim(xmin[1], xmax[1]) + ax.grid(b=False) # remove the grid if present, it doesn't look good + ax.set_aspect('auto') # set a nice aspect ratio + + if plot_inducing: + ax.plot(model.Z[:, input_1], model.Z[:, input_2], '^w') + + if updates: + fig.canvas.show() + raw_input('Enter to continue') + + pb.title('Magnification Factor') + return ax + +
+
[docs]def plot_steepest_gradient_map(model, fignum=None, ax=None, which_indices=None, labels=None, data_labels=None, data_marker='o', data_s=40, resolution=20, aspect='auto', updates=False, ** kwargs): + + input_1, input_2 = significant_dims = most_significant_input_dimensions(model, which_indices) + + X = np.zeros((resolution ** 2, model.input_dim)) + indices = np.r_[:X.shape[0]] + if labels is None: + labels = range(model.output_dim) + + def plot_function(x): + X[:, significant_dims] = x + dmu_dX = model.dmu_dXnew(X) + argmax = np.argmax(dmu_dX, 1) + return dmu_dX[indices, argmax], np.array(labels)[argmax] + + if ax is None: + fig = pb.figure(num=fignum) + ax = fig.add_subplot(111) + + if data_labels is None: + data_labels = np.ones(model.num_data) + ulabels = [] + for lab in data_labels: + if not lab in ulabels: + ulabels.append(lab) + marker = itertools.cycle(list(data_marker)) + for i, ul in enumerate(ulabels): + if type(ul) is np.string_: + this_label = ul + elif type(ul) is np.int64: + this_label = 'class %i' % ul + else: + this_label = 'class %i' % i + m = marker.next() + index = np.nonzero(data_labels == ul)[0] + x = model.X[index, input_1] + y = model.X[index, input_2] + ax.scatter(x, y, marker=m, s=data_s, color=Tango.nextMedium(), label=this_label) + + ax.set_xlabel('latent dimension %i' % input_1) + ax.set_ylabel('latent dimension %i' % input_2) + + controller = ImAnnotateController(ax, + plot_function, + tuple(model.X.min(0)[:, significant_dims]) + tuple(model.X.max(0)[:, significant_dims]), + resolution=resolution, + aspect=aspect, + cmap=get_cmap('jet'), + **kwargs) + ax.legend() + ax.figure.tight_layout() + if updates: + pb.show() + clear = raw_input('Enter to continue') + if clear.lower() in 'yes' or clear == '': + controller.deactivate() + return controller.view
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/img_plots.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/img_plots.html new file mode 100644 index 00000000..b4eabe2f --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/img_plots.html @@ -0,0 +1,152 @@ + + + + + + + + GPy.plotting.matplot_dep.img_plots — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.img_plots

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+"""
+The module contains the tools for ploting 2D image visualizations
+"""
+
+import numpy as np
+from matplotlib.cm import jet
+
+width_max = 15
+height_max = 12
+
+def _calculateFigureSize(x_size, y_size, fig_ncols, fig_nrows, pad):
+    width = (x_size*fig_ncols+pad*(fig_ncols-1))
+    height = (y_size*fig_nrows+pad*(fig_nrows-1))
+    if width > float(height)/height_max*width_max:
+        return (width_max, float(width_max)/width*height)
+    else:
+        return (float(height_max)/height*width, height_max)
+
+
[docs]def plot_2D_images(figure, arr, symmetric=False, pad=None, zoom=None, mode=None, interpolation='nearest'): + ax = figure.add_subplot(111) + if len(arr.shape)==2: + arr = arr.reshape(*((1,)+arr.shape)) + fig_num = arr.shape[0] + y_size = arr.shape[1] + x_size = arr.shape[2] + fig_ncols = int(np.ceil(np.sqrt(fig_num))) + fig_nrows = int(np.ceil((float)(fig_num)/fig_ncols)) + if pad==None: + pad = max(int(min(y_size,x_size)/10),1) + + figsize = _calculateFigureSize(x_size, y_size, fig_ncols, fig_nrows, pad) + #figure.set_size_inches(figsize,forward=True) + #figure.subplots_adjust(left=0.05, bottom=0.05, right=0.95, top=0.95) + + if symmetric: + # symmetric around zero: fix zero as the middle color + mval = max(abs(arr.max()),abs(arr.min())) + arr = arr/(2.*mval)+0.5 + else: + minval,maxval = arr.min(),arr.max() + arr = (arr-minval)/(maxval-minval) + + if mode=='L': + arr_color = np.empty(arr.shape+(3,)) + arr_color[:] = arr.reshape(*(arr.shape+(1,))) + elif mode==None or mode=='jet': + arr_color = jet(arr) + + buf = np.ones((y_size*fig_nrows+pad*(fig_nrows-1), x_size*fig_ncols+pad*(fig_ncols-1), 3),dtype=arr.dtype) + + for y in xrange(fig_nrows): + for x in xrange(fig_ncols): + if y*fig_ncols+x<fig_num: + buf[y*y_size+y*pad:(y+1)*y_size+y*pad, x*x_size+x*pad:(x+1)*x_size+x*pad] = arr_color[y*fig_ncols+x,:,:,:3] + img_plot = ax.imshow(buf, interpolation=interpolation) + ax.axis('off')
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/inference_plots.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/inference_plots.html new file mode 100644 index 00000000..2cd9c339 --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/inference_plots.html @@ -0,0 +1,125 @@ + + + + + + + + GPy.plotting.matplot_dep.inference_plots — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.inference_plots

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+try:
+    import pylab as pb
+except:
+    pass
+#import numpy as np
+#import Tango
+#from base_plots import gpplot, x_frame1D, x_frame2D
+
+
+
[docs]def plot_optimizer(optimizer): + if optimizer.trace == None: + print "No trace present so I can't plot it. Please check that the optimizer actually supplies a trace." + else: + pb.figure() + pb.plot(optimizer.trace) + pb.xlabel('Iteration') + pb.ylabel('f(x)') +
+
[docs]def plot_sgd_traces(optimizer): + pb.figure() + pb.subplot(211) + pb.title('Parameters') + for k in optimizer.param_traces.keys(): + pb.plot(optimizer.param_traces[k], label=k) + pb.legend(loc=0) + pb.subplot(212) + pb.title('Objective function') + pb.plot(optimizer.fopt_trace)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/kernel_plots.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/kernel_plots.html new file mode 100644 index 00000000..60a342fa --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/kernel_plots.html @@ -0,0 +1,265 @@ + + + + + + + + GPy.plotting.matplot_dep.kernel_plots — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.kernel_plots

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+import pylab as pb
+import Tango
+from matplotlib.textpath import TextPath
+from matplotlib.transforms import offset_copy
+from .base_plots import ax_default
+
+
+
+
[docs]def add_bar_labels(fig, ax, bars, bottom=0): + transOffset = offset_copy(ax.transData, fig=fig, + x=0., y= -2., units='points') + transOffsetUp = offset_copy(ax.transData, fig=fig, + x=0., y=1., units='points') + for bar in bars: + for i, [patch, num] in enumerate(zip(bar.patches, np.arange(len(bar.patches)))): + if len(bottom) == len(bar): b = bottom[i] + else: b = bottom + height = patch.get_height() + b + xi = patch.get_x() + patch.get_width() / 2. + va = 'top' + c = 'w' + t = TextPath((0, 0), "${xi}$".format(xi=xi), rotation=0, ha='center') + transform = transOffset + if patch.get_extents().height <= t.get_extents().height + 5: + va = 'bottom' + c = 'k' + transform = transOffsetUp + ax.text(xi, height, "${xi}$".format(xi=int(num)), color=c, rotation=0, ha='center', va=va, transform=transform) + + ax.set_xticks([]) + +
+
[docs]def plot_bars(fig, ax, x, ard_params, color, name, bottom=0): + return ax.bar(left=x, height=ard_params.view(np.ndarray), width=.8, + bottom=bottom, align='center', + color=color, edgecolor='k', linewidth=1.2, + label=name.replace("_"," ")) +
+
[docs]def plot_ARD(kernel, fignum=None, ax=None, title='', legend=False, filtering=None): + """ + If an ARD kernel is present, plot a bar representation using matplotlib + + :param fignum: figure number of the plot + :param ax: matplotlib axis to plot on + :param title: + title of the plot, + pass '' to not print a title + pass None for a generic title + :param filtering: list of names, which to use for plotting ARD parameters. + Only kernels which match names in the list of names in filtering + will be used for plotting. + :type filtering: list of names to use for ARD plot + """ + fig, ax = ax_default(fignum,ax) + + if title is None: + ax.set_title('ARD parameters, %s kernel' % kernel.name) + else: + ax.set_title(title) + + Tango.reset() + bars = [] + + ard_params = np.atleast_2d(kernel.input_sensitivity(summarize=False)) + bottom = 0 + last_bottom = bottom + + x = np.arange(kernel.input_dim) + + if filtering is None: + filtering = kernel.parameter_names(recursive=False) + + for i in range(ard_params.shape[0]): + if kernel.parameters[i].name in filtering: + c = Tango.nextMedium() + bars.append(plot_bars(fig, ax, x, ard_params[i,:], c, kernel.parameters[i].name, bottom=bottom)) + last_bottom = ard_params[i,:] + bottom += last_bottom + else: + print "filtering out {}".format(kernel.parameters[i].name) + + ax.set_xlim(-.5, kernel.input_dim - .5) + add_bar_labels(fig, ax, [bars[-1]], bottom=bottom-last_bottom) + + if legend: + if title is '': + mode = 'expand' + if len(bars) > 1: + mode = 'expand' + ax.legend(bbox_to_anchor=(0., 1.02, 1., 1.02), loc=3, + ncol=len(bars), mode=mode, borderaxespad=0.) + fig.tight_layout(rect=(0, 0, 1, .9)) + else: + ax.legend() + return ax + + +
+
[docs]def plot(kernel,x=None, fignum=None, ax=None, title=None, plot_limits=None, resolution=None, **mpl_kwargs): + """ + plot a kernel. + :param x: the value to use for the other kernel argument (kernels are a function of two variables!) + :param fignum: figure number of the plot + :param ax: matplotlib axis to plot on + :param title: the matplotlib title + :param plot_limits: the range over which to plot the kernel + :resolution: the resolution of the lines used in plotting + :mpl_kwargs avalid keyword arguments to pass through to matplotlib (e.g. lw=7) + """ + fig, ax = ax_default(fignum,ax) + + if title is None: + ax.set_title('%s kernel' % kernel.name) + else: + ax.set_title(title) + + + if kernel.input_dim == 1: + if x is None: + x = np.zeros((1, 1)) + else: + x = np.asarray(x) + assert x.size == 1, "The size of the fixed variable x is not 1" + x = x.reshape((1, 1)) + + if plot_limits == None: + xmin, xmax = (x - 5).flatten(), (x + 5).flatten() + elif len(plot_limits) == 2: + xmin, xmax = plot_limits + else: + raise ValueError, "Bad limits for plotting" + + Xnew = np.linspace(xmin, xmax, resolution or 201)[:, None] + Kx = kernel.K(Xnew, x) + ax.plot(Xnew, Kx, **mpl_kwargs) + ax.set_xlim(xmin, xmax) + ax.set_xlabel("x") + ax.set_ylabel("k(x,%0.1f)" % x) + + elif kernel.input_dim == 2: + if x is None: + x = np.zeros((1, 2)) + else: + x = np.asarray(x) + assert x.size == 2, "The size of the fixed variable x is not 2" + x = x.reshape((1, 2)) + + if plot_limits is None: + xmin, xmax = (x - 5).flatten(), (x + 5).flatten() + elif len(plot_limits) == 2: + xmin, xmax = plot_limits + else: + raise ValueError, "Bad limits for plotting" + + resolution = resolution or 51 + xx, yy = np.mgrid[xmin[0]:xmax[0]:1j * resolution, xmin[1]:xmax[1]:1j * resolution] + Xnew = np.vstack((xx.flatten(), yy.flatten())).T + Kx = kernel.K(Xnew, x) + Kx = Kx.reshape(resolution, resolution).T + ax.contour(xx, yy, Kx, vmin=Kx.min(), vmax=Kx.max(), cmap=pb.cm.jet, **mpl_kwargs) # @UndefinedVariable + ax.set_xlim(xmin[0], xmax[0]) + ax.set_ylim(xmin[1], xmax[1]) + ax.set_xlabel("x1") + ax.set_ylabel("x2") + ax.set_title("k(x1,x2 ; %0.1f,%0.1f)" % (x[0, 0], x[0, 1])) + else: + raise NotImplementedError, "Cannot plot a kernel with more than two input dimensions"
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/axis_event_controller.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/axis_event_controller.html new file mode 100644 index 00000000..e1dfe6b2 --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/axis_event_controller.html @@ -0,0 +1,241 @@ + + + + + + + + GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller

+'''
+Created on 24 Jul 2013
+
+@author: maxz
+'''
+import numpy
+
+
[docs]class AxisEventController(object): + def __init__(self, ax): + self.ax = ax + self.activate() +
[docs] def deactivate(self): + for cb_class in self.ax.callbacks.callbacks.values(): + for cb_num in cb_class.keys(): + self.ax.callbacks.disconnect(cb_num)
+
[docs] def activate(self): + self.ax.callbacks.connect('xlim_changed', self.xlim_changed) + self.ax.callbacks.connect('ylim_changed', self.ylim_changed)
+
[docs] def xlim_changed(self, ax): + pass
+
[docs] def ylim_changed(self, ax): + pass + +
+
[docs]class AxisChangedController(AxisEventController): + ''' + Buffered control of axis limit changes + ''' + _changing = False + + def __init__(self, ax, update_lim=None): + ''' + Constructor + ''' + super(AxisChangedController, self).__init__(ax) + self._lim_ratio_threshold = update_lim or .95 + self._x_lim = self.ax.get_xlim() + self._y_lim = self.ax.get_ylim() + +
[docs] def update(self, ax): + pass +
+
[docs] def xlim_changed(self, ax): + super(AxisChangedController, self).xlim_changed(ax) + if not self._changing and self.lim_changed(ax.get_xlim(), self._x_lim): + self._changing = True + self._x_lim = ax.get_xlim() + self.update(ax) + self._changing = False +
+
[docs] def ylim_changed(self, ax): + super(AxisChangedController, self).ylim_changed(ax) + if not self._changing and self.lim_changed(ax.get_ylim(), self._y_lim): + self._changing = True + self._y_lim = ax.get_ylim() + self.update(ax) + self._changing = False +
+
[docs] def extent(self, lim): + return numpy.subtract(*lim) +
+
[docs] def lim_changed(self, axlim, savedlim): + axextent = self.extent(axlim) + extent = self.extent(savedlim) + lim_changed = ((axextent / extent) < self._lim_ratio_threshold ** 2 + or (extent / axextent) < self._lim_ratio_threshold ** 2 + or ((1 - (self.extent((axlim[0], savedlim[0])) / self.extent((savedlim[0], axlim[1])))) + < self._lim_ratio_threshold) + or ((1 - (self.extent((savedlim[0], axlim[0])) / self.extent((axlim[0], savedlim[1])))) + < self._lim_ratio_threshold) + ) + return lim_changed +
+ def _buffer_lim(self, lim): + # buffer_size = 1 - self._lim_ratio_threshold + # extent = self.extent(lim) + return lim + +
+
[docs]class BufferedAxisChangedController(AxisChangedController): + def __init__(self, ax, plot_function, plot_limits, resolution=50, update_lim=None, **kwargs): + """ + Buffered axis changed controller. Controls the buffer and handles update events for when the axes changed. + + Updated plotting will be after first reload (first time will be within plot limits, after that the limits will be buffered) + + :param plot_function: + function to use for creating image for plotting (return ndarray-like) + plot_function gets called with (2D!) Xtest grid if replotting required + :type plot_function: function + :param plot_limits: + beginning plot limits [xmin, ymin, xmax, ymax] + + :param kwargs: additional kwargs are for pyplot.imshow(**kwargs) + """ + super(BufferedAxisChangedController, self).__init__(ax, update_lim=update_lim) + self.plot_function = plot_function + xmin, ymin, xmax, ymax = plot_limits#self._x_lim # self._compute_buffered(*self._x_lim) + # imshow acts on the limits of the plot, this is why we need to override the limits here, to make sure the right plot limits are used: + self._x_lim = xmin, xmax + self._y_lim = ymin, ymax + self.resolution = resolution + self._not_init = False + self.view = self._init_view(self.ax, self.recompute_X(buffered=False), xmin, xmax, ymin, ymax, **kwargs) + self._not_init = True + +
[docs] def update(self, ax): + super(BufferedAxisChangedController, self).update(ax) + if self._not_init: + xmin, xmax = self._compute_buffered(*self._x_lim) + ymin, ymax = self._compute_buffered(*self._y_lim) + self.update_view(self.view, self.recompute_X(), xmin, xmax, ymin, ymax) +
+ def _init_view(self, ax, X, xmin, xmax, ymin, ymax): + raise NotImplementedError('return view for this controller') + +
[docs] def update_view(self, view, X, xmin, xmax, ymin, ymax): + raise NotImplementedError('update view given in here') +
+
[docs] def get_grid(self, buffered=True): + if buffered: comp = self._compute_buffered + else: comp = lambda a,b: (a,b) + xmin, xmax = comp(*self._x_lim) + ymin, ymax = comp(*self._y_lim) + x, y = numpy.mgrid[xmin:xmax:1j * self.resolution, ymin:ymax:1j * self.resolution] + return numpy.hstack((x.flatten()[:, None], y.flatten()[:, None])) +
+
[docs] def recompute_X(self, buffered=True): + X = self.plot_function(self.get_grid(buffered)) + if isinstance(X, (tuple, list)): + for x in X: + x.shape = [self.resolution, self.resolution] + x[:, :] = x.T[::-1, :] + return X + return X.reshape(self.resolution, self.resolution).T[::-1, :] +
+ def _compute_buffered(self, mi, ma): + buffersize = self._buffersize() + size = ma - mi + return mi - (buffersize * size), ma + (buffersize * size) + + def _buffersize(self): + try: + buffersize = 1. - self._lim_ratio_threshold + except: + buffersize = .4 + return buffersize
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/imshow_controller.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/imshow_controller.html new file mode 100644 index 00000000..cddaa948 --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/imshow_controller.html @@ -0,0 +1,165 @@ + + + + + + + + GPy.plotting.matplot_dep.latent_space_visualizations.controllers.imshow_controller — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.latent_space_visualizations.controllers.imshow_controller

+'''
+Created on 24 Jul 2013
+
+@author: maxz
+'''
+from axis_event_controller import BufferedAxisChangedController
+import itertools
+import numpy
+
+
+
[docs]class ImshowController(BufferedAxisChangedController): + def __init__(self, ax, plot_function, plot_limits, resolution=50, update_lim=.8, **kwargs): + """ + :param plot_function: + function to use for creating image for plotting (return ndarray-like) + plot_function gets called with (2D!) Xtest grid if replotting required + :type plot_function: function + :param plot_limits: + beginning plot limits [xmin, ymin, xmax, ymax] + + :param kwargs: additional kwargs are for pyplot.imshow(**kwargs) + """ + super(ImshowController, self).__init__(ax, plot_function, plot_limits, resolution, update_lim, **kwargs) + + def _init_view(self, ax, X, xmin, xmax, ymin, ymax, **kwargs): + return ax.imshow(X, extent=(xmin, xmax, + ymin, ymax), + vmin=X.min(), + vmax=X.max(), + **kwargs) + +
[docs] def update_view(self, view, X, xmin, xmax, ymin, ymax): + view.set_data(X) + view.set_extent((xmin, xmax, ymin, ymax)) +
+
[docs]class ImAnnotateController(ImshowController): + def __init__(self, ax, plot_function, plot_limits, resolution=20, update_lim=.99, **kwargs): + """ + :param plot_function: + function to use for creating image for plotting (return ndarray-like) + plot_function gets called with (2D!) Xtest grid if replotting required + :type plot_function: function + :param plot_limits: + beginning plot limits [xmin, ymin, xmax, ymax] + :param text_props: kwargs for pyplot.text(**text_props) + :param kwargs: additional kwargs are for pyplot.imshow(**kwargs) + """ + super(ImAnnotateController, self).__init__(ax, plot_function, plot_limits, resolution, update_lim, **kwargs) + + def _init_view(self, ax, X, xmin, xmax, ymin, ymax, text_props={}, **kwargs): + view = [super(ImAnnotateController, self)._init_view(ax, X[0], xmin, xmax, ymin, ymax, **kwargs)] + xoffset, yoffset = self._offsets(xmin, xmax, ymin, ymax) + xlin = numpy.linspace(xmin, xmax, self.resolution, endpoint=False) + ylin = numpy.linspace(ymin, ymax, self.resolution, endpoint=False) + for [i, x], [j, y] in itertools.product(enumerate(xlin), enumerate(ylin[::-1])): + view.append(ax.text(x + xoffset, y + yoffset, "{}".format(X[1][j, i]), ha='center', va='center', **text_props)) + return view + +
[docs] def update_view(self, view, X, xmin, xmax, ymin, ymax): + super(ImAnnotateController, self).update_view(view[0], X[0], xmin, xmax, ymin, ymax) + xoffset, yoffset = self._offsets(xmin, xmax, ymin, ymax) + xlin = numpy.linspace(xmin, xmax, self.resolution, endpoint=False) + ylin = numpy.linspace(ymin, ymax, self.resolution, endpoint=False) + for [[i, x], [j, y]], text in itertools.izip(itertools.product(enumerate(xlin), enumerate(ylin[::-1])), view[1:]): + text.set_x(x + xoffset) + text.set_y(y + yoffset) + text.set_text("{}".format(X[1][j, i])) + return view +
+ def _offsets(self, xmin, xmax, ymin, ymax): + return (xmax - xmin) / (2 * self.resolution), (ymax - ymin) / (2 * self.resolution)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/mapping_plots.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/mapping_plots.html new file mode 100644 index 00000000..f5bcc03f --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/mapping_plots.html @@ -0,0 +1,178 @@ + + + + + + + + GPy.plotting.matplot_dep.mapping_plots — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.mapping_plots

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+try:
+    import Tango
+    import pylab as pb
+except:
+    pass
+from base_plots import x_frame1D, x_frame2D
+
+
+
[docs]def plot_mapping(self, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, samples=0, fignum=None, ax=None, fixed_inputs=[], linecol=Tango.colorsHex['darkBlue']): + """ + Plots the mapping associated with the model. + - In one dimension, the function is plotted. + - In two dimsensions, a contour-plot shows the function + - In higher dimensions, we've not implemented this yet !TODO! + + Can plot only part of the data and part of the posterior functions + using which_data and which_functions + + :param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits + :type plot_limits: np.array + :param which_data: which if the training data to plot (default all) + :type which_data: 'all' or a slice object to slice self.X, self.Y + :param which_parts: which of the kernel functions to plot (additively) + :type which_parts: 'all', or list of bools + :param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D + :type resolution: int + :param levels: number of levels to plot in a contour plot. + :type levels: int + :param samples: the number of a posteriori samples to plot + :type samples: int + :param fignum: figure to plot on. + :type fignum: figure number + :param ax: axes to plot on. + :type ax: axes handle + :param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v. + :type fixed_inputs: a list of tuples + :param linecol: color of line to plot. + :type linecol: + :param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure + + """ + # TODO include samples + if which_data == 'all': + which_data = slice(None) + + if ax is None: + fig = pb.figure(num=fignum) + ax = fig.add_subplot(111) + + plotdims = self.input_dim - len(fixed_inputs) + + if plotdims == 1: + + Xu = self.X * self._Xscale + self._Xoffset # NOTE self.X are the normalized values now + + fixed_dims = np.array([i for i,v in fixed_inputs]) + freedim = np.setdiff1d(np.arange(self.input_dim),fixed_dims) + + Xnew, xmin, xmax = x_frame1D(Xu[:,freedim], plot_limits=plot_limits) + Xgrid = np.empty((Xnew.shape[0],self.input_dim)) + Xgrid[:,freedim] = Xnew + for i,v in fixed_inputs: + Xgrid[:,i] = v + + f = self.predict(Xgrid, which_parts=which_parts) + for d in range(y.shape[1]): + ax.plot(Xnew, f[:, d], edgecol=linecol) + + elif self.X.shape[1] == 2: + resolution = resolution or 50 + Xnew, _, _, xmin, xmax = x_frame2D(self.X, plot_limits, resolution) + x, y = np.linspace(xmin[0], xmax[0], resolution), np.linspace(xmin[1], xmax[1], resolution) + f = self.predict(Xnew, which_parts=which_parts) + m = m.reshape(resolution, resolution).T + ax.contour(x, y, f, levels, vmin=m.min(), vmax=m.max(), cmap=pb.cm.jet) # @UndefinedVariable + ax.set_xlim(xmin[0], xmax[0]) + ax.set_ylim(xmin[1], xmax[1]) + + else: + raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/maps.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/maps.html new file mode 100644 index 00000000..3410923a --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/maps.html @@ -0,0 +1,269 @@ + + + + + + + + GPy.plotting.matplot_dep.maps — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.maps

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+import numpy as np
+try:
+    import pylab as pb
+    from matplotlib.patches import Polygon
+    from matplotlib.collections import PatchCollection
+    #from matplotlib import cm
+    pb.ion()
+except:
+    pass
+import re
+
+
[docs]def plot(shape_records,facecolor='w',edgecolor='k',linewidths=.5, ax=None,xlims=None,ylims=None): + """ + Plot the geometry of a shapefile + + :param shape_records: geometry and attributes list + :type shape_records: ShapeRecord object (output of a shapeRecords() method) + :param facecolor: color to be used to fill in polygons + :param edgecolor: color to be used for lines + :param ax: axes to plot on. + :type ax: axes handle + """ + #Axes handle + if ax is None: + fig = pb.figure() + ax = fig.add_subplot(111) + + #Iterate over shape_records + for srec in shape_records: + points = np.vstack(srec.shape.points) + sparts = srec.shape.parts + par = list(sparts) + [points.shape[0]] + + polygs = [] + for pj in xrange(len(sparts)): + polygs.append(Polygon(points[par[pj]:par[pj+1]])) + ax.add_collection(PatchCollection(polygs,facecolor=facecolor,edgecolor=edgecolor, linewidths=linewidths)) + + #Plot limits + _box = np.vstack([srec.shape.bbox for srec in shape_records]) + minx,miny = np.min(_box[:,:2],0) + maxx,maxy = np.max(_box[:,2:],0) + + if xlims is not None: + minx,maxx = xlims + if ylims is not None: + miny,maxy = ylims + ax.set_xlim(minx,maxx) + ax.set_ylim(miny,maxy) + +
+
[docs]def string_match(sf,regex,field=2): + """ + Return the geometry and attributes of a shapefile whose fields match a regular expression given + + :param sf: shapefile + :type sf: shapefile object + :regex: regular expression to match + :type regex: string + :field: field number to be matched with the regex + :type field: integer + """ + index = [] + shape_records = [] + for rec in enumerate(sf.shapeRecords()): + m = re.search(regex,rec[1].record[field]) + if m is not None: + index.append(rec[0]) + shape_records.append(rec[1]) + return index,shape_records +
+
[docs]def bbox_match(sf,bbox,inside_only=True): + """ + Return the geometry and attributes of a shapefile that lie within (or intersect) a bounding box + + :param sf: shapefile + :type sf: shapefile object + :param bbox: bounding box + :type bbox: list of floats [x_min,y_min,x_max,y_max] + :inside_only: True if the objects returned are those that lie within the bbox and False if the objects returned are any that intersect the bbox + :type inside_only: Boolean + """ + A,B,C,D = bbox + index = [] + shape_records = [] + for rec in enumerate(sf.shapeRecords()): + a,b,c,d = rec[1].shape.bbox + if inside_only: + if A <= a and B <= b and C >= c and D >= d: + index.append(rec[0]) + shape_records.append(rec[1]) + else: + cond1 = A <= a and B <= b and C >= a and D >= b + cond2 = A <= c and B <= d and C >= c and D >= d + cond3 = A <= a and D >= d and C >= a and B <= d + cond4 = A <= c and D >= b and C >= c and B <= b + cond5 = a <= C and b <= B and d >= D + cond6 = c <= A and b <= B and d >= D + cond7 = d <= B and a <= A and c >= C + cond8 = b <= D and a <= A and c >= C + if cond1 or cond2 or cond3 or cond4 or cond5 or cond6 or cond7 or cond8: + index.append(rec[0]) + shape_records.append(rec[1]) + return index,shape_records + +
+
[docs]def plot_bbox(sf,bbox,inside_only=True): + """ + Plot the geometry of a shapefile within a bbox + + :param sf: shapefile + :type sf: shapefile object + :param bbox: bounding box + :type bbox: list of floats [x_min,y_min,x_max,y_max] + :inside_only: True if the objects returned are those that lie within the bbox and False if the objects returned are any that intersect the bbox + :type inside_only: Boolean + """ + index,shape_records = bbox_match(sf,bbox,inside_only) + A,B,C,D = bbox + plot(shape_records,xlims=[bbox[0],bbox[2]],ylims=[bbox[1],bbox[3]]) +
+
[docs]def plot_string_match(sf,regex,field,**kwargs): + """ + Plot the geometry of a shapefile whose fields match a regular expression given + + :param sf: shapefile + :type sf: shapefile object + :regex: regular expression to match + :type regex: string + :field: field number to be matched with the regex + :type field: integer + """ + index,shape_records = string_match(sf,regex,field) + plot(shape_records,**kwargs) + +
+
[docs]def new_shape_string(sf,name,regex,field=2,type=None): + import shapefile + if type is None: + type = shapefile.POINT + newshp = shapefile.Writer(shapeType = sf.shapeType) + newshp.autoBalance = 1 + + index,shape_records = string_match(sf,regex,field) + + _fi = [sf.fields[j] for j in index] + for f in _fi: + newshp.field(name=f[0],fieldType=f[1],size=f[2],decimal=f[3]) + + _shre = shape_records + for sr in _shre: + _points = [] + _parts = [] + for point in sr.shape.points: + _points.append(point) + _parts.append(_points) + + newshp.line(parts=_parts) + newshp.records.append(sr.record) + print len(sr.record) + + newshp.save(name) + print index +
+
[docs]def apply_bbox(sf,ax): + """ + Use bbox as xlim and ylim in ax + """ + limits = sf.bbox + xlim = limits[0],limits[2] + ylim = limits[1],limits[3] + ax.set_xlim(xlim) + ax.set_ylim(ylim)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/models_plots.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/models_plots.html new file mode 100644 index 00000000..899d7f1c --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/models_plots.html @@ -0,0 +1,282 @@ + + + + + + + + GPy.plotting.matplot_dep.models_plots — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.models_plots

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+try:
+    import Tango
+    import pylab as pb
+except:
+    pass
+import numpy as np
+from base_plots import gpplot, x_frame1D, x_frame2D
+from ...models.gp_coregionalized_regression import GPCoregionalizedRegression
+from ...models.sparse_gp_coregionalized_regression import SparseGPCoregionalizedRegression
+from scipy import sparse
+
+
[docs]def plot_fit(model, plot_limits=None, which_data_rows='all', + which_data_ycols='all', fixed_inputs=[], + levels=20, samples=0, fignum=None, ax=None, resolution=None, + plot_raw=False, + linecol=Tango.colorsHex['darkBlue'],fillcol=Tango.colorsHex['lightBlue'], Y_metadata=None, data_symbol='kx'): + """ + Plot the posterior of the GP. + - In one dimension, the function is plotted with a shaded region identifying two standard deviations. + - In two dimsensions, a contour-plot shows the mean predicted function + - In higher dimensions, use fixed_inputs to plot the GP with some of the inputs fixed. + + Can plot only part of the data and part of the posterior functions + using which_data_rowsm which_data_ycols. + + :param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits + :type plot_limits: np.array + :param which_data_rows: which of the training data to plot (default all) + :type which_data_rows: 'all' or a slice object to slice model.X, model.Y + :param which_data_ycols: when the data has several columns (independant outputs), only plot these + :type which_data_rows: 'all' or a list of integers + :param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v. + :type fixed_inputs: a list of tuples + :param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D + :type resolution: int + :param levels: number of levels to plot in a contour plot. + :type levels: int + :param samples: the number of a posteriori samples to plot + :type samples: int + :param fignum: figure to plot on. + :type fignum: figure number + :param ax: axes to plot on. + :type ax: axes handle + :type output: integer (first output is 0) + :param linecol: color of line to plot. + :type linecol: + :param fillcol: color of fill + :param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure + """ + #deal with optional arguments + if which_data_rows == 'all': + which_data_rows = slice(None) + if which_data_ycols == 'all': + which_data_ycols = np.arange(model.output_dim) + #if len(which_data_ycols)==0: + #raise ValueError('No data selected for plotting') + if ax is None: + fig = pb.figure(num=fignum) + ax = fig.add_subplot(111) + + if hasattr(model, 'has_uncertain_inputs') and model.has_uncertain_inputs(): + X = model.X.mean + X_variance = model.X.variance + else: + X = model.X + Y = model.Y + if sparse.issparse(Y): Y = Y.todense().view(np.ndarray) + + if hasattr(model, 'Z'): Z = model.Z + + #work out what the inputs are for plotting (1D or 2D) + fixed_dims = np.array([i for i,v in fixed_inputs]) + free_dims = np.setdiff1d(np.arange(model.input_dim),fixed_dims) + plots = {} + #one dimensional plotting + if len(free_dims) == 1: + + #define the frame on which to plot + Xnew, xmin, xmax = x_frame1D(X[:,free_dims], plot_limits=plot_limits, resolution=resolution or 200) + Xgrid = np.empty((Xnew.shape[0],model.input_dim)) + Xgrid[:,free_dims] = Xnew + for i,v in fixed_inputs: + Xgrid[:,i] = v + + #make a prediction on the frame and plot it + if plot_raw: + m, v = model._raw_predict(Xgrid) + lower = m - 2*np.sqrt(v) + upper = m + 2*np.sqrt(v) + else: + if isinstance(model,GPCoregionalizedRegression) or isinstance(model,SparseGPCoregionalizedRegression): + meta = {'output_index': Xgrid[:,-1:].astype(np.int)} + else: + meta = None + m, v = model.predict(Xgrid, full_cov=False, Y_metadata=meta) + lower, upper = model.predict_quantiles(Xgrid, Y_metadata=meta) + + + for d in which_data_ycols: + plots['gpplot'] = gpplot(Xnew, m[:, d], lower[:, d], upper[:, d], ax=ax, edgecol=linecol, fillcol=fillcol) + if not plot_raw: plots['dataplot'] = ax.plot(X[which_data_rows,free_dims], Y[which_data_rows, d], data_symbol, mew=1.5) + + #optionally plot some samples + if samples: #NOTE not tested with fixed_inputs + Ysim = model.posterior_samples(Xgrid, samples) + for yi in Ysim.T: + plots['posterior_samples'] = ax.plot(Xnew, yi[:,None], Tango.colorsHex['darkBlue'], linewidth=0.25) + #ax.plot(Xnew, yi[:,None], marker='x', linestyle='--',color=Tango.colorsHex['darkBlue']) #TODO apply this line for discrete outputs. + + + #add error bars for uncertain (if input uncertainty is being modelled) + if hasattr(model,"has_uncertain_inputs") and model.has_uncertain_inputs(): + plots['xerrorbar'] = ax.errorbar(X[which_data_rows, free_dims].flatten(), Y[which_data_rows, which_data_ycols].flatten(), + xerr=2 * np.sqrt(X_variance[which_data_rows, free_dims].flatten()), + ecolor='k', fmt=None, elinewidth=.5, alpha=.5) + + + #set the limits of the plot to some sensible values + ymin, ymax = min(np.append(Y[which_data_rows, which_data_ycols].flatten(), lower)), max(np.append(Y[which_data_rows, which_data_ycols].flatten(), upper)) + ymin, ymax = ymin - 0.1 * (ymax - ymin), ymax + 0.1 * (ymax - ymin) + ax.set_xlim(xmin, xmax) + ax.set_ylim(ymin, ymax) + + #add inducing inputs (if a sparse model is used) + if hasattr(model,"Z"): + #Zu = model.Z[:,free_dims] * model._Xscale[:,free_dims] + model._Xoffset[:,free_dims] + if isinstance(model,SparseGPCoregionalizedRegression): + Z = Z[Z[:,-1] == Y_metadata['output_index'],:] + Zu = Z[:,free_dims] + z_height = ax.get_ylim()[0] + plots['inducing_inputs'] = ax.plot(Zu, np.zeros_like(Zu) + z_height, 'r|', mew=1.5, markersize=12) + + + + #2D plotting + elif len(free_dims) == 2: + + #define the frame for plotting on + resolution = resolution or 50 + Xnew, _, _, xmin, xmax = x_frame2D(X[:,free_dims], plot_limits, resolution) + Xgrid = np.empty((Xnew.shape[0],model.input_dim)) + Xgrid[:,free_dims] = Xnew + for i,v in fixed_inputs: + Xgrid[:,i] = v + x, y = np.linspace(xmin[0], xmax[0], resolution), np.linspace(xmin[1], xmax[1], resolution) + + #predict on the frame and plot + if plot_raw: + m, _ = model._raw_predict(Xgrid) + else: + if isinstance(model,GPCoregionalizedRegression) or isinstance(model,SparseGPCoregionalizedRegression): + meta = {'output_index': Xgrid[:,-1:].astype(np.int)} + else: + meta = None + m, v = model.predict(Xgrid, full_cov=False, Y_metadata=meta) + for d in which_data_ycols: + m_d = m[:,d].reshape(resolution, resolution).T + plots['contour'] = ax.contour(x, y, m_d, levels, vmin=m.min(), vmax=m.max(), cmap=pb.cm.jet) + if not plot_raw: plots['dataplot'] = ax.scatter(X[which_data_rows, free_dims[0]], X[which_data_rows, free_dims[1]], 40, Y[which_data_rows, d], cmap=pb.cm.jet, vmin=m.min(), vmax=m.max(), linewidth=0.) + + #set the limits of the plot to some sensible values + ax.set_xlim(xmin[0], xmax[0]) + ax.set_ylim(xmin[1], xmax[1]) + + if samples: + warnings.warn("Samples are rather difficult to plot for 2D inputs...") + + #add inducing inputs (if a sparse model is used) + if hasattr(model,"Z"): + #Zu = model.Z[:,free_dims] * model._Xscale[:,free_dims] + model._Xoffset[:,free_dims] + Zu = Z[:,free_dims] + plots['inducing_inputs'] = ax.plot(Zu[:,free_dims[0]], Zu[:,free_dims[1]], 'wo') + + else: + raise NotImplementedError, "Cannot define a frame with more than two input dimensions" + return plots +
+
[docs]def plot_fit_f(model, *args, **kwargs): + """ + Plot the GP's view of the world, where the data is normalized and before applying a likelihood. + + All args and kwargs are passed on to models_plots.plot. + """ + kwargs['plot_raw'] = True + plot_fit(model,*args, **kwargs)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/netpbmfile.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/netpbmfile.html new file mode 100644 index 00000000..ef26c42c --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/netpbmfile.html @@ -0,0 +1,425 @@ + + + + + + + + GPy.plotting.matplot_dep.netpbmfile — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.netpbmfile

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# netpbmfile.py
+
+# Copyright (c) 2011-2013, Christoph Gohlke
+# Copyright (c) 2011-2013, The Regents of the University of California
+# Produced at the Laboratory for Fluorescence Dynamics.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# * Neither the name of the copyright holders nor the names of any
+#   contributors may be used to endorse or promote products derived
+#   from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+"""Read and write image data from respectively to Netpbm files.
+
+This implementation follows the Netpbm format specifications at
+http://netpbm.sourceforge.net/doc/. No gamma correction is performed.
+
+The following image formats are supported: PBM (bi-level), PGM (grayscale),
+PPM (color), PAM (arbitrary), XV thumbnail (RGB332, read-only).
+
+:Author:
+  `Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/>`_
+
+:Organization:
+  Laboratory for Fluorescence Dynamics, University of California, Irvine
+
+:Version: 2013.01.18
+
+Requirements
+------------
+* `CPython 2.7, 3.2 or 3.3 <http://www.python.org>`_
+* `Numpy 1.7 <http://www.numpy.org>`_
+* `Matplotlib 1.2 <http://www.matplotlib.org>`_  (optional for plotting)
+
+Examples
+--------
+>>> im1 = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16)
+>>> imsave('_tmp.pgm', im1)
+>>> im2 = imread('_tmp.pgm')
+>>> assert numpy.all(im1 == im2)
+
+"""
+
+from __future__ import division, print_function
+
+import sys
+import re
+import math
+from copy import deepcopy
+
+import numpy
+
+__version__ = '2013.01.18'
+__docformat__ = 'restructuredtext en'
+__all__ = ['imread', 'imsave', 'NetpbmFile']
+
+
+
[docs]def imread(filename, *args, **kwargs): + """Return image data from Netpbm file as numpy array. + + `args` and `kwargs` are arguments to NetpbmFile.asarray(). + + Examples + -------- + >>> image = imread('_tmp.pgm') + + """ + try: + netpbm = NetpbmFile(filename) + image = netpbm.asarray() + finally: + netpbm.close() + return image + +
+
[docs]def imsave(filename, data, maxval=None, pam=False): + """Write image data to Netpbm file. + + Examples + -------- + >>> image = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16) + >>> imsave('_tmp.pgm', image) + + """ + try: + netpbm = NetpbmFile(data, maxval=maxval) + netpbm.write(filename, pam=pam) + finally: + netpbm.close() + +
+
[docs]class NetpbmFile(object): + """Read and write Netpbm PAM, PBM, PGM, PPM, files.""" + + _types = {b'P1': b'BLACKANDWHITE', b'P2': b'GRAYSCALE', b'P3': b'RGB', + b'P4': b'BLACKANDWHITE', b'P5': b'GRAYSCALE', b'P6': b'RGB', + b'P7 332': b'RGB', b'P7': b'RGB_ALPHA'} + + def __init__(self, arg=None, **kwargs): + """Initialize instance from filename, open file, or numpy array.""" + for attr in ('header', 'magicnum', 'width', 'height', 'maxval', + 'depth', 'tupltypes', '_filename', '_fh', '_data'): + setattr(self, attr, None) + if arg is None: + self._fromdata([], **kwargs) + elif isinstance(arg, basestring): + self._fh = open(arg, 'rb') + self._filename = arg + self._fromfile(self._fh, **kwargs) + elif hasattr(arg, 'seek'): + self._fromfile(arg, **kwargs) + self._fh = arg + else: + self._fromdata(arg, **kwargs) + +
[docs] def asarray(self, copy=True, cache=False, **kwargs): + """Return image data from file as numpy array.""" + data = self._data + if data is None: + data = self._read_data(self._fh, **kwargs) + if cache: + self._data = data + else: + return data + return deepcopy(data) if copy else data +
+
[docs] def write(self, arg, **kwargs): + """Write instance to file.""" + if hasattr(arg, 'seek'): + self._tofile(arg, **kwargs) + else: + with open(arg, 'wb') as fid: + self._tofile(fid, **kwargs) +
+
[docs] def close(self): + """Close open file. Future asarray calls might fail.""" + if self._filename and self._fh: + self._fh.close() + self._fh = None +
+ def __del__(self): + self.close() + + def _fromfile(self, fh): + """Initialize instance from open file.""" + fh.seek(0) + data = fh.read(4096) + if (len(data) < 7) or not (b'0' < data[1:2] < b'8'): + raise ValueError("Not a Netpbm file:\n%s" % data[:32]) + try: + self._read_pam_header(data) + except Exception: + try: + self._read_pnm_header(data) + except Exception: + raise ValueError("Not a Netpbm file:\n%s" % data[:32]) + + def _read_pam_header(self, data): + """Read PAM header and initialize instance.""" + regroups = re.search( + b"(^P7[\n\r]+(?:(?:[\n\r]+)|(?:#.*)|" + b"(HEIGHT\s+\d+)|(WIDTH\s+\d+)|(DEPTH\s+\d+)|(MAXVAL\s+\d+)|" + b"(?:TUPLTYPE\s+\w+))*ENDHDR\n)", data).groups() + self.header = regroups[0] + self.magicnum = b'P7' + for group in regroups[1:]: + key, value = group.split() + setattr(self, unicode(key).lower(), int(value)) + matches = re.findall(b"(TUPLTYPE\s+\w+)", self.header) + self.tupltypes = [s.split(None, 1)[1] for s in matches] + + def _read_pnm_header(self, data): + """Read PNM header and initialize instance.""" + bpm = data[1:2] in b"14" + regroups = re.search(b"".join(( + b"(^(P[123456]|P7 332)\s+(?:#.*[\r\n])*", + b"\s*(\d+)\s+(?:#.*[\r\n])*", + b"\s*(\d+)\s+(?:#.*[\r\n])*" * (not bpm), + b"\s*(\d+)\s(?:\s*#.*[\r\n]\s)*)")), data).groups() + (1, ) * bpm + self.header = regroups[0] + self.magicnum = regroups[1] + self.width = int(regroups[2]) + self.height = int(regroups[3]) + self.maxval = int(regroups[4]) + self.depth = 3 if self.magicnum in b"P3P6P7 332" else 1 + self.tupltypes = [self._types[self.magicnum]] + + def _read_data(self, fh, byteorder='>'): + """Return image data from open file as numpy array.""" + fh.seek(len(self.header)) + data = fh.read() + dtype = 'u1' if self.maxval < 256 else byteorder + 'u2' + depth = 1 if self.magicnum == b"P7 332" else self.depth + shape = [-1, self.height, self.width, depth] + size = numpy.prod(shape[1:]) + if self.magicnum in b"P1P2P3": + data = numpy.array(data.split(None, size)[:size], dtype) + data = data.reshape(shape) + elif self.maxval == 1: + shape[2] = int(math.ceil(self.width / 8)) + data = numpy.frombuffer(data, dtype).reshape(shape) + data = numpy.unpackbits(data, axis=-2)[:, :, :self.width, :] + else: + data = numpy.frombuffer(data, dtype) + data = data[:size * (data.size // size)].reshape(shape) + if data.shape[0] < 2: + data = data.reshape(data.shape[1:]) + if data.shape[-1] < 2: + data = data.reshape(data.shape[:-1]) + if self.magicnum == b"P7 332": + rgb332 = numpy.array(list(numpy.ndindex(8, 8, 4)), numpy.uint8) + rgb332 *= [36, 36, 85] + data = numpy.take(rgb332, data, axis=0) + return data + + def _fromdata(self, data, maxval=None): + """Initialize instance from numpy array.""" + data = numpy.array(data, ndmin=2, copy=True) + if data.dtype.kind not in "uib": + raise ValueError("not an integer type: %s" % data.dtype) + if data.dtype.kind == 'i' and numpy.min(data) < 0: + raise ValueError("data out of range: %i" % numpy.min(data)) + if maxval is None: + maxval = numpy.max(data) + maxval = 255 if maxval < 256 else 65535 + if maxval < 0 or maxval > 65535: + raise ValueError("data out of range: %i" % maxval) + data = data.astype('u1' if maxval < 256 else '>u2') + self._data = data + if data.ndim > 2 and data.shape[-1] in (3, 4): + self.depth = data.shape[-1] + self.width = data.shape[-2] + self.height = data.shape[-3] + self.magicnum = b'P7' if self.depth == 4 else b'P6' + else: + self.depth = 1 + self.width = data.shape[-1] + self.height = data.shape[-2] + self.magicnum = b'P5' if maxval > 1 else b'P4' + self.maxval = maxval + self.tupltypes = [self._types[self.magicnum]] + self.header = self._header() + + def _tofile(self, fh, pam=False): + """Write Netbm file.""" + fh.seek(0) + fh.write(self._header(pam)) + data = self.asarray(copy=False) + if self.maxval == 1: + data = numpy.packbits(data, axis=-1) + data.tofile(fh) + + def _header(self, pam=False): + """Return file header as byte string.""" + if pam or self.magicnum == b'P7': + header = "\n".join(( + "P7", + "HEIGHT %i" % self.height, + "WIDTH %i" % self.width, + "DEPTH %i" % self.depth, + "MAXVAL %i" % self.maxval, + "\n".join("TUPLTYPE %s" % unicode(i) for i in self.tupltypes), + "ENDHDR\n")) + elif self.maxval == 1: + header = "P4 %i %i\n" % (self.width, self.height) + elif self.depth == 1: + header = "P5 %i %i %i\n" % (self.width, self.height, self.maxval) + else: + header = "P6 %i %i %i\n" % (self.width, self.height, self.maxval) + if sys.version_info[0] > 2: + header = bytes(header, 'ascii') + return header + + def __str__(self): + """Return information about instance.""" + return unicode(self.header) + +
+if sys.version_info[0] > 2: + basestring = str + unicode = lambda x: str(x, 'ascii') + +if __name__ == "__main__": + # Show images specified on command line or all images in current directory + from glob import glob + from matplotlib import pyplot + files = sys.argv[1:] if len(sys.argv) > 1 else glob('*.p*m') + for fname in files: + try: + pam = NetpbmFile(fname) + img = pam.asarray(copy=False) + if False: + pam.write('_tmp.pgm.out', pam=True) + img2 = imread('_tmp.pgm.out') + assert numpy.all(img == img2) + imsave('_tmp.pgm.out', img) + img2 = imread('_tmp.pgm.out') + assert numpy.all(img == img2) + pam.close() + except ValueError as e: + print(fname, e) + continue + _shape = img.shape + if img.ndim > 3 or (img.ndim > 2 and img.shape[-1] not in (3, 4)): + img = img[0] + cmap = 'gray' if pam.maxval > 1 else 'binary' + pyplot.imshow(img, cmap, interpolation='nearest') + pyplot.title("%s %s %s %s" % (fname, unicode(pam.magicnum), + _shape, img.dtype)) + pyplot.show() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/priors_plots.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/priors_plots.html new file mode 100644 index 00000000..c473829d --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/priors_plots.html @@ -0,0 +1,126 @@ + + + + + + + + GPy.plotting.matplot_dep.priors_plots — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.priors_plots

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+try:
+    import pylab as pb
+except:
+    pass
+
+
+
[docs]def univariate_plot(prior): + rvs = prior.rvs(1000) + pb.hist(rvs, 100, normed=True) + xmin, xmax = pb.xlim() + xx = np.linspace(xmin, xmax, 1000) + pb.plot(xx, prior.pdf(xx), 'r', linewidth=2) +
+
[docs]def plot(prior): + + if prior.input_dim == 2: + rvs = prior.rvs(200) + pb.plot(rvs[:, 0], rvs[:, 1], 'kx', mew=1.5) + xmin, xmax = pb.xlim() + ymin, ymax = pb.ylim() + xx, yy = np.mgrid[xmin:xmax:100j, ymin:ymax:100j] + xflat = np.vstack((xx.flatten(), yy.flatten())).T + zz = prior.pdf(xflat).reshape(100, 100) + pb.contour(xx, yy, zz, linewidths=2) + + else: + raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/ssgplvm.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/ssgplvm.html new file mode 100644 index 00000000..3f30a9e5 --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/ssgplvm.html @@ -0,0 +1,122 @@ + + + + + + + + GPy.plotting.matplot_dep.ssgplvm — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.ssgplvm

+"""
+The module plotting results for SSGPLVM
+"""
+
+import pylab
+
+from ...models import SSGPLVM
+from img_plots import plot_2D_images
+
+
[docs]class SSGPLVM_plot(object): + def __init__(self,model, imgsize): + assert isinstance(model,SSGPLVM) + self.model = model + self.imgsize= imgsize + assert model.Y.shape[1] == imgsize[0]*imgsize[1] + +
[docs] def plot_inducing(self): + fig1 = pylab.figure() + mean = self.model.posterior.mean + arr = mean.reshape(*(mean.shape[0],self.imgsize[1],self.imgsize[0])) + plot_2D_images(fig1, arr) + fig1.gca().set_title('The mean of inducing points') + + fig2 = pylab.figure() + covar = self.model.posterior.covariance + plot_2D_images(fig2, covar) + fig2.gca().set_title('The variance of inducing points') +
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/svig_plots.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/svig_plots.html new file mode 100644 index 00000000..27a58121 --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/svig_plots.html @@ -0,0 +1,137 @@ + + + + + + + + GPy.plotting.matplot_dep.svig_plots — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.svig_plots

+# Copyright (c) 2012, James Hensman and Nicolo' Fusi
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+import pylab as pb
+
+
+
[docs]def plot(model, ax=None, fignum=None, Z_height=None, **kwargs): + + if ax is None: + fig = pb.figure(num=fignum) + ax = fig.add_subplot(111) + + #horrible hack here: + data = model.likelihood.data.copy() + model.likelihood.data = model.Y + GP.plot(model, ax=ax, **kwargs) + model.likelihood.data = data + + Zu = model.Z * model._Xscale + model._Xoffset + if model.input_dim==1: + ax.plot(model.X_batch, model.likelihood.data, 'gx',mew=2) + if Z_height is None: + Z_height = ax.get_ylim()[0] + ax.plot(Zu, np.zeros_like(Zu) + Z_height, 'r|', mew=1.5, markersize=12) + + if model.input_dim==2: + ax.scatter(model.X[:,0], model.X[:,1], 20., model.Y[:,0], linewidth=0, cmap=pb.cm.jet) # @UndefinedVariable + ax.plot(Zu[:,0], Zu[:,1], 'w^') +
+
[docs]def plot_traces(model): + + pb.figure() + t = np.array(model._param_trace) + pb.subplot(2,1,1) + for l,ti in zip(model._get_param_names(),t.T): + if not l[:3]=='iip': + pb.plot(ti,label=l) + pb.legend(loc=0) + + pb.subplot(2,1,2) + pb.plot(np.asarray(model._ll_trace),label='stochastic likelihood') + pb.legend(loc=0)
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/variational_plots.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/variational_plots.html new file mode 100644 index 00000000..91f7b038 --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/variational_plots.html @@ -0,0 +1,194 @@ + + + + + + + + GPy.plotting.matplot_dep.variational_plots — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.variational_plots

+import pylab as pb, numpy as np
+
+
[docs]def plot(parameterized, fignum=None, ax=None, colors=None): + """ + Plot latent space X in 1D: + + - if fig is given, create input_dim subplots in fig and plot in these + - if ax is given plot input_dim 1D latent space plots of X into each `axis` + - if neither fig nor ax is given create a figure with fignum and plot in there + + colors: + colors of different latent space dimensions input_dim + + """ + if ax is None: + fig = pb.figure(num=fignum, figsize=(8, min(12, (2 * parameterized.mean.shape[1])))) + if colors is None: + colors = pb.gca()._get_lines.color_cycle + pb.clf() + else: + colors = iter(colors) + plots = [] + means, variances = parameterized.mean, parameterized.variance + x = np.arange(means.shape[0]) + for i in range(means.shape[1]): + if ax is None: + a = fig.add_subplot(means.shape[1], 1, i + 1) + elif isinstance(ax, (tuple, list)): + a = ax[i] + else: + raise ValueError("Need one ax per latent dimension input_dim") + a.plot(means, c='k', alpha=.3) + plots.extend(a.plot(x, means.T[i], c=colors.next(), label=r"$\mathbf{{X_{{{}}}}}$".format(i))) + a.fill_between(x, + means.T[i] - 2 * np.sqrt(variances.T[i]), + means.T[i] + 2 * np.sqrt(variances.T[i]), + facecolor=plots[-1].get_color(), + alpha=.3) + a.legend(borderaxespad=0.) + a.set_xlim(x.min(), x.max()) + if i < means.shape[1] - 1: + a.set_xticklabels('') + pb.draw() + fig.tight_layout(h_pad=.01) # , rect=(0, 0, 1, .95)) + return fig +
+
[docs]def plot_SpikeSlab(parameterized, fignum=None, ax=None, colors=None, side_by_side=True): + """ + Plot latent space X in 1D: + + - if fig is given, create input_dim subplots in fig and plot in these + - if ax is given plot input_dim 1D latent space plots of X into each `axis` + - if neither fig nor ax is given create a figure with fignum and plot in there + + colors: + colors of different latent space dimensions input_dim + + """ + if ax is None: + if side_by_side: + fig = pb.figure(num=fignum, figsize=(16, min(12, (2 * parameterized.mean.shape[1])))) + else: + fig = pb.figure(num=fignum, figsize=(8, min(12, (2 * parameterized.mean.shape[1])))) + if colors is None: + colors = pb.gca()._get_lines.color_cycle + pb.clf() + else: + colors = iter(colors) + plots = [] + means, variances, gamma = parameterized.mean, parameterized.variance, parameterized.binary_prob + x = np.arange(means.shape[0]) + for i in range(means.shape[1]): + if side_by_side: + sub1 = (means.shape[1],2,2*i+1) + sub2 = (means.shape[1],2,2*i+2) + else: + sub1 = (means.shape[1]*2,1,2*i+1) + sub2 = (means.shape[1]*2,1,2*i+2) + + # mean and variance plot + a = fig.add_subplot(*sub1) + a.plot(means, c='k', alpha=.3) + plots.extend(a.plot(x, means.T[i], c=colors.next(), label=r"$\mathbf{{X_{{{}}}}}$".format(i))) + a.fill_between(x, + means.T[i] - 2 * np.sqrt(variances.T[i]), + means.T[i] + 2 * np.sqrt(variances.T[i]), + facecolor=plots[-1].get_color(), + alpha=.3) + a.legend(borderaxespad=0.) + a.set_xlim(x.min(), x.max()) + if i < means.shape[1] - 1: + a.set_xticklabels('') + # binary prob plot + a = fig.add_subplot(*sub2) + a.bar(x,gamma[:,i],bottom=0.,linewidth=0,width=1.0,align='center') + a.set_xlim(x.min(), x.max()) + a.set_ylim([0.,1.]) + pb.draw() + fig.tight_layout(h_pad=.01) # , rect=(0, 0, 1, .95)) + return fig
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/plotting/matplot_dep/visualize.html b/doc/_build/html/_modules/GPy/plotting/matplot_dep/visualize.html new file mode 100644 index 00000000..79e232c1 --- /dev/null +++ b/doc/_build/html/_modules/GPy/plotting/matplot_dep/visualize.html @@ -0,0 +1,656 @@ + + + + + + + + GPy.plotting.matplot_dep.visualize — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.plotting.matplot_dep.visualize

+import matplotlib.pyplot as plt
+from mpl_toolkits.mplot3d import Axes3D
+import GPy
+import numpy as np
+import matplotlib as mpl
+import time
+from GPy.core.parameterization.variational import VariationalPosterior
+try:
+    import visual
+    visual_available = True
+
+except ImportError:
+    visual_available = False
+
+
+
[docs]class data_show: + """ + The data_show class is a base class which describes how to visualize a + particular data set. For example, motion capture data can be plotted as a + stick figure, or images are shown using imshow. This class enables latent + to data visualizations for the GP-LVM. + """ + def __init__(self, vals): + self.vals = vals.copy() + # If no axes are defined, create some. + +
[docs] def modify(self, vals): + raise NotImplementedError, "this needs to be implemented to use the data_show class" +
+
[docs] def close(self): + raise NotImplementedError, "this needs to be implemented to use the data_show class" +
+
[docs]class vpython_show(data_show): + """ + the vpython_show class is a base class for all visualization methods that use vpython to display. It is initialized with a scene. If the scene is set to None it creates a scene window. + """ + + def __init__(self, vals, scene=None): + data_show.__init__(self, vals) + # If no axes are defined, create some. + + if scene==None: + self.scene = visual.display(title='Data Visualization') + else: + self.scene = scene + +
[docs] def close(self): + self.scene.exit() + + +
+
[docs]class matplotlib_show(data_show): + """ + the matplotlib_show class is a base class for all visualization methods that use matplotlib. It is initialized with an axis. If the axis is set to None it creates a figure window. + """ + def __init__(self, vals, axes=None): + data_show.__init__(self, vals) + # If no axes are defined, create some. + + if axes==None: + fig = plt.figure() + self.axes = fig.add_subplot(111) + else: + self.axes = axes + +
[docs] def close(self): + plt.close(self.axes.get_figure()) +
+
[docs]class vector_show(matplotlib_show): + """ + A base visualization class that just shows a data vector as a plot of + vector elements alongside their indices. + """ + def __init__(self, vals, axes=None): + matplotlib_show.__init__(self, vals, axes) + #assert vals.ndim == 2, "Please give a vector in [n x 1] to plot" + #assert vals.shape[1] == 1, "only showing a vector in one dimension" + self.size = vals.size + self.handle = self.axes.plot(np.arange(0, vals.size)[:, None], vals)[0] + +
[docs] def modify(self, vals): + self.vals = vals.copy() + xdata, ydata = self.handle.get_data() + assert vals.size == self.size, "values passed into modify changed size! vals.size:{} != in.size:{}".format(vals.size, self.size) + self.handle.set_data(xdata, self.vals) + self.axes.figure.canvas.draw() + +
+
[docs]class lvm(matplotlib_show): + def __init__(self, vals, model, data_visualize, latent_axes=None, sense_axes=None, latent_index=[0,1], disable_drag=False): + """Visualize a latent variable model + + :param model: the latent variable model to visualize. + :param data_visualize: the object used to visualize the data which has been modelled. + :type data_visualize: visualize.data_show type. + :param latent_axes: the axes where the latent visualization should be plotted. + """ + if vals is None: + if isinstance(model.X, VariationalPosterior): + vals = model.X.mean.values + else: + vals = model.X.values + if len(vals.shape)==1: + vals = vals[None,:] + matplotlib_show.__init__(self, vals, axes=latent_axes) + + if isinstance(latent_axes,mpl.axes.Axes): + self.cid = latent_axes.figure.canvas.mpl_connect('button_press_event', self.on_click) + if not disable_drag: + self.cid = latent_axes.figure.canvas.mpl_connect('motion_notify_event', self.on_move) + self.cid = latent_axes.figure.canvas.mpl_connect('axes_leave_event', self.on_leave) + self.cid = latent_axes.figure.canvas.mpl_connect('axes_enter_event', self.on_enter) + else: + self.cid = latent_axes[0].figure.canvas.mpl_connect('button_press_event', self.on_click) + if not disable_drag: + self.cid = latent_axes[0].figure.canvas.mpl_connect('motion_notify_event', self.on_move) + self.cid = latent_axes[0].figure.canvas.mpl_connect('axes_leave_event', self.on_leave) + self.cid = latent_axes[0].figure.canvas.mpl_connect('axes_enter_event', self.on_enter) + + self.data_visualize = data_visualize + self.model = model + self.latent_axes = latent_axes + self.sense_axes = sense_axes + self.called = False + self.move_on = False + self.latent_index = latent_index + self.latent_dim = model.input_dim + self.disable_drag = disable_drag + + # The red cross which shows current latent point. + self.latent_values = vals + self.latent_handle = self.latent_axes.plot([0],[0],'rx',mew=2)[0] + self.modify(vals) + self.show_sensitivities() + +
[docs] def modify(self, vals): + """When latent values are modified update the latent representation and ulso update the output visualization.""" + self.vals = vals.view(np.ndarray).copy() + y = self.model.predict(self.vals)[0] + self.data_visualize.modify(y) + self.latent_handle.set_data(self.vals[0,self.latent_index[0]], self.vals[0,self.latent_index[1]]) + self.axes.figure.canvas.draw() + +
+
[docs] def on_enter(self,event): + pass
+
[docs] def on_leave(self,event): + pass +
+
[docs] def on_click(self, event): + if event.inaxes!=self.latent_axes: return + if self.disable_drag: + self.move_on = True + self.called = True + self.on_move(event) + else: + self.move_on = not self.move_on + self.called = True +
+
[docs] def on_move(self, event): + if event.inaxes!=self.latent_axes: return + if self.called and self.move_on: + # Call modify code on move + self.latent_values[:, self.latent_index[0]]=event.xdata + self.latent_values[:, self.latent_index[1]]=event.ydata + self.modify(self.latent_values) +
+
[docs] def show_sensitivities(self): + # A click in the bar chart axis for selection a dimension. + if self.sense_axes != None: + self.sense_axes.cla() + self.sense_axes.bar(np.arange(self.model.input_dim), self.model.input_sensitivity(), color='b') + + if self.latent_index[1] == self.latent_index[0]: + self.sense_axes.bar(np.array(self.latent_index[0]), self.model.input_sensitivity()[self.latent_index[0]], color='y') + self.sense_axes.bar(np.array(self.latent_index[1]), self.model.input_sensitivity()[self.latent_index[1]], color='y') + + else: + self.sense_axes.bar(np.array(self.latent_index[0]), self.model.input_sensitivity()[self.latent_index[0]], color='g') + self.sense_axes.bar(np.array(self.latent_index[1]), self.model.input_sensitivity()[self.latent_index[1]], color='r') + + self.sense_axes.figure.canvas.draw() + +
+
[docs]class lvm_subplots(lvm): + """ + latent_axes is a np array of dimension np.ceil(input_dim/2), + one for each pair of the latent dimensions. + """ + def __init__(self, vals, Model, data_visualize, latent_axes=None, sense_axes=None): + self.nplots = int(np.ceil(Model.input_dim/2.))+1 + assert len(latent_axes)==self.nplots + if vals==None: + vals = Model.X[0, :] + self.latent_values = vals + + for i, axis in enumerate(latent_axes): + if i == self.nplots-1: + if self.nplots*2!=Model.input_dim: + latent_index = [i*2, i*2] + lvm.__init__(self, self.latent_vals, Model, data_visualize, axis, sense_axes, latent_index=latent_index) + else: + latent_index = [i*2, i*2+1] + lvm.__init__(self, self.latent_vals, Model, data_visualize, axis, latent_index=latent_index) + + +
+
[docs]class lvm_dimselect(lvm): + """ + A visualizer for latent variable models which allows selection of the latent dimensions to use by clicking on a bar chart of their length scales. + + For an example of the visualizer's use try: + + GPy.examples.dimensionality_reduction.BGPVLM_oil() + + """ + def __init__(self, vals, model, data_visualize, latent_axes=None, sense_axes=None, latent_index=[0, 1], labels=None): + if latent_axes==None and sense_axes==None: + self.fig,(latent_axes,self.sense_axes) = plt.subplots(1,2) + elif sense_axes==None: + fig=plt.figure() + self.sense_axes = fig.add_subplot(111) + else: + self.sense_axes = sense_axes + self.labels = labels + lvm.__init__(self,vals,model,data_visualize,latent_axes,sense_axes,latent_index) + self.show_sensitivities() + print self.latent_values + print "use left and right mouse buttons to select dimensions" + + +
[docs] def on_click(self, event): + if event.inaxes==self.sense_axes: + new_index = max(0,min(int(np.round(event.xdata-0.5)),self.model.input_dim-1)) + if event.button == 1: + # Make it red if and y-axis (red=port=left) if it is a left button click + self.latent_index[1] = new_index + else: + # Make it green and x-axis (green=starboard=right) if it is a right button click + self.latent_index[0] = new_index + + self.show_sensitivities() + + self.latent_axes.cla() + self.model.plot_latent(which_indices=self.latent_index, + ax=self.latent_axes, labels=self.labels) + self.latent_handle = self.latent_axes.plot([0],[0],'rx',mew=2)[0] + self.modify(self.latent_values) + + elif event.inaxes==self.latent_axes: + self.move_on = not self.move_on + + self.called = True + + +
+
[docs] def on_leave(self,event): + print type(self.latent_values) + latent_values = self.latent_values.copy() + y = self.model.predict(latent_values[None,:])[0] + self.data_visualize.modify(y) + + +
+
[docs]class image_show(matplotlib_show): + """Show a data vector as an image. This visualizer rehapes the output vector and displays it as an image. + + :param vals: the values of the output to display. + :type vals: ndarray + :param axes: the axes to show the output on. + :type vals: axes handle + :param dimensions: the dimensions that the image needs to be transposed to for display. + :type dimensions: tuple + :param transpose: whether to transpose the image before display. + :type bool: default is False. + :param order: whether array is in Fortan ordering ('F') or Python ordering ('C'). Default is python ('C'). + :type order: string + :param invert: whether to invert the pixels or not (default False). + :type invert: bool + :param palette: a palette to use for the image. + :param preset_mean: the preset mean of a scaled image. + :type preset_mean: double + :param preset_std: the preset standard deviation of a scaled image. + :type preset_std: double + :param cmap: the colormap for image visualization + :type cmap: matplotlib.cm""" + + def __init__(self, vals, axes=None, dimensions=(16,16), transpose=False, order='C', invert=False, scale=False, palette=[], preset_mean=0., preset_std=1., select_image=0, cmap=None): + matplotlib_show.__init__(self, vals, axes) + self.dimensions = dimensions + self.transpose = transpose + self.order = order + self.invert = invert + self.scale = scale + self.palette = palette + self.preset_mean = preset_mean + self.preset_std = preset_std + self.select_image = select_image # This is used when the y vector contains multiple images concatenated. + + self.set_image(self.vals) + if not self.palette == []: # Can just show the image (self.set_image() took care of setting the palette) + self.handle = self.axes.imshow(self.vals, interpolation='nearest') + elif cmap==None: # Use a jet map. + self.handle = self.axes.imshow(self.vals, cmap=plt.cm.jet, interpolation='nearest') # @UndefinedVariable + else: # Use the selected map. + self.handle = self.axes.imshow(self.vals, cmap=cmap, interpolation='nearest') # @UndefinedVariable + plt.show() + +
[docs] def modify(self, vals): + self.set_image(vals.copy()) + self.handle.set_array(self.vals) + self.axes.figure.canvas.draw() +
+
[docs] def set_image(self, vals): + dim = self.dimensions[0] * self.dimensions[1] + num_images = np.sqrt(vals[0,].size/dim) + if num_images > 1 and num_images.is_integer(): # Show a mosaic of images + num_images = np.int(num_images) + self.vals = np.zeros((self.dimensions[0]*num_images, self.dimensions[1]*num_images)) + for iR in range(num_images): + for iC in range(num_images): + cur_img_id = iR*num_images + iC + cur_img = np.reshape(vals[0,dim*cur_img_id+np.array(range(dim))], self.dimensions, order=self.order) + first_row = iR*self.dimensions[0] + last_row = (iR+1)*self.dimensions[0] + first_col = iC*self.dimensions[1] + last_col = (iC+1)*self.dimensions[1] + self.vals[first_row:last_row, first_col:last_col] = cur_img + + else: + self.vals = np.reshape(vals[0,dim*self.select_image+np.array(range(dim))], self.dimensions, order=self.order) + if self.transpose: + self.vals = self.vals.T + # if not self.scale: + # self.vals = self.vals + if self.invert: + self.vals = -self.vals + + # un-normalizing, for visualisation purposes: + self.vals = self.vals*self.preset_std + self.preset_mean + # Clipping the values: + #self.vals[self.vals < 0] = 0 + #self.vals[self.vals > 255] = 255 + #else: + #self.vals = 255*(self.vals - self.vals.min())/(self.vals.max() - self.vals.min()) + if not self.palette == []: # applying using an image palette (e.g. if the image has been quantized) + from PIL import Image + self.vals = Image.fromarray(self.vals.astype('uint8')) + self.vals.putpalette(self.palette) # palette is a list, must be loaded before calling this function +
+
[docs]class mocap_data_show_vpython(vpython_show): + """Base class for visualizing motion capture data using visual module.""" + + def __init__(self, vals, scene=None, connect=None, radius=0.1): + vpython_show.__init__(self, vals, scene) + self.radius = radius + self.connect = connect + self.process_values() + self.draw_edges() + self.draw_vertices() + +
[docs] def draw_vertices(self): + self.spheres = [] + for i in range(self.vals.shape[0]): + self.spheres.append(visual.sphere(pos=(self.vals[i, 0], self.vals[i, 2], self.vals[i, 1]), radius=self.radius)) + self.scene.visible=True +
+
[docs] def draw_edges(self): + self.rods = [] + self.line_handle = [] + if not self.connect==None: + self.I, self.J = np.nonzero(self.connect) + for i, j in zip(self.I, self.J): + pos, axis = self.pos_axis(i, j) + self.rods.append(visual.cylinder(pos=pos, axis=axis, radius=self.radius)) +
+
[docs] def modify_vertices(self): + for i in range(self.vals.shape[0]): + self.spheres[i].pos = (self.vals[i, 0], self.vals[i, 2], self.vals[i, 1]) +
+
[docs] def modify_edges(self): + self.line_handle = [] + if not self.connect==None: + self.I, self.J = np.nonzero(self.connect) + for rod, i, j in zip(self.rods, self.I, self.J): + rod.pos, rod.axis = self.pos_axis(i, j) +
+
[docs] def pos_axis(self, i, j): + pos = [] + axis = [] + pos.append(self.vals[i, 0]) + axis.append(self.vals[j, 0]-self.vals[i,0]) + pos.append(self.vals[i, 2]) + axis.append(self.vals[j, 2]-self.vals[i,2]) + pos.append(self.vals[i, 1]) + axis.append(self.vals[j, 1]-self.vals[i,1]) + return pos, axis +
+
[docs] def modify(self, vals): + self.vals = vals.copy() + self.process_values() + self.modify_edges() + self.modify_vertices() +
+
[docs] def process_values(self): + raise NotImplementedError, "this needs to be implemented to use the data_show class" +
+
[docs]class mocap_data_show(matplotlib_show): + """Base class for visualizing motion capture data.""" + + def __init__(self, vals, axes=None, connect=None): + if axes==None: + fig = plt.figure() + axes = fig.add_subplot(111, projection='3d', aspect='equal') + matplotlib_show.__init__(self, vals, axes) + + self.connect = connect + self.process_values() + self.initialize_axes() + self.draw_vertices() + self.finalize_axes() + self.draw_edges() + self.axes.figure.canvas.draw() + +
[docs] def draw_vertices(self): + self.points_handle = self.axes.scatter(self.vals[:, 0], self.vals[:, 1], self.vals[:, 2]) +
+
[docs] def draw_edges(self): + self.line_handle = [] + if not self.connect==None: + x = [] + y = [] + z = [] + self.I, self.J = np.nonzero(self.connect) + for i, j in zip(self.I, self.J): + x.append(self.vals[i, 0]) + x.append(self.vals[j, 0]) + x.append(np.NaN) + y.append(self.vals[i, 1]) + y.append(self.vals[j, 1]) + y.append(np.NaN) + z.append(self.vals[i, 2]) + z.append(self.vals[j, 2]) + z.append(np.NaN) + self.line_handle = self.axes.plot(np.array(x), np.array(y), np.array(z), 'b-') +
+
[docs] def modify(self, vals): + self.vals = vals.copy() + self.process_values() + self.initialize_axes_modify() + self.draw_vertices() + self.initialize_axes() + self.finalize_axes_modify() + self.draw_edges() + self.axes.figure.canvas.draw() +
+
[docs] def process_values(self): + raise NotImplementedError, "this needs to be implemented to use the data_show class" +
+
[docs] def initialize_axes(self, boundary=0.05): + """Set up the axes with the right limits and scaling.""" + bs = [(self.vals[:, i].max()-self.vals[:, i].min())*boundary for i in xrange(3)] + self.x_lim = np.array([self.vals[:, 0].min()-bs[0], self.vals[:, 0].max()+bs[0]]) + self.y_lim = np.array([self.vals[:, 1].min()-bs[1], self.vals[:, 1].max()+bs[1]]) + self.z_lim = np.array([self.vals[:, 2].min()-bs[2], self.vals[:, 2].max()+bs[2]]) +
+
[docs] def initialize_axes_modify(self): + self.points_handle.remove() + self.line_handle[0].remove() +
+
[docs] def finalize_axes(self): + self.axes.set_xlim(self.x_lim) + self.axes.set_ylim(self.y_lim) + self.axes.set_zlim(self.z_lim) + self.axes.auto_scale_xyz([-1., 1.], [-1., 1.], [-1., 1.]) + +# self.axes.set_aspect('equal') +# self.axes.autoscale(enable=False) +
+
[docs] def finalize_axes_modify(self): + self.axes.set_xlim(self.x_lim) + self.axes.set_ylim(self.y_lim) + self.axes.set_zlim(self.z_lim) +
+
[docs]class stick_show(mocap_data_show): + """Show a three dimensional point cloud as a figure. Connect elements of the figure together using the matrix connect.""" + def __init__(self, vals, connect=None, axes=None): + if len(vals.shape)==1: + vals = vals[None,:] + mocap_data_show.__init__(self, vals, axes=axes, connect=connect) + +
[docs] def process_values(self): + self.vals = self.vals.reshape((3, self.vals.shape[1]/3)).T +
+
[docs]class skeleton_show(mocap_data_show): + """data_show class for visualizing motion capture data encoded as a skeleton with angles.""" + def __init__(self, vals, skel, axes=None, padding=0): + """data_show class for visualizing motion capture data encoded as a skeleton with angles. + :param vals: set of modeled angles to use for printing in the axis when it's first created. + :type vals: np.array + :param skel: skeleton object that has the parameters of the motion capture skeleton associated with it. + :type skel: mocap.skeleton object + :param padding: + :type int + """ + self.skel = skel + self.padding = padding + connect = skel.connection_matrix() + mocap_data_show.__init__(self, vals, axes=axes, connect=connect) +
[docs] def process_values(self): + """Takes a set of angles and converts them to the x,y,z coordinates in the internal prepresentation of the class, ready for plotting. + + :param vals: the values that are being modelled.""" + + if self.padding>0: + channels = np.zeros((self.vals.shape[0], self.vals.shape[1]+self.padding)) + channels[:, 0:self.vals.shape[0]] = self.vals + else: + channels = self.vals + vals_mat = self.skel.to_xyz(channels.flatten()) + self.vals = np.zeros_like(vals_mat) + # Flip the Y and Z axes + self.vals[:, 0] = vals_mat[:, 0].copy() + self.vals[:, 1] = vals_mat[:, 2].copy() + self.vals[:, 2] = vals_mat[:, 1].copy() +
+
[docs] def wrap_around(self, lim, connect): + quot = lim[1] - lim[0] + self.vals = rem(self.vals, quot)+lim[0] + nVals = floor(self.vals/quot) + for i in range(connect.shape[0]): + for j in find(connect[i, :]): + if nVals[i] != nVals[j]: + connect[i, j] = False + return connect + +
+
[docs]def data_play(Y, visualizer, frame_rate=30): + """Play a data set using the data_show object given. + + :Y: the data set to be visualized. + :param visualizer: the data show objectwhether to display during optimisation + :type visualizer: data_show + + Example usage: + + This example loads in the CMU mocap database (http://mocap.cs.cmu.edu) subject number 35 motion number 01. It then plays it using the mocap_show visualize object. + + .. code-block:: python + + data = GPy.util.datasets.cmu_mocap(subject='35', train_motions=['01']) + Y = data['Y'] + Y[:, 0:3] = 0. # Make figure walk in place + visualize = GPy.util.visualize.skeleton_show(Y[0, :], data['skel']) + GPy.util.visualize.data_play(Y, visualize) + + """ + + + for y in Y: + visualizer.modify(y[None, :]) + time.sleep(1./float(frame_rate))
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing.html b/doc/_build/html/_modules/GPy/testing.html new file mode 100644 index 00000000..2491ec56 --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing.html @@ -0,0 +1,108 @@ + + + + + + + + GPy.testing — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing

+# Copyright (c) 2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+"""
+
+MaxZ
+
+"""
+import unittest
+import sys
+
+
[docs]def deepTest(reason): + if reason: + return lambda x:x + return unittest.skip("Not deep scanning, enable deepscan by adding 'deep' argument")
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/examples_tests.html b/doc/_build/html/_modules/GPy/testing/examples_tests.html new file mode 100644 index 00000000..f25d2c91 --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/examples_tests.html @@ -0,0 +1,201 @@ + + + + + + + + GPy.testing.examples_tests — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.examples_tests

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import unittest
+import numpy as np
+import GPy
+import inspect
+import pkgutil
+import os
+import random
+from nose.tools import nottest
+import sys
+import itertools
+
+
[docs]class ExamplesTests(unittest.TestCase): + def _checkgrad(self, Model): + self.assertTrue(Model.checkgrad()) + + def _model_instance(self, Model): + self.assertTrue(isinstance(Model, GPy.models)) +
+
[docs]def model_checkgrads(model): + model.randomize() + #NOTE: Step as 1e-4, this should be acceptable for more peaky models + return model.checkgrad(step=1e-4) +
+
[docs]def model_instance(model): + return isinstance(model, GPy.core.model.Model) +
+
[docs]def flatten_nested(lst): + result = [] + for element in lst: + if hasattr(element, '__iter__'): + result.extend(flatten_nested(element)) + else: + result.append(element) + return result +
+@nottest +
[docs]def test_models(): + optimize=False + plot=True + examples_path = os.path.dirname(GPy.examples.__file__) + # Load modules + failing_models = {} + for loader, module_name, is_pkg in pkgutil.iter_modules([examples_path]): + # Load examples + module_examples = loader.find_module(module_name).load_module(module_name) + print "MODULE", module_examples + print "Before" + print inspect.getmembers(module_examples, predicate=inspect.isfunction) + functions = [ func for func in inspect.getmembers(module_examples, predicate=inspect.isfunction) if func[0].startswith('_') is False ][::-1] + print "After" + print functions + for example in functions: + if example[0] in ['epomeo_gpx']: + #These are the edge cases that we might want to handle specially + if example[0] == 'epomeo_gpx' and not GPy.util.datasets.gpxpy_available: + print "Skipping as gpxpy is not available to parse GPS" + continue + + print "Testing example: ", example[0] + # Generate model + + try: + models = [ example[1](optimize=optimize, plot=plot) ] + #If more than one model returned, flatten them + models = flatten_nested(models) + except Exception as e: + failing_models[example[0]] = "Cannot make model: \n{e}".format(e=e) + else: + print models + model_checkgrads.description = 'test_checkgrads_%s' % example[0] + try: + for model in models: + if not model_checkgrads(model): + failing_models[model_checkgrads.description] = False + except Exception as e: + failing_models[model_checkgrads.description] = e + + model_instance.description = 'test_instance_%s' % example[0] + try: + for model in models: + if not model_instance(model): + failing_models[model_instance.description] = False + except Exception as e: + failing_models[model_instance.description] = e + + #yield model_checkgrads, model + #yield model_instance, model + + print "Finished checking module {m}".format(m=module_name) + if len(failing_models.keys()) > 0: + print "Failing models: " + print failing_models + + if len(failing_models.keys()) > 0: + print failing_models + raise Exception(failing_models) + +
+if __name__ == "__main__": + print "Running unit tests, please be (very) patient..." + # unittest.main() + test_models() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/fitc.html b/doc/_build/html/_modules/GPy/testing/fitc.html new file mode 100644 index 00000000..bc6de069 --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/fitc.html @@ -0,0 +1,129 @@ + + + + + + + + GPy.testing.fitc — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.fitc

+# Copyright (c) 2014, James Hensman
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import unittest
+import numpy as np
+import GPy
+
+
[docs]class FITCtest(unittest.TestCase): +
[docs] def setUp(self): + ###################################### + # # 1 dimensional example + + N = 20 + # sample inputs and outputs + self.X1D = np.random.uniform(-3., 3., (N, 1)) + self.Y1D = np.sin(self.X1D) + np.random.randn(N, 1) * 0.05 + + ###################################### + # # 2 dimensional example + + # sample inputs and outputs + self.X2D = np.random.uniform(-3., 3., (N, 2)) + self.Y2D = np.sin(self.X2D[:, 0:1]) * np.sin(self.X2D[:, 1:2]) + np.random.randn(N, 1) * 0.05 +
+
[docs] def test_fitc_1d(self): + m = GPy.models.SparseGPRegression(self.X1D, self.Y1D) + m.inference_method=GPy.inference.latent_function_inference.FITC() + self.assertTrue(m.checkgrad()) +
+
[docs] def test_fitc_2d(self): + m = GPy.models.SparseGPRegression(self.X2D, self.Y2D) + m.inference_method=GPy.inference.latent_function_inference.FITC() + self.assertTrue(m.checkgrad()) +
+ +
+
+ + +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/index_operations_tests.html b/doc/_build/html/_modules/GPy/testing/index_operations_tests.html new file mode 100644 index 00000000..ffb20ca9 --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/index_operations_tests.html @@ -0,0 +1,231 @@ + + + + + + + + GPy.testing.index_operations_tests — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.index_operations_tests

+# Copyright (c) 2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import unittest
+import numpy as np
+from GPy.core.parameterization.index_operations import ParameterIndexOperations,\
+    ParameterIndexOperationsView
+
+one, two, three = 'one', 'two', 'three'
+
+
[docs]class Test(unittest.TestCase): + +
[docs] def setUp(self): + self.param_index = ParameterIndexOperations() + self.param_index.add(one, [3,9]) + self.param_index.add(two, [0,5]) + self.param_index.add(three, [2,4,7,10]) + self.view = ParameterIndexOperationsView(self.param_index, 2, 6) +
+
[docs] def test_clear(self): + self.param_index.clear() + self.assertDictEqual(self.param_index._properties, {}) +
+
[docs] def test_remove(self): + removed = self.param_index.remove(three, np.r_[3:13]) + self.assertListEqual(removed.tolist(), [4,7,10]) + self.assertListEqual(self.param_index[three].tolist(), [2]) + removed = self.param_index.remove(one, [1]) + self.assertListEqual(removed.tolist(), []) + self.assertListEqual(self.param_index[one].tolist(), [3,9]) + self.assertListEqual(self.param_index.remove('not in there', []).tolist(), []) + removed = self.param_index.remove(one, [9]) + self.assertListEqual(removed.tolist(), [9]) + self.assertListEqual(self.param_index[one].tolist(), [3]) + self.assertListEqual(self.param_index.remove('not in there', [2,3,4]).tolist(), []) + self.assertListEqual(self.view.remove('not in there', [2,3,4]).tolist(), []) +
+
[docs] def test_shift_left(self): + self.view.shift_left(0, 2) + self.assertListEqual(self.param_index[three].tolist(), [2,5,8]) + self.assertListEqual(self.param_index[two].tolist(), [0,3]) + self.assertListEqual(self.param_index[one].tolist(), [7]) + #======================================================================= + # 0 1 2 3 4 5 6 7 8 9 10 + # one + # two two + # three three three + # view: [0 1 2 3 4 5 ] + #======================================================================= + self.assertListEqual(self.view[three].tolist(), [0,3]) + self.assertListEqual(self.view[two].tolist(), [1]) + self.assertListEqual(self.view[one].tolist(), [5]) + self.param_index.shift_left(7, 1) + #======================================================================= + # 0 1 2 3 4 5 6 7 8 9 10 + # + # two two + # three three three + # view: [0 1 2 3 4 5 ] + #======================================================================= + self.assertListEqual(self.param_index[three].tolist(), [2,5,7]) + self.assertListEqual(self.param_index[two].tolist(), [0,3]) + self.assertListEqual(self.param_index[one].tolist(), []) + self.assertListEqual(self.view[three].tolist(), [0,3,5]) + self.assertListEqual(self.view[two].tolist(), [1]) + self.assertListEqual(self.view[one].tolist(), []) +
+
[docs] def test_shift_right(self): + self.view.shift_right(3, 2) + self.assertListEqual(self.param_index[three].tolist(), [2,4,9,12]) + self.assertListEqual(self.param_index[two].tolist(), [0,7]) + self.assertListEqual(self.param_index[one].tolist(), [3,11]) +
+
[docs] def test_index_view(self): + #======================================================================= + # 0 1 2 3 4 5 6 7 8 9 10 + # one one + # two two + # three three three three + # view: [0 1 2 3 4 5 ] + #======================================================================= + self.view = ParameterIndexOperationsView(self.param_index, 2, 6) + self.assertSetEqual(set(self.view.properties()), set([one, two, three])) + for v,p in zip(self.view.properties_for(np.r_[:6]), self.param_index.properties_for(np.r_[2:2+6])): + self.assertEqual(v, p) + self.assertSetEqual(set(self.view[two]), set([3])) + self.assertSetEqual(set(self.param_index[two]), set([0, 5])) + self.view.add(two, np.array([0])) + self.assertSetEqual(set(self.view[two]), set([0,3])) + self.assertSetEqual(set(self.param_index[two]), set([0, 2, 5])) + self.view.clear() + for v,p in zip(self.view.properties_for(np.r_[:6]), self.param_index.properties_for(np.r_[2:2+6])): + self.assertEqual(v, p) + self.assertEqual(v, []) + param_index = ParameterIndexOperations() + param_index.add(one, [3,9]) + param_index.add(two, [0,5]) + param_index.add(three, [2,4,7,10]) + view2 = ParameterIndexOperationsView(param_index, 2, 8) + self.view.update(view2) + for [i,v],[i2,v2] in zip(sorted(param_index.items()), sorted(self.param_index.items())): + self.assertEqual(i, i2) + np.testing.assert_equal(v, v2) +
+
[docs] def test_view_of_view(self): + #======================================================================= + # 0 1 2 3 4 5 6 7 8 9 10 + # one one + # two two + # three three three three + # view: [0 1 2 3 4 5 ] + # view2: [0 1 2 3 4 5 ] + #======================================================================= + view2 = ParameterIndexOperationsView(self.view, 2, 6) + view2.shift_right(0, 2) +
+
[docs] def test_indexview_remove(self): + removed = self.view.remove(two, [3]) + self.assertListEqual(removed.tolist(), [3]) + removed = self.view.remove(three, np.r_[:5]) + self.assertListEqual(removed.tolist(), [0, 2]) +
+
[docs] def test_misc(self): + for k,v in self.param_index.copy()._properties.iteritems(): + self.assertListEqual(self.param_index[k].tolist(), v.tolist()) + self.assertEqual(self.param_index.size, 8) + self.assertEqual(self.view.size, 5) +
+
[docs] def test_print(self): + print self.param_index + print self.view +
+if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.test_index_view'] + unittest.main() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/inference_tests.html b/doc/_build/html/_modules/GPy/testing/inference_tests.html new file mode 100644 index 00000000..200f2790 --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/inference_tests.html @@ -0,0 +1,180 @@ + + + + + + + + GPy.testing.inference_tests — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.inference_tests

+# Copyright (c) 2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+"""
+The test cases for various inference algorithms
+"""
+
+import unittest, itertools
+import numpy as np
+import GPy
+
+
+
[docs]class InferenceXTestCase(unittest.TestCase): + +
[docs] def genData(self): + D1,D2,N = 12,12,50 + np.random.seed(1234) + + x = np.linspace(0, 4 * np.pi, N)[:, None] + s1 = np.vectorize(lambda x: np.sin(x)) + s2 = np.vectorize(lambda x: np.cos(x)**2) + s3 = np.vectorize(lambda x:-np.exp(-np.cos(2 * x))) + sS = np.vectorize(lambda x: np.cos(x)) + + s1 = s1(x) + s2 = s2(x) + s3 = s3(x) + sS = sS(x) + + s1 -= s1.mean(); s1 /= s1.std(0) + s2 -= s2.mean(); s2 /= s2.std(0) + s3 -= s3.mean(); s3 /= s3.std(0) + sS -= sS.mean(); sS /= sS.std(0) + + S1 = np.hstack([s1, sS]) + S2 = np.hstack([s3, sS]) + + P1 = np.random.randn(S1.shape[1], D1) + P2 = np.random.randn(S2.shape[1], D2) + + Y1 = S1.dot(P1) + Y2 = S2.dot(P2) + + Y1 += .01 * np.random.randn(*Y1.shape) + Y2 += .01 * np.random.randn(*Y2.shape) + + Y1 -= Y1.mean(0) + Y2 -= Y2.mean(0) + Y1 /= Y1.std(0) + Y2 /= Y2.std(0) + + slist = [s1, s2, s3, sS] + slist_names = ["s1", "s2", "s3", "sS"] + Ylist = [Y1, Y2] + + return Ylist +
+
[docs] def test_inferenceX_BGPLVM(self): + Ys = self.genData() + m = GPy.models.BayesianGPLVM(Ys[0],5,kernel=GPy.kern.Linear(5,ARD=True)) + + x,mi = m.infer_newX(m.Y, optimize=False) + self.assertTrue(mi.checkgrad()) + + m.optimize(max_iters=10000) + x,mi = m.infer_newX(m.Y) + + self.assertTrue(np.allclose(m.X.mean, mi.X.mean)) + self.assertTrue(np.allclose(m.X.variance, mi.X.variance)) +
+
[docs] def test_inferenceX_GPLVM(self): + Ys = self.genData() + m = GPy.models.GPLVM(Ys[0],3,kernel=GPy.kern.RBF(3,ARD=True)) + + x,mi = m.infer_newX(m.Y, optimize=False) + self.assertTrue(mi.checkgrad()) + +# m.optimize(max_iters=10000) +# x,mi = m.infer_newX(m.Y) +# self.assertTrue(np.allclose(m.X, x)) + +
+if __name__ == "__main__": + unittest.main() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/kernel_tests.html b/doc/_build/html/_modules/GPy/testing/kernel_tests.html new file mode 100644 index 00000000..3f1d0306 --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/kernel_tests.html @@ -0,0 +1,525 @@ + + + + + + + + GPy.testing.kernel_tests — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.kernel_tests

+# Copyright (c) 2012, 2013 GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import unittest
+import numpy as np
+import GPy
+import sys
+from GPy.core.parameterization.param import Param
+
+verbose = 0
+
+
+
[docs]class Kern_check_model(GPy.core.Model): + """ + This is a dummy model class used as a base class for checking that the + gradients of a given kernel are implemented correctly. It enables + checkgrad() to be called independently on a kernel. + """ + def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): + GPy.core.Model.__init__(self, 'kernel_test_model') + if kernel==None: + kernel = GPy.kern.RBF(1) + kernel.randomize(loc=1, scale=0.1) + if X is None: + X = np.random.randn(20, kernel.input_dim) + if dL_dK is None: + if X2 is None: + dL_dK = np.ones((X.shape[0], X.shape[0])) + else: + dL_dK = np.ones((X.shape[0], X2.shape[0])) + + self.kernel = kernel + self.X = X + self.X2 = X2 + self.dL_dK = dL_dK + +
[docs] def is_positive_semi_definite(self): + v = np.linalg.eig(self.kernel.K(self.X))[0] + if any(v.real<=-1e-10): + print v.real.min() + return False + else: + return True +
+
[docs] def log_likelihood(self): + return np.sum(self.dL_dK*self.kernel.K(self.X, self.X2)) +
+
[docs]class Kern_check_dK_dtheta(Kern_check_model): + """ + This class allows gradient checks for the gradient of a kernel with + respect to parameters. + """ + def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): + Kern_check_model.__init__(self,kernel=kernel,dL_dK=dL_dK, X=X, X2=X2) + self.link_parameter(self.kernel) + +
[docs] def parameters_changed(self): + return self.kernel.update_gradients_full(self.dL_dK, self.X, self.X2) + +
+
[docs]class Kern_check_dKdiag_dtheta(Kern_check_model): + """ + This class allows gradient checks of the gradient of the diagonal of a + kernel with respect to the parameters. + """ + def __init__(self, kernel=None, dL_dK=None, X=None): + Kern_check_model.__init__(self,kernel=kernel,dL_dK=dL_dK, X=X, X2=None) + self.link_parameter(self.kernel) + +
[docs] def log_likelihood(self): + return (np.diag(self.dL_dK)*self.kernel.Kdiag(self.X)).sum() +
+
[docs] def parameters_changed(self): + self.kernel.update_gradients_diag(np.diag(self.dL_dK), self.X) +
+
[docs]class Kern_check_dK_dX(Kern_check_model): + """This class allows gradient checks for the gradient of a kernel with respect to X. """ + def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): + Kern_check_model.__init__(self,kernel=kernel,dL_dK=dL_dK, X=X, X2=X2) + self.X = Param('X',X) + self.link_parameter(self.X) + +
[docs] def parameters_changed(self): + self.X.gradient[:] = self.kernel.gradients_X(self.dL_dK, self.X, self.X2) +
+
[docs]class Kern_check_dKdiag_dX(Kern_check_dK_dX): + """This class allows gradient checks for the gradient of a kernel diagonal with respect to X. """ + def __init__(self, kernel=None, dL_dK=None, X=None, X2=None): + Kern_check_dK_dX.__init__(self,kernel=kernel,dL_dK=dL_dK, X=X, X2=None) + +
[docs] def log_likelihood(self): + return (np.diag(self.dL_dK)*self.kernel.Kdiag(self.X)).sum() +
+
[docs] def parameters_changed(self): + self.X.gradient[:] = self.kernel.gradients_X_diag(self.dL_dK.diagonal(), self.X) + + +
+
[docs]def check_kernel_gradient_functions(kern, X=None, X2=None, output_ind=None, verbose=False, fixed_X_dims=None): + """ + This function runs on kernels to check the correctness of their + implementation. It checks that the covariance function is positive definite + for a randomly generated data set. + + :param kern: the kernel to be tested. + :type kern: GPy.kern.Kernpart + :param X: X input values to test the covariance function. + :type X: ndarray + :param X2: X2 input values to test the covariance function. + :type X2: ndarray + + """ + pass_checks = True + if X is None: + X = np.random.randn(10, kern.input_dim) + if output_ind is not None: + X[:, output_ind] = np.random.randint(kern.output_dim, X.shape[0]) + if X2 is None: + X2 = np.random.randn(20, kern.input_dim) + if output_ind is not None: + X2[:, output_ind] = np.random.randint(kern.output_dim, X2.shape[0]) + + if verbose: + print("Checking covariance function is positive definite.") + result = Kern_check_model(kern, X=X).is_positive_semi_definite() + if result and verbose: + print("Check passed.") + if not result: + print("Positive definite check failed for " + kern.name + " covariance function.") + pass_checks = False + assert(result) + return False + + if verbose: + print("Checking gradients of K(X, X) wrt theta.") + result = Kern_check_dK_dtheta(kern, X=X, X2=None).checkgrad(verbose=verbose) + if result and verbose: + print("Check passed.") + if not result: + print("Gradient of K(X, X) wrt theta failed for " + kern.name + " covariance function. Gradient values as follows:") + Kern_check_dK_dtheta(kern, X=X, X2=None).checkgrad(verbose=True) + pass_checks = False + assert(result) + return False + + if verbose: + print("Checking gradients of K(X, X2) wrt theta.") + result = Kern_check_dK_dtheta(kern, X=X, X2=X2).checkgrad(verbose=verbose) + if result and verbose: + print("Check passed.") + if not result: + print("Gradient of K(X, X) wrt theta failed for " + kern.name + " covariance function. Gradient values as follows:") + Kern_check_dK_dtheta(kern, X=X, X2=X2).checkgrad(verbose=True) + pass_checks = False + assert(result) + return False + + if verbose: + print("Checking gradients of Kdiag(X) wrt theta.") + try: + result = Kern_check_dKdiag_dtheta(kern, X=X).checkgrad(verbose=verbose) + except NotImplementedError: + result=True + if verbose: + print("update_gradients_diag not implemented for " + kern.name) + if result and verbose: + print("Check passed.") + if not result: + print("Gradient of Kdiag(X) wrt theta failed for " + kern.name + " covariance function. Gradient values as follows:") + Kern_check_dKdiag_dtheta(kern, X=X).checkgrad(verbose=True) + pass_checks = False + assert(result) + return False + + if verbose: + print("Checking gradients of K(X, X) wrt X.") + try: + testmodel = Kern_check_dK_dX(kern, X=X, X2=None) + if fixed_X_dims is not None: + testmodel.X[:,fixed_X_dims].fix() + result = testmodel.checkgrad(verbose=verbose) + except NotImplementedError: + result=True + if verbose: + print("gradients_X not implemented for " + kern.name) + if result and verbose: + print("Check passed.") + if not result: + print("Gradient of K(X, X) wrt X failed for " + kern.name + " covariance function. Gradient values as follows:") + testmodel.checkgrad(verbose=True) + import ipdb;ipdb.set_trace() + assert(result) + pass_checks = False + return False + + if verbose: + print("Checking gradients of K(X, X2) wrt X.") + try: + testmodel = Kern_check_dK_dX(kern, X=X, X2=X2) + if fixed_X_dims is not None: + testmodel.X[:,fixed_X_dims].fix() + result = testmodel.checkgrad(verbose=verbose) + except NotImplementedError: + result=True + if verbose: + print("gradients_X not implemented for " + kern.name) + if result and verbose: + print("Check passed.") + if not result: + print("Gradient of K(X, X2) wrt X failed for " + kern.name + " covariance function. Gradient values as follows:") + testmodel.checkgrad(verbose=True) + assert(result) + pass_checks = False + return False + + if verbose: + print("Checking gradients of Kdiag(X) wrt X.") + try: + testmodel = Kern_check_dKdiag_dX(kern, X=X) + if fixed_X_dims is not None: + testmodel.X[:,fixed_X_dims].fix() + result = testmodel.checkgrad(verbose=verbose) + except NotImplementedError: + result=True + if verbose: + print("gradients_X not implemented for " + kern.name) + if result and verbose: + print("Check passed.") + if not result: + print("Gradient of Kdiag(X) wrt X failed for " + kern.name + " covariance function. Gradient values as follows:") + Kern_check_dKdiag_dX(kern, X=X).checkgrad(verbose=True) + pass_checks = False + assert(result) + return False + + return pass_checks + + +
+
[docs]class KernelGradientTestsContinuous(unittest.TestCase): +
[docs] def setUp(self): + self.N, self.D = 10, 5 + self.X = np.random.randn(self.N,self.D) + self.X2 = np.random.randn(self.N+10,self.D) + + continuous_kerns = ['RBF', 'Linear'] + self.kernclasses = [getattr(GPy.kern, s) for s in continuous_kerns] +
+
[docs] def test_Matern32(self): + k = GPy.kern.Matern32(self.D) + k.randomize() + self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) +
+
[docs] def test_Prod(self): + k = GPy.kern.Matern32(2, active_dims=[2,3]) * GPy.kern.RBF(2, active_dims=[0,4]) + GPy.kern.Linear(self.D) + k.randomize() + self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) +
+
[docs] def test_Prod2(self): + k = (GPy.kern.RBF(2, active_dims=[0,4]) * GPy.kern.Linear(self.D)) + k.randomize() + self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) +
+
[docs] def test_Prod3(self): + k = (GPy.kern.RBF(2, active_dims=[0,4]) * GPy.kern.Linear(self.D)) + k.randomize() + self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) +
+
[docs] def test_Add(self): + k = GPy.kern.Matern32(2, active_dims=[2,3]) + GPy.kern.RBF(2, active_dims=[0,4]) + GPy.kern.Linear(self.D) + k += GPy.kern.Matern32(2, active_dims=[2,3]) + GPy.kern.RBF(2, active_dims=[0,4]) + GPy.kern.Linear(self.D) + k.randomize() + self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) +
+
[docs] def test_Add_dims(self): + k = GPy.kern.Matern32(2, active_dims=[2,self.D]) + GPy.kern.RBF(2, active_dims=[0,4]) + GPy.kern.Linear(self.D) + k.randomize() + self.assertRaises(IndexError, k.K, self.X) + k = GPy.kern.Matern32(2, active_dims=[2,self.D-1]) + GPy.kern.RBF(2, active_dims=[0,4]) + GPy.kern.Linear(self.D) + k.randomize() + # assert it runs: + try: + k.K(self.X) + except AssertionError: + raise AssertionError, "k.K(X) should run on self.D-1 dimension" +
+
[docs] def test_Matern52(self): + k = GPy.kern.Matern52(self.D) + k.randomize() + self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) +
+
[docs] def test_RBF(self): + k = GPy.kern.RBF(self.D) + k.randomize() + self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) +
+
[docs] def test_Linear(self): + k = GPy.kern.Linear(self.D) + k.randomize() + self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) +
+
[docs] def test_LinearFull(self): + k = GPy.kern.LinearFull(self.D, self.D-1) + k.randomize() + self.assertTrue(check_kernel_gradient_functions(k, X=self.X, X2=self.X2, verbose=verbose)) +
+
[docs]class KernelTestsMiscellaneous(unittest.TestCase): +
[docs] def setUp(self): + N, D = 100, 10 + self.X = np.linspace(-np.pi, +np.pi, N)[:,None] * np.random.uniform(-10,10,D) + self.rbf = GPy.kern.RBF(2, active_dims=np.arange(0,4,2)) + self.linear = GPy.kern.Linear(2, active_dims=(3,9)) + self.matern = GPy.kern.Matern32(3, active_dims=np.array([1,7,9])) + self.sumkern = self.rbf + self.linear + self.sumkern += self.matern + self.sumkern.randomize() +
+
[docs] def test_which_parts(self): + self.assertTrue(np.allclose(self.sumkern.K(self.X, which_parts=[self.linear, self.matern]), self.linear.K(self.X)+self.matern.K(self.X))) + self.assertTrue(np.allclose(self.sumkern.K(self.X, which_parts=[self.linear, self.rbf]), self.linear.K(self.X)+self.rbf.K(self.X))) + self.assertTrue(np.allclose(self.sumkern.K(self.X, which_parts=self.sumkern.parts[0]), self.rbf.K(self.X))) +
+
[docs]class KernelTestsNonContinuous(unittest.TestCase): +
[docs] def setUp(self): + N0 = 3 + N1 = 9 + N2 = 4 + N = N0+N1+N2 + self.D = 3 + self.X = np.random.randn(N, self.D+1) + indices = np.random.random_integers(0, 2, size=N) + self.X[indices==0, -1] = 0 + self.X[indices==1, -1] = 1 + self.X[indices==2, -1] = 2 + #self.X = self.X[self.X[:, -1].argsort(), :] + self.X2 = np.random.randn((N0+N1)*2, self.D+1) + self.X2[:(N0*2), -1] = 0 + self.X2[(N0*2):, -1] = 1 +
+
[docs] def test_IndependentOutputs(self): + k = GPy.kern.RBF(self.D, active_dims=range(self.D)) + kern = GPy.kern.IndependentOutputs(k, -1, 'ind_single') + self.assertTrue(check_kernel_gradient_functions(kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1)) + k = [GPy.kern.RBF(1, active_dims=[1], name='rbf1'), GPy.kern.RBF(self.D, active_dims=range(self.D), name='rbf012'), GPy.kern.RBF(2, active_dims=[0,2], name='rbf02')] + kern = GPy.kern.IndependentOutputs(k, -1, name='ind_split') + self.assertTrue(check_kernel_gradient_functions(kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1)) +
+
[docs] def test_Hierarchical(self): + k = [GPy.kern.RBF(2, active_dims=[0,2], name='rbf1'), GPy.kern.RBF(2, active_dims=[0,2], name='rbf2')] + kern = GPy.kern.IndependentOutputs(k, -1, name='ind_split') + self.assertTrue(check_kernel_gradient_functions(kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1)) + +
+
[docs] def test_ODE_UY(self): + kern = GPy.kern.ODE_UY(2, active_dims=[0, self.D]) + X = self.X[self.X[:,-1]!=2] + X2 = self.X2[self.X2[:,-1]!=2] + self.assertTrue(check_kernel_gradient_functions(kern, X=X, X2=X2, verbose=verbose, fixed_X_dims=-1)) +
+
[docs]class Coregionalize_weave_test(unittest.TestCase): + """ + Make sure that the coregionalize kernel work with and without weave enabled + """ +
[docs] def setUp(self): + self.k = GPy.kern.Coregionalize(1, output_dim=12) + self.N1, self.N2 = 100, 200 + self.X = np.random.randint(0,12,(self.N1,1)) + self.X2 = np.random.randint(0,12,(self.N2,1)) +
+
[docs] def test_sym(self): + dL_dK = np.random.randn(self.N1, self.N1) + GPy.util.config.config.set('weave', 'working', 'True') + K_weave = self.k.K(self.X) + self.k.update_gradients_full(dL_dK, self.X) + grads_weave = self.k.gradient.copy() + + GPy.util.config.config.set('weave', 'working', 'False') + K_numpy = self.k.K(self.X) + self.k.update_gradients_full(dL_dK, self.X) + grads_numpy = self.k.gradient.copy() + + self.assertTrue(np.allclose(K_numpy, K_weave)) + self.assertTrue(np.allclose(grads_numpy, grads_weave)) +
+
[docs] def test_nonsym(self): + dL_dK = np.random.randn(self.N1, self.N2) + GPy.util.config.config.set('weave', 'working', 'True') + K_weave = self.k.K(self.X, self.X2) + self.k.update_gradients_full(dL_dK, self.X, self.X2) + grads_weave = self.k.gradient.copy() + + GPy.util.config.config.set('weave', 'working', 'False') + K_numpy = self.k.K(self.X, self.X2) + self.k.update_gradients_full(dL_dK, self.X, self.X2) + grads_numpy = self.k.gradient.copy() + + self.assertTrue(np.allclose(K_numpy, K_weave)) + self.assertTrue(np.allclose(grads_numpy, grads_weave)) + + #reset the weave state for any other tests
+ GPy.util.config.config.set('weave', 'working', 'False') + + + +
+if __name__ == "__main__": + print "Running unit tests, please be (very) patient..." + unittest.main() +# np.random.seed(0) +# N0 = 3 +# N1 = 9 +# N2 = 4 +# N = N0+N1+N2 +# D = 3 +# X = np.random.randn(N, D+1) +# indices = np.random.random_integers(0, 2, size=N) +# X[indices==0, -1] = 0 +# X[indices==1, -1] = 1 +# X[indices==2, -1] = 2 +# #X = X[X[:, -1].argsort(), :] +# X2 = np.random.randn((N0+N1)*2, D+1) +# X2[:(N0*2), -1] = 0 +# X2[(N0*2):, -1] = 1 +# k = [GPy.kern.RBF(1, active_dims=[1], name='rbf1'), GPy.kern.RBF(D, name='rbf012'), GPy.kern.RBF(2, active_dims=[0,2], name='rbf02')] +# kern = GPy.kern.IndependentOutputs(k, -1, name='ind_split') +# assert(check_kernel_gradient_functions(kern, X=X, X2=X2, verbose=verbose, fixed_X_dims=-1)) +# k = GPy.kern.RBF(D) +# kern = GPy.kern.IndependentOutputs(k, -1, 'ind_single') +# assert(check_kernel_gradient_functions(kern, X=X, X2=X2, verbose=verbose, fixed_X_dims=-1)) +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/likelihood_tests.html b/doc/_build/html/_modules/GPy/testing/likelihood_tests.html new file mode 100644 index 00000000..9444a50d --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/likelihood_tests.html @@ -0,0 +1,806 @@ + + + + + + + + GPy.testing.likelihood_tests — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.likelihood_tests

+# Copyright (c) 2014, Alan Saul
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+import numpy as np
+import unittest
+import GPy
+from GPy.models import GradientChecker
+import functools
+import inspect
+from GPy.likelihoods import link_functions
+from GPy.core.parameterization import Param
+from functools import partial
+#np.random.seed(300)
+#np.random.seed(7)
+
+#np.seterr(divide='raise')
+
[docs]def dparam_partial(inst_func, *args): + """ + If we have a instance method that needs to be called but that doesn't + take the parameter we wish to change to checkgrad, then this function + will change the variable using set params. + + inst_func: should be a instance function of an object that we would like + to change + param: the param that will be given to set_params + args: anything else that needs to be given to the function (for example + the f or Y that are being used in the function whilst we tweak the + param + """ + def param_func(param_val, param_name, inst_func, args): + #inst_func.im_self._set_params(param) + #inst_func.im_self.add_parameter(Param(param_name, param_val)) + inst_func.im_self[param_name] = param_val + return inst_func(*args) + return functools.partial(param_func, inst_func=inst_func, args=args) +
+
[docs]def dparam_checkgrad(func, dfunc, params, params_names, args, constraints=None, randomize=False, verbose=False): + """ + checkgrad expects a f: R^N -> R^1 and df: R^N -> R^N + However if we are holding other parameters fixed and moving something else + We need to check the gradient of each of the fixed parameters + (f and y for example) seperately, whilst moving another parameter. + Otherwise f: gives back R^N and + df: gives back R^NxM where M is + The number of parameters and N is the number of data + Need to take a slice out from f and a slice out of df + """ + print "\n{} likelihood: {} vs {}".format(func.im_self.__class__.__name__, + func.__name__, dfunc.__name__) + partial_f = dparam_partial(func, *args) + partial_df = dparam_partial(dfunc, *args) + gradchecking = True + zipped_params = zip(params, params_names) + for param_ind, (param_val, param_name) in enumerate(zipped_params): + #Check one parameter at a time, make sure it is 2d (as some gradients only return arrays) then strip out the parameter + fnum = np.atleast_2d(partial_f(param_val, param_name))[:, param_ind].shape[0] + dfnum = np.atleast_2d(partial_df(param_val, param_name))[:, param_ind].shape[0] + for fixed_val in range(dfnum): + #dlik and dlik_dvar gives back 1 value for each + f_ind = min(fnum, fixed_val+1) - 1 + print "fnum: {} dfnum: {} f_ind: {} fixed_val: {}".format(fnum, dfnum, f_ind, fixed_val) + #Make grad checker with this param moving, note that set_params is NOT being called + #The parameter is being set directly with __setattr__ + #Check only the parameter and function value we wish to check at a time + grad = GradientChecker(lambda p_val: np.atleast_2d(partial_f(p_val, param_name))[f_ind, param_ind], + lambda p_val: np.atleast_2d(partial_df(p_val, param_name))[fixed_val, param_ind], + param_val, [param_name]) + + if constraints is not None: + for constrain_param, constraint in constraints: + if grad.grep_param_names(constrain_param): + constraint(constrain_param, grad) + else: + print "parameter didn't exist" + print constrain_param, " ", constraint + if randomize: + grad.randomize() + if verbose: + print grad + grad.checkgrad(verbose=1) + if not grad.checkgrad(verbose=True): + gradchecking = False + + return gradchecking + +
+from nose.tools import with_setup +
[docs]class TestNoiseModels(object): + """ + Generic model checker + """ +
[docs] def setUp(self): + self.N = 15 + self.D = 3 + self.X = np.random.rand(self.N, self.D)*10 + + self.real_std = 0.1 + noise = np.random.randn(*self.X[:, 0].shape)*self.real_std + self.Y = (np.sin(self.X[:, 0]*2*np.pi) + noise)[:, None] + self.f = np.random.rand(self.N, 1) + self.binary_Y = np.asarray(np.random.rand(self.N) > 0.5, dtype=np.int)[:, None] + self.positive_Y = np.exp(self.Y.copy()) + tmp = np.round(self.X[:, 0]*3-3)[:, None] + np.random.randint(0,3, self.X.shape[0])[:, None] + self.integer_Y = np.where(tmp > 0, tmp, 0) + + self.var = 0.2 + + self.var = np.random.rand(1) + + #Make a bigger step as lower bound can be quite curved + self.step = 1e-4 +
+
[docs] def tearDown(self): + self.Y = None + self.f = None + self.X = None +
+
[docs] def test_scale2_models(self): + self.setUp() + + #################################################### + # Constraint wrappers so we can just list them off # + #################################################### + def constrain_fixed(regex, model): + model[regex].constrain_fixed() + + def constrain_negative(regex, model): + model[regex].constrain_negative() + + def constrain_positive(regex, model): + model[regex].constrain_positive() + + def constrain_bounded(regex, model, lower, upper): + """ + Used like: partial(constrain_bounded, lower=0, upper=1) + """ + model[regex].constrain_bounded(lower, upper) + + """ + Dictionary where we nest models we would like to check + Name: { + "model": model_instance, + "grad_params": { + "names": [names_of_params_we_want, to_grad_check], + "vals": [values_of_params, to_start_at], + "constrain": [constraint_wrappers, listed_here] + }, + "laplace": boolean_of_whether_model_should_work_for_laplace, + "ep": boolean_of_whether_model_should_work_for_laplace, + "link_f_constraints": [constraint_wrappers, listed_here] + } + """ + noise_models = {"Student_t_default": { + "model": GPy.likelihoods.StudentT(deg_free=5, sigma2=self.var), + "grad_params": { + "names": [".*t_scale2"], + "vals": [self.var], + "constraints": [(".*t_scale2", constrain_positive), (".*deg_free", constrain_fixed)] + #"constraints": [("t_scale2", constrain_positive), ("deg_free", partial(constrain_fixed, value=5))] + }, + "laplace": True + }, + "Student_t_1_var": { + "model": GPy.likelihoods.StudentT(deg_free=5, sigma2=self.var), + "grad_params": { + "names": [".*t_scale2"], + "vals": [1.0], + "constraints": [(".*t_scale2", constrain_positive), (".*deg_free", constrain_fixed)] + }, + "laplace": True + }, + "Student_t_small_deg_free": { + "model": GPy.likelihoods.StudentT(deg_free=1.5, sigma2=self.var), + "grad_params": { + "names": [".*t_scale2"], + "vals": [self.var], + "constraints": [(".*t_scale2", constrain_positive), (".*deg_free", constrain_fixed)] + }, + "laplace": True + }, + "Student_t_small_var": { + "model": GPy.likelihoods.StudentT(deg_free=5, sigma2=self.var), + "grad_params": { + "names": [".*t_scale2"], + "vals": [0.001], + "constraints": [(".*t_scale2", constrain_positive), (".*deg_free", constrain_fixed)] + }, + "laplace": True + }, + "Student_t_large_var": { + "model": GPy.likelihoods.StudentT(deg_free=5, sigma2=self.var), + "grad_params": { + "names": [".*t_scale2"], + "vals": [10.0], + "constraints": [(".*t_scale2", constrain_positive), (".*deg_free", constrain_fixed)] + }, + "laplace": True + }, + "Student_t_approx_gauss": { + "model": GPy.likelihoods.StudentT(deg_free=1000, sigma2=self.var), + "grad_params": { + "names": [".*t_scale2"], + "vals": [self.var], + "constraints": [(".*t_scale2", constrain_positive), (".*deg_free", constrain_fixed)] + }, + "laplace": True + }, + "Student_t_log": { + "model": GPy.likelihoods.StudentT(gp_link=link_functions.Log(), deg_free=5, sigma2=self.var), + "grad_params": { + "names": [".*t_scale2"], + "vals": [self.var], + "constraints": [(".*t_scale2", constrain_positive), (".*deg_free", constrain_fixed)] + }, + "laplace": True + }, + "Gaussian_default": { + "model": GPy.likelihoods.Gaussian(variance=self.var), + "grad_params": { + "names": [".*variance"], + "vals": [self.var], + "constraints": [(".*variance", constrain_positive)] + }, + "laplace": True, + "ep": False # FIXME: Should be True when we have it working again + }, + #"Gaussian_log": { + #"model": GPy.likelihoods.gaussian(gp_link=link_functions.Log(), variance=self.var, D=self.D, N=self.N), + #"grad_params": { + #"names": ["noise_model_variance"], + #"vals": [self.var], + #"constraints": [constrain_positive] + #}, + #"laplace": True + #}, + #"Gaussian_probit": { + #"model": GPy.likelihoods.gaussian(gp_link=link_functions.Probit(), variance=self.var, D=self.D, N=self.N), + #"grad_params": { + #"names": ["noise_model_variance"], + #"vals": [self.var], + #"constraints": [constrain_positive] + #}, + #"laplace": True + #}, + #"Gaussian_log_ex": { + #"model": GPy.likelihoods.gaussian(gp_link=link_functions.Log_ex_1(), variance=self.var, D=self.D, N=self.N), + #"grad_params": { + #"names": ["noise_model_variance"], + #"vals": [self.var], + #"constraints": [constrain_positive] + #}, + #"laplace": True + #}, + "Bernoulli_default": { + "model": GPy.likelihoods.Bernoulli(), + "link_f_constraints": [partial(constrain_bounded, lower=0, upper=1)], + "laplace": True, + "Y": self.binary_Y, + "ep": False # FIXME: Should be True when we have it working again + }, + "Exponential_default": { + "model": GPy.likelihoods.Exponential(), + "link_f_constraints": [constrain_positive], + "Y": self.positive_Y, + "laplace": True, + }, + "Poisson_default": { + "model": GPy.likelihoods.Poisson(), + "link_f_constraints": [constrain_positive], + "Y": self.integer_Y, + "laplace": True, + "ep": False #Should work though... + }#, + #GAMMA needs some work!"Gamma_default": { + #"model": GPy.likelihoods.Gamma(), + #"link_f_constraints": [constrain_positive], + #"Y": self.positive_Y, + #"laplace": True + #} + } + + for name, attributes in noise_models.iteritems(): + model = attributes["model"] + if "grad_params" in attributes: + params = attributes["grad_params"] + param_vals = params["vals"] + param_names= params["names"] + param_constraints = params["constraints"] + else: + params = [] + param_vals = [] + param_names = [] + constrain_positive = [] + param_constraints = [] # ??? TODO: Saul to Fix. + if "link_f_constraints" in attributes: + link_f_constraints = attributes["link_f_constraints"] + else: + link_f_constraints = [] + if "Y" in attributes: + Y = attributes["Y"].copy() + else: + Y = self.Y.copy() + if "f" in attributes: + f = attributes["f"].copy() + else: + f = self.f.copy() + if "laplace" in attributes: + laplace = attributes["laplace"] + else: + laplace = False + if "ep" in attributes: + ep = attributes["ep"] + else: + ep = False + + #if len(param_vals) > 1: + #raise NotImplementedError("Cannot support multiple params in likelihood yet!") + + #Required by all + #Normal derivatives + yield self.t_logpdf, model, Y, f + yield self.t_dlogpdf_df, model, Y, f + yield self.t_d2logpdf_df2, model, Y, f + #Link derivatives + yield self.t_dlogpdf_dlink, model, Y, f, link_f_constraints + yield self.t_d2logpdf_dlink2, model, Y, f, link_f_constraints + if laplace: + #Laplace only derivatives + yield self.t_d3logpdf_df3, model, Y, f + yield self.t_d3logpdf_dlink3, model, Y, f, link_f_constraints + #Params + yield self.t_dlogpdf_dparams, model, Y, f, param_vals, param_names, param_constraints + yield self.t_dlogpdf_df_dparams, model, Y, f, param_vals, param_names, param_constraints + yield self.t_d2logpdf2_df2_dparams, model, Y, f, param_vals, param_names, param_constraints + #Link params + yield self.t_dlogpdf_link_dparams, model, Y, f, param_vals, param_names, param_constraints + yield self.t_dlogpdf_dlink_dparams, model, Y, f, param_vals, param_names, param_constraints + yield self.t_d2logpdf2_dlink2_dparams, model, Y, f, param_vals, param_names, param_constraints + + #laplace likelihood gradcheck + yield self.t_laplace_fit_rbf_white, model, self.X, Y, f, self.step, param_vals, param_names, param_constraints + if ep: + #ep likelihood gradcheck + yield self.t_ep_fit_rbf_white, model, self.X, Y, f, self.step, param_vals, param_names, param_constraints + + + self.tearDown() + + ############# + # dpdf_df's # + #############
+ @with_setup(setUp, tearDown) +
[docs] def t_logpdf(self, model, Y, f): + print "\n{}".format(inspect.stack()[0][3]) + print model + #print model._get_params() + np.testing.assert_almost_equal( + model.pdf(f.copy(), Y.copy()).prod(), + np.exp(model.logpdf(f.copy(), Y.copy()).sum()) + ) +
+ @with_setup(setUp, tearDown) +
[docs] def t_dlogpdf_df(self, model, Y, f): + print "\n{}".format(inspect.stack()[0][3]) + self.description = "\n{}".format(inspect.stack()[0][3]) + logpdf = functools.partial(model.logpdf, y=Y) + dlogpdf_df = functools.partial(model.dlogpdf_df, y=Y) + grad = GradientChecker(logpdf, dlogpdf_df, f.copy(), 'g') + grad.randomize() + print model + assert grad.checkgrad(verbose=1) +
+ @with_setup(setUp, tearDown) +
[docs] def t_d2logpdf_df2(self, model, Y, f): + print "\n{}".format(inspect.stack()[0][3]) + dlogpdf_df = functools.partial(model.dlogpdf_df, y=Y) + d2logpdf_df2 = functools.partial(model.d2logpdf_df2, y=Y) + grad = GradientChecker(dlogpdf_df, d2logpdf_df2, f.copy(), 'g') + grad.randomize() + print model + assert grad.checkgrad(verbose=1) +
+ @with_setup(setUp, tearDown) +
[docs] def t_d3logpdf_df3(self, model, Y, f): + print "\n{}".format(inspect.stack()[0][3]) + d2logpdf_df2 = functools.partial(model.d2logpdf_df2, y=Y) + d3logpdf_df3 = functools.partial(model.d3logpdf_df3, y=Y) + grad = GradientChecker(d2logpdf_df2, d3logpdf_df3, f.copy(), 'g') + grad.randomize() + print model + assert grad.checkgrad(verbose=1) + + ############## + # df_dparams # + ##############
+ @with_setup(setUp, tearDown) +
[docs] def t_dlogpdf_dparams(self, model, Y, f, params, params_names, param_constraints): + print "\n{}".format(inspect.stack()[0][3]) + print model + assert ( + dparam_checkgrad(model.logpdf, model.dlogpdf_dtheta, + params, params_names, args=(f, Y), constraints=param_constraints, + randomize=False, verbose=True) + ) +
+ @with_setup(setUp, tearDown) +
[docs] def t_dlogpdf_df_dparams(self, model, Y, f, params, params_names, param_constraints): + print "\n{}".format(inspect.stack()[0][3]) + print model + assert ( + dparam_checkgrad(model.dlogpdf_df, model.dlogpdf_df_dtheta, + params, params_names, args=(f, Y), constraints=param_constraints, + randomize=False, verbose=True) + ) +
+ @with_setup(setUp, tearDown) +
[docs] def t_d2logpdf2_df2_dparams(self, model, Y, f, params, params_names, param_constraints): + print "\n{}".format(inspect.stack()[0][3]) + print model + assert ( + dparam_checkgrad(model.d2logpdf_df2, model.d2logpdf_df2_dtheta, + params, params_names, args=(f, Y), constraints=param_constraints, + randomize=False, verbose=True) + ) + + ################ + # dpdf_dlink's # + ################
+ @with_setup(setUp, tearDown) + + @with_setup(setUp, tearDown) +
[docs] def t_d2logpdf_dlink2(self, model, Y, f, link_f_constraints): + print "\n{}".format(inspect.stack()[0][3]) + dlogpdf_dlink = functools.partial(model.dlogpdf_dlink, y=Y) + d2logpdf_dlink2 = functools.partial(model.d2logpdf_dlink2, y=Y) + grad = GradientChecker(dlogpdf_dlink, d2logpdf_dlink2, f.copy(), 'g') + + #Apply constraints to link_f values + for constraint in link_f_constraints: + constraint('g', grad) + + grad.randomize() + print grad + print model + assert grad.checkgrad(verbose=1) +
+ @with_setup(setUp, tearDown) +
[docs] def t_d3logpdf_dlink3(self, model, Y, f, link_f_constraints): + print "\n{}".format(inspect.stack()[0][3]) + d2logpdf_dlink2 = functools.partial(model.d2logpdf_dlink2, y=Y) + d3logpdf_dlink3 = functools.partial(model.d3logpdf_dlink3, y=Y) + grad = GradientChecker(d2logpdf_dlink2, d3logpdf_dlink3, f.copy(), 'g') + + #Apply constraints to link_f values + for constraint in link_f_constraints: + constraint('g', grad) + + grad.randomize() + print grad + print model + assert grad.checkgrad(verbose=1) + + ################# + # dlink_dparams # + #################
+ @with_setup(setUp, tearDown) + + @with_setup(setUp, tearDown) + + @with_setup(setUp, tearDown) +
[docs] def t_d2logpdf2_dlink2_dparams(self, model, Y, f, params, param_names, param_constraints): + print "\n{}".format(inspect.stack()[0][3]) + print model + assert ( + dparam_checkgrad(model.d2logpdf_dlink2, model.d2logpdf_dlink2_dtheta, + params, param_names, args=(f, Y), constraints=param_constraints, + randomize=False, verbose=True) + ) + + ################ + # laplace test # + ################
+ @with_setup(setUp, tearDown) +
[docs] def t_laplace_fit_rbf_white(self, model, X, Y, f, step, param_vals, param_names, constraints): + print "\n{}".format(inspect.stack()[0][3]) + #Normalize + Y = Y/Y.max() + white_var = 1e-6 + kernel = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) + laplace_likelihood = GPy.inference.latent_function_inference.Laplace() + m = GPy.core.GP(X.copy(), Y.copy(), kernel, likelihood=model, inference_method=laplace_likelihood) + m['.*white'].constrain_fixed(white_var) + + #Set constraints + for constrain_param, constraint in constraints: + constraint(constrain_param, m) + + print m + m.randomize() + + #Set params + for param_num in range(len(param_names)): + name = param_names[param_num] + m[name] = param_vals[param_num] + + #m.optimize(max_iters=8) + print m + #if not m.checkgrad(step=step): + #m.checkgrad(verbose=1, step=step) + #NOTE this test appears to be stochastic for some likelihoods (student t?) + # appears to all be working in test mode right now... + #if isinstance(model, GPy.likelihoods.StudentT): + assert m.checkgrad(verbose=1, step=step) + + ########### + # EP test # + ###########
+ @with_setup(setUp, tearDown) +
[docs] def t_ep_fit_rbf_white(self, model, X, Y, f, step, param_vals, param_names, constraints): + print "\n{}".format(inspect.stack()[0][3]) + #Normalize + Y = Y/Y.max() + white_var = 1e-6 + kernel = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) + ep_inf = GPy.inference.latent_function_inference.EP() + m = GPy.core.GP(X.copy(), Y.copy(), kernel=kernel, likelihood=model, inference_method=ep_inf) + m['.*white'].constrain_fixed(white_var) + + for param_num in range(len(param_names)): + name = param_names[param_num] + m[name] = param_vals[param_num] + constraints[param_num](name, m) + + m.randomize() + print m + assert m.checkgrad(verbose=1, step=step) + +
+
[docs]class LaplaceTests(unittest.TestCase): + """ + Specific likelihood tests, not general enough for the above tests + """ + +
[docs] def setUp(self): + self.N = 5 + self.D = 3 + self.X = np.random.rand(self.N, self.D)*10 + + self.real_std = 0.1 + noise = np.random.randn(*self.X[:, 0].shape)*self.real_std + self.Y = (np.sin(self.X[:, 0]*2*np.pi) + noise)[:, None] + self.f = np.random.rand(self.N, 1) + + self.var = 0.2 + + self.var = np.random.rand(1) + self.stu_t = GPy.likelihoods.StudentT(deg_free=5, sigma2=self.var) + #TODO: gaussians with on Identity link. self.gauss = GPy.likelihoods.Gaussian(gp_link=link_functions.Log(), variance=self.var) + self.gauss = GPy.likelihoods.Gaussian(variance=self.var) + + #Make a bigger step as lower bound can be quite curved + self.step = 1e-6 +
+
[docs] def tearDown(self): + self.stu_t = None + self.gauss = None + self.Y = None + self.f = None + self.X = None +
+
[docs] def test_gaussian_d2logpdf_df2_2(self): + print "\n{}".format(inspect.stack()[0][3]) + self.Y = None + + self.N = 2 + self.D = 1 + self.X = np.linspace(0, self.D, self.N)[:, None] + self.real_std = 0.2 + noise = np.random.randn(*self.X.shape)*self.real_std + self.Y = np.sin(self.X*2*np.pi) + noise + self.f = np.random.rand(self.N, 1) + + dlogpdf_df = functools.partial(self.gauss.dlogpdf_df, y=self.Y) + d2logpdf_df2 = functools.partial(self.gauss.d2logpdf_df2, y=self.Y) + grad = GradientChecker(dlogpdf_df, d2logpdf_df2, self.f.copy(), 'g') + grad.randomize() + + self.assertTrue(grad.checkgrad(verbose=1)) +
+
[docs] def test_laplace_log_likelihood(self): + debug = False + real_std = 0.1 + initial_var_guess = 0.5 + + #Start a function, any function + X = np.linspace(0.0, np.pi*2, 100)[:, None] + Y = np.sin(X) + np.random.randn(*X.shape)*real_std + Y = Y/Y.max() + #Yc = Y.copy() + #Yc[75:80] += 1 + kernel1 = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) + #FIXME: Make sure you can copy kernels when params is fixed + #kernel2 = kernel1.copy() + kernel2 = GPy.kern.RBF(X.shape[1]) + GPy.kern.White(X.shape[1]) + + gauss_distr1 = GPy.likelihoods.Gaussian(variance=initial_var_guess) + exact_inf = GPy.inference.latent_function_inference.ExactGaussianInference() + m1 = GPy.core.GP(X, Y.copy(), kernel=kernel1, likelihood=gauss_distr1, inference_method=exact_inf) + m1['.*white'].constrain_fixed(1e-6) + m1['.*rbf.variance'] = initial_var_guess + m1['.*rbf.variance'].constrain_bounded(1e-4, 10) + m1.randomize() + + gauss_distr2 = GPy.likelihoods.Gaussian(variance=initial_var_guess) + laplace_inf = GPy.inference.latent_function_inference.Laplace() + m2 = GPy.core.GP(X, Y.copy(), kernel=kernel2, likelihood=gauss_distr2, inference_method=laplace_inf) + m2['.*white'].constrain_fixed(1e-6) + m2['.*rbf.variance'].constrain_bounded(1e-4, 10) + m2.randomize() + + if debug: + print m1 + print m2 + optimizer = 'scg' + print "Gaussian" + m1.optimize(optimizer, messages=debug) + print "Laplace Gaussian" + m2.optimize(optimizer, messages=debug) + if debug: + print m1 + print m2 + + m2[:] = m1[:] + + #Predict for training points to get posterior mean and variance + post_mean, post_var = m1.predict(X) + post_mean_approx, post_var_approx, = m2.predict(X) + + if debug: + import pylab as pb + pb.figure(5) + pb.title('posterior means') + pb.scatter(X, post_mean, c='g') + pb.scatter(X, post_mean_approx, c='r', marker='x') + + pb.figure(6) + pb.title('plot_f') + m1.plot_f(fignum=6) + m2.plot_f(fignum=6) + fig, axes = pb.subplots(2, 1) + fig.suptitle('Covariance matricies') + a1 = pb.subplot(121) + a1.matshow(m1.likelihood.covariance_matrix) + a2 = pb.subplot(122) + a2.matshow(m2.likelihood.covariance_matrix) + + pb.figure(8) + pb.scatter(X, m1.likelihood.Y, c='g') + pb.scatter(X, m2.likelihood.Y, c='r', marker='x') + + + + #Check Y's are the same + np.testing.assert_almost_equal(m1.Y, m2.Y, decimal=5) + #Check marginals are the same + np.testing.assert_almost_equal(m1.log_likelihood(), m2.log_likelihood(), decimal=2) + #Check marginals are the same with random + m1.randomize() + m2[:] = m1[:] + + np.testing.assert_almost_equal(m1.log_likelihood(), m2.log_likelihood(), decimal=2) + + #Check they are checkgradding + #m1.checkgrad(verbose=1) + #m2.checkgrad(verbose=1) + self.assertTrue(m1.checkgrad(verbose=True)) + self.assertTrue(m2.checkgrad(verbose=True)) +
+if __name__ == "__main__": + print "Running unit tests" + unittest.main() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/model_tests.html b/doc/_build/html/_modules/GPy/testing/model_tests.html new file mode 100644 index 00000000..467fe747 --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/model_tests.html @@ -0,0 +1,605 @@ + + + + + + + + GPy.testing.model_tests — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.model_tests

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import unittest
+import numpy as np
+import GPy
+
+
[docs]class MiscTests(unittest.TestCase): +
[docs] def setUp(self): + self.N = 20 + self.N_new = 50 + self.D = 1 + self.X = np.random.uniform(-3., 3., (self.N, 1)) + self.Y = np.sin(self.X) + np.random.randn(self.N, self.D) * 0.05 + self.X_new = np.random.uniform(-3., 3., (self.N_new, 1)) +
+
[docs] def test_raw_predict(self): + k = GPy.kern.RBF(1) + m = GPy.models.GPRegression(self.X, self.Y, kernel=k) + m.randomize() + m.likelihood.variance = .5 + Kinv = np.linalg.pinv(k.K(self.X) + np.eye(self.N) * m.likelihood.variance) + K_hat = k.K(self.X_new) - k.K(self.X_new, self.X).dot(Kinv).dot(k.K(self.X, self.X_new)) + mu_hat = k.K(self.X_new, self.X).dot(Kinv).dot(m.Y_normalized) + + mu, covar = m._raw_predict(self.X_new, full_cov=True) + self.assertEquals(mu.shape, (self.N_new, self.D)) + self.assertEquals(covar.shape, (self.N_new, self.N_new)) + np.testing.assert_almost_equal(K_hat, covar) + np.testing.assert_almost_equal(mu_hat, mu) + + mu, var = m._raw_predict(self.X_new) + self.assertEquals(mu.shape, (self.N_new, self.D)) + self.assertEquals(var.shape, (self.N_new, 1)) + np.testing.assert_almost_equal(np.diag(K_hat)[:, None], var) + np.testing.assert_almost_equal(mu_hat, mu) +
+
[docs] def test_sparse_raw_predict(self): + k = GPy.kern.RBF(1) + m = GPy.models.SparseGPRegression(self.X, self.Y, kernel=k) + m.randomize() + Z = m.Z[:] + X = self.X[:] + + # Not easy to check if woodbury_inv is correct in itself as it requires a large derivation and expression + Kinv = m.posterior.woodbury_inv + K_hat = k.K(self.X_new) - k.K(self.X_new, Z).dot(Kinv).dot(k.K(Z, self.X_new)) + + mu, covar = m._raw_predict(self.X_new, full_cov=True) + self.assertEquals(mu.shape, (self.N_new, self.D)) + self.assertEquals(covar.shape, (self.N_new, self.N_new)) + np.testing.assert_almost_equal(K_hat, covar) + # np.testing.assert_almost_equal(mu_hat, mu) + + mu, var = m._raw_predict(self.X_new) + self.assertEquals(mu.shape, (self.N_new, self.D)) + self.assertEquals(var.shape, (self.N_new, 1)) + np.testing.assert_almost_equal(np.diag(K_hat)[:, None], var) + # np.testing.assert_almost_equal(mu_hat, mu) +
+
[docs] def test_likelihood_replicate(self): + m = GPy.models.GPRegression(self.X, self.Y) + m2 = GPy.models.GPRegression(self.X, self.Y) + np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) + m.randomize() + m2[:] = m[''].values() + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) + m.randomize() + m2[''] = m[:] + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) + m.randomize() + m2[:] = m[:] + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) + m.randomize() + m2[''] = m[''] + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) + + m.kern.lengthscale.randomize() + m2[:] = m[:] + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) + + m.Gaussian_noise.randomize() + m2[:] = m[:] + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) + + m['.*var'] = 2 + m2['.*var'] = m['.*var'] + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) + +
+
[docs] def test_likelihood_set(self): + m = GPy.models.GPRegression(self.X, self.Y) + m2 = GPy.models.GPRegression(self.X, self.Y) + np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) + + m.kern.lengthscale.randomize() + m2.kern.lengthscale = m.kern.lengthscale + np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) + + m.kern.lengthscale.randomize() + m2['.*lengthscale'] = m.kern.lengthscale + np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) + + m.kern.lengthscale.randomize() + m2['.*lengthscale'] = m.kern['.*lengthscale'] + np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) + + m.kern.lengthscale.randomize() + m2.kern.lengthscale = m.kern['.*lengthscale'] + np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) +
+
[docs] def test_missing_data(self): + from GPy import kern + from GPy.models.bayesian_gplvm_minibatch import BayesianGPLVMMiniBatch + from GPy.examples.dimensionality_reduction import _simulate_matern + + D1, D2, D3, N, num_inducing, Q = 13, 5, 8, 400, 3, 4 + _, _, Ylist = _simulate_matern(D1, D2, D3, N, num_inducing, False) + Y = Ylist[0] + + inan = np.random.binomial(1, .9, size=Y.shape).astype(bool) # 80% missing data + Ymissing = Y.copy() + Ymissing[inan] = np.nan + + k = kern.Linear(Q, ARD=True) + kern.White(Q, np.exp(-2)) # + kern.bias(Q) + m = BayesianGPLVMMiniBatch(Ymissing, Q, init="random", num_inducing=num_inducing, + kernel=k, missing_data=True) + assert(m.checkgrad()) + + k = kern.RBF(Q, ARD=True) + kern.White(Q, np.exp(-2)) # + kern.bias(Q) + m = BayesianGPLVMMiniBatch(Ymissing, Q, init="random", num_inducing=num_inducing, + kernel=k, missing_data=True) + assert(m.checkgrad()) +
+
[docs] def test_likelihood_replicate_kern(self): + m = GPy.models.GPRegression(self.X, self.Y) + m2 = GPy.models.GPRegression(self.X, self.Y) + np.testing.assert_equal(m.log_likelihood(), m2.log_likelihood()) + m.kern.randomize() + m2.kern[''] = m.kern[:] + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) + m.kern.randomize() + m2.kern[:] = m.kern[:] + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) + m.kern.randomize() + m2.kern[''] = m.kern[''] + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) + m.kern.randomize() + m2.kern[:] = m.kern[''].values() + np.testing.assert_almost_equal(m.log_likelihood(), m2.log_likelihood()) +
+
[docs] def test_big_model(self): + m = GPy.examples.dimensionality_reduction.mrd_simulation(optimize=0, plot=0, plot_sim=0) + m.X.fix() + print m + m.unfix() + m.checkgrad() + print m + m.fix() + print m + m.inducing_inputs.unfix() + print m + m.checkgrad() + m.unfix() + m.checkgrad() + m.checkgrad() + print m +
+
[docs] def test_model_set_params(self): + m = GPy.models.GPRegression(self.X, self.Y) + lengthscale = np.random.uniform() + m.kern.lengthscale = lengthscale + np.testing.assert_equal(m.kern.lengthscale, lengthscale) + m.kern.lengthscale *= 1 + m['.*var'] -= .1 + np.testing.assert_equal(m.kern.lengthscale, lengthscale) + m.optimize() + print m +
+
[docs] def test_model_optimize(self): + X = np.random.uniform(-3., 3., (20, 1)) + Y = np.sin(X) + np.random.randn(20, 1) * 0.05 + m = GPy.models.GPRegression(X, Y) + m.optimize() + print m +
+
[docs]class GradientTests(np.testing.TestCase): +
[docs] def setUp(self): + ###################################### + # # 1 dimensional example + + # sample inputs and outputs + self.X1D = np.random.uniform(-3., 3., (20, 1)) + self.Y1D = np.sin(self.X1D) + np.random.randn(20, 1) * 0.05 + + ###################################### + # # 2 dimensional example + + # sample inputs and outputs + self.X2D = np.random.uniform(-3., 3., (40, 2)) + self.Y2D = np.sin(self.X2D[:, 0:1]) * np.sin(self.X2D[:, 1:2]) + np.random.randn(40, 1) * 0.05 +
+
[docs] def check_model(self, kern, model_type='GPRegression', dimension=1, uncertain_inputs=False): + # Get the correct gradients + if dimension == 1: + X = self.X1D + Y = self.Y1D + else: + X = self.X2D + Y = self.Y2D + # Get model type (GPRegression, SparseGPRegression, etc) + model_fit = getattr(GPy.models, model_type) + + # noise = GPy.kern.White(dimension) + kern = kern # + noise + if uncertain_inputs: + m = model_fit(X, Y, kernel=kern, X_variance=np.random.rand(X.shape[0], X.shape[1])) + else: + m = model_fit(X, Y, kernel=kern) + m.randomize() + # contrain all parameters to be positive + self.assertTrue(m.checkgrad()) +
+
[docs] def test_GPRegression_rbf_1d(self): + ''' Testing the GP regression with rbf kernel with white kernel on 1d data ''' + rbf = GPy.kern.RBF(1) + self.check_model(rbf, model_type='GPRegression', dimension=1) +
+
[docs] def test_GPRegression_rbf_2D(self): + ''' Testing the GP regression with rbf kernel on 2d data ''' + rbf = GPy.kern.RBF(2) + self.check_model(rbf, model_type='GPRegression', dimension=2) +
+
[docs] def test_GPRegression_rbf_ARD_2D(self): + ''' Testing the GP regression with rbf kernel on 2d data ''' + k = GPy.kern.RBF(2, ARD=True) + self.check_model(k, model_type='GPRegression', dimension=2) +
+
[docs] def test_GPRegression_mlp_1d(self): + ''' Testing the GP regression with mlp kernel with white kernel on 1d data ''' + mlp = GPy.kern.MLP(1) + self.check_model(mlp, model_type='GPRegression', dimension=1) + + # TODO: + # def test_GPRegression_poly_1d(self): + # ''' Testing the GP regression with polynomial kernel with white kernel on 1d data ''' + # mlp = GPy.kern.Poly(1, degree=5) + # self.check_model(mlp, model_type='GPRegression', dimension=1) +
+
[docs] def test_GPRegression_matern52_1D(self): + ''' Testing the GP regression with matern52 kernel on 1d data ''' + matern52 = GPy.kern.Matern52(1) + self.check_model(matern52, model_type='GPRegression', dimension=1) +
+
[docs] def test_GPRegression_matern52_2D(self): + ''' Testing the GP regression with matern52 kernel on 2d data ''' + matern52 = GPy.kern.Matern52(2) + self.check_model(matern52, model_type='GPRegression', dimension=2) +
+
[docs] def test_GPRegression_matern52_ARD_2D(self): + ''' Testing the GP regression with matern52 kernel on 2d data ''' + matern52 = GPy.kern.Matern52(2, ARD=True) + self.check_model(matern52, model_type='GPRegression', dimension=2) +
+
[docs] def test_GPRegression_matern32_1D(self): + ''' Testing the GP regression with matern32 kernel on 1d data ''' + matern32 = GPy.kern.Matern32(1) + self.check_model(matern32, model_type='GPRegression', dimension=1) +
+
[docs] def test_GPRegression_matern32_2D(self): + ''' Testing the GP regression with matern32 kernel on 2d data ''' + matern32 = GPy.kern.Matern32(2) + self.check_model(matern32, model_type='GPRegression', dimension=2) +
+
[docs] def test_GPRegression_matern32_ARD_2D(self): + ''' Testing the GP regression with matern32 kernel on 2d data ''' + matern32 = GPy.kern.Matern32(2, ARD=True) + self.check_model(matern32, model_type='GPRegression', dimension=2) +
+
[docs] def test_GPRegression_exponential_1D(self): + ''' Testing the GP regression with exponential kernel on 1d data ''' + exponential = GPy.kern.Exponential(1) + self.check_model(exponential, model_type='GPRegression', dimension=1) +
+
[docs] def test_GPRegression_exponential_2D(self): + ''' Testing the GP regression with exponential kernel on 2d data ''' + exponential = GPy.kern.Exponential(2) + self.check_model(exponential, model_type='GPRegression', dimension=2) +
+
[docs] def test_GPRegression_exponential_ARD_2D(self): + ''' Testing the GP regression with exponential kernel on 2d data ''' + exponential = GPy.kern.Exponential(2, ARD=True) + self.check_model(exponential, model_type='GPRegression', dimension=2) +
+
[docs] def test_GPRegression_bias_kern_1D(self): + ''' Testing the GP regression with bias kernel on 1d data ''' + bias = GPy.kern.Bias(1) + self.check_model(bias, model_type='GPRegression', dimension=1) +
+
[docs] def test_GPRegression_bias_kern_2D(self): + ''' Testing the GP regression with bias kernel on 2d data ''' + bias = GPy.kern.Bias(2) + self.check_model(bias, model_type='GPRegression', dimension=2) +
+
[docs] def test_GPRegression_linear_kern_1D_ARD(self): + ''' Testing the GP regression with linear kernel on 1d data ''' + linear = GPy.kern.Linear(1, ARD=True) + self.check_model(linear, model_type='GPRegression', dimension=1) +
+
[docs] def test_GPRegression_linear_kern_2D_ARD(self): + ''' Testing the GP regression with linear kernel on 2d data ''' + linear = GPy.kern.Linear(2, ARD=True) + self.check_model(linear, model_type='GPRegression', dimension=2) +
+
[docs] def test_GPRegression_linear_kern_1D(self): + ''' Testing the GP regression with linear kernel on 1d data ''' + linear = GPy.kern.Linear(1) + self.check_model(linear, model_type='GPRegression', dimension=1) +
+
[docs] def test_GPRegression_linear_kern_2D(self): + ''' Testing the GP regression with linear kernel on 2d data ''' + linear = GPy.kern.Linear(2) + self.check_model(linear, model_type='GPRegression', dimension=2) +
+
[docs] def test_SparseGPRegression_rbf_white_kern_1d(self): + ''' Testing the sparse GP regression with rbf kernel with white kernel on 1d data ''' + rbf = GPy.kern.RBF(1) + self.check_model(rbf, model_type='SparseGPRegression', dimension=1) +
+
[docs] def test_SparseGPRegression_rbf_white_kern_2D(self): + ''' Testing the sparse GP regression with rbf kernel on 2d data ''' + rbf = GPy.kern.RBF(2) + self.check_model(rbf, model_type='SparseGPRegression', dimension=2) +
+
[docs] def test_SparseGPRegression_rbf_linear_white_kern_1D(self): + ''' Testing the sparse GP regression with rbf kernel on 2d data ''' + rbflin = GPy.kern.RBF(1) + GPy.kern.Linear(1) + self.check_model(rbflin, model_type='SparseGPRegression', dimension=1) +
+
[docs] def test_SparseGPRegression_rbf_linear_white_kern_2D(self): + ''' Testing the sparse GP regression with rbf kernel on 2d data ''' + rbflin = GPy.kern.RBF(2) + GPy.kern.Linear(2) + self.check_model(rbflin, model_type='SparseGPRegression', dimension=2) + + # @unittest.expectedFailure
+
[docs] def test_SparseGPRegression_rbf_linear_white_kern_2D_uncertain_inputs(self): + ''' Testing the sparse GP regression with rbf, linear kernel on 2d data with uncertain inputs''' + rbflin = GPy.kern.RBF(2) + GPy.kern.Linear(2) + raise unittest.SkipTest("This is not implemented yet!") + self.check_model(rbflin, model_type='SparseGPRegression', dimension=2, uncertain_inputs=1) + + # @unittest.expectedFailure
+
[docs] def test_SparseGPRegression_rbf_linear_white_kern_1D_uncertain_inputs(self): + ''' Testing the sparse GP regression with rbf, linear kernel on 1d data with uncertain inputs''' + rbflin = GPy.kern.RBF(1) + GPy.kern.Linear(1) + raise unittest.SkipTest("This is not implemented yet!") + self.check_model(rbflin, model_type='SparseGPRegression', dimension=1, uncertain_inputs=1) +
+
[docs] def test_GPLVM_rbf_bias_white_kern_2D(self): + """ Testing GPLVM with rbf + bias kernel """ + N, input_dim, D = 50, 1, 2 + X = np.random.rand(N, input_dim) + k = GPy.kern.RBF(input_dim, 0.5, 0.9 * np.ones((1,))) + GPy.kern.Bias(input_dim, 0.1) + GPy.kern.White(input_dim, 0.05) + K = k.K(X) + Y = np.random.multivariate_normal(np.zeros(N), K, input_dim).T + m = GPy.models.GPLVM(Y, input_dim, kernel=k) + self.assertTrue(m.checkgrad()) +
+
[docs] def test_GPLVM_rbf_linear_white_kern_2D(self): + """ Testing GPLVM with rbf + bias kernel """ + N, input_dim, D = 50, 1, 2 + X = np.random.rand(N, input_dim) + k = GPy.kern.Linear(input_dim) + GPy.kern.Bias(input_dim, 0.1) + GPy.kern.White(input_dim, 0.05) + K = k.K(X) + Y = np.random.multivariate_normal(np.zeros(N), K, input_dim).T + m = GPy.models.GPLVM(Y, input_dim, init='PCA', kernel=k) + self.assertTrue(m.checkgrad()) +
+
[docs] def test_GP_EP_probit(self): + N = 20 + X = np.hstack([np.random.normal(5, 2, N / 2), np.random.normal(10, 2, N / 2)])[:, None] + Y = np.hstack([np.ones(N / 2), np.zeros(N / 2)])[:, None] + kernel = GPy.kern.RBF(1) + m = GPy.models.GPClassification(X, Y, kernel=kernel) + self.assertTrue(m.checkgrad()) +
+
[docs] def test_sparse_EP_DTC_probit(self): + N = 20 + X = np.hstack([np.random.normal(5, 2, N / 2), np.random.normal(10, 2, N / 2)])[:, None] + Y = np.hstack([np.ones(N / 2), np.zeros(N / 2)])[:, None] + Z = np.linspace(0, 15, 4)[:, None] + kernel = GPy.kern.RBF(1) + m = GPy.models.SparseGPClassification(X, Y, kernel=kernel, Z=Z) + # distribution = GPy.likelihoods.likelihood_functions.Bernoulli() + # likelihood = GPy.likelihoods.EP(Y, distribution) + # m = GPy.core.SparseGP(X, likelihood, kernel, Z) + # m.ensure_default_constraints() + self.assertTrue(m.checkgrad()) +
+ @unittest.expectedFailure +
[docs] def test_generalized_FITC(self): + N = 20 + X = np.hstack([np.random.rand(N / 2) + 1, np.random.rand(N / 2) - 1])[:, None] + k = GPy.kern.RBF(1) + GPy.kern.White(1) + Y = np.hstack([np.ones(N / 2), np.zeros(N / 2)])[:, None] + m = GPy.models.FITCClassification(X, Y, kernel=k) + m.update_likelihood_approximation() + self.assertTrue(m.checkgrad()) +
+ @unittest.expectedFailure +
[docs] def test_multioutput_regression_1D(self): + X1 = np.random.rand(50, 1) * 8 + X2 = np.random.rand(30, 1) * 5 + X = np.vstack((X1, X2)) + Y1 = np.sin(X1) + np.random.randn(*X1.shape) * 0.05 + Y2 = -np.sin(X2) + np.random.randn(*X2.shape) * 0.05 + Y = np.vstack((Y1, Y2)) + + k1 = GPy.kern.RBF(1) + m = GPy.models.GPMultioutputRegression(X_list=[X1, X2], Y_list=[Y1, Y2], kernel_list=[k1]) + import ipdb;ipdb.set_trace() + m.constrain_fixed('.*rbf_var', 1.) + self.assertTrue(m.checkgrad()) +
+ @unittest.expectedFailure +
[docs] def test_multioutput_sparse_regression_1D(self): + X1 = np.random.rand(500, 1) * 8 + X2 = np.random.rand(300, 1) * 5 + X = np.vstack((X1, X2)) + Y1 = np.sin(X1) + np.random.randn(*X1.shape) * 0.05 + Y2 = -np.sin(X2) + np.random.randn(*X2.shape) * 0.05 + Y = np.vstack((Y1, Y2)) + + k1 = GPy.kern.RBF(1) + m = GPy.models.SparseGPMultioutputRegression(X_list=[X1, X2], Y_list=[Y1, Y2], kernel_list=[k1]) + m.constrain_fixed('.*rbf_var', 1.) + self.assertTrue(m.checkgrad()) +
+
[docs] def test_gp_heteroscedastic_regression(self): + num_obs = 25 + X = np.random.randint(0, 140, num_obs) + X = X[:, None] + Y = 25. + np.sin(X / 20.) * 2. + np.random.rand(num_obs)[:, None] + kern = GPy.kern.Bias(1) + GPy.kern.RBF(1) + m = GPy.models.GPHeteroscedasticRegression(X, Y, kern) + self.assertTrue(m.checkgrad()) +
+
[docs] def test_sparse_gp_heteroscedastic_regression(self): + num_obs = 25 + X = np.random.randint(0, 140, num_obs) + X = X[:, None] + Y = 25. + np.sin(X / 20.) * 2. + np.random.rand(num_obs)[:, None] + kern = GPy.kern.Bias(1) + GPy.kern.RBF(1) + Y_metadata = {'output_index':np.arange(num_obs)[:,None]} + noise_terms = np.unique(Y_metadata['output_index'].flatten()) + likelihoods_list = [GPy.likelihoods.Gaussian(name="Gaussian_noise_%s" %j) for j in noise_terms] + likelihood = GPy.likelihoods.MixedNoise(likelihoods_list=likelihoods_list) + m = GPy.core.SparseGP(X, Y, X[np.random.choice(num_obs, 10)], + kern, likelihood, + GPy.inference.latent_function_inference.VarDTC(), + Y_metadata=Y_metadata) + self.assertTrue(m.checkgrad()) +
+
[docs] def test_gp_kronecker_gaussian(self): + N1, N2 = 30, 20 + X1 = np.random.randn(N1, 1) + X2 = np.random.randn(N2, 1) + X1.sort(0); X2.sort(0) + k1 = GPy.kern.RBF(1) # + GPy.kern.White(1) + k2 = GPy.kern.RBF(1) # + GPy.kern.White(1) + Y = np.random.randn(N1, N2) + Y = Y - Y.mean(0) + Y = Y / Y.std(0) + m = GPy.models.GPKroneckerGaussianRegression(X1, X2, Y, k1, k2) + + # build the model the dumb way + assert (N1 * N2 < 1000), "too much data for standard GPs!" + yy, xx = np.meshgrid(X2, X1) + Xgrid = np.vstack((xx.flatten(order='F'), yy.flatten(order='F'))).T + kg = GPy.kern.RBF(1, active_dims=[0]) * GPy.kern.RBF(1, active_dims=[1]) + mm = GPy.models.GPRegression(Xgrid, Y.reshape(-1, 1, order='F'), kernel=kg) + + m.randomize() + mm[:] = m[:] + assert np.allclose(m.log_likelihood(), mm.log_likelihood()) + assert np.allclose(m.gradient, mm.gradient) + X1test = np.random.randn(100, 1) + X2test = np.random.randn(100, 1) + mean1, var1 = m.predict(X1test, X2test) + yy, xx = np.meshgrid(X2test, X1test) + Xgrid = np.vstack((xx.flatten(order='F'), yy.flatten(order='F'))).T + mean2, var2 = mm.predict(Xgrid) + assert np.allclose(mean1, mean2) + assert np.allclose(var1, var2) +
+
[docs] def test_gp_VGPC(self): + num_obs = 25 + X = np.random.randint(0, 140, num_obs) + X = X[:, None] + Y = 25. + np.sin(X / 20.) * 2. + np.random.rand(num_obs)[:, None] + kern = GPy.kern.Bias(1) + GPy.kern.RBF(1) + m = GPy.models.GPVariationalGaussianApproximation(X, Y, kern) + self.assertTrue(m.checkgrad()) + +
+if __name__ == "__main__": + print "Running unit tests, please be (very) patient..." + unittest.main() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/observable_tests.html b/doc/_build/html/_modules/GPy/testing/observable_tests.html new file mode 100644 index 00000000..a8465f26 --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/observable_tests.html @@ -0,0 +1,228 @@ + + + + + + + + GPy.testing.observable_tests — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.observable_tests

+# Copyright (c) 2014, Max Zwiessele
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+import unittest
+from GPy.core.parameterization.parameterized import Parameterized
+from GPy.core.parameterization.param import Param
+import numpy
+
+# One trigger in init
+_trigger_start = -1
+
+
[docs]class ParamTestParent(Parameterized): + parent_changed_count = _trigger_start +
[docs] def parameters_changed(self): + self.parent_changed_count += 1 +
+
[docs]class ParameterizedTest(Parameterized): + # One trigger after initialization + params_changed_count = _trigger_start +
[docs] def parameters_changed(self): + self.params_changed_count += 1 +
+
[docs]class Test(unittest.TestCase): + +
[docs] def setUp(self): + self.parent = ParamTestParent('test parent') + self.par = ParameterizedTest('test model') + self.par2 = ParameterizedTest('test model 2') + self.p = Param('test parameter', numpy.random.normal(1,2,(10,3))) + + self.par.link_parameter(self.p) + self.par.link_parameter(Param('test1', numpy.random.normal(0,1,(1,)))) + self.par.link_parameter(Param('test2', numpy.random.normal(0,1,(1,)))) + + self.par2.link_parameter(Param('par2 test1', numpy.random.normal(0,1,(1,)))) + self.par2.link_parameter(Param('par2 test2', numpy.random.normal(0,1,(1,)))) + + self.parent.link_parameter(self.par) + self.parent.link_parameter(self.par2) + + self._observer_triggered = None + self._trigger_count = 0 + self._first = None + self._second = None +
+ def _trigger(self, me, which): + self._observer_triggered = which + self._trigger_count += 1 + if self._first is not None: + self._second = self._trigger + else: + self._first = self._trigger + + def _trigger_priority(self, me, which): + if self._first is not None: + self._second = self._trigger_priority + else: + self._first = self._trigger_priority + +
[docs] def test_observable(self): + self.par.add_observer(self, self._trigger, -1) + self.assertEqual(self.par.params_changed_count, 0, 'no params changed yet') + self.assertEqual(self.par.params_changed_count, self.parent.parent_changed_count, 'parent should be triggered as often as param') + + self.p[0,1] = 3 # trigger observers + self.assertIs(self._observer_triggered, self.p, 'observer should have triggered') + self.assertEqual(self._trigger_count, 1, 'observer should have triggered once') + self.assertEqual(self.par.params_changed_count, 1, 'params changed once') + self.assertEqual(self.par.params_changed_count, self.parent.parent_changed_count, 'parent should be triggered as often as param') + + self.par.remove_observer(self) + self.p[0,1] = 4 + self.assertIs(self._observer_triggered, self.p, 'observer should not have triggered') + self.assertEqual(self._trigger_count, 1, 'observer should have triggered once') + self.assertEqual(self.par.params_changed_count, 2, 'params changed second') + self.assertEqual(self.par.params_changed_count, self.parent.parent_changed_count, 'parent should be triggered as often as param') + + self.par.add_observer(self, self._trigger, -1) + self.p[0,1] = 4 + self.assertIs(self._observer_triggered, self.p, 'observer should have triggered') + self.assertEqual(self._trigger_count, 2, 'observer should have triggered once') + self.assertEqual(self.par.params_changed_count, 3, 'params changed second') + self.assertEqual(self.par.params_changed_count, self.parent.parent_changed_count, 'parent should be triggered as often as param') + + self.par.remove_observer(self, self._trigger) + self.p[0,1] = 3 + self.assertIs(self._observer_triggered, self.p, 'observer should not have triggered') + self.assertEqual(self._trigger_count, 2, 'observer should have triggered once') + self.assertEqual(self.par.params_changed_count, 4, 'params changed second') + self.assertEqual(self.par.params_changed_count, self.parent.parent_changed_count, 'parent should be triggered as often as param') +
+
[docs] def test_set_params(self): + self.assertEqual(self.par.params_changed_count, 0, 'no params changed yet') + self.par.param_array[:] = 1 + self.par._trigger_params_changed() + self.assertEqual(self.par.params_changed_count, 1, 'now params changed') + self.assertEqual(self.parent.parent_changed_count, self.par.params_changed_count) + + self.par.param_array[:] = 2 + self.par._trigger_params_changed() + self.assertEqual(self.par.params_changed_count, 2, 'now params changed') + self.assertEqual(self.parent.parent_changed_count, self.par.params_changed_count) + +
+
[docs] def test_priority_notify(self): + self.assertEqual(self.par.params_changed_count, 0) + self.par.notify_observers(0, None) + self.assertEqual(self.par.params_changed_count, 1) + self.assertEqual(self.parent.parent_changed_count, self.par.params_changed_count) + + self.par.notify_observers(0, -numpy.inf) + self.assertEqual(self.par.params_changed_count, 2) + self.assertEqual(self.parent.parent_changed_count, 1) +
+
[docs] def test_priority(self): + self.par.add_observer(self, self._trigger, -1) + self.par.add_observer(self, self._trigger_priority, 0) + self.par.notify_observers(0) + self.assertEqual(self._first, self._trigger_priority, 'priority should be first') + self.assertEqual(self._second, self._trigger, 'priority should be first') + + self.par.remove_observer(self) + self._first = self._second = None + + self.par.add_observer(self, self._trigger, 1) + self.par.add_observer(self, self._trigger_priority, 0) + self.par.notify_observers(0) + self.assertEqual(self._first, self._trigger, 'priority should be second') + self.assertEqual(self._second, self._trigger_priority, 'priority should be second') +
+if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/parameterized_tests.html b/doc/_build/html/_modules/GPy/testing/parameterized_tests.html new file mode 100644 index 00000000..734308e5 --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/parameterized_tests.html @@ -0,0 +1,353 @@ + + + + + + + + GPy.testing.parameterized_tests — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.parameterized_tests

+'''
+Created on Feb 13, 2014
+
+@author: maxzwiessele
+'''
+import unittest
+import GPy
+import numpy as np
+from GPy.core.parameterization.parameter_core import HierarchyError
+from GPy.core.parameterization.observable_array import ObsAr
+from GPy.core.parameterization.transformations import NegativeLogexp, Logistic
+from GPy.core.parameterization.parameterized import Parameterized
+from GPy.core.parameterization.param import Param
+from GPy.core.parameterization.index_operations import ParameterIndexOperations
+
+
[docs]class ArrayCoreTest(unittest.TestCase): +
[docs] def setUp(self): + self.X = np.random.normal(1,1, size=(100,10)) + self.obsX = ObsAr(self.X) +
+
[docs] def test_init(self): + X = ObsAr(self.X) + X2 = ObsAr(X) + self.assertIs(X, X2, "no new Observable array, when Observable is given") +
+
[docs] def test_slice(self): + t1 = self.X[2:78] + t2 = self.obsX[2:78] + self.assertListEqual(t1.tolist(), t2.tolist(), "Slicing should be the exact same, as in ndarray") +
+
[docs]class ParameterizedTest(unittest.TestCase): + +
[docs] def setUp(self): + self.rbf = GPy.kern.RBF(20) + self.white = GPy.kern.White(1) + from GPy.core.parameterization import Param + from GPy.core.parameterization.transformations import Logistic + self.param = Param('param', np.random.uniform(0,1,(10,5)), Logistic(0, 1)) + + self.test1 = GPy.core.Parameterized("test model") + self.test1.param = self.param + self.test1.kern = self.rbf+self.white + self.test1.link_parameter(self.test1.kern) + self.test1.link_parameter(self.param, 0) + + # print self.test1: + #============================================================================= + # test_model. | Value | Constraint | Prior | Tied to + # param | (25L, 2L) | {0.0,1.0} | | + # add.rbf.variance | 1.0 | 0.0,1.0 +ve | | + # add.rbf.lengthscale | 1.0 | 0.0,1.0 +ve | | + # add.white.variance | 1.0 | 0.0,1.0 +ve | | + #============================================================================= + + x = np.linspace(-2,6,4)[:,None] + y = np.sin(x) + self.testmodel = GPy.models.GPRegression(x,y) + # print self.testmodel: + #============================================================================= + # GP_regression. | Value | Constraint | Prior | Tied to + # rbf.variance | 1.0 | +ve | | + # rbf.lengthscale | 1.0 | +ve | | + # Gaussian_noise.variance | 1.0 | +ve | | + #============================================================================= +
+
[docs] def test_add_parameter(self): + self.assertEquals(self.rbf._parent_index_, 0) + self.assertEquals(self.white._parent_index_, 1) + self.assertEquals(self.param._parent_index_, 0) + pass +
+
[docs] def test_fixes(self): + self.white.fix(warning=False) + self.test1.unlink_parameter(self.param) + self.assertTrue(self.test1._has_fixes()) + from GPy.core.parameterization.transformations import FIXED, UNFIXED + self.assertListEqual(self.test1._fixes_.tolist(),[UNFIXED,UNFIXED,FIXED]) + self.test1.kern.link_parameter(self.white, 0) + self.assertListEqual(self.test1._fixes_.tolist(),[FIXED,UNFIXED,UNFIXED]) + self.test1.kern.rbf.fix() + self.assertListEqual(self.test1._fixes_.tolist(),[FIXED]*3) + self.test1.fix() + self.assertTrue(self.test1.is_fixed) + self.assertListEqual(self.test1._fixes_.tolist(),[FIXED]*self.test1.size) +
+
[docs] def test_remove_parameter(self): + from GPy.core.parameterization.transformations import FIXED, UNFIXED, __fixed__, Logexp + self.white.fix() + self.test1.kern.unlink_parameter(self.white) + self.assertIs(self.test1._fixes_,None) + + self.assertIsInstance(self.white.constraints, ParameterIndexOperations) + self.assertListEqual(self.white._fixes_.tolist(), [FIXED]) + self.assertIs(self.test1.constraints, self.rbf.constraints._param_index_ops) + self.assertIs(self.test1.constraints, self.param.constraints._param_index_ops) + + self.test1.link_parameter(self.white, 0) + self.assertIs(self.test1.constraints, self.white.constraints._param_index_ops) + self.assertIs(self.test1.constraints, self.rbf.constraints._param_index_ops) + self.assertIs(self.test1.constraints, self.param.constraints._param_index_ops) + self.assertListEqual(self.test1.constraints[__fixed__].tolist(), [0]) + self.assertIs(self.white._fixes_,None) + self.assertListEqual(self.test1._fixes_.tolist(),[FIXED] + [UNFIXED] * 52) + + self.test1.unlink_parameter(self.white) + self.assertIs(self.test1._fixes_,None) + self.assertListEqual(self.white._fixes_.tolist(), [FIXED]) + self.assertIs(self.test1.constraints, self.rbf.constraints._param_index_ops) + self.assertIs(self.test1.constraints, self.param.constraints._param_index_ops) + self.assertListEqual(self.test1.constraints[Logexp()].tolist(), range(self.param.size, self.param.size+self.rbf.size)) +
+
[docs] def test_remove_parameter_param_array_grad_array(self): + val = self.test1.kern.param_array.copy() + self.test1.kern.unlink_parameter(self.white) + self.assertListEqual(self.test1.kern.param_array.tolist(), val[:2].tolist()) +
+
[docs] def test_add_parameter_already_in_hirarchy(self): + self.assertRaises(HierarchyError, self.test1.link_parameter, self.white.parameters[0]) +
+
[docs] def test_default_constraints(self): + self.assertIs(self.rbf.variance.constraints._param_index_ops, self.rbf.constraints._param_index_ops) + self.assertIs(self.test1.constraints, self.rbf.constraints._param_index_ops) + self.assertListEqual(self.rbf.constraints.indices()[0].tolist(), range(2)) + from GPy.core.parameterization.transformations import Logexp + kern = self.test1.kern + self.test1.unlink_parameter(kern) + self.assertListEqual(kern.constraints[Logexp()].tolist(), range(3)) +
+
[docs] def test_constraints(self): + self.rbf.constrain(GPy.transformations.Square(), False) + self.assertListEqual(self.test1.constraints[GPy.transformations.Square()].tolist(), range(self.param.size, self.param.size+self.rbf.size)) + self.assertListEqual(self.test1.constraints[GPy.transformations.Logexp()].tolist(), [self.param.size+self.rbf.size]) + + self.test1.kern.unlink_parameter(self.rbf) + self.assertListEqual(self.test1.constraints[GPy.transformations.Square()].tolist(), []) +
+ +
[docs] def test_constraints_views(self): + self.assertEqual(self.white.constraints._offset, self.param.size+self.rbf.size) + self.assertEqual(self.rbf.constraints._offset, self.param.size) + self.assertEqual(self.param.constraints._offset, 0) +
+
[docs] def test_fixing_randomize(self): + self.white.fix(warning=True) + val = float(self.white.variance) + self.test1.randomize() + self.assertEqual(val, self.white.variance) +
+
[docs] def test_randomize(self): + ps = self.test1.param.view(np.ndarray).copy() + self.test1.param[2:5].fix() + self.test1.param.randomize() + self.assertFalse(np.all(ps==self.test1.param),str(ps)+str(self.test1.param)) +
+
[docs] def test_fixing_randomize_parameter_handling(self): + self.rbf.fix(warning=True) + val = float(self.rbf.variance) + self.test1.kern.randomize() + self.assertEqual(val, self.rbf.variance) +
+
[docs] def test_updates(self): + val = float(self.testmodel.log_likelihood()) + self.testmodel.update_model(False) + self.testmodel.kern.randomize() + self.testmodel.likelihood.randomize() + self.assertEqual(val, self.testmodel.log_likelihood()) + self.testmodel.update_model(True) + self.assertNotEqual(val, self.testmodel.log_likelihood()) +
+
[docs] def test_fixing_optimize(self): + self.testmodel.kern.lengthscale.fix() + val = float(self.testmodel.kern.lengthscale) + self.testmodel.randomize() + self.assertEqual(val, self.testmodel.kern.lengthscale) +
+
[docs] def test_add_parameter_in_hierarchy(self): + self.test1.kern.rbf.link_parameter(Param("NEW", np.random.rand(2), NegativeLogexp()), 1) + self.assertListEqual(self.test1.constraints[NegativeLogexp()].tolist(), range(self.param.size+1, self.param.size+1 + 2)) + self.assertListEqual(self.test1.constraints[GPy.transformations.Logistic(0,1)].tolist(), range(self.param.size)) + self.assertListEqual(self.test1.constraints[GPy.transformations.Logexp(0,1)].tolist(), np.r_[50, 53:55].tolist()) +
+
[docs] def test_regular_expression_misc(self): + self.testmodel.kern.lengthscale.fix() + val = float(self.testmodel.kern.lengthscale) + self.testmodel.randomize() + self.assertEqual(val, self.testmodel.kern.lengthscale) + + variances = self.testmodel['.*var'].values() + self.testmodel['.*var'].fix() + self.testmodel.randomize() + np.testing.assert_equal(variances, self.testmodel['.*var'].values()) +
+
[docs] def test_fix_unfix(self): + fixed = self.testmodel.kern.lengthscale.fix() + self.assertListEqual(fixed.tolist(), [0]) + unfixed = self.testmodel.kern.lengthscale.unfix() + self.testmodel.kern.lengthscale.constrain_positive() + self.assertListEqual(unfixed.tolist(), [0]) + + fixed = self.testmodel.kern.fix() + self.assertListEqual(fixed.tolist(), [0,1]) + unfixed = self.testmodel.kern.unfix() + self.assertListEqual(unfixed.tolist(), [0,1]) +
+
[docs] def test_constraints_in_init(self): + class Test(Parameterized): + def __init__(self, name=None, parameters=[], *a, **kw): + super(Test, self).__init__(name=name) + self.x = Param('x', np.random.uniform(0,1,(3,4))) + self.x[0].constrain_bounded(0,1) + self.link_parameter(self.x) + self.x[1].fix() + t = Test() + c = {Logistic(0,1): np.array([0, 1, 2, 3]), 'fixed': np.array([4, 5, 6, 7])} + np.testing.assert_equal(t.x.constraints[Logistic(0,1)], c[Logistic(0,1)]) + np.testing.assert_equal(t.x.constraints['fixed'], c['fixed']) +
+
[docs] def test_parameter_modify_in_init(self): + class TestLikelihood(Parameterized): + def __init__(self, param1 = 2., param2 = 3.): + super(TestLikelihood, self).__init__("TestLike") + self.p1 = Param('param1', param1) + self.p2 = Param('param2', param2) + + self.link_parameter(self.p1) + self.link_parameter(self.p2) + + self.p1.fix() + self.p1.unfix() + self.p2.constrain_negative() + self.p1.fix() + self.p2.constrain_positive() + self.p2.fix() + self.p2.constrain_positive() + + m = TestLikelihood() + print m + val = m.p1.values.copy() + self.assert_(m.p1.is_fixed) + self.assert_(m.constraints[GPy.constraints.Logexp()].tolist(), [1]) + m.randomize() + self.assertEqual(m.p1, val) +
+
[docs] def test_printing(self): + print self.test1 + print self.param + print self.test1[''] +
+if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.test_add_parameter'] + unittest.main() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/pickle_tests.html b/doc/_build/html/_modules/GPy/testing/pickle_tests.html new file mode 100644 index 00000000..7114a4ef --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/pickle_tests.html @@ -0,0 +1,316 @@ + + + + + + + + GPy.testing.pickle_tests — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.pickle_tests

+'''
+Created on 13 Mar 2014
+
+@author: maxz
+'''
+import unittest, itertools
+#import cPickle as pickle
+import pickle
+import numpy as np
+from GPy.core.parameterization.index_operations import ParameterIndexOperations,\
+    ParameterIndexOperationsView
+import tempfile
+from GPy.core.parameterization.param import Param
+from GPy.core.parameterization.observable_array import ObsAr
+from GPy.core.parameterization.priors import Gaussian
+from GPy.kern._src.rbf import RBF
+from GPy.kern._src.linear import Linear
+from GPy.kern._src.static import Bias, White
+from GPy.examples.dimensionality_reduction import mrd_simulation
+from GPy.core.parameterization.variational import NormalPosterior
+from GPy.models.gp_regression import GPRegression
+
+
[docs]def toy_model(): + X = np.linspace(0,1,50)[:, None] + Y = np.sin(X) + m = GPRegression(X=X, Y=Y) + return m +
+
[docs]class ListDictTestCase(unittest.TestCase): +
[docs] def assertListDictEquals(self, d1, d2, msg=None): + for k,v in d1.iteritems(): + self.assertListEqual(list(v), list(d2[k]), msg)
+
[docs] def assertArrayListEquals(self, l1, l2): + for a1, a2 in itertools.izip(l1,l2): + np.testing.assert_array_equal(a1, a2) +
+
[docs]class Test(ListDictTestCase): +
[docs] def test_parameter_index_operations(self): + pio = ParameterIndexOperations(dict(test1=np.array([4,3,1,6,4]), test2=np.r_[2:130])) + piov = ParameterIndexOperationsView(pio, 20, 250) + self.assertListDictEquals(dict(piov.items()), dict(piov.copy().iteritems())) + self.assertListDictEquals(dict(pio.iteritems()), dict(pio.copy().items())) + + self.assertArrayListEquals(pio.copy().indices(), pio.indices()) + self.assertArrayListEquals(piov.copy().indices(), piov.indices()) + + with tempfile.TemporaryFile('w+b') as f: + pickle.dump(pio, f) + f.seek(0) + pio2 = pickle.load(f) + self.assertListDictEquals(pio._properties, pio2._properties) + + with tempfile.TemporaryFile('w+b') as f: + pickle.dump(piov, f) + f.seek(0) + pio2 = pickle.load(f) + self.assertListDictEquals(dict(piov.items()), dict(pio2.iteritems())) +
+
[docs] def test_param(self): + param = Param('test', np.arange(4*2).reshape(4,2)) + param[0].constrain_positive() + param[1].fix() + param[2].set_prior(Gaussian(0,1)) + pcopy = param.copy() + self.assertListEqual(param.tolist(), pcopy.tolist()) + self.assertListEqual(str(param).split('\n'), str(pcopy).split('\n')) + self.assertIsNot(param, pcopy) + with tempfile.TemporaryFile('w+b') as f: + pickle.dump(param, f) + f.seek(0) + pcopy = pickle.load(f) + self.assertListEqual(param.tolist(), pcopy.tolist()) + self.assertSequenceEqual(str(param), str(pcopy)) +
+
[docs] def test_observable_array(self): + obs = ObsAr(np.arange(4*2).reshape(4,2)) + pcopy = obs.copy() + self.assertListEqual(obs.tolist(), pcopy.tolist()) + with tempfile.TemporaryFile('w+b') as f: + pickle.dump(obs, f) + f.seek(0) + pcopy = pickle.load(f) + self.assertListEqual(obs.tolist(), pcopy.tolist()) + self.assertSequenceEqual(str(obs), str(pcopy)) +
+
[docs] def test_parameterized(self): + par = RBF(1, active_dims=[1]) + Linear(2, active_dims=[0,2]) + Bias(3) + White(3) + par.gradient = 10 + par.randomize() + pcopy = par.copy() + self.assertIsInstance(pcopy.constraints, ParameterIndexOperations) + self.assertIsInstance(pcopy.rbf.constraints, ParameterIndexOperationsView) + self.assertIs(pcopy.constraints, pcopy.rbf.constraints._param_index_ops) + self.assertIs(pcopy.constraints, pcopy.rbf.lengthscale.constraints._param_index_ops) + self.assertIs(pcopy.constraints, pcopy.linear.constraints._param_index_ops) + self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + pcopy.gradient = 10 # gradient does not get copied anymore + self.assertListEqual(par.gradient_full.tolist(), pcopy.gradient_full.tolist()) + self.assertSequenceEqual(str(par), str(pcopy)) + self.assertIsNot(par.param_array, pcopy.param_array) + self.assertIsNot(par.gradient_full, pcopy.gradient_full) + with tempfile.TemporaryFile('w+b') as f: + par.pickle(f) + f.seek(0) + pcopy = pickle.load(f) + self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + pcopy.gradient = 10 + np.testing.assert_allclose(par.linear.gradient_full, pcopy.linear.gradient_full) + np.testing.assert_allclose(pcopy.linear.gradient_full, 10) + self.assertSequenceEqual(str(par), str(pcopy)) +
+
[docs] def test_model(self): + par = toy_model() + pcopy = par.copy() + self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) + self.assertSequenceEqual(str(par), str(pcopy)) + self.assertIsNot(par.param_array, pcopy.param_array) + self.assertIsNot(par.gradient_full, pcopy.gradient_full) + self.assertTrue(pcopy.checkgrad()) + self.assert_(np.any(pcopy.gradient!=0.0)) + with tempfile.TemporaryFile('w+b') as f: + par.pickle(f) + f.seek(0) + pcopy = pickle.load(f) + self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) + self.assertSequenceEqual(str(par), str(pcopy)) + self.assert_(pcopy.checkgrad()) +
+
[docs] def test_modelrecreation(self): + par = toy_model() + pcopy = GPRegression(par.X.copy(), par.Y.copy(), kernel=par.kern.copy()) + np.testing.assert_allclose(par.param_array, pcopy.param_array) + np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) + self.assertSequenceEqual(str(par), str(pcopy)) + self.assertIsNot(par.param_array, pcopy.param_array) + self.assertIsNot(par.gradient_full, pcopy.gradient_full) + self.assertTrue(pcopy.checkgrad()) + self.assert_(np.any(pcopy.gradient!=0.0)) + pcopy.optimize('bfgs') + par.optimize('bfgs') + np.testing.assert_allclose(pcopy.param_array, par.param_array, atol=1e-6) + par.randomize() + with tempfile.TemporaryFile('w+b') as f: + par.pickle(f) + f.seek(0) + pcopy = pickle.load(f) + np.testing.assert_allclose(par.param_array, pcopy.param_array) + np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full, atol=1e-6) + self.assertSequenceEqual(str(par), str(pcopy)) + self.assert_(pcopy.checkgrad()) +
+
[docs] def test_posterior(self): + X = np.random.randn(3,5) + Xv = np.random.rand(*X.shape) + par = NormalPosterior(X,Xv) + par.gradient = 10 + pcopy = par.copy() + pcopy.gradient = 10 + self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + self.assertListEqual(par.gradient_full.tolist(), pcopy.gradient_full.tolist()) + self.assertSequenceEqual(str(par), str(pcopy)) + self.assertIsNot(par.param_array, pcopy.param_array) + self.assertIsNot(par.gradient_full, pcopy.gradient_full) + with tempfile.TemporaryFile('w+b') as f: + par.pickle(f) + f.seek(0) + pcopy = pickle.load(f) + self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + pcopy.gradient = 10 + np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) + np.testing.assert_allclose(pcopy.mean.gradient_full, 10) + self.assertSequenceEqual(str(par), str(pcopy)) +
+
[docs] def test_model_concat(self): + par = mrd_simulation(optimize=0, plot=0, plot_sim=0) + par.randomize() + pcopy = par.copy() + self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + self.assertListEqual(par.gradient_full.tolist(), pcopy.gradient_full.tolist()) + self.assertSequenceEqual(str(par), str(pcopy)) + self.assertIsNot(par.param_array, pcopy.param_array) + self.assertIsNot(par.gradient_full, pcopy.gradient_full) + self.assertTrue(par.checkgrad()) + self.assertTrue(pcopy.checkgrad()) + self.assert_(np.any(pcopy.gradient!=0.0)) + with tempfile.TemporaryFile('w+b') as f: + par.pickle(f) + f.seek(0) + pcopy = pickle.load(f) + self.assertListEqual(par.param_array.tolist(), pcopy.param_array.tolist()) + np.testing.assert_allclose(par.gradient_full, pcopy.gradient_full) + self.assertSequenceEqual(str(par), str(pcopy)) + self.assert_(pcopy.checkgrad()) +
+ def _callback(self, what, which): + what.count += 1 + + @unittest.skip + def test_add_observer(self): + par = toy_model() + par.name = "original" + par.count = 0 + par.add_observer(self, self._callback, 1) + pcopy = GPRegression(par.X.copy(), par.Y.copy(), kernel=par.kern.copy()) + self.assertNotIn(par.observers[0], pcopy.observers) + pcopy = par.copy() + pcopy.name = "copy" + self.assertTrue(par.checkgrad()) + self.assertTrue(pcopy.checkgrad()) + self.assertTrue(pcopy.kern.checkgrad()) + import ipdb;ipdb.set_trace() + self.assertIn(par.observers[0], pcopy.observers) + self.assertEqual(par.count, 3) + self.assertEqual(pcopy.count, 6) # 3 of each call to checkgrad +
+if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.test_parameter_index_operations'] + unittest.main() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/testing/prior_tests.html b/doc/_build/html/_modules/GPy/testing/prior_tests.html new file mode 100644 index 00000000..a93d160f --- /dev/null +++ b/doc/_build/html/_modules/GPy/testing/prior_tests.html @@ -0,0 +1,210 @@ + + + + + + + + GPy.testing.prior_tests — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.testing.prior_tests

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import unittest
+import numpy as np
+import GPy
+
+
[docs]class PriorTests(unittest.TestCase): +
[docs] def test_lognormal(self): + xmin, xmax = 1, 2.5*np.pi + b, C, SNR = 1, 0, 0.1 + X = np.linspace(xmin, xmax, 500) + y = b*X + C + 1*np.sin(X) + y += 0.05*np.random.randn(len(X)) + X, y = X[:, None], y[:, None] + m = GPy.models.GPRegression(X, y) + lognormal = GPy.priors.LogGaussian(1, 2) + m.rbf.set_prior(lognormal) + m.randomize() + self.assertTrue(m.checkgrad()) +
+
[docs] def test_Gamma(self): + xmin, xmax = 1, 2.5*np.pi + b, C, SNR = 1, 0, 0.1 + X = np.linspace(xmin, xmax, 500) + y = b*X + C + 1*np.sin(X) + y += 0.05*np.random.randn(len(X)) + X, y = X[:, None], y[:, None] + m = GPy.models.GPRegression(X, y) + Gamma = GPy.priors.Gamma(1, 1) + m.rbf.set_prior(Gamma) + m.randomize() + self.assertTrue(m.checkgrad()) +
+
[docs] def test_incompatibility(self): + xmin, xmax = 1, 2.5*np.pi + b, C, SNR = 1, 0, 0.1 + X = np.linspace(xmin, xmax, 500) + y = b*X + C + 1*np.sin(X) + y += 0.05*np.random.randn(len(X)) + X, y = X[:, None], y[:, None] + m = GPy.models.GPRegression(X, y) + gaussian = GPy.priors.Gaussian(1, 1) + # setting a Gaussian prior on non-negative parameters + # should raise an assertionerror. + self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) +
+
[docs] def test_set_prior(self): + xmin, xmax = 1, 2.5*np.pi + b, C, SNR = 1, 0, 0.1 + X = np.linspace(xmin, xmax, 500) + y = b*X + C + 1*np.sin(X) + y += 0.05*np.random.randn(len(X)) + X, y = X[:, None], y[:, None] + m = GPy.models.GPRegression(X, y) + + gaussian = GPy.priors.Gaussian(1, 1) + #m.rbf.set_prior(gaussian) + # setting a Gaussian prior on non-negative parameters + # should raise an assertionerror. + self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) +
+
[docs] def test_set_gaussian_for_reals(self): + xmin, xmax = 1, 2.5*np.pi + b, C, SNR = 1, 0, 0.1 + X = np.linspace(xmin, xmax, 500) + y = b*X + C + 1*np.sin(X) + y += 0.05*np.random.randn(len(X)) + X, y = X[:, None], y[:, None] + m = GPy.models.SparseGPRegression(X, y) + + gaussian = GPy.priors.Gaussian(1, 1) + m.Z.set_prior(gaussian) + # setting a Gaussian prior on non-negative parameters + # should raise an assertionerror. + #self.assertRaises(AssertionError, m.Z.set_prior, gaussian) + + +
+
[docs] def test_fixed_domain_check(self): + xmin, xmax = 1, 2.5*np.pi + b, C, SNR = 1, 0, 0.1 + X = np.linspace(xmin, xmax, 500) + y = b*X + C + 1*np.sin(X) + y += 0.05*np.random.randn(len(X)) + X, y = X[:, None], y[:, None] + m = GPy.models.GPRegression(X, y) + + m.rbf.fix() + gaussian = GPy.priors.Gaussian(1, 1) + # setting a Gaussian prior on non-negative parameters + # should raise an assertionerror. + self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) +
+
[docs] def test_fixed_domain_check1(self): + xmin, xmax = 1, 2.5*np.pi + b, C, SNR = 1, 0, 0.1 + X = np.linspace(xmin, xmax, 500) + y = b*X + C + 1*np.sin(X) + y += 0.05*np.random.randn(len(X)) + X, y = X[:, None], y[:, None] + m = GPy.models.GPRegression(X, y) + + m.kern.lengthscale.fix() + gaussian = GPy.priors.Gaussian(1, 1) + # setting a Gaussian prior on non-negative parameters + # should raise an assertionerror. + self.assertRaises(AssertionError, m.rbf.set_prior, gaussian) + + +
+if __name__ == "__main__": + print "Running unit tests, please be (very) patient..." + unittest.main() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/block_matrices.html b/doc/_build/html/_modules/GPy/util/block_matrices.html new file mode 100644 index 00000000..db4d90d5 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/block_matrices.html @@ -0,0 +1,120 @@ + + + + + + + + GPy.util.block_matrices — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.block_matrices

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+import numpy as np
+
+
[docs]def get_blocks(A, blocksizes): + assert (A.shape[0]==A.shape[1]) and len(A.shape)==2, "can;t blockify this non-square matrix" + N = np.sum(blocksizes) + assert A.shape[0] == N, "bad blocksizes" + num_blocks = len(blocksizes) + B = np.empty(shape=(num_blocks, num_blocks), dtype=np.object) + count_i = 0 + for Bi, i in enumerate(blocksizes): + count_j = 0 + for Bj, j in enumerate(blocksizes): + B[Bi, Bj] = A[count_i:count_i + i, count_j : count_j + j] + count_j += j + count_i += i + return B + + +
+if __name__=='__main__': + A = np.zeros((5,5)) + B = get_blocks(A,[2,3]) + B[0,0] += 7 + print B +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/caching.html b/doc/_build/html/_modules/GPy/util/caching.html new file mode 100644 index 00000000..fa213467 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/caching.html @@ -0,0 +1,289 @@ + + + + + + + + GPy.util.caching — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.caching

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+from ..core.parameterization.observable import Observable
+import collections, weakref
+
+
[docs]class Cacher(object): + def __init__(self, operation, limit=5, ignore_args=(), force_kwargs=()): + """ + Parameters: + *********** + :param callable operation: function to cache + :param int limit: depth of cacher + :param [int] ignore_args: list of indices, pointing at arguments to ignore in *args of operation(*args). This includes self! + :param [str] force_kwargs: list of kwarg names (strings). If a kwarg with that name is given, the cacher will force recompute and wont cache anything. + :param int verbose: verbosity level. 0: no print outs, 1: casual print outs, 2: debug level print outs + """ + self.limit = int(limit) + self.ignore_args = ignore_args + self.force_kwargs = force_kwargs + self.operation = operation + self.order = collections.deque() + self.cached_inputs = {} # point from cache_ids to a list of [ind_ids], which where used in cache cache_id + + #======================================================================= + # point from each ind_id to [ref(obj), cache_ids] + # 0: a weak reference to the object itself + # 1: the cache_ids in which this ind_id is used (len will be how many times we have seen this ind_id) + self.cached_input_ids = {} + #======================================================================= + + self.cached_outputs = {} # point from cache_ids to outputs + self.inputs_changed = {} # point from cache_ids to bools + +
[docs] def id(self, obj): + """returns the self.id of an object, to be used in caching individual self.ids""" + return hex(id(obj)) +
+
[docs] def combine_inputs(self, args, kw, ignore_args): + "Combines the args and kw in a unique way, such that ordering of kwargs does not lead to recompute" + inputs= args + tuple(c[1] for c in sorted(kw.items(), key=lambda x: x[0])) + # REMOVE the ignored arguments from input and PREVENT it from being checked!!! + return [a for i,a in enumerate(inputs) if i not in ignore_args] +
+
[docs] def prepare_cache_id(self, combined_args_kw): + "get the cacheid (conc. string of argument self.ids in order)" + cache_id = "".join(self.id(a) for a in combined_args_kw) + return cache_id +
+
[docs] def ensure_cache_length(self, cache_id): + "Ensures the cache is within its limits and has one place free" + if len(self.order) == self.limit: + # we have reached the limit, so lets release one element + cache_id = self.order.popleft() + combined_args_kw = self.cached_inputs[cache_id] + for ind in combined_args_kw: + if ind is not None: + ind_id = self.id(ind) + tmp = self.cached_input_ids.get(ind_id, None) + if tmp is not None: + ref, cache_ids = tmp + if len(cache_ids) == 1 and ref() is not None: + ref().remove_observer(self, self.on_cache_changed) + del self.cached_input_ids[ind_id] + else: + cache_ids.remove(cache_id) + self.cached_input_ids[ind_id] = [ref, cache_ids] + del self.cached_outputs[cache_id] + del self.inputs_changed[cache_id] + del self.cached_inputs[cache_id] +
+
[docs] def add_to_cache(self, cache_id, inputs, output): + """This adds cache_id to the cache, with inputs and output""" + self.inputs_changed[cache_id] = False + self.cached_outputs[cache_id] = output + self.order.append(cache_id) + self.cached_inputs[cache_id] = inputs + for a in inputs: + if a is not None: + ind_id = self.id(a) + v = self.cached_input_ids.get(ind_id, [weakref.ref(a), []]) + v[1].append(cache_id) + if len(v[1]) == 1: + a.add_observer(self, self.on_cache_changed) + self.cached_input_ids[ind_id] = v +
+ def __call__(self, *args, **kw): + """ + A wrapper function for self.operation, + """ + #======================================================================= + # !WARNING CACHE OFFSWITCH! + # return self.operation(*args, **kw) + #======================================================================= + + # 1: Check whether we have forced recompute arguments: + if len(self.force_kwargs) != 0: + for k in self.force_kwargs: + if k in kw and kw[k] is not None: + return self.operation(*args, **kw) + + # 2: prepare_cache_id and get the unique self.id string for this call + inputs = self.combine_inputs(args, kw, self.ignore_args) + cache_id = self.prepare_cache_id(inputs) + # 2: if anything is not cachable, we will just return the operation, without caching + if reduce(lambda a, b: a or (not (isinstance(b, Observable) or b is None)), inputs, False): + #print 'WARNING: '+self.operation.__name__ + ' not cacheable!' + #print [not (isinstance(b, Observable)) for b in inputs] + return self.operation(*args, **kw) + # 3&4: check whether this cache_id has been cached, then has it changed? + try: + if(self.inputs_changed[cache_id]): + # 4: This happens, when elements have changed for this cache self.id + self.inputs_changed[cache_id] = False + self.cached_outputs[cache_id] = self.operation(*args, **kw) + except KeyError: + # 3: This is when we never saw this chache_id: + self.ensure_cache_length(cache_id) + self.add_to_cache(cache_id, inputs, self.operation(*args, **kw)) + except: + self.reset() + raise + # 5: We have seen this cache_id and it is cached: + return self.cached_outputs[cache_id] + +
[docs] def on_cache_changed(self, direct, which=None): + """ + A callback funtion, which sets local flags when the elements of some cached inputs change + + this function gets 'hooked up' to the inputs when we cache them, and upon their elements being changed we update here. + """ + for what in [direct, which]: + if what is not None: + ind_id = self.id(what) + _, cache_ids = self.cached_input_ids.get(ind_id, [None, []]) + for cache_id in cache_ids: + self.inputs_changed[cache_id] = True +
+
[docs] def reset(self): + """ + Totally reset the cache + """ + [a().remove_observer(self, self.on_cache_changed) if (a() is not None) else None for [a, _] in self.cached_input_ids.values()] + self.cached_input_ids = {} + self.cached_outputs = {} + self.inputs_changed = {} +
+ def __deepcopy__(self, memo=None): + return Cacher(self.operation, self.limit, self.ignore_args, self.force_kwargs) + + def __getstate__(self, memo=None): + raise NotImplementedError, "Trying to pickle Cacher object with function {}, pickling functions not possible.".format(str(self.operation)) + + def __setstate__(self, memo=None): + raise NotImplementedError, "Trying to pickle Cacher object with function {}, pickling functions not possible.".format(str(self.operation)) + + @property + def __name__(self): + return self.operation.__name__ +
+from functools import partial, update_wrapper + +
[docs]class Cacher_wrap(object): + def __init__(self, f, limit, ignore_args, force_kwargs): + self.limit = limit + self.ignore_args = ignore_args + self.force_kwargs = force_kwargs + self.f = f + update_wrapper(self, self.f) + def __get__(self, obj, objtype=None): + return partial(self, obj) + def __call__(self, *args, **kwargs): + obj = args[0] + # import ipdb;ipdb.set_trace() + try: + caches = obj.__cachers + except AttributeError: + caches = obj.__cachers = {} + try: + cacher = caches[self.f] + except KeyError: + cacher = caches[self.f] = Cacher(self.f, self.limit, self.ignore_args, self.force_kwargs) + return cacher(*args, **kwargs) +
+
[docs]class Cache_this(object): + """ + A decorator which can be applied to bound methods in order to cache them + """ + def __init__(self, limit=5, ignore_args=(), force_kwargs=()): + self.limit = limit + self.ignore_args = ignore_args + self.force_args = force_kwargs + def __call__(self, f): + newf = Cacher_wrap(f, self.limit, self.ignore_args, self.force_args) + update_wrapper(newf, f) + return newf
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/classification.html b/doc/_build/html/_modules/GPy/util/classification.html new file mode 100644 index 00000000..1528ca1d --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/classification.html @@ -0,0 +1,127 @@ + + + + + + + + GPy.util.classification — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.classification

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+import numpy as np
+
+
[docs]def conf_matrix(p,labels,names=['1','0'],threshold=.5,show=True): + """ + Returns error rate and true/false positives in a binary classification problem + - Actual classes are displayed by column. + - Predicted classes are displayed by row. + + :param p: array of class '1' probabilities. + :param labels: array of actual classes. + :param names: list of class names, defaults to ['1','0']. + :param threshold: probability value used to decide the class. + :param show: whether the matrix should be shown or not + :type show: False|True + """ + assert p.size == labels.size, "Arrays p and labels have different dimensions." + decision = np.ones((labels.size,1)) + decision[p<threshold] = 0 + diff = decision - labels + false_0 = diff[diff == -1].size + false_1 = diff[diff == 1].size + true_1 = np.sum(decision[diff ==0]) + true_0 = labels.size - true_1 - false_0 - false_1 + error = (false_1 + false_0)/np.float(labels.size) + if show: + print 100. - error * 100,'% instances correctly classified' + print '%-10s| %-10s| %-10s| ' % ('',names[0],names[1]) + print '----------|------------|------------|' + print '%-10s| %-10s| %-10s| ' % (names[0],true_1,false_0) + print '%-10s| %-10s| %-10s| ' % (names[1],false_1,true_0) + return error,true_1, false_1, true_0, false_0
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/datasets.html b/doc/_build/html/_modules/GPy/util/datasets.html new file mode 100644 index 00000000..16c47ae5 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/datasets.html @@ -0,0 +1,1563 @@ + + + + + + + + GPy.util.datasets — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.datasets

+import csv
+import os
+import copy
+import numpy as np
+import GPy
+import scipy.io
+import cPickle as pickle
+import zipfile
+import tarfile
+import datetime
+import json
+import re
+
+from config import *
+
+ipython_available=True
+try:
+    import IPython
+except ImportError:
+    ipython_available=False
+
+
+import sys, urllib2
+
+
[docs]def reporthook(a,b,c): + # ',' at the end of the line is important! + #print "% 3.1f%% of %d bytes\r" % (min(100, float(a * b) / c * 100), c), + #you can also use sys.stdout.write + sys.stdout.write("\r% 3.1f%% of %d bytes" % (min(100, float(a * b) / c * 100), c)) + sys.stdout.flush() + +# Global variables
+data_path = os.path.expandvars(config.get('datasets', 'dir')) +#data_path = os.path.join(os.path.dirname(__file__), 'datasets') +default_seed = 10000 +overide_manual_authorize=False +neil_url = 'http://staffwww.dcs.shef.ac.uk/people/N.Lawrence/dataset_mirror/' + +# Read data resources from json file. +# Don't do this when ReadTheDocs is scanning as it breaks things +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' #Checks if RTD is scanning + +if not (on_rtd): + path = os.path.join(os.path.dirname(__file__), 'data_resources.json') + json_data=open(path).read() + data_resources = json.loads(json_data) + +if not (on_rtd): + path = os.path.join(os.path.dirname(__file__), 'football_teams.json') + json_data=open(path).read() + football_dict = json.loads(json_data) + + + +
[docs]def prompt_user(prompt): + """Ask user for agreeing to data set licenses.""" + # raw_input returns the empty string for "enter" + yes = set(['yes', 'y']) + no = set(['no','n']) + + try: + print(prompt) + choice = raw_input().lower() + # would like to test for exception here, but not sure if we can do that without importing IPython + except: + print('Stdin is not implemented.') + print('You need to set') + print('overide_manual_authorize=True') + print('to proceed with the download. Please set that variable and continue.') + raise + + + if choice in yes: + return True + elif choice in no: + return False + else: + print("Your response was a " + choice) + print("Please respond with 'yes', 'y' or 'no', 'n'") + #return prompt_user() + +
+
[docs]def data_available(dataset_name=None): + """Check if the data set is available on the local machine already.""" + from itertools import izip_longest + dr = data_resources[dataset_name] + zip_urls = (dr['files'], ) + if dr.has_key('save_names'): zip_urls += (dr['save_names'], ) + else: zip_urls += ([],) + + for file_list, save_list in izip_longest(*zip_urls, fillvalue=[]): + for f, s in izip_longest(file_list, save_list, fillvalue=None): + if s is not None: f=s # If there is a save_name given, use that one + if not os.path.exists(os.path.join(data_path, dataset_name, f)): + return False + return True +
+
[docs]def download_url(url, store_directory, save_name=None, messages=True, suffix=''): + """Download a file from a url and save it to disk.""" + i = url.rfind('/') + file = url[i+1:] + print file + dir_name = os.path.join(data_path, store_directory) + + if save_name is None: save_name = os.path.join(dir_name, file) + else: save_name = os.path.join(dir_name, save_name) + + if suffix is None: suffix='' + + print "Downloading ", url, "->", save_name + if not os.path.exists(dir_name): + os.makedirs(dir_name) + try: + response = urllib2.urlopen(url+suffix) + except urllib2.URLError, e: + if not hasattr(e, "code"): + raise + response = e + if response.code > 399 and response.code<500: + raise ValueError('Tried url ' + url + suffix + ' and received client error ' + str(response.code)) + elif response.code > 499: + raise ValueError('Tried url ' + url + suffix + ' and received server error ' + str(response.code)) + with open(save_name, 'wb') as f: + meta = response.info() + content_length_str = meta.getheaders("Content-Length") + if content_length_str: + file_size = int(content_length_str[0]) + else: + file_size = None + status = "" + file_size_dl = 0 + block_sz = 8192 + line_length=30 + while True: + buff = response.read(block_sz) + if not buff: + break + file_size_dl += len(buff) + f.write(buff) + sys.stdout.write(" "*(len(status)) + "\r") + if file_size: + status = r"[{perc: <{ll}}] {dl:7.3f}/{full:.3f}MB".format(dl=file_size_dl/(1048576.), + full=file_size/(1048576.), ll=line_length, + perc="="*int(line_length*float(file_size_dl)/file_size)) + else: + status = r"[{perc: <{ll}}] {dl:7.3f}MB".format(dl=file_size_dl/(1048576.), + ll=line_length, + perc="."*int(line_length*float(file_size_dl/(10*1048576.)))) + + sys.stdout.write(status) + sys.stdout.flush() + sys.stdout.write(" "*(len(status)) + "\r") + print status + # if we wanted to get more sophisticated maybe we should check the response code here again even for successes. + #with open(save_name, 'wb') as f: + # f.write(response.read()) + + #urllib.urlretrieve(url+suffix, save_name, reporthook) +
+
[docs]def authorize_download(dataset_name=None): + """Check with the user that the are happy with terms and conditions for the data set.""" + print('Acquiring resource: ' + dataset_name) + # TODO, check resource is in dictionary! + print('') + dr = data_resources[dataset_name] + print('Details of data: ') + print(dr['details']) + print('') + if dr['citation']: + print('Please cite:') + print(dr['citation']) + print('') + if dr['size']: + print('After downloading the data will take up ' + str(dr['size']) + ' bytes of space.') + print('') + print('Data will be stored in ' + os.path.join(data_path, dataset_name) + '.') + print('') + if overide_manual_authorize: + if dr['license']: + print('You have agreed to the following license:') + print(dr['license']) + print('') + return True + else: + if dr['license']: + print('You must also agree to the following license:') + print(dr['license']) + print('') + return prompt_user('Do you wish to proceed with the download? [yes/no]') +
+
[docs]def download_data(dataset_name=None): + """Check with the user that the are happy with terms and conditions for the data set, then download it.""" + import itertools + + dr = data_resources[dataset_name] + if not authorize_download(dataset_name): + raise Exception("Permission to download data set denied.") + + zip_urls = (dr['urls'], dr['files']) + + if dr.has_key('save_names'): zip_urls += (dr['save_names'], ) + else: zip_urls += ([],) + + if dr.has_key('suffices'): zip_urls += (dr['suffices'], ) + else: zip_urls += ([],) + + for url, files, save_names, suffices in itertools.izip_longest(*zip_urls, fillvalue=[]): + for f, save_name, suffix in itertools.izip_longest(files, save_names, suffices, fillvalue=None): + download_url(os.path.join(url,f), dataset_name, save_name, suffix=suffix) + + return True +
+
[docs]def data_details_return(data, data_set): + """Update the data component of the data dictionary with details drawn from the data_resources.""" + data.update(data_resources[data_set]) + return data + +
+
[docs]def cmu_urls_files(subj_motions, messages = True): + ''' + Find which resources are missing on the local disk for the requested CMU motion capture motions. + ''' + dr = data_resources['cmu_mocap_full'] + cmu_url = dr['urls'][0] + + subjects_num = subj_motions[0] + motions_num = subj_motions[1] + + resource = {'urls' : [], 'files' : []} + # Convert numbers to strings + subjects = [] + motions = [list() for _ in range(len(subjects_num))] + for i in range(len(subjects_num)): + curSubj = str(int(subjects_num[i])) + if int(subjects_num[i]) < 10: + curSubj = '0' + curSubj + subjects.append(curSubj) + for j in range(len(motions_num[i])): + curMot = str(int(motions_num[i][j])) + if int(motions_num[i][j]) < 10: + curMot = '0' + curMot + motions[i].append(curMot) + + all_skels = [] + + assert len(subjects) == len(motions) + + all_motions = [] + + for i in range(len(subjects)): + skel_dir = os.path.join(data_path, 'cmu_mocap') + cur_skel_file = os.path.join(skel_dir, subjects[i] + '.asf') + + url_required = False + file_download = [] + if not os.path.exists(cur_skel_file): + # Current skel file doesn't exist. + if not os.path.isdir(skel_dir): + os.makedirs(skel_dir) + # Add skel file to list. + url_required = True + file_download.append(subjects[i] + '.asf') + for j in range(len(motions[i])): + file_name = subjects[i] + '_' + motions[i][j] + '.amc' + cur_motion_file = os.path.join(skel_dir, file_name) + if not os.path.exists(cur_motion_file): + url_required = True + file_download.append(subjects[i] + '_' + motions[i][j] + '.amc') + if url_required: + resource['urls'].append(cmu_url + '/' + subjects[i] + '/') + resource['files'].append(file_download) + return resource +
+try: + import gpxpy + import gpxpy.gpx + gpxpy_available = True + +except ImportError: + gpxpy_available = False + +if gpxpy_available: + def epomeo_gpx(data_set='epomeo_gpx', sample_every=4): + if not data_available(data_set): + download_data(data_set) + files = ['endomondo_1', 'endomondo_2', 'garmin_watch_via_endomondo','viewranger_phone', 'viewranger_tablet'] + + X = [] + for file in files: + gpx_file = open(os.path.join(data_path, 'epomeo_gpx', file + '.gpx'), 'r') + + gpx = gpxpy.parse(gpx_file) + segment = gpx.tracks[0].segments[0] + points = [point for track in gpx.tracks for segment in track.segments for point in segment.points] + data = [[(point.time-datetime.datetime(2013,8,21)).total_seconds(), point.latitude, point.longitude, point.elevation] for point in points] + X.append(np.asarray(data)[::sample_every, :]) + gpx_file.close() + return data_details_return({'X' : X, 'info' : 'Data is an array containing time in seconds, latitude, longitude and elevation in that order.'}, data_set) + +#del gpxpy_available + + + +# Some general utilities. +
[docs]def sample_class(f): + p = 1. / (1. + np.exp(-f)) + c = np.random.binomial(1, p) + c = np.where(c, 1, -1) + return c +
+
[docs]def boston_housing(data_set='boston_housing'): + if not data_available(data_set): + download_data(data_set) + all_data = np.genfromtxt(os.path.join(data_path, data_set, 'housing.data')) + X = all_data[:, 0:13] + Y = all_data[:, 13:14] + return data_details_return({'X' : X, 'Y': Y}, data_set) +
+
[docs]def brendan_faces(data_set='brendan_faces'): + if not data_available(data_set): + download_data(data_set) + mat_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'frey_rawface.mat')) + Y = mat_data['ff'].T + return data_details_return({'Y': Y}, data_set) +
+
[docs]def della_gatta_TRP63_gene_expression(data_set='della_gatta', gene_number=None): + if not data_available(data_set): + download_data(data_set) + mat_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'DellaGattadata.mat')) + X = np.double(mat_data['timepoints']) + if gene_number == None: + Y = mat_data['exprs_tp53_RMA'] + else: + Y = mat_data['exprs_tp53_RMA'][:, gene_number] + if len(Y.shape) == 1: + Y = Y[:, None] + return data_details_return({'X': X, 'Y': Y, 'gene_number' : gene_number}, data_set) + + +
+
[docs]def football_data(season='1314', data_set='football_data'): + """Football data from English games since 1993. This downloads data from football-data.co.uk for the given season. """ + def league2num(string): + league_dict = {'E0':0, 'E1':1, 'E2': 2, 'E3': 3, 'EC':4} + return league_dict[string] + + def football2num(string): + if football_dict.has_key(string): + return football_dict[string] + else: + football_dict[string] = len(football_dict)+1 + return len(football_dict)+1 + + data_set_season = data_set + '_' + season + data_resources[data_set_season] = copy.deepcopy(data_resources[data_set]) + data_resources[data_set_season]['urls'][0]+=season + '/' + start_year = int(season[0:2]) + end_year = int(season[2:4]) + files = ['E0.csv', 'E1.csv', 'E2.csv', 'E3.csv'] + if start_year>4 and start_year < 93: + files += ['EC.csv'] + data_resources[data_set_season]['files'] = [files] + if not data_available(data_set_season): + download_data(data_set_season) + import pylab as pb + for file in reversed(files): + filename = os.path.join(data_path, data_set_season, file) + # rewrite files removing blank rows. + writename = os.path.join(data_path, data_set_season, 'temp.csv') + input = open(filename, 'rb') + output = open(writename, 'wb') + writer = csv.writer(output) + for row in csv.reader(input): + if any(field.strip() for field in row): + writer.writerow(row) + input.close() + output.close() + table = np.loadtxt(writename,skiprows=1, usecols=(0, 1, 2, 3, 4, 5), converters = {0: league2num, 1: pb.datestr2num, 2:football2num, 3:football2num}, delimiter=',') + X = table[:, :4] + Y = table[:, 4:] + return data_details_return({'X': X, 'Y': Y}, data_set) +
+
[docs]def sod1_mouse(data_set='sod1_mouse'): + if not data_available(data_set): + download_data(data_set) + from pandas import read_csv + dir_path = os.path.join(data_path, data_set) + filename = os.path.join(dir_path, 'sod1_C57_129_exprs.csv') + Y = read_csv(filename, header=0, index_col=0) + num_repeats=4 + num_time=4 + num_cond=4 + X = 1 + return data_details_return({'X': X, 'Y': Y}, data_set) +
+
[docs]def spellman_yeast(data_set='spellman_yeast'): + if not data_available(data_set): + download_data(data_set) + from pandas import read_csv + dir_path = os.path.join(data_path, data_set) + filename = os.path.join(dir_path, 'combined.txt') + Y = read_csv(filename, header=0, index_col=0, sep='\t') + return data_details_return({'Y': Y}, data_set) +
+
[docs]def spellman_yeast_cdc15(data_set='spellman_yeast'): + if not data_available(data_set): + download_data(data_set) + from pandas import read_csv + dir_path = os.path.join(data_path, data_set) + filename = os.path.join(dir_path, 'combined.txt') + Y = read_csv(filename, header=0, index_col=0, sep='\t') + t = np.asarray([10, 30, 50, 70, 80, 90, 100, 110, 120, 130, 140, 150, 170, 180, 190, 200, 210, 220, 230, 240, 250, 270, 290]) + times = ['cdc15_'+str(time) for time in t] + Y = Y[times].T + t = t[:, None] + return data_details_return({'Y' : Y, 't': t, 'info': 'Time series of synchronized yeast cells from the CDC-15 experiment of Spellman et al (1998).'}, data_set) +
+
[docs]def lee_yeast_ChIP(data_set='lee_yeast_ChIP'): + if not data_available(data_set): + download_data(data_set) + from pandas import read_csv + import zipfile + dir_path = os.path.join(data_path, data_set) + filename = os.path.join(dir_path, 'binding_by_gene.tsv') + S = read_csv(filename, header=1, index_col=0, sep='\t') + transcription_factors = [col for col in S.columns if col[:7] != 'Unnamed'] + annotations = S[['Unnamed: 1', 'Unnamed: 2', 'Unnamed: 3']] + S = S[transcription_factors] + return data_details_return({'annotations' : annotations, 'Y' : S, 'transcription_factors': transcription_factors}, data_set) + + +
+
[docs]def fruitfly_tomancak(data_set='fruitfly_tomancak', gene_number=None): + if not data_available(data_set): + download_data(data_set) + from pandas import read_csv + dir_path = os.path.join(data_path, data_set) + filename = os.path.join(dir_path, 'tomancak_exprs.csv') + Y = read_csv(filename, header=0, index_col=0).T + num_repeats = 3 + num_time = 12 + xt = np.linspace(0, num_time-1, num_time) + xr = np.linspace(0, num_repeats-1, num_repeats) + xtime, xrepeat = np.meshgrid(xt, xr) + X = np.vstack((xtime.flatten(), xrepeat.flatten())).T + return data_details_return({'X': X, 'Y': Y, 'gene_number' : gene_number}, data_set) +
+
[docs]def drosophila_protein(data_set='drosophila_protein'): + if not data_available(data_set): + download_data(data_set) + from pandas import read_csv + dir_path = os.path.join(data_path, data_set) + filename = os.path.join(dir_path, 'becker_et_al.csv') + Y = read_csv(filename, header=0) + return data_details_return({'Y': Y}, data_set) +
+
[docs]def drosophila_knirps(data_set='drosophila_protein'): + if not data_available(data_set): + download_data(data_set) + from pandas import read_csv + dir_path = os.path.join(data_path, data_set) + filename = os.path.join(dir_path, 'becker_et_al.csv') + # in the csv file we have facts_kni and ext_kni. We treat facts_kni as protein and ext_kni as mRNA + df = read_csv(filename, header=0) + t = df['t'][:,None] + x = df['x'][:,None] + + g = df['expression1'][:,None] + p = df['expression2'][:,None] + + leng = x.shape[0] + + T = np.vstack([t,t]) + S = np.vstack([x,x]) + inx = np.zeros(leng*2)[:,None] + + inx[leng*2/2:leng*2]=1 + X = np.hstack([T,S,inx]) + Y = np.vstack([g,p]) + return data_details_return({'Y': Y, 'X': X}, data_set) + +# This will be for downloading google trends data.
+ +
[docs]def oil(data_set='three_phase_oil_flow'): + """The three phase oil data from Bishop and James (1993).""" + if not data_available(data_set): + download_data(data_set) + oil_train_file = os.path.join(data_path, data_set, 'DataTrn.txt') + oil_trainlbls_file = os.path.join(data_path, data_set, 'DataTrnLbls.txt') + oil_test_file = os.path.join(data_path, data_set, 'DataTst.txt') + oil_testlbls_file = os.path.join(data_path, data_set, 'DataTstLbls.txt') + oil_valid_file = os.path.join(data_path, data_set, 'DataVdn.txt') + oil_validlbls_file = os.path.join(data_path, data_set, 'DataVdnLbls.txt') + fid = open(oil_train_file) + X = np.fromfile(fid, sep='\t').reshape((-1, 12)) + fid.close() + fid = open(oil_test_file) + Xtest = np.fromfile(fid, sep='\t').reshape((-1, 12)) + fid.close() + fid = open(oil_valid_file) + Xvalid = np.fromfile(fid, sep='\t').reshape((-1, 12)) + fid.close() + fid = open(oil_trainlbls_file) + Y = np.fromfile(fid, sep='\t').reshape((-1, 3)) * 2. - 1. + fid.close() + fid = open(oil_testlbls_file) + Ytest = np.fromfile(fid, sep='\t').reshape((-1, 3)) * 2. - 1. + fid.close() + fid = open(oil_validlbls_file) + Yvalid = np.fromfile(fid, sep='\t').reshape((-1, 3)) * 2. - 1. + fid.close() + return data_details_return({'X': X, 'Y': Y, 'Xtest': Xtest, 'Ytest': Ytest, 'Xtest' : Xtest, 'Xvalid': Xvalid, 'Yvalid': Yvalid}, data_set) + #else: + # throw an error +
+
[docs]def oil_100(seed=default_seed, data_set = 'three_phase_oil_flow'): + np.random.seed(seed=seed) + data = oil() + indices = np.random.permutation(1000) + indices = indices[0:100] + X = data['X'][indices, :] + Y = data['Y'][indices, :] + return data_details_return({'X': X, 'Y': Y, 'info': "Subsample of the full oil data extracting 100 values randomly without replacement, here seed was " + str(seed)}, data_set) +
+
[docs]def pumadyn(seed=default_seed, data_set='pumadyn-32nm'): + if not data_available(data_set): + download_data(data_set) + path = os.path.join(data_path, data_set) + tar = tarfile.open(os.path.join(path, 'pumadyn-32nm.tar.gz')) + print('Extracting file.') + tar.extractall(path=path) + tar.close() + # Data is variance 1, no need to normalize. + data = np.loadtxt(os.path.join(data_path, data_set, 'pumadyn-32nm', 'Dataset.data.gz')) + indices = np.random.permutation(data.shape[0]) + indicesTrain = indices[0:7168] + indicesTest = indices[7168:-1] + indicesTrain.sort(axis=0) + indicesTest.sort(axis=0) + X = data[indicesTrain, 0:-2] + Y = data[indicesTrain, -1][:, None] + Xtest = data[indicesTest, 0:-2] + Ytest = data[indicesTest, -1][:, None] + return data_details_return({'X': X, 'Y': Y, 'Xtest': Xtest, 'Ytest': Ytest, 'seed': seed}, data_set) +
+
[docs]def robot_wireless(data_set='robot_wireless'): + # WiFi access point strengths on a tour around UW Paul Allen building. + if not data_available(data_set): + download_data(data_set) + file_name = os.path.join(data_path, data_set, 'uw-floor.txt') + all_time = np.genfromtxt(file_name, usecols=(0)) + macaddress = np.genfromtxt(file_name, usecols=(1), dtype='string') + x = np.genfromtxt(file_name, usecols=(2)) + y = np.genfromtxt(file_name, usecols=(3)) + strength = np.genfromtxt(file_name, usecols=(4)) + addresses = np.unique(macaddress) + times = np.unique(all_time) + addresses.sort() + times.sort() + allY = np.zeros((len(times), len(addresses))) + allX = np.zeros((len(times), 2)) + allY[:]=-92. + strengths={} + for address, j in zip(addresses, range(len(addresses))): + ind = np.nonzero(address==macaddress) + temp_strengths=strength[ind] + temp_x=x[ind] + temp_y=y[ind] + temp_times = all_time[ind] + for time in temp_times: + vals = time==temp_times + if any(vals): + ind2 = np.nonzero(vals) + i = np.nonzero(time==times) + allY[i, j] = temp_strengths[ind2] + allX[i, 0] = temp_x[ind2] + allX[i, 1] = temp_y[ind2] + allY = (allY + 85.)/15. + + X = allX[0:215, :] + Y = allY[0:215, :] + + Xtest = allX[215:, :] + Ytest = allY[215:, :] + return data_details_return({'X': X, 'Y': Y, 'Xtest': Xtest, 'Ytest': Ytest, 'addresses' : addresses, 'times' : times}, data_set) +
+
[docs]def silhouette(data_set='ankur_pose_data'): + # Ankur Agarwal and Bill Trigg's silhoutte data. + if not data_available(data_set): + download_data(data_set) + mat_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'ankurDataPoseSilhouette.mat')) + inMean = np.mean(mat_data['Y']) + inScales = np.sqrt(np.var(mat_data['Y'])) + X = mat_data['Y'] - inMean + X = X / inScales + Xtest = mat_data['Y_test'] - inMean + Xtest = Xtest / inScales + Y = mat_data['Z'] + Ytest = mat_data['Z_test'] + return data_details_return({'X': X, 'Y': Y, 'Xtest': Xtest, 'Ytest': Ytest}, data_set) +
+
[docs]def decampos_digits(data_set='decampos_characters', which_digits=[0,1,2,3,4,5,6,7,8,9]): + if not data_available(data_set): + download_data(data_set) + path = os.path.join(data_path, data_set) + digits = np.load(os.path.join(path, 'digits.npy')) + digits = digits[which_digits,:,:,:] + num_classes, num_samples, height, width = digits.shape + Y = digits.reshape((digits.shape[0]*digits.shape[1],digits.shape[2]*digits.shape[3])) + lbls = np.array([[l]*num_samples for l in which_digits]).reshape(Y.shape[0], 1) + str_lbls = np.array([[str(l)]*num_samples for l in which_digits]) + return data_details_return({'Y': Y, 'lbls': lbls, 'str_lbls' : str_lbls, 'info': 'Digits data set from the de Campos characters data'}, data_set) +
+
[docs]def ripley_synth(data_set='ripley_prnn_data'): + if not data_available(data_set): + download_data(data_set) + train = np.genfromtxt(os.path.join(data_path, data_set, 'synth.tr'), skip_header=1) + X = train[:, 0:2] + y = train[:, 2:3] + test = np.genfromtxt(os.path.join(data_path, data_set, 'synth.te'), skip_header=1) + Xtest = test[:, 0:2] + ytest = test[:, 2:3] + return data_details_return({'X': X, 'Y': y, 'Xtest': Xtest, 'Ytest': ytest, 'info': 'Synthetic data generated by Ripley for a two class classification problem.'}, data_set) +
+
[docs]def global_average_temperature(data_set='global_temperature', num_train=1000, refresh_data=False): + path = os.path.join(data_path, data_set) + if data_available(data_set) and not refresh_data: + print 'Using cached version of the data set, to use latest version set refresh_data to True' + else: + download_data(data_set) + data = np.loadtxt(os.path.join(data_path, data_set, 'GLBTS.long.data')) + print 'Most recent data observation from month ', data[-1, 1], ' in year ', data[-1, 0] + allX = data[data[:, 3]!=-99.99, 2:3] + allY = data[data[:, 3]!=-99.99, 3:4] + X = allX[:num_train, 0:1] + Xtest = allX[num_train:, 0:1] + Y = allY[:num_train, 0:1] + Ytest = allY[num_train:, 0:1] + return data_details_return({'X': X, 'Y': Y, 'Xtest': Xtest, 'Ytest': Ytest, 'info': "Mauna Loa data with " + str(num_train) + " values used as training points."}, data_set) +
+
[docs]def mauna_loa(data_set='mauna_loa', num_train=545, refresh_data=False): + path = os.path.join(data_path, data_set) + if data_available(data_set) and not refresh_data: + print 'Using cached version of the data set, to use latest version set refresh_data to True' + else: + download_data(data_set) + data = np.loadtxt(os.path.join(data_path, data_set, 'co2_mm_mlo.txt')) + print 'Most recent data observation from month ', data[-1, 1], ' in year ', data[-1, 0] + allX = data[data[:, 3]!=-99.99, 2:3] + allY = data[data[:, 3]!=-99.99, 3:4] + X = allX[:num_train, 0:1] + Xtest = allX[num_train:, 0:1] + Y = allY[:num_train, 0:1] + Ytest = allY[num_train:, 0:1] + return data_details_return({'X': X, 'Y': Y, 'Xtest': Xtest, 'Ytest': Ytest, 'info': "Mauna Loa data with " + str(num_train) + " values used as training points."}, data_set) + +
+
[docs]def boxjenkins_airline(data_set='boxjenkins_airline', num_train=96): + path = os.path.join(data_path, data_set) + if not data_available(data_set): + download_data(data_set) + data = np.loadtxt(os.path.join(data_path, data_set, 'boxjenkins_airline.csv'), delimiter=',') + Y = data[:num_train, 1:2] + X = data[:num_train, 0:1] + Xtest = data[num_train:, 0:1] + Ytest = data[num_train:, 1:2] + return data_details_return({'X': X, 'Y': Y, 'Xtest': Xtest, 'Ytest': Ytest, 'info': "Montly airline passenger data from Box & Jenkins 1976."}, data_set) + +
+
[docs]def osu_run1(data_set='osu_run1', sample_every=4): + path = os.path.join(data_path, data_set) + if not data_available(data_set): + download_data(data_set) + zip = zipfile.ZipFile(os.path.join(data_path, data_set, 'run1TXT.ZIP'), 'r') + for name in zip.namelist(): + zip.extract(name, path) + Y, connect = GPy.util.mocap.load_text_data('Aug210106', path) + Y = Y[0:-1:sample_every, :] + return data_details_return({'Y': Y, 'connect' : connect}, data_set) +
+
[docs]def swiss_roll_generated(num_samples=1000, sigma=0.0): + with open(os.path.join(os.path.dirname(__file__), 'datasets', 'swiss_roll.pickle')) as f: + data = pickle.load(f) + Na = data['Y'].shape[0] + perm = np.random.permutation(np.r_[:Na])[:num_samples] + Y = data['Y'][perm, :] + t = data['t'][perm] + c = data['colors'][perm, :] + so = np.argsort(t) + Y = Y[so, :] + t = t[so] + c = c[so, :] + return {'Y':Y, 't':t, 'colors':c} +
+
[docs]def hapmap3(data_set='hapmap3'): + """ + The HapMap phase three SNP dataset - 1184 samples out of 11 populations. + + SNP_matrix (A) encoding [see Paschou et all. 2007 (PCA-Correlated SNPs...)]: + Let (B1,B2) be the alphabetically sorted bases, which occur in the j-th SNP, then + + / 1, iff SNPij==(B1,B1) + Aij = | 0, iff SNPij==(B1,B2) + \ -1, iff SNPij==(B2,B2) + + The SNP data and the meta information (such as iid, sex and phenotype) are + stored in the dataframe datadf, index is the Individual ID, + with following columns for metainfo: + + * family_id -> Family ID + * paternal_id -> Paternal ID + * maternal_id -> Maternal ID + * sex -> Sex (1=male; 2=female; other=unknown) + * phenotype -> Phenotype (-9, or 0 for unknown) + * population -> Population string (e.g. 'ASW' - 'YRI') + * rest are SNP rs (ids) + + More information is given in infodf: + + * Chromosome: + - autosomal chromosemes -> 1-22 + - X X chromosome -> 23 + - Y Y chromosome -> 24 + - XY Pseudo-autosomal region of X -> 25 + - MT Mitochondrial -> 26 + * Relative Positon (to Chromosome) [base pairs] + """ + try: + from pandas import read_pickle, DataFrame + from sys import stdout + import bz2 + except ImportError as i: + raise i, "Need pandas for hapmap dataset, make sure to install pandas (http://pandas.pydata.org/) before loading the hapmap dataset" + + dir_path = os.path.join(data_path,'hapmap3') + hapmap_file_name = 'hapmap3_r2_b36_fwd.consensus.qc.poly' + unpacked_files = [os.path.join(dir_path, hapmap_file_name+ending) for ending in ['.ped', '.map']] + unpacked_files_exist = reduce(lambda a, b:a and b, map(os.path.exists, unpacked_files)) + + if not unpacked_files_exist and not data_available(data_set): + download_data(data_set) + + preprocessed_data_paths = [os.path.join(dir_path,hapmap_file_name + file_name) for file_name in \ + ['.snps.pickle', + '.info.pickle', + '.nan.pickle']] + + if not reduce(lambda a,b: a and b, map(os.path.exists, preprocessed_data_paths)): + if not overide_manual_authorize and not prompt_user("Preprocessing requires ~25GB " + "of memory and can take a (very) long time, continue? [Y/n]"): + print "Preprocessing required for further usage." + return + status = "Preprocessing data, please be patient..." + print status + def write_status(message, progress, status): + stdout.write(" "*len(status)); stdout.write("\r"); stdout.flush() + status = r"[{perc: <{ll}}] {message: <13s}".format(message=message, ll=20, + perc="="*int(20.*progress/100.)) + stdout.write(status); stdout.flush() + return status + if not unpacked_files_exist: + status=write_status('unpacking...', 0, '') + curr = 0 + for newfilepath in unpacked_files: + if not os.path.exists(newfilepath): + filepath = newfilepath + '.bz2' + file_size = os.path.getsize(filepath) + with open(newfilepath, 'wb') as new_file, open(filepath, 'rb') as f: + decomp = bz2.BZ2Decompressor() + file_processed = 0 + buffsize = 100 * 1024 + for data in iter(lambda : f.read(buffsize), b''): + new_file.write(decomp.decompress(data)) + file_processed += len(data) + status=write_status('unpacking...', curr+12.*file_processed/(file_size), status) + curr += 12 + status=write_status('unpacking...', curr, status) + os.remove(filepath) + status=write_status('reading .ped...', 25, status) + # Preprocess data: + snpstrnp = np.loadtxt(unpacked_files[0], dtype=str) + status=write_status('reading .map...', 33, status) + mapnp = np.loadtxt(unpacked_files[1], dtype=str) + status=write_status('reading relationships.txt...', 42, status) + # and metainfo: + infodf = DataFrame.from_csv(os.path.join(dir_path,'./relationships_w_pops_121708.txt'), header=0, sep='\t') + infodf.set_index('IID', inplace=1) + status=write_status('filtering nan...', 45, status) + snpstr = snpstrnp[:,6:].astype('S1').reshape(snpstrnp.shape[0], -1, 2) + inan = snpstr[:,:,0] == '0' + status=write_status('filtering reference alleles...', 55, status) + ref = np.array(map(lambda x: np.unique(x)[-2:], snpstr.swapaxes(0,1)[:,:,:])) + status=write_status('encoding snps...', 70, status) + # Encode the information for each gene in {-1,0,1}: + status=write_status('encoding snps...', 73, status) + snps = (snpstr==ref[None,:,:]) + status=write_status('encoding snps...', 76, status) + snps = (snps*np.array([1,-1])[None,None,:]) + status=write_status('encoding snps...', 78, status) + snps = snps.sum(-1) + status=write_status('encoding snps...', 81, status) + snps = snps.astype('i8') + status=write_status('marking nan values...', 88, status) + # put in nan values (masked as -128): + snps[inan] = -128 + status=write_status('setting up meta...', 94, status) + # get meta information: + metaheader = np.r_[['family_id', 'iid', 'paternal_id', 'maternal_id', 'sex', 'phenotype']] + metadf = DataFrame(columns=metaheader, data=snpstrnp[:,:6]) + metadf.set_index('iid', inplace=1) + metadf = metadf.join(infodf.population) + metadf.to_pickle(preprocessed_data_paths[1]) + # put everything together: + status=write_status('setting up snps...', 96, status) + snpsdf = DataFrame(index=metadf.index, data=snps, columns=mapnp[:,1]) + with open(preprocessed_data_paths[0], 'wb') as f: + pickle.dump(f, snpsdf, protocoll=-1) + status=write_status('setting up snps...', 98, status) + inandf = DataFrame(index=metadf.index, data=inan, columns=mapnp[:,1]) + inandf.to_pickle(preprocessed_data_paths[2]) + status=write_status('done :)', 100, status) + print '' + else: + print "loading snps..." + snpsdf = read_pickle(preprocessed_data_paths[0]) + print "loading metainfo..." + metadf = read_pickle(preprocessed_data_paths[1]) + print "loading nan entries..." + inandf = read_pickle(preprocessed_data_paths[2]) + snps = snpsdf.values + populations = metadf.population.values.astype('S3') + hapmap = dict(name=data_set, + description='The HapMap phase three SNP dataset - ' + '1184 samples out of 11 populations. inan is a ' + 'boolean array, containing wheather or not the ' + 'given entry is nan (nans are masked as ' + '-128 in snps).', + snpsdf=snpsdf, + metadf=metadf, + snps=snps, + inan=inandf.values, + inandf=inandf, + populations=populations) + return hapmap +
+
[docs]def singlecell(data_set='singlecell'): + if not data_available(data_set): + download_data(data_set) + + from pandas import read_csv + dir_path = os.path.join(data_path, data_set) + filename = os.path.join(dir_path, 'singlecell.csv') + Y = read_csv(filename, header=0, index_col=0) + genes = Y.columns + labels = Y.index + # data = np.loadtxt(os.path.join(dir_path, 'singlecell.csv'), delimiter=",", dtype=str) + return data_details_return({'Y': Y, 'info' : "qPCR singlecell experiment in Mouse, measuring 48 gene expressions in 1-64 cell states. The labels have been created as in Guo et al. [2010]", + 'genes': genes, 'labels':labels, + }, data_set) +
+
[docs]def singlecell_rna_seq_islam(dataset='singlecell_islam'): + if not data_available(dataset): + download_data(dataset) + + from pandas import read_csv, DataFrame, concat + dir_path = os.path.join(data_path, dataset) + filename = os.path.join(dir_path, 'GSE29087_L139_expression_tab.txt.gz') + data = read_csv(filename, sep='\t', skiprows=6, compression='gzip', header=None) + header1 = read_csv(filename, sep='\t', header=None, skiprows=5, nrows=1, compression='gzip') + header2 = read_csv(filename, sep='\t', header=None, skiprows=3, nrows=1, compression='gzip') + data.columns = np.concatenate((header1.ix[0, :], header2.ix[0, 7:])) + Y = data.set_index("Feature").ix[8:, 6:-4].T.astype(float) + + # read the info .soft + filename = os.path.join(dir_path, 'GSE29087_family.soft.gz') + info = read_csv(filename, sep='\t', skiprows=0, compression='gzip', header=None) + # split at ' = ' + info = DataFrame(info.ix[:,0].str.split(' = ').tolist()) + # only take samples: + info = info[info[0].str.contains("!Sample")] + info[0] = info[0].apply(lambda row: row[len("!Sample_"):]) + + groups = info.groupby(0).groups + # remove 'GGG' from barcodes + barcode = info[1][groups['barcode']].apply(lambda row: row[:-3]) + + title = info[1][groups['title']] + title.index = barcode + title.name = 'title' + geo_accession = info[1][groups['geo_accession']] + geo_accession.index = barcode + geo_accession.name = 'geo_accession' + case_id = info[1][groups['source_name_ch1']] + case_id.index = barcode + case_id.name = 'source_name_ch1' + + info = concat([title, geo_accession, case_id], axis=1) + labels = info.join(Y).source_name_ch1[:-4] + labels[labels=='Embryonic stem cell'] = "ES" + labels[labels=='Embryonic fibroblast'] = "MEF" + + return data_details_return({'Y': Y, + 'info': '92 single cells (48 mouse ES cells, 44 mouse embryonic fibroblasts and 4 negative controls) were analyzed by single-cell tagged reverse transcription (STRT)', + 'genes': Y.columns, + 'labels': labels, + 'datadf': data, + 'infodf': info}, dataset) +
+
[docs]def singlecell_rna_seq_deng(dataset='singlecell_deng'): + if not data_available(dataset): + download_data(dataset) + + from pandas import read_csv, isnull + dir_path = os.path.join(data_path, dataset) + + # read the info .soft + filename = os.path.join(dir_path, 'GSE45719_series_matrix.txt.gz') + info = read_csv(filename, sep='\t', skiprows=0, compression='gzip', header=None, nrows=29, index_col=0) + summary = info.loc['!Series_summary'][1] + design = info.loc['!Series_overall_design'] + + # only take samples: + sample_info = read_csv(filename, sep='\t', skiprows=30, compression='gzip', header=0, index_col=0).T + sample_info.columns = sample_info.columns.to_series().apply(lambda row: row[len("!Sample_"):]) + sample_info.columns.name = sample_info.columns.name[len("!Sample_"):] + sample_info = sample_info[['geo_accession', 'characteristics_ch1', 'description']] + sample_info = sample_info.iloc[:, np.r_[0:4, 5:sample_info.shape[1]]] + c = sample_info.columns.to_series() + c[1:4] = ['strain', 'cross', 'developmental_stage'] + sample_info.columns = c + + # get the labels right: + rep = re.compile('\(.*\)') + def filter_dev_stage(row): + if isnull(row): + row = "2-cell stage embryo" + if row.startswith("developmental stage: "): + row = row[len("developmental stage: "):] + if row == 'adult': + row += " liver" + row = row.replace(' stage ', ' ') + row = rep.sub(' ', row) + row = row.strip(' ') + return row + labels = sample_info.developmental_stage.apply(filter_dev_stage) + + # Extract the tar file + filename = os.path.join(dir_path, 'GSE45719_Raw.tar') + with tarfile.open(filename, 'r') as files: + print "Extracting Archive {}...".format(files.name) + data = None + gene_info = None + message = '' + members = files.getmembers() + overall = len(members) + for i, file_info in enumerate(members): + f = files.extractfile(file_info) + inner = read_csv(f, sep='\t', header=0, compression='gzip', index_col=0) + print ' '*(len(message)+1) + '\r', + message = "{: >7.2%}: Extracting: {}".format(float(i+1)/overall, file_info.name[:20]+"...txt.gz") + print message, + if data is None: + data = inner.RPKM.to_frame() + data.columns = [file_info.name[:-18]] + gene_info = inner.Refseq_IDs.to_frame() + gene_info.columns = [file_info.name[:-18]] + else: + data[file_info.name[:-18]] = inner.RPKM + gene_info[file_info.name[:-18]] = inner.Refseq_IDs + + # Strip GSM number off data index + rep = re.compile('GSM\d+_') + data.columns = data.columns.to_series().apply(lambda row: row[rep.match(row).end():]) + data = data.T + + # make sure the same index gets used + sample_info.index = data.index + + # get the labels from the description + #rep = re.compile('fibroblast|\d+-cell|embryo|liver|early blastocyst|mid blastocyst|late blastocyst|blastomere|zygote', re.IGNORECASE) + + sys.stdout.write(' '*len(message) + '\r') + sys.stdout.flush() + print + print "Read Archive {}".format(files.name) + + return data_details_return({'Y': data, + 'series_info': info, + 'sample_info': sample_info, + 'gene_info': gene_info, + 'summary': summary, + 'design': design, + 'genes': data.columns, + 'labels': labels, + }, dataset) + +
+
[docs]def swiss_roll_1000(): + return swiss_roll(num_samples=1000) +
+
[docs]def swiss_roll(num_samples=3000, data_set='swiss_roll'): + if not data_available(data_set): + download_data(data_set) + mat_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'swiss_roll_data.mat')) + Y = mat_data['X_data'][:, 0:num_samples].transpose() + return data_details_return({'Y': Y, 'X': mat_data['X_data'], 'info': "The first " + str(num_samples) + " points from the swiss roll data of Tennenbaum, de Silva and Langford (2001)."}, data_set) +
+
[docs]def isomap_faces(num_samples=698, data_set='isomap_face_data'): + if not data_available(data_set): + download_data(data_set) + mat_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'face_data.mat')) + Y = mat_data['images'][:, 0:num_samples].transpose() + return data_details_return({'Y': Y, 'poses' : mat_data['poses'], 'lights': mat_data['lights'], 'info': "The first " + str(num_samples) + " points from the face data of Tennenbaum, de Silva and Langford (2001)."}, data_set) +
+
[docs]def simulation_BGPLVM(): + mat_data = scipy.io.loadmat(os.path.join(data_path, 'BGPLVMSimulation.mat')) + Y = np.array(mat_data['Y'], dtype=float) + S = np.array(mat_data['initS'], dtype=float) + mu = np.array(mat_data['initMu'], dtype=float) + #return data_details_return({'S': S, 'Y': Y, 'mu': mu}, data_set) + return {'Y': Y, 'S': S, + 'mu' : mu, + 'info': "Simulated test dataset generated in MATLAB to compare BGPLVM between python and MATLAB"} +
+
[docs]def toy_rbf_1d(seed=default_seed, num_samples=500): + """ + Samples values of a function from an RBF covariance with very small noise for inputs uniformly distributed between -1 and 1. + + :param seed: seed to use for random sampling. + :type seed: int + :param num_samples: number of samples to sample in the function (default 500). + :type num_samples: int + + """ + np.random.seed(seed=seed) + num_in = 1 + X = np.random.uniform(low= -1.0, high=1.0, size=(num_samples, num_in)) + X.sort(axis=0) + rbf = GPy.kern.RBF(num_in, variance=1., lengthscale=np.array((0.25,))) + white = GPy.kern.White(num_in, variance=1e-2) + kernel = rbf + white + K = kernel.K(X) + y = np.reshape(np.random.multivariate_normal(np.zeros(num_samples), K), (num_samples, 1)) + return {'X':X, 'Y':y, 'info': "Sampled " + str(num_samples) + " values of a function from an RBF covariance with very small noise for inputs uniformly distributed between -1 and 1."} +
+
[docs]def toy_rbf_1d_50(seed=default_seed): + np.random.seed(seed=seed) + data = toy_rbf_1d() + indices = np.random.permutation(data['X'].shape[0]) + indices = indices[0:50] + indices.sort(axis=0) + X = data['X'][indices, :] + Y = data['Y'][indices, :] + return {'X': X, 'Y': Y, 'info': "Subsamples the toy_rbf_sample with 50 values randomly taken from the original sample.", 'seed' : seed} + +
+
[docs]def toy_linear_1d_classification(seed=default_seed): + np.random.seed(seed=seed) + x1 = np.random.normal(-3, 5, 20) + x2 = np.random.normal(3, 5, 20) + X = (np.r_[x1, x2])[:, None] + return {'X': X, 'Y': sample_class(2.*X), 'F': 2.*X, 'seed' : seed} +
+
[docs]def olivetti_glasses(data_set='olivetti_glasses', num_training=200, seed=default_seed): + path = os.path.join(data_path, data_set) + if not data_available(data_set): + download_data(data_set) + y = np.load(os.path.join(path, 'has_glasses.np')) + y = np.where(y=='y',1,0).reshape(-1,1) + faces = scipy.io.loadmat(os.path.join(path, 'olivettifaces.mat'))['faces'].T + np.random.seed(seed=seed) + index = np.random.permutation(faces.shape[0]) + X = faces[index[:num_training],:] + Xtest = faces[index[num_training:],:] + Y = y[index[:num_training],:] + Ytest = y[index[num_training:]] + return data_details_return({'X': X, 'Y': Y, 'Xtest': Xtest, 'Ytest': Ytest, 'seed' : seed, 'info': "ORL Faces with labels identifiying who is wearing glasses and who isn't. Data is randomly partitioned according to given seed. Presence or absence of glasses was labelled by James Hensman."}, 'olivetti_faces') +
+
[docs]def olivetti_faces(data_set='olivetti_faces'): + path = os.path.join(data_path, data_set) + if not data_available(data_set): + download_data(data_set) + zip = zipfile.ZipFile(os.path.join(path, 'att_faces.zip'), 'r') + for name in zip.namelist(): + zip.extract(name, path) + Y = [] + lbls = [] + for subject in range(40): + for image in range(10): + image_path = os.path.join(path, 'orl_faces', 's'+str(subject+1), str(image+1) + '.pgm') + from GPy.util import netpbmfile + Y.append(netpbmfile.imread(image_path).flatten()) + lbls.append(subject) + Y = np.asarray(Y) + lbls = np.asarray(lbls)[:, None] + return data_details_return({'Y': Y, 'lbls' : lbls, 'info': "ORL Faces processed to 64x64 images."}, data_set) +
+
[docs]def xw_pen(data_set='xw_pen'): + if not data_available(data_set): + download_data(data_set) + Y = np.loadtxt(os.path.join(data_path, data_set, 'xw_pen_15.csv'), delimiter=',') + X = np.arange(485)[:, None] + return data_details_return({'Y': Y, 'X': X, 'info': "Tilt data from a personalized digital assistant pen. Plot in original paper showed regression between time steps 175 and 275."}, data_set) + +
+
[docs]def download_rogers_girolami_data(data_set='rogers_girolami_data'): + if not data_available('rogers_girolami_data'): + download_data(data_set) + path = os.path.join(data_path, data_set) + tar_file = os.path.join(path, 'firstcoursemldata.tar.gz') + tar = tarfile.open(tar_file) + print('Extracting file.') + tar.extractall(path=path) + tar.close() +
+
[docs]def olympic_100m_men(data_set='rogers_girolami_data'): + download_rogers_girolami_data() + olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['male100'] + + X = olympic_data[:, 0][:, None] + Y = olympic_data[:, 1][:, None] + return data_details_return({'X': X, 'Y': Y, 'info': "Olympic sprint times for 100 m men from 1896 until 2008. Example is from Rogers and Girolami's First Course in Machine Learning."}, data_set) +
+
[docs]def olympic_100m_women(data_set='rogers_girolami_data'): + download_rogers_girolami_data() + olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['female100'] + + X = olympic_data[:, 0][:, None] + Y = olympic_data[:, 1][:, None] + return data_details_return({'X': X, 'Y': Y, 'info': "Olympic sprint times for 100 m women from 1896 until 2008. Example is from Rogers and Girolami's First Course in Machine Learning."}, data_set) +
+
[docs]def olympic_200m_women(data_set='rogers_girolami_data'): + download_rogers_girolami_data() + olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['female200'] + + X = olympic_data[:, 0][:, None] + Y = olympic_data[:, 1][:, None] + return data_details_return({'X': X, 'Y': Y, 'info': "Olympic 200 m winning times for women from 1896 until 2008. Data is from Rogers and Girolami's First Course in Machine Learning."}, data_set) +
+
[docs]def olympic_200m_men(data_set='rogers_girolami_data'): + download_rogers_girolami_data() + olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['male200'] + + X = olympic_data[:, 0][:, None] + Y = olympic_data[:, 1][:, None] + return data_details_return({'X': X, 'Y': Y, 'info': "Male 200 m winning times for women from 1896 until 2008. Data is from Rogers and Girolami's First Course in Machine Learning."}, data_set) +
+
[docs]def olympic_400m_women(data_set='rogers_girolami_data'): + download_rogers_girolami_data() + olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['female400'] + + X = olympic_data[:, 0][:, None] + Y = olympic_data[:, 1][:, None] + return data_details_return({'X': X, 'Y': Y, 'info': "Olympic 400 m winning times for women until 2008. Data is from Rogers and Girolami's First Course in Machine Learning."}, data_set) +
+
[docs]def olympic_400m_men(data_set='rogers_girolami_data'): + download_rogers_girolami_data() + olympic_data = scipy.io.loadmat(os.path.join(data_path, data_set, 'data', 'olympics.mat'))['male400'] + + X = olympic_data[:, 0][:, None] + Y = olympic_data[:, 1][:, None] + return data_details_return({'X': X, 'Y': Y, 'info': "Male 400 m winning times for women until 2008. Data is from Rogers and Girolami's First Course in Machine Learning."}, data_set) +
+
[docs]def olympic_marathon_men(data_set='olympic_marathon_men'): + if not data_available(data_set): + download_data(data_set) + olympics = np.genfromtxt(os.path.join(data_path, data_set, 'olympicMarathonTimes.csv'), delimiter=',') + X = olympics[:, 0:1] + Y = olympics[:, 1:2] + return data_details_return({'X': X, 'Y': Y}, data_set) +
+
[docs]def olympic_sprints(data_set='rogers_girolami_data'): + """All olympics sprint winning times for multiple output prediction.""" + X = np.zeros((0, 2)) + Y = np.zeros((0, 1)) + for i, dataset in enumerate([olympic_100m_men, + olympic_100m_women, + olympic_200m_men, + olympic_200m_women, + olympic_400m_men, + olympic_400m_women]): + data = dataset() + year = data['X'] + time = data['Y'] + X = np.vstack((X, np.hstack((year, np.ones_like(year)*i)))) + Y = np.vstack((Y, time)) + data['X'] = X + data['Y'] = Y + data['info'] = "Olympics sprint event winning for men and women to 2008. Data is from Rogers and Girolami's First Course in Machine Learning." + return data_details_return({ + 'X': X, + 'Y': Y, + 'info': "Olympics sprint event winning for men and women to 2008. Data is from Rogers and Girolami's First Course in Machine Learning.", + 'output_info': { + 0:'100m Men', + 1:'100m Women', + 2:'200m Men', + 3:'200m Women', + 4:'400m Men', + 5:'400m Women'} + }, data_set) + +# def movielens_small(partNo=1,seed=default_seed): +# np.random.seed(seed=seed) + +# fileName = os.path.join(data_path, 'movielens', 'small', 'u' + str(partNo) + '.base') +# fid = open(fileName) +# uTrain = np.fromfile(fid, sep='\t', dtype=np.int16).reshape((-1, 4)) +# fid.close() +# maxVals = np.amax(uTrain, axis=0) +# numUsers = maxVals[0] +# numFilms = maxVals[1] +# numRatings = uTrain.shape[0] + +# Y = scipy.sparse.lil_matrix((numFilms, numUsers), dtype=np.int8) +# for i in range(numUsers): +# ind = pb.mlab.find(uTrain[:, 0]==i+1) +# Y[uTrain[ind, 1]-1, i] = uTrain[ind, 2] + +# fileName = os.path.join(data_path, 'movielens', 'small', 'u' + str(partNo) + '.test') +# fid = open(fileName) +# uTest = np.fromfile(fid, sep='\t', dtype=np.int16).reshape((-1, 4)) +# fid.close() +# numTestRatings = uTest.shape[0] + +# Ytest = scipy.sparse.lil_matrix((numFilms, numUsers), dtype=np.int8) +# for i in range(numUsers): +# ind = pb.mlab.find(uTest[:, 0]==i+1) +# Ytest[uTest[ind, 1]-1, i] = uTest[ind, 2] + +# lbls = np.empty((1,1)) +# lblstest = np.empty((1,1)) +# return {'Y':Y, 'lbls':lbls, 'Ytest':Ytest, 'lblstest':lblstest} + +
+
[docs]def crescent_data(num_data=200, seed=default_seed): + """ +Data set formed from a mixture of four Gaussians. In each class two of the Gaussians are elongated at right angles to each other and offset to form an approximation to the crescent data that is popular in semi-supervised learning as a toy problem. + + :param num_data_part: number of data to be sampled (default is 200). + :type num_data: int + :param seed: random seed to be used for data generation. + :type seed: int + + """ + np.random.seed(seed=seed) + sqrt2 = np.sqrt(2) + # Rotation matrix + R = np.array([[sqrt2 / 2, -sqrt2 / 2], [sqrt2 / 2, sqrt2 / 2]]) + # Scaling matrices + scales = [] + scales.append(np.array([[3, 0], [0, 1]])) + scales.append(np.array([[3, 0], [0, 1]])) + scales.append([[1, 0], [0, 3]]) + scales.append([[1, 0], [0, 3]]) + means = [] + means.append(np.array([4, 4])) + means.append(np.array([0, 4])) + means.append(np.array([-4, -4])) + means.append(np.array([0, -4])) + + Xparts = [] + num_data_part = [] + num_data_total = 0 + for i in range(0, 4): + num_data_part.append(round(((i + 1) * num_data) / 4.)) + num_data_part[i] -= num_data_total + part = np.random.normal(size=(num_data_part[i], 2)) + part = np.dot(np.dot(part, scales[i]), R) + means[i] + Xparts.append(part) + num_data_total += num_data_part[i] + X = np.vstack((Xparts[0], Xparts[1], Xparts[2], Xparts[3])) + + Y = np.vstack((np.ones((num_data_part[0] + num_data_part[1], 1)), -np.ones((num_data_part[2] + num_data_part[3], 1)))) + return {'X':X, 'Y':Y, 'info': "Two separate classes of data formed approximately in the shape of two crescents."} +
+
[docs]def creep_data(data_set='creep_rupture'): + """Brun and Yoshida's metal creep rupture data.""" + if not data_available(data_set): + download_data(data_set) + path = os.path.join(data_path, data_set) + tar_file = os.path.join(path, 'creeprupt.tar') + tar = tarfile.open(tar_file) + print('Extracting file.') + tar.extractall(path=path) + tar.close() + all_data = np.loadtxt(os.path.join(data_path, data_set, 'taka')) + y = all_data[:, 1:2].copy() + features = [0] + features.extend(range(2, 31)) + X = all_data[:, features].copy() + return data_details_return({'X': X, 'y': y}, data_set) +
+
[docs]def cifar10_patches(data_set='cifar-10'): + """The Candian Institute for Advanced Research 10 image data set. Code for loading in this data is taken from this Boris Babenko's blog post, original code available here: http://bbabenko.tumblr.com/post/86756017649/learning-low-level-vision-feautres-in-10-lines-of-code""" + dir_path = os.path.join(data_path, data_set) + filename = os.path.join(dir_path, 'cifar-10-python.tar.gz') + if not data_available(data_set): + download_data(data_set) + import tarfile + # This code is from Boris Babenko's blog post. + # http://bbabenko.tumblr.com/post/86756017649/learning-low-level-vision-feautres-in-10-lines-of-code + tfile = tarfile.open(filename, 'r:gz') + tfile.extractall(dir_path) + + with open(os.path.join(dir_path, 'cifar-10-batches-py','data_batch_1'),'rb') as f: + data = pickle.load(f) + + images = data['data'].reshape((-1,3,32,32)).astype('float32')/255 + images = np.rollaxis(images, 1, 4) + patches = np.zeros((0,5,5,3)) + for x in range(0,32-5,5): + for y in range(0,32-5,5): + patches = np.concatenate((patches, images[:,x:x+5,y:y+5,:]), axis=0) + patches = patches.reshape((patches.shape[0],-1)) + return data_details_return({'Y': patches, "info" : "32x32 pixel patches extracted from the CIFAR-10 data by Boris Babenko to demonstrate k-means features."}, data_set) +
+
[docs]def cmu_mocap_49_balance(data_set='cmu_mocap'): + """Load CMU subject 49's one legged balancing motion that was used by Alvarez, Luengo and Lawrence at AISTATS 2009.""" + train_motions = ['18', '19'] + test_motions = ['20'] + data = cmu_mocap('49', train_motions, test_motions, sample_every=4, data_set=data_set) + data['info'] = "One legged balancing motions from CMU data base subject 49. As used in Alvarez, Luengo and Lawrence at AISTATS 2009. It consists of " + data['info'] + return data +
+
[docs]def cmu_mocap_35_walk_jog(data_set='cmu_mocap'): + """Load CMU subject 35's walking and jogging motions, the same data that was used by Taylor, Roweis and Hinton at NIPS 2007. but without their preprocessing. Also used by Lawrence at AISTATS 2007.""" + train_motions = ['01', '02', '03', '04', '05', '06', + '07', '08', '09', '10', '11', '12', + '13', '14', '15', '16', '17', '19', + '20', '21', '22', '23', '24', '25', + '26', '28', '30', '31', '32', '33', '34'] + test_motions = ['18', '29'] + data = cmu_mocap('35', train_motions, test_motions, sample_every=4, data_set=data_set) + data['info'] = "Walk and jog data from CMU data base subject 35. As used in Tayor, Roweis and Hinton at NIPS 2007, but without their pre-processing (i.e. as used by Lawrence at AISTATS 2007). It consists of " + data['info'] + return data +
+
[docs]def cmu_mocap(subject, train_motions, test_motions=[], sample_every=4, data_set='cmu_mocap'): + """Load a given subject's training and test motions from the CMU motion capture data.""" + # Load in subject skeleton. + subject_dir = os.path.join(data_path, data_set) + + # Make sure the data is downloaded. + all_motions = train_motions + test_motions + resource = cmu_urls_files(([subject], [all_motions])) + data_resources[data_set] = data_resources['cmu_mocap_full'].copy() + data_resources[data_set]['files'] = resource['files'] + data_resources[data_set]['urls'] = resource['urls'] + if resource['urls']: + download_data(data_set) + + skel = GPy.util.mocap.acclaim_skeleton(os.path.join(subject_dir, subject + '.asf')) + + # Set up labels for each sequence + exlbls = np.eye(len(train_motions)) + + # Load sequences + tot_length = 0 + temp_Y = [] + temp_lbls = [] + for i in range(len(train_motions)): + temp_chan = skel.load_channels(os.path.join(subject_dir, subject + '_' + train_motions[i] + '.amc')) + temp_Y.append(temp_chan[::sample_every, :]) + temp_lbls.append(np.tile(exlbls[i, :], (temp_Y[i].shape[0], 1))) + tot_length += temp_Y[i].shape[0] + + Y = np.zeros((tot_length, temp_Y[0].shape[1])) + lbls = np.zeros((tot_length, temp_lbls[0].shape[1])) + + end_ind = 0 + for i in range(len(temp_Y)): + start_ind = end_ind + end_ind += temp_Y[i].shape[0] + Y[start_ind:end_ind, :] = temp_Y[i] + lbls[start_ind:end_ind, :] = temp_lbls[i] + if len(test_motions) > 0: + temp_Ytest = [] + temp_lblstest = [] + + testexlbls = np.eye(len(test_motions)) + tot_test_length = 0 + for i in range(len(test_motions)): + temp_chan = skel.load_channels(os.path.join(subject_dir, subject + '_' + test_motions[i] + '.amc')) + temp_Ytest.append(temp_chan[::sample_every, :]) + temp_lblstest.append(np.tile(testexlbls[i, :], (temp_Ytest[i].shape[0], 1))) + tot_test_length += temp_Ytest[i].shape[0] + + # Load test data + Ytest = np.zeros((tot_test_length, temp_Ytest[0].shape[1])) + lblstest = np.zeros((tot_test_length, temp_lblstest[0].shape[1])) + + end_ind = 0 + for i in range(len(temp_Ytest)): + start_ind = end_ind + end_ind += temp_Ytest[i].shape[0] + Ytest[start_ind:end_ind, :] = temp_Ytest[i] + lblstest[start_ind:end_ind, :] = temp_lblstest[i] + else: + Ytest = None + lblstest = None + + info = 'Subject: ' + subject + '. Training motions: ' + for motion in train_motions: + info += motion + ', ' + info = info[:-2] + if len(test_motions) > 0: + info += '. Test motions: ' + for motion in test_motions: + info += motion + ', ' + info = info[:-2] + '.' + else: + info += '.' + if sample_every != 1: + info += ' Data is sub-sampled to every ' + str(sample_every) + ' frames.' + return data_details_return({'Y': Y, 'lbls' : lbls, 'Ytest': Ytest, 'lblstest' : lblstest, 'info': info, 'skel': skel}, data_set) +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/debug.html b/doc/_build/html/_modules/GPy/util/debug.html new file mode 100644 index 00000000..8c5bc593 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/debug.html @@ -0,0 +1,129 @@ + + + + + + + + GPy.util.debug — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.debug

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+"""
+The module for some general debug tools
+"""
+
+import numpy as np
+
+
[docs]def checkFinite(arr, name=None): + if name is None: + name = 'Array with ID['+str(id(arr))+']' + + if np.any(np.logical_not(np.isfinite(arr))): + idx = np.where(np.logical_not(np.isfinite(arr)))[0] + print name+' at indices '+str(idx)+' have not finite values: '+str(arr[idx])+'!' + return False + return True +
+
[docs]def checkFullRank(m, tol=1e-10, name=None, force_check=False): + if name is None: + name = 'Matrix with ID['+str(id(m))+']' + assert len(m.shape)==2 and m.shape[0]==m.shape[1], 'The input of checkFullRank has to be a square matrix!' + + if not force_check and m.shape[0]>=10000: + print 'The size of '+name+'is too big to check (>=10000)!' + return True + + s = np.real(np.linalg.eigvals(m)) + + if s.min()/s.max()<tol: + print name+' is close to singlar!' + print 'The eigen values of '+name+' is '+str(s) + return False + return True
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/decorators.html b/doc/_build/html/_modules/GPy/util/decorators.html new file mode 100644 index 00000000..8dfb80f3 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/decorators.html @@ -0,0 +1,112 @@ + + + + + + + + GPy.util.decorators — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.decorators

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+import numpy as np
+from functools import wraps
+
+
[docs]def silence_errors(f): + """ + This wraps a function and it silences numpy errors that + happen during the execution. After the function has exited, it restores + the previous state of the warnings. + """ + @wraps(f) + def wrapper(*args, **kwds): + status = np.seterr(all='ignore') + result = f(*args, **kwds) + np.seterr(**status) + return result + return wrapper
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/diag.html b/doc/_build/html/_modules/GPy/util/diag.html new file mode 100644 index 00000000..78aa335c --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/diag.html @@ -0,0 +1,209 @@ + + + + + + + + GPy.util.diag — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.diag

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+
+
[docs]def view(A, offset=0): + """ + Get a view on the diagonal elements of a 2D array. + + This is actually a view (!) on the diagonal of the array, so you can + in-place adjust the view. + + :param :class:`ndarray` A: 2 dimensional numpy array + :param int offset: view offset to give back (negative entries allowed) + :rtype: :class:`ndarray` view of diag(A) + + >>> import numpy as np + >>> X = np.arange(9).reshape(3,3) + >>> view(X) + array([0, 4, 8]) + >>> d = view(X) + >>> d += 2 + >>> view(X) + array([ 2, 6, 10]) + >>> view(X, offset=-1) + array([3, 7]) + >>> subtract(X, 3, offset=-1) + array([[ 2, 1, 2], + [ 0, 6, 5], + [ 6, 4, 10]]) + """ + from numpy.lib.stride_tricks import as_strided + assert A.ndim == 2, "only implemented for 2 dimensions" + assert A.shape[0] == A.shape[1], "attempting to get the view of non-square matrix?!" + if offset > 0: + return as_strided(A[0, offset:], shape=(A.shape[0] - offset, ), strides=((A.shape[0]+1)*A.itemsize, )) + elif offset < 0: + return as_strided(A[-offset:, 0], shape=(A.shape[0] + offset, ), strides=((A.shape[0]+1)*A.itemsize, )) + else: + return as_strided(A, shape=(A.shape[0], ), strides=((A.shape[0]+1)*A.itemsize, )) +
+
[docs]def offdiag_view(A, offset=0): + from numpy.lib.stride_tricks import as_strided + assert A.ndim == 2, "only implemented for 2 dimensions" + Af = as_strided(A, shape=(A.size,), strides=(A.itemsize,)) + return as_strided(Af[(1+offset):], shape=(A.shape[0]-1, A.shape[1]), strides=(A.strides[0] + A.itemsize, A.strides[1])) +
+def _diag_ufunc(A,b,offset,func): + dA = view(A, offset); func(dA,b,dA) + return A + +
[docs]def times(A, b, offset=0): + """ + Times the view of A with b in place (!). + Returns modified A + Broadcasting is allowed, thus b can be scalar. + + if offset is not zero, make sure b is of right shape! + + :param ndarray A: 2 dimensional array + :param ndarray-like b: either one dimensional or scalar + :param int offset: same as in view. + :rtype: view of A, which is adjusted inplace + """ + return _diag_ufunc(A, b, offset, np.multiply)
+multiply = times + +
[docs]def divide(A, b, offset=0): + """ + Divide the view of A by b in place (!). + Returns modified A + Broadcasting is allowed, thus b can be scalar. + + if offset is not zero, make sure b is of right shape! + + :param ndarray A: 2 dimensional array + :param ndarray-like b: either one dimensional or scalar + :param int offset: same as in view. + :rtype: view of A, which is adjusted inplace + """ + return _diag_ufunc(A, b, offset, np.divide) +
+
[docs]def add(A, b, offset=0): + """ + Add b to the view of A in place (!). + Returns modified A. + Broadcasting is allowed, thus b can be scalar. + + if offset is not zero, make sure b is of right shape! + + :param ndarray A: 2 dimensional array + :param ndarray-like b: either one dimensional or scalar + :param int offset: same as in view. + :rtype: view of A, which is adjusted inplace + """ + return _diag_ufunc(A, b, offset, np.add) +
+
[docs]def subtract(A, b, offset=0): + """ + Subtract b from the view of A in place (!). + Returns modified A. + Broadcasting is allowed, thus b can be scalar. + + if offset is not zero, make sure b is of right shape! + + :param ndarray A: 2 dimensional array + :param ndarray-like b: either one dimensional or scalar + :param int offset: same as in view. + :rtype: view of A, which is adjusted inplace + """ + return _diag_ufunc(A, b, offset, np.subtract) +
+if __name__ == '__main__': + import doctest + doctest.testmod() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/erfcx.html b/doc/_build/html/_modules/GPy/util/erfcx.html new file mode 100644 index 00000000..61793218 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/erfcx.html @@ -0,0 +1,156 @@ + + + + + + + + GPy.util.erfcx — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.erfcx

+## Copyright (C) 2010 Soren Hauberg
+##
+## Copyright James Hensman 2011
+## 
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+import numpy as np
+
+
[docs]def erfcx (arg): + arg = np.atleast_1d(arg) + assert(np.all(np.isreal(arg)),"erfcx: input must be real") + + ## Get precision dependent thresholds -- or not :p + xneg = -26.628; + xmax = 2.53e+307; + + ## Allocate output + result = np.zeros (arg.shape) + + ## Find values where erfcx can be evaluated + idx_neg = (arg < xneg); + idx_max = (arg > xmax); + idx = ~(idx_neg | idx_max); + + arg = arg [idx]; + + ## Perform the actual computation + t = 3.97886080735226 / (np.abs (arg) + 3.97886080735226); + u = t - 0.5; + y = (((((((((u * 0.00127109764952614092 + 1.19314022838340944e-4) * u \ + - 0.003963850973605135) * u - 8.70779635317295828e-4) * u + \ + 0.00773672528313526668) * u + 0.00383335126264887303) * u - \ + 0.0127223813782122755) * u - 0.0133823644533460069) * u + \ + 0.0161315329733252248) * u + 0.0390976845588484035) * u + \ + 0.00249367200053503304; + y = ((((((((((((y * u - 0.0838864557023001992) * u - \ + 0.119463959964325415) * u + 0.0166207924969367356) * u + \ + 0.357524274449531043) * u + 0.805276408752910567) * u + \ + 1.18902982909273333) * u + 1.37040217682338167) * u + \ + 1.31314653831023098) * u + 1.07925515155856677) * u + \ + 0.774368199119538609) * u + 0.490165080585318424) * u + \ + 0.275374741597376782) * t; + + y [arg < 0] = 2 * np.exp (arg [arg < 0]**2) - y [arg < 0]; + + ## Put the results back into something with the same size is the original input + result [idx] = y; + result [idx_neg] = np.inf; + ## result (idx_max) = 0; # not needed as we initialise with zeros + return(result) +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/functions.html b/doc/_build/html/_modules/GPy/util/functions.html new file mode 100644 index 00000000..d3250c5d --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/functions.html @@ -0,0 +1,121 @@ + + + + + + + + GPy.util.functions — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.functions

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+import numpy as np
+from scipy.special import erf, erfc, erfcx
+import sys
+epsilon = sys.float_info.epsilon
+lim_val = -np.log(epsilon) 
+
+
[docs]def logisticln(x): + return np.where(x<lim_val, np.where(x>-lim_val, -np.log(1+np.exp(-x)), -x), -np.log(1+epsilon)) +
+
[docs]def logistic(x): + return np.where(x<lim_val, np.where(x>-lim_val, 1/(1+np.exp(-x)), epsilon/(epsilon+1)), 1/(1+epsilon)) +
+
[docs]def normcdf(x): + g=0.5*erfc(-x/np.sqrt(2)) + return np.where(g==0, epsilon, np.where(g==1, 1-epsilon, g)) +
+
[docs]def normcdfln(x): + return np.where(x < 0, -.5*x*x + np.log(.5) + np.log(erfcx(-x/np.sqrt(2))), np.log(normcdf(x))) +
+
[docs]def clip_exp(x): + return np.where(x<lim_val, np.where(x>-lim_val, np.exp(x), epsilon), 1/epsilon) +
+
[docs]def differfln(x0, x1): + # this is a, hopefully!, a numerically more stable variant of log(erf(x0)-erf(x1)) = log(erfc(x1)-erfc(x0)). + return np.where(x0>x1, -x1*x1 + np.log(erfcx(x1)-np.exp(-x0**2+x1**2)*erfcx(x0)), -x0*x0 + np.log(np.exp(-x1**2+x0**2)*erfcx(x1) - erfcx(x0)))
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/gpu_init.html b/doc/_build/html/_modules/GPy/util/gpu_init.html new file mode 100644 index 00000000..13b7ff9e --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/gpu_init.html @@ -0,0 +1,142 @@ + + + + + + + + GPy.util.gpu_init — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.gpu_init

+"""
+The package for scikits.cuda initialization
+
+Global variables: initSuccess
+providing CUBLAS handle: cublas_handle
+"""
+
+gpu_initialized = False
+gpu_device = None
+gpu_context = None
+MPI_enabled = False
+
+try:
+    from mpi4py import MPI
+    MPI_enabled = True
+except:
+    pass
+
+try:
+    if MPI_enabled and MPI.COMM_WORLD.size>1:
+        from .parallel import get_id_within_node
+        gpuid = get_id_within_node()
+        import pycuda.driver
+        pycuda.driver.init()
+        if gpuid>=pycuda.driver.Device.count():
+            print '['+MPI.Get_processor_name()+'] more processes than the GPU numbers!'
+            #MPI.COMM_WORLD.Abort()
+            raise
+        gpu_device = pycuda.driver.Device(gpuid)
+        gpu_context = gpu_device.make_context()
+        gpu_initialized = True
+    else:
+        import pycuda.autoinit
+        gpu_initialized = True
+except:
+    pass
+
+try:
+    from scikits.cuda import cublas
+    import scikits.cuda.linalg as culinalg
+    culinalg.init()
+    cublas_handle = cublas.cublasCreate()
+except:
+    pass
+
+
[docs]def closeGPU(): + if gpu_context is not None: + gpu_context.detach()
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/initialization.html b/doc/_build/html/_modules/GPy/util/initialization.html new file mode 100644 index 00000000..4eda4d50 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/initialization.html @@ -0,0 +1,117 @@ + + + + + + + + GPy.util.initialization — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.initialization

+'''
+Created on 24 Feb 2014
+
+@author: maxz
+'''
+
+import numpy as np
+from GPy.util.pca import PCA
+
+
[docs]def initialize_latent(init, input_dim, Y): + Xr = np.asfortranarray(np.random.randn(Y.shape[0], input_dim)) + if init == 'PCA': + p = PCA(Y) + PC = p.project(Y, min(input_dim, Y.shape[1])) + Xr[:PC.shape[0], :PC.shape[1]] = PC + var = .1*p.fracs[:input_dim] + else: + var = Xr.var(0) + + Xr -= Xr.mean(0) + Xr /= Xr.std(0) + + return Xr, var/var.max()
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/linalg.html b/doc/_build/html/_modules/GPy/util/linalg.html new file mode 100644 index 00000000..9f44dfe9 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/linalg.html @@ -0,0 +1,627 @@ + + + + + + + + GPy.util.linalg — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.linalg

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+# tdot function courtesy of Ian Murray:
+# Iain Murray, April 2013. iain contactable via iainmurray.net
+# http://homepages.inf.ed.ac.uk/imurray2/code/tdot/tdot.py
+
+import numpy as np
+from scipy import linalg, weave
+import types
+import ctypes
+from ctypes import byref, c_char, c_int, c_double # TODO
+import scipy
+import warnings
+import os
+from config import config
+import logging
+
+_scipyversion = np.float64((scipy.__version__).split('.')[:2])
+_fix_dpotri_scipy_bug = True
+if np.all(_scipyversion >= np.array([0, 14])):
+    from scipy.linalg import lapack
+    _fix_dpotri_scipy_bug = False
+elif np.all(_scipyversion >= np.array([0, 12])):
+    #import scipy.linalg.lapack.clapack as lapack
+    from scipy.linalg import lapack
+else:
+    from scipy.linalg.lapack import flapack as lapack
+
+if config.getboolean('anaconda', 'installed') and config.getboolean('anaconda', 'MKL'):
+    try:
+        anaconda_path = str(config.get('anaconda', 'location'))
+        mkl_rt = ctypes.cdll.LoadLibrary(os.path.join(anaconda_path, 'DLLs', 'mkl_rt.dll'))
+        dsyrk = mkl_rt.dsyrk
+        dsyr = mkl_rt.dsyr
+        _blas_available = True
+        print 'anaconda installed and mkl is loaded'
+    except:
+        _blas_available = False
+else:
+    try:
+        _blaslib = ctypes.cdll.LoadLibrary(np.core._dotblas.__file__) # @UndefinedVariable
+        dsyrk = _blaslib.dsyrk_
+        dsyr = _blaslib.dsyr_
+        _blas_available = True
+    except AttributeError as e:
+        _blas_available = False
+        warnings.warn("warning: caught this exception:" + str(e))
+
+
[docs]def force_F_ordered_symmetric(A): + """ + return a F ordered version of A, assuming A is symmetric + """ + if A.flags['F_CONTIGUOUS']: + return A + if A.flags['C_CONTIGUOUS']: + return A.T + else: + return np.asfortranarray(A) +
+
[docs]def force_F_ordered(A): + """ + return a F ordered version of A, assuming A is triangular + """ + if A.flags['F_CONTIGUOUS']: + return A + print "why are your arrays not F order?" + return np.asfortranarray(A) + +# def jitchol(A, maxtries=5): +# A = force_F_ordered_symmetric(A) +# L, info = lapack.dpotrf(A, lower=1) +# if info == 0: +# return L +# else: +# if maxtries==0: +# raise linalg.LinAlgError, "not positive definite, even with jitter." +# diagA = np.diag(A) +# if np.any(diagA <= 0.): +# raise linalg.LinAlgError, "not pd: non-positive diagonal elements" +# jitter = diagA.mean() * 1e-6 + +# return jitchol(A+np.eye(A.shape[0])*jitter, maxtries-1) +
+
[docs]def jitchol(A, maxtries=5): + A = np.ascontiguousarray(A) + L, info = lapack.dpotrf(A, lower=1) + if info == 0: + return L + else: + diagA = np.diag(A) + if np.any(diagA <= 0.): + raise linalg.LinAlgError, "not pd: non-positive diagonal elements" + jitter = diagA.mean() * 1e-6 + while maxtries > 0 and np.isfinite(jitter): + try: + L = linalg.cholesky(A + np.eye(A.shape[0]) * jitter, lower=True) + except: + jitter *= 10 + finally: + maxtries -= 1 + raise linalg.LinAlgError, "not positive definite, even with jitter." + import traceback + try: raise + except: + logging.warning('\n'.join(['Added jitter of {:.10e}'.format(jitter), + ' in '+traceback.format_list(traceback.extract_stack(limit=2)[-2:-1])[0][2:]])) + import ipdb;ipdb.set_trace() + return L + + + + + +# def dtrtri(L, lower=1): +# """ +# Wrapper for lapack dtrtri function +# Inverse of L +# +# :param L: Triangular Matrix L +# :param lower: is matrix lower (true) or upper (false) +# :returns: Li, info +# """ +# L = force_F_ordered(L) +# return lapack.dtrtri(L, lower=lower) +
+
[docs]def dtrtrs(A, B, lower=1, trans=0, unitdiag=0): + """ + Wrapper for lapack dtrtrs function + + DTRTRS solves a triangular system of the form + + A * X = B or A**T * X = B, + + where A is a triangular matrix of order N, and B is an N-by-NRHS + matrix. A check is made to verify that A is nonsingular. + + :param A: Matrix A(triangular) + :param B: Matrix B + :param lower: is matrix lower (true) or upper (false) + :returns: Solution to A * X = B or A**T * X = B + + """ + A = np.asfortranarray(A) + #Note: B does not seem to need to be F ordered! + return lapack.dtrtrs(A, B, lower=lower, trans=trans, unitdiag=unitdiag) +
+
[docs]def dpotrs(A, B, lower=1): + """ + Wrapper for lapack dpotrs function + :param A: Matrix A + :param B: Matrix B + :param lower: is matrix lower (true) or upper (false) + :returns: + """ + A = force_F_ordered(A) + return lapack.dpotrs(A, B, lower=lower) +
+
[docs]def dpotri(A, lower=1): + """ + Wrapper for lapack dpotri function + + DPOTRI - compute the inverse of a real symmetric positive + definite matrix A using the Cholesky factorization A = + U**T*U or A = L*L**T computed by DPOTRF + + :param A: Matrix A + :param lower: is matrix lower (true) or upper (false) + :returns: A inverse + + """ + if _fix_dpotri_scipy_bug: + assert lower==1, "scipy linalg behaviour is very weird. please use lower, fortran ordered arrays" + lower = 0 + + A = force_F_ordered(A) + R, info = lapack.dpotri(A, lower=lower) #needs to be zero here, seems to be a scipy bug + + symmetrify(R) + return R, info +
+
[docs]def pddet(A): + """ + Determinant of a positive definite matrix, only symmetric matricies though + """ + L = jitchol(A) + logdetA = 2*sum(np.log(np.diag(L))) + return logdetA +
+
[docs]def trace_dot(a, b): + """ + Efficiently compute the trace of the matrix product of a and b + """ + return np.sum(a * b) +
+
[docs]def mdot(*args): + """ + Multiply all the arguments using matrix product rules. + The output is equivalent to multiplying the arguments one by one + from left to right using dot(). + Precedence can be controlled by creating tuples of arguments, + for instance mdot(a,((b,c),d)) multiplies a (a*((b*c)*d)). + Note that this means the output of dot(a,b) and mdot(a,b) will differ if + a or b is a pure tuple of numbers. + + """ + if len(args) == 1: + return args[0] + elif len(args) == 2: + return _mdot_r(args[0], args[1]) + else: + return _mdot_r(args[:-1], args[-1]) +
+def _mdot_r(a, b): + """Recursive helper for mdot""" + if type(a) == types.TupleType: + if len(a) > 1: + a = mdot(*a) + else: + a = a[0] + if type(b) == types.TupleType: + if len(b) > 1: + b = mdot(*b) + else: + b = b[0] + return np.dot(a, b) + +
[docs]def pdinv(A, *args): + """ + :param A: A DxD pd numpy array + + :rval Ai: the inverse of A + :rtype Ai: np.ndarray + :rval L: the Cholesky decomposition of A + :rtype L: np.ndarray + :rval Li: the Cholesky decomposition of Ai + :rtype Li: np.ndarray + :rval logdet: the log of the determinant of A + :rtype logdet: float64 + + """ + L = jitchol(A, *args) + logdet = 2.*np.sum(np.log(np.diag(L))) + Li = dtrtri(L) + Ai, _ = dpotri(L, lower=1) + # Ai = np.tril(Ai) + np.tril(Ai,-1).T + symmetrify(Ai) + + return Ai, L, Li, logdet + +
+
[docs]def dtrtri(L): + """ + Inverts a Cholesky lower triangular matrix + + :param L: lower triangular matrix + :rtype: inverse of L + + """ + + L = force_F_ordered(L) + return lapack.dtrtri(L, lower=1)[0] + +
+
[docs]def multiple_pdinv(A): + """ + :param A: A DxDxN numpy array (each A[:,:,i] is pd) + + :rval invs: the inverses of A + :rtype invs: np.ndarray + :rval hld: 0.5* the log of the determinants of A + :rtype hld: np.array + + """ + N = A.shape[-1] + chols = [jitchol(A[:, :, i]) for i in range(N)] + halflogdets = [np.sum(np.log(np.diag(L[0]))) for L in chols] + invs = [dpotri(L[0], True)[0] for L in chols] + invs = [np.triu(I) + np.triu(I, 1).T for I in invs] + return np.dstack(invs), np.array(halflogdets) + +
+
[docs]def pca(Y, input_dim): + """ + Principal component analysis: maximum likelihood solution by SVD + + :param Y: NxD np.array of data + :param input_dim: int, dimension of projection + + + :rval X: - Nxinput_dim np.array of dimensionality reduced data + :rval W: - input_dimxD mapping from X to Y + + """ + if not np.allclose(Y.mean(axis=0), 0.0): + print "Y is not zero mean, centering it locally (GPy.util.linalg.pca)" + + # Y -= Y.mean(axis=0) + + Z = linalg.svd(Y - Y.mean(axis=0), full_matrices=False) + [X, W] = [Z[0][:, 0:input_dim], np.dot(np.diag(Z[1]), Z[2]).T[:, 0:input_dim]] + v = X.std(axis=0) + X /= v; + W *= v; + return X, W.T +
+
[docs]def ppca(Y, Q, iterations=100): + """ + EM implementation for probabilistic pca. + + :param array-like Y: Observed Data + :param int Q: Dimensionality for reduced array + :param int iterations: number of iterations for EM + """ + from numpy.ma import dot as madot + N, D = Y.shape + # Initialise W randomly + W = np.random.randn(D, Q) * 1e-3 + Y = np.ma.masked_invalid(Y, copy=0) + mu = Y.mean(0) + Ycentered = Y - mu + try: + for _ in range(iterations): + exp_x = np.asarray_chkfinite(np.linalg.solve(W.T.dot(W), madot(W.T, Ycentered.T))).T + W = np.asarray_chkfinite(np.linalg.solve(exp_x.T.dot(exp_x), madot(exp_x.T, Ycentered))).T + except np.linalg.linalg.LinAlgError: + #"converged" + pass + return np.asarray_chkfinite(exp_x), np.asarray_chkfinite(W) +
+
[docs]def tdot_numpy(mat, out=None): + return np.dot(mat, mat.T, out) +
+
[docs]def tdot_blas(mat, out=None): + """returns np.dot(mat, mat.T), but faster for large 2D arrays of doubles.""" + if (mat.dtype != 'float64') or (len(mat.shape) != 2): + return np.dot(mat, mat.T) + nn = mat.shape[0] + if out is None: + out = np.zeros((nn, nn)) + else: + assert(out.dtype == 'float64') + assert(out.shape == (nn, nn)) + # FIXME: should allow non-contiguous out, and copy output into it: + assert(8 in out.strides) + # zeroing needed because of dumb way I copy across triangular answer + out[:] = 0.0 + + # # Call to DSYRK from BLAS + # If already in Fortran order (rare), and has the right sorts of strides I + # could avoid the copy. I also thought swapping to cblas API would allow use + # of C order. However, I tried that and had errors with large matrices: + # http://homepages.inf.ed.ac.uk/imurray2/code/tdot/tdot_broken.py + mat = np.asfortranarray(mat) + TRANS = c_char('n') + N = c_int(mat.shape[0]) + K = c_int(mat.shape[1]) + LDA = c_int(mat.shape[0]) + UPLO = c_char('l') + ALPHA = c_double(1.0) + A = mat.ctypes.data_as(ctypes.c_void_p) + BETA = c_double(0.0) + C = out.ctypes.data_as(ctypes.c_void_p) + LDC = c_int(np.max(out.strides) / 8) + dsyrk(byref(UPLO), byref(TRANS), byref(N), byref(K), + byref(ALPHA), A, byref(LDA), byref(BETA), C, byref(LDC)) + + symmetrify(out, upper=True) + + + return np.ascontiguousarray(out) +
+
[docs]def tdot(*args, **kwargs): + if _blas_available: + return tdot_blas(*args, **kwargs) + else: + return tdot_numpy(*args, **kwargs) +
+
[docs]def DSYR_blas(A, x, alpha=1.): + """ + Performs a symmetric rank-1 update operation: + A <- A + alpha * np.dot(x,x.T) + + :param A: Symmetric NxN np.array + :param x: Nx1 np.array + :param alpha: scalar + + """ + N = c_int(A.shape[0]) + LDA = c_int(A.shape[0]) + UPLO = c_char('l') + ALPHA = c_double(alpha) + A_ = A.ctypes.data_as(ctypes.c_void_p) + x_ = x.ctypes.data_as(ctypes.c_void_p) + INCX = c_int(1) + dsyr(byref(UPLO), byref(N), byref(ALPHA), + x_, byref(INCX), A_, byref(LDA)) + symmetrify(A, upper=True) +
+
[docs]def DSYR_numpy(A, x, alpha=1.): + """ + Performs a symmetric rank-1 update operation: + A <- A + alpha * np.dot(x,x.T) + + :param A: Symmetric NxN np.array + :param x: Nx1 np.array + :param alpha: scalar + + """ + A += alpha * np.dot(x[:, None], x[None, :]) + +
+
[docs]def DSYR(*args, **kwargs): + if _blas_available: + return DSYR_blas(*args, **kwargs) + else: + return DSYR_numpy(*args, **kwargs) +
+
[docs]def symmetrify(A, upper=False): + """ + Take the square matrix A and make it symmetrical by copting elements from the lower half to the upper + + works IN PLACE. + + note: tries to use weave, falls back to a slower numpy version + """ + if config.getboolean('weave', 'working'): + try: + symmetrify_weave(A, upper) + except: + print "\n Weave compilation failed. Falling back to (slower) numpy implementation\n" + config.set('weave', 'working', 'False') + symmetrify_numpy(A, upper) + else: + symmetrify_numpy(A, upper) + +
+
[docs]def symmetrify_weave(A, upper=False): + """ + Take the square matrix A and make it symmetrical by copting elements from the lower half to the upper + + works IN PLACE. + + + """ + N, M = A.shape + assert N == M + + c_contig_code = """ + int iN; + for (int i=1; i<N; i++){ + iN = i*N; + for (int j=0; j<i; j++){ + A[i+j*N] = A[iN+j]; + } + } + """ + f_contig_code = """ + int iN; + for (int i=1; i<N; i++){ + iN = i*N; + for (int j=0; j<i; j++){ + A[iN+j] = A[i+j*N]; + } + } + """ + + N = int(N) # for safe type casting + if A.flags['C_CONTIGUOUS'] and upper: + weave.inline(f_contig_code, ['A', 'N'], extra_compile_args=['-O3']) + elif A.flags['C_CONTIGUOUS'] and not upper: + weave.inline(c_contig_code, ['A', 'N'], extra_compile_args=['-O3']) + elif A.flags['F_CONTIGUOUS'] and upper: + weave.inline(c_contig_code, ['A', 'N'], extra_compile_args=['-O3']) + elif A.flags['F_CONTIGUOUS'] and not upper: + weave.inline(f_contig_code, ['A', 'N'], extra_compile_args=['-O3']) + else: + if upper: + tmp = np.tril(A.T) + else: + tmp = np.tril(A) + A[:] = 0.0 + A += tmp + A += np.tril(tmp, -1).T + +
+
[docs]def symmetrify_numpy(A, upper=False): + """ + Force a matrix to be symmetric + """ + triu = np.triu_indices_from(A,k=1) + if upper: + A.T[triu] = A[triu] + else: + A[triu] = A.T[triu] +
+
[docs]def cholupdate(L, x): + """ + update the LOWER cholesky factor of a pd matrix IN PLACE + + if L is the lower chol. of K, then this function computes L\_ + where L\_ is the lower chol of K + x*x^T + + """ + support_code = """ + #include <math.h> + """ + code = """ + double r,c,s; + int j,i; + for(j=0; j<N; j++){ + r = sqrt(L(j,j)*L(j,j) + x(j)*x(j)); + c = r / L(j,j); + s = x(j) / L(j,j); + L(j,j) = r; + for (i=j+1; i<N; i++){ + L(i,j) = (L(i,j) + s*x(i))/c; + x(i) = c*x(i) - s*L(i,j); + } + } + """ + x = x.copy() + N = x.size + weave.inline(code, support_code=support_code, arg_names=['N', 'L', 'x'], type_converters=weave.converters.blitz) +
+
[docs]def backsub_both_sides(L, X, transpose='left'): + """ Return L^-T * X * L^-1, assumuing X is symmetrical and L is lower cholesky""" + if transpose == 'left': + tmp, _ = dtrtrs(L, X, lower=1, trans=1) + return dtrtrs(L, tmp.T, lower=1, trans=1)[0].T + else: + tmp, _ = dtrtrs(L, X, lower=1, trans=0) + return dtrtrs(L, tmp.T, lower=1, trans=0)[0].T +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/ln_diff_erfs.html b/doc/_build/html/_modules/GPy/util/ln_diff_erfs.html new file mode 100644 index 00000000..d9e797f2 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/ln_diff_erfs.html @@ -0,0 +1,204 @@ + + + + + + + + GPy.util.ln_diff_erfs — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.ln_diff_erfs

+# Copyright (c) 2013, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+#Only works for scipy 0.12+
+try:
+    from scipy.special import erfcx, erf
+except ImportError:
+    from scipy.special import erf
+    from erfcx import erfcx
+
+import numpy as np
+
+
[docs]def ln_diff_erfs(x1, x2, return_sign=False): + """Function for stably computing the log of difference of two erfs in a numerically stable manner. + :param x1 : argument of the positive erf + :type x1: ndarray + :param x2 : argument of the negative erf + :type x2: ndarray + :return: tuple containing (log(abs(erf(x1) - erf(x2))), sign(erf(x1) - erf(x2))) + + Based on MATLAB code that was written by Antti Honkela and modified by David Luengo and originally derived from code by Neil Lawrence. + """ + x1 = np.require(x1).real + x2 = np.require(x2).real + if x1.size==1: + x1 = np.reshape(x1, (1, 1)) + if x2.size==1: + x2 = np.reshape(x2, (1, 1)) + + if x1.shape==x2.shape: + v = np.zeros_like(x1) + else: + if x1.size==1: + v = np.zeros(x2.shape) + elif x2.size==1: + v = np.zeros(x1.shape) + else: + raise ValueError, "This function does not broadcast unless provided with a scalar." + + if x1.size == 1: + x1 = np.tile(x1, x2.shape) + + if x2.size == 1: + x2 = np.tile(x2, x1.shape) + + sign = np.sign(x1 - x2) + if x1.size == 1: + if sign== -1: + swap = x1 + x1 = x2 + x2 = swap + else: + I = sign == -1 + swap = x1[I] + x1[I] = x2[I] + x2[I] = swap + + with np.errstate(divide='ignore'): + # switch off log of zero warnings. + + # Case 0: arguments of different sign, no problems with loss of accuracy + I0 = np.logical_or(np.logical_and(x1>0, x2<0), np.logical_and(x2>0, x1<0)) # I1=(x1*x2)<0 + + # Case 1: x1 = x2 so we have log of zero. + I1 = (x1 == x2) + + # Case 2: Both arguments are non-negative + I2 = np.logical_and(x1 > 0, np.logical_and(np.logical_not(I0), + np.logical_not(I1))) + # Case 3: Both arguments are non-positive + I3 = np.logical_and(np.logical_and(np.logical_not(I0), + np.logical_not(I1)), + np.logical_not(I2)) + _x2 = x2.flatten() + _x1 = x1.flatten() + for group, flags in zip((0, 1, 2, 3), (I0, I1, I2, I3)): + + if np.any(flags): + if not x1.size==1: + _x1 = x1[flags] + if not x2.size==1: + _x2 = x2[flags] + if group==0: + v[flags] = np.log( erf(_x1) - erf(_x2) ) + elif group==1: + v[flags] = -np.inf + elif group==2: + v[flags] = np.log(erfcx(_x2) + -erfcx(_x1)*np.exp(_x2**2 + -_x1**2)) - _x2**2 + elif group==3: + v[flags] = np.log(erfcx(-_x1) + -erfcx(-_x2)*np.exp(_x1**2 + -_x2**2))-_x1**2 + + # TODO: switch back on log of zero warnings. + + if return_sign: + return v, sign + else: + if v.size==1: + if sign==-1: + v = v.view('complex64') + v += np.pi*1j + else: + # Need to add in a complex part because argument is negative. + v = v.view('complex64') + v[I] += np.pi*1j + + return v
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/misc.html b/doc/_build/html/_modules/GPy/util/misc.html new file mode 100644 index 00000000..2455e03c --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/misc.html @@ -0,0 +1,192 @@ + + + + + + + + GPy.util.misc — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.misc

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from config import *
+
+
[docs]def chain_1(df_dg, dg_dx): + """ + Generic chaining function for first derivative + + .. math:: + \\frac{d(f . g)}{dx} = \\frac{df}{dg} \\frac{dg}{dx} + """ + return df_dg * dg_dx +
+
[docs]def chain_2(d2f_dg2, dg_dx, df_dg, d2g_dx2): + """ + Generic chaining function for second derivative + + .. math:: + \\frac{d^{2}(f . g)}{dx^{2}} = \\frac{d^{2}f}{dg^{2}}(\\frac{dg}{dx})^{2} + \\frac{df}{dg}\\frac{d^{2}g}{dx^{2}} + """ + return d2f_dg2*(dg_dx**2) + df_dg*d2g_dx2 +
+
[docs]def chain_3(d3f_dg3, dg_dx, d2f_dg2, d2g_dx2, df_dg, d3g_dx3): + """ + Generic chaining function for third derivative + + .. math:: + \\frac{d^{3}(f . g)}{dx^{3}} = \\frac{d^{3}f}{dg^{3}}(\\frac{dg}{dx})^{3} + 3\\frac{d^{2}f}{dg^{2}}\\frac{dg}{dx}\\frac{d^{2}g}{dx^{2}} + \\frac{df}{dg}\\frac{d^{3}g}{dx^{3}} + """ + return d3f_dg3*(dg_dx**3) + 3*d2f_dg2*dg_dx*d2g_dx2 + df_dg*d3g_dx3 +
+
[docs]def opt_wrapper(m, **kwargs): + """ + This function just wraps the optimization procedure of a GPy + object so that optimize() pickleable (necessary for multiprocessing). + """ + m.optimize(**kwargs) + return m.optimization_runs[-1] + +
+
[docs]def linear_grid(D, n = 100, min_max = (-100, 100)): + """ + Creates a D-dimensional grid of n linearly spaced points + + :param D: dimension of the grid + :param n: number of points + :param min_max: (min, max) list + + """ + + g = np.linspace(min_max[0], min_max[1], n) + G = np.ones((n, D)) + + return G*g[:,None] +
+
[docs]def kmm_init(X, m = 10): + """ + This is the same initialization algorithm that is used + in Kmeans++. It's quite simple and very useful to initialize + the locations of the inducing points in sparse GPs. + + :param X: data + :param m: number of inducing points + + """ + + # compute the distances + XXT = np.dot(X, X.T) + D = (-2.*XXT + np.diag(XXT)[:,np.newaxis] + np.diag(XXT)[np.newaxis,:]) + + # select the first point + s = np.random.permutation(X.shape[0])[0] + inducing = [s] + prob = D[s]/D[s].sum() + + for z in range(m-1): + s = np.random.multinomial(1, prob.flatten()).argmax() + inducing.append(s) + prob = D[s]/D[s].sum() + + inducing = np.array(inducing) + return X[inducing] + +### make a parameter to its corresponding array:
+
[docs]def param_to_array(*param): + """ +Convert an arbitrary number of parameters to :class:ndarray class objects. This is for +converting parameter objects to numpy arrays, when using scipy.weave.inline routine. +In scipy.weave.blitz there is no automatic array detection (even when the array inherits +from :class:ndarray)""" + import warnings + warnings.warn("Please use param.values, as this function will be deprecated in the next release.", DeprecationWarning) + assert len(param) > 0, "At least one parameter needed" + if len(param) == 1: + return param[0].view(np.ndarray) + return [x.view(np.ndarray) for x in param]
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/mocap.html b/doc/_build/html/_modules/GPy/util/mocap.html new file mode 100644 index 00000000..e7ef937b --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/mocap.html @@ -0,0 +1,796 @@ + + + + + + + + GPy.util.mocap — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.mocap

+import os
+import numpy as np
+import math
+from GPy.util import datasets as dat
+import urllib2
+
+
[docs]class vertex: + def __init__(self, name, id, parents=[], children=[], meta = {}): + self.name = name + self.id = id + self.parents = parents + self.children = children + self.meta = meta + + def __str__(self): + return self.name + '(' + str(self.id) + ').' +
+
[docs]class tree: + def __init__(self): + self.vertices = [] + self.vertices.append(vertex(name='root', id=0)) + + def __str__(self): + index = self.find_root() + return self.branch_str(index) + +
[docs] def branch_str(self, index, indent=''): + out = indent + str(self.vertices[index]) + '\n' + for child in self.vertices[index].children: + out+=self.branch_str(child, indent+' ') + return out +
+
[docs] def find_children(self): + """Take a tree and set the children according to the parents. + + Takes a tree structure which lists the parents of each vertex + and computes the children for each vertex and places them in.""" + for i in range(len(self.vertices)): + self.vertices[i].children = [] + for i in range(len(self.vertices)): + for parent in self.vertices[i].parents: + if i not in self.vertices[parent].children: + self.vertices[parent].children.append(i) +
+
[docs] def find_parents(self): + """Take a tree and set the parents according to the children + + Takes a tree structure which lists the children of each vertex + and computes the parents for each vertex and places them in.""" + for i in range(len(self.vertices)): + self.vertices[i].parents = [] + for i in range(len(self.vertices)): + for child in self.vertices[i].children: + if i not in self.vertices[child].parents: + self.vertices[child].parents.append(i) +
+
[docs] def find_root(self): + """Finds the index of the root node of the tree.""" + self.find_parents() + index = 0 + while len(self.vertices[index].parents)>0: + index = self.vertices[index].parents[0] + return index +
+
[docs] def get_index_by_id(self, id): + """Give the index associated with a given vertex id.""" + for i in range(len(self.vertices)): + if self.vertices[i].id == id: + return i + raise ValueError('Reverse look up of id failed.') +
+
[docs] def get_index_by_name(self, name): + """Give the index associated with a given vertex name.""" + for i in range(len(self.vertices)): + if self.vertices[i].name == name: + return i + raise ValueError('Reverse look up of name failed.') +
+
[docs] def order_vertices(self): + """Order vertices in the graph such that parents always have a lower index than children.""" + + ordered = False + while ordered == False: + for i in range(len(self.vertices)): + ordered = True + for parent in self.vertices[i].parents: + if parent>i: + ordered = False + self.swap_vertices(i, parent) + + + +
+
[docs] def swap_vertices(self, i, j): + """ + Swap two vertices in the tree structure array. + swap_vertex swaps the location of two vertices in a tree structure array. + + :param tree: the tree for which two vertices are to be swapped. + :param i: the index of the first vertex to be swapped. + :param j: the index of the second vertex to be swapped. + :rval tree: the tree structure with the two vertex locations swapped. + + """ + store_vertex_i = self.vertices[i] + store_vertex_j = self.vertices[j] + self.vertices[j] = store_vertex_i + self.vertices[i] = store_vertex_j + for k in range(len(self.vertices)): + for swap_list in [self.vertices[k].children, self.vertices[k].parents]: + if i in swap_list: + swap_list[swap_list.index(i)] = -1 + if j in swap_list: + swap_list[swap_list.index(j)] = i + if -1 in swap_list: + swap_list[swap_list.index(-1)] = j + + +
+
[docs]def rotation_matrix(xangle, yangle, zangle, order='zxy', degrees=False): + + """ + + Compute the rotation matrix for an angle in each direction. + This is a helper function for computing the rotation matrix for a given set of angles in a given order. + + :param xangle: rotation for x-axis. + :param yangle: rotation for y-axis. + :param zangle: rotation for z-axis. + :param order: the order for the rotations. + + """ + if degrees: + xangle = math.radians(xangle) + yangle = math.radians(yangle) + zangle = math.radians(zangle) + + # Here we assume we rotate z, then x then y. + c1 = math.cos(xangle) # The x angle + c2 = math.cos(yangle) # The y angle + c3 = math.cos(zangle) # the z angle + s1 = math.sin(xangle) + s2 = math.sin(yangle) + s3 = math.sin(zangle) + + # see http://en.wikipedia.org/wiki/Rotation_matrix for + # additional info. + + if order=='zxy': + rot_mat = np.array([[c2*c3-s1*s2*s3, c2*s3+s1*s2*c3, -s2*c1],[-c1*s3, c1*c3, s1],[s2*c3+c2*s1*s3, s2*s3-c2*s1*c3, c2*c1]]) + else: + rot_mat = np.eye(3) + for i in range(len(order)): + if order[i]=='x': + rot_mat = np.dot(np.array([[1, 0, 0], [0, c1, s1], [0, -s1, c1]]),rot_mat) + elif order[i] == 'y': + rot_mat = np.dot(np.array([[c2, 0, -s2], [0, 1, 0], [s2, 0, c2]]),rot_mat) + elif order[i] == 'z': + rot_mat = np.dot(np.array([[c3, s3, 0], [-s3, c3, 0], [0, 0, 1]]),rot_mat) + + return rot_mat + + +# Motion capture data routines.
+
[docs]class skeleton(tree): + def __init__(self): + tree.__init__(self) + +
[docs] def connection_matrix(self): + connection = np.zeros((len(self.vertices), len(self.vertices)), dtype=bool) + for i in range(len(self.vertices)): + for j in range(len(self.vertices[i].children)): + connection[i, self.vertices[i].children[j]] = True + return connection +
+
[docs] def to_xyz(self, channels): + raise NotImplementedError, "this needs to be implemented to use the skeleton class" + +
+
[docs] def finalize(self): + """After loading in a skeleton ensure parents are correct, vertex orders are correct and rotation matrices are correct.""" + + self.find_parents() + self.order_vertices() + self.set_rotation_matrices() +
+
[docs] def smooth_angle_channels(self, channels): + """Remove discontinuities in angle channels so that they don't cause artifacts in algorithms that rely on the smoothness of the functions.""" + for vertex in self.vertices: + for col in vertex.meta['rot_ind']: + if col: + for k in range(1, channels.shape[0]): + diff=channels[k, col]-channels[k-1, col] + if abs(diff+360.)<abs(diff): + channels[k:, col]=channels[k:, col]+360. + elif abs(diff-360.)<abs(diff): + channels[k:, col]=channels[k:, col]-360. + +# class bvh_skeleton(skeleton): +# def __init__(self): +# skeleton.__init__(self) + +# def to_xyz(self, channels): +
+
[docs]class acclaim_skeleton(skeleton): + def __init__(self, file_name=None): + skeleton.__init__(self) + self.documentation = [] + self.angle = 'deg' + self.length = 1.0 + self.mass = 1.0 + self.type = 'acclaim' + self.vertices[0] = vertex(name='root', id=0, + parents = [0], children=[], + meta = {'orientation': [], + 'axis': [0., 0., 0.], + 'axis_order': [], + 'C': np.eye(3), + 'Cinv': np.eye(3), + 'channels': [], + 'bodymass': [], + 'confmass': [], + 'order': [], + 'rot_ind': [], + 'pos_ind': [], + 'limits': [], + 'xyz': np.array([0., 0., 0.]), + 'rot': np.eye(3)}) + + if file_name: + self.load_skel(file_name) + +
[docs] def to_xyz(self, channels): + rot_val = list(self.vertices[0].meta['orientation']) + for i in range(len(self.vertices[0].meta['rot_ind'])): + rind = self.vertices[0].meta['rot_ind'][i] + if rind != -1: + rot_val[i] += channels[rind] + + self.vertices[0].meta['rot'] = rotation_matrix(rot_val[0], + rot_val[1], + rot_val[2], + self.vertices[0].meta['axis_order'], + degrees=True) + # vertex based store of the xyz location + self.vertices[0].meta['xyz'] = list(self.vertices[0].meta['offset']) + + for i in range(len(self.vertices[0].meta['pos_ind'])): + pind = self.vertices[0].meta['pos_ind'][i] + if pind != -1: + self.vertices[0].meta['xyz'][i] += channels[pind] + + + for i in range(len(self.vertices[0].children)): + ind = self.vertices[0].children[i] + self.get_child_xyz(ind, channels) + + xyz = [] + for vertex in self.vertices: + xyz.append(vertex.meta['xyz']) + return np.array(xyz) + + +
+
[docs] def get_child_xyz(self, ind, channels): + + parent = self.vertices[ind].parents[0] + children = self.vertices[ind].children + rot_val = np.zeros(3) + for j in range(len(self.vertices[ind].meta['rot_ind'])): + rind = self.vertices[ind].meta['rot_ind'][j] + if rind != -1: + rot_val[j] = channels[rind] + else: + rot_val[j] = 0 + tdof = rotation_matrix(rot_val[0], rot_val[1], rot_val[2], + self.vertices[ind].meta['order'], + degrees=True) + + torient = rotation_matrix(self.vertices[ind].meta['axis'][0], + self.vertices[ind].meta['axis'][1], + self.vertices[ind].meta['axis'][2], + self.vertices[ind].meta['axis_order'], + degrees=True) + + torient_inv = rotation_matrix(-self.vertices[ind].meta['axis'][0], + -self.vertices[ind].meta['axis'][1], + -self.vertices[ind].meta['axis'][2], + self.vertices[ind].meta['axis_order'][::-1], + degrees=True) + + self.vertices[ind].meta['rot'] = np.dot(np.dot(np.dot(torient_inv,tdof),torient),self.vertices[parent].meta['rot']) + + + self.vertices[ind].meta['xyz'] = self.vertices[parent].meta['xyz'] + np.dot(self.vertices[ind].meta['offset'],self.vertices[ind].meta['rot']) + + for i in range(len(children)): + cind = children[i] + self.get_child_xyz(cind, channels) + +
+
[docs] def load_channels(self, file_name): + + fid=open(file_name, 'r') + channels = self.read_channels(fid) + fid.close() + return channels +
+
[docs] def load_skel(self, file_name): + + """ + Loads an ASF file into a skeleton structure. + + :param file_name: The file name to load in. + + """ + + fid = open(file_name, 'r') + self.read_skel(fid) + fid.close() + self.name = file_name + +
+
[docs] def read_bonedata(self, fid): + """Read bone data from an acclaim skeleton file stream.""" + + bone_count = 0 + lin = self.read_line(fid) + while lin[0]!=':': + parts = lin.split() + if parts[0] == 'begin': + bone_count += 1 + self.vertices.append(vertex(name = '', id=np.NaN, + meta={'name': [], + 'id': [], + 'offset': [], + 'orientation': [], + 'axis': [0., 0., 0.], + 'axis_order': [], + 'C': np.eye(3), + 'Cinv': np.eye(3), + 'channels': [], + 'bodymass': [], + 'confmass': [], + 'order': [], + 'rot_ind': [], + 'pos_ind': [], + 'limits': [], + 'xyz': np.array([0., 0., 0.]), + 'rot': np.eye(3)})) + lin = self.read_line(fid) + + + elif parts[0]=='id': + self.vertices[bone_count].id = int(parts[1]) + lin = self.read_line(fid) + + self.vertices[bone_count].children = [] + + elif parts[0]=='name': + self.vertices[bone_count].name = parts[1] + lin = self.read_line(fid) + + + elif parts[0]=='direction': + direction = np.array([float(parts[1]), float(parts[2]), float(parts[3])]) + lin = self.read_line(fid) + + + elif parts[0]=='length': + lgth = float(parts[1]) + lin = self.read_line(fid) + + + elif parts[0]=='axis': + self.vertices[bone_count].meta['axis'] = np.array([float(parts[1]), + float(parts[2]), + float(parts[3])]) + # order is reversed compared to bvh + self.vertices[bone_count].meta['axis_order'] = parts[-1][::-1].lower() + lin = self.read_line(fid) + + elif parts[0]=='dof': + order = [] + for i in range(1, len(parts)): + if parts[i]== 'rx': + chan = 'Xrotation' + order.append('x') + elif parts[i] =='ry': + chan = 'Yrotation' + order.append('y') + elif parts[i] == 'rz': + chan = 'Zrotation' + order.append('z') + elif parts[i] == 'tx': + chan = 'Xposition' + elif parts[i] == 'ty': + chan = 'Yposition' + elif parts[i] == 'tz': + chan = 'Zposition' + elif parts[i] == 'l': + chan = 'length' + self.vertices[bone_count].meta['channels'].append(chan) + # order is reversed compared to bvh + self.vertices[bone_count].meta['order'] = order[::-1] + lin = self.read_line(fid) + + elif parts[0]=='limits': + self.vertices[bone_count].meta['limits'] = [[float(parts[1][1:]), float(parts[2][:-1])]] + + lin = self.read_line(fid) + + while lin !='end': + parts = lin.split() + + self.vertices[bone_count].meta['limits'].append([float(parts[0][1:]), float(parts[1][:-1])]) + lin = self.read_line(fid) + self.vertices[bone_count].meta['limits'] = np.array(self.vertices[bone_count].meta['limits']) + + elif parts[0]=='end': + self.vertices[bone_count].meta['offset'] = direction*lgth + lin = self.read_line(fid) + + return lin +
+
[docs] def read_channels(self, fid): + """Read channels from an acclaim file.""" + bones = [[] for i in self.vertices] + num_channels = 0 + for vertex in self.vertices: + num_channels = num_channels + len(vertex.meta['channels']) + + lin = self.read_line(fid) + while lin != ':DEGREES': + lin = self.read_line(fid) + if lin == '': + raise ValueError('Could not find :DEGREES in ' + fid.name) + + counter = 0 + lin = self.read_line(fid) + while lin: + parts = lin.split() + if len(parts)==1: + frame_no = int(parts[0]) + if frame_no: + counter += 1 + if counter != frame_no: + raise ValueError('Unexpected frame number.') + else: + raise ValueError('Single bone name ...') + else: + ind = self.get_index_by_name(parts[0]) + bones[ind].append(np.array([float(channel) for channel in parts[1:]])) + lin = self.read_line(fid) + + num_frames = counter + + channels = np.zeros((num_frames, num_channels)) + + end_val = 0 + for i in range(len(self.vertices)): + vertex = self.vertices[i] + if len(vertex.meta['channels'])>0: + start_val = end_val + end_val = end_val + len(vertex.meta['channels']) + for j in range(num_frames): + channels[j, start_val:end_val] = bones[i][j] + self.resolve_indices(i, start_val) + + self.smooth_angle_channels(channels) + return channels + +
+
[docs] def read_documentation(self, fid): + """Read documentation from an acclaim skeleton file stream.""" + + lin = self.read_line(fid) + while lin[0] != ':': + self.documentation.append(lin) + lin = self.read_line(fid) + return lin +
+
[docs] def read_hierarchy(self, fid): + """Read hierarchy information from acclaim skeleton file stream.""" + + lin = self.read_line(fid) + + while lin != 'end': + parts = lin.split() + if lin != 'begin': + ind = self.get_index_by_name(parts[0]) + for i in range(1, len(parts)): + self.vertices[ind].children.append(self.get_index_by_name(parts[i])) + lin = self.read_line(fid) + lin = self.read_line(fid) + return lin +
+
[docs] def read_line(self, fid): + """Read a line from a file string and check it isn't either empty or commented before returning.""" + lin = '#' + while lin[0] == '#': + lin = fid.readline().strip() + if lin == '': + return lin + return lin + +
+
[docs] def read_root(self, fid): + """Read the root node from an acclaim skeleton file stream.""" + lin = self.read_line(fid) + while lin[0] != ':': + parts = lin.split() + if parts[0]=='order': + order = [] + for i in range(1, len(parts)): + if parts[i].lower()=='rx': + chan = 'Xrotation' + order.append('x') + elif parts[i].lower()=='ry': + chan = 'Yrotation' + order.append('y') + elif parts[i].lower()=='rz': + chan = 'Zrotation' + order.append('z') + elif parts[i].lower()=='tx': + chan = 'Xposition' + elif parts[i].lower()=='ty': + chan = 'Yposition' + elif parts[i].lower()=='tz': + chan = 'Zposition' + elif parts[i].lower()=='l': + chan = 'length' + self.vertices[0].meta['channels'].append(chan) + # order is reversed compared to bvh + self.vertices[0].meta['order'] = order[::-1] + + elif parts[0]=='axis': + # order is reversed compared to bvh + self.vertices[0].meta['axis_order'] = parts[1][::-1].lower() + elif parts[0]=='position': + self.vertices[0].meta['offset'] = [float(parts[1]), + float(parts[2]), + float(parts[3])] + elif parts[0]=='orientation': + self.vertices[0].meta['orientation'] = [float(parts[1]), + float(parts[2]), + float(parts[3])] + lin = self.read_line(fid) + return lin +
+
[docs] def read_skel(self, fid): + """Loads an acclaim skeleton format from a file stream.""" + lin = self.read_line(fid) + while lin: + if lin[0]==':': + if lin[1:]== 'name': + lin = self.read_line(fid) + self.name = lin + elif lin[1:]=='units': + lin = self.read_units(fid) + elif lin[1:]=='documentation': + lin = self.read_documentation(fid) + elif lin[1:]=='root': + lin = self.read_root(fid) + elif lin[1:]=='bonedata': + lin = self.read_bonedata(fid) + elif lin[1:]=='hierarchy': + lin = self.read_hierarchy(fid) + elif lin[1:8]=='version': + lin = self.read_line(fid) + continue + else: + if not lin: + self.finalize() + return + lin = self.read_line(fid) + else: + raise ValueError('Unrecognised file format') + self.finalize() +
+
[docs] def read_units(self, fid): + """Read units from an acclaim skeleton file stream.""" + lin = self.read_line(fid) + while lin[0] != ':': + parts = lin.split() + if parts[0]=='mass': + self.mass = float(parts[1]) + elif parts[0]=='length': + self.length = float(parts[1]) + elif parts[0]=='angle': + self.angle = parts[1] + lin = self.read_line(fid) + return lin +
+
[docs] def resolve_indices(self, index, start_val): + """Get indices for the skeleton from the channels when loading in channel data.""" + + channels = self.vertices[index].meta['channels'] + base_channel = start_val + rot_ind = -np.ones(3, dtype=int) + pos_ind = -np.ones(3, dtype=int) + for i in range(len(channels)): + if channels[i]== 'Xrotation': + rot_ind[0] = base_channel + i + elif channels[i]=='Yrotation': + rot_ind[1] = base_channel + i + elif channels[i]=='Zrotation': + rot_ind[2] = base_channel + i + elif channels[i]=='Xposition': + pos_ind[0] = base_channel + i + elif channels[i]=='Yposition': + pos_ind[1] = base_channel + i + elif channels[i]=='Zposition': + pos_ind[2] = base_channel + i + self.vertices[index].meta['rot_ind'] = list(rot_ind) + self.vertices[index].meta['pos_ind'] = list(pos_ind) +
+
[docs] def set_rotation_matrices(self): + """Set the meta information at each vertex to contain the correct matrices C and Cinv as prescribed by the rotations and rotation orders.""" + for i in range(len(self.vertices)): + self.vertices[i].meta['C'] = rotation_matrix(self.vertices[i].meta['axis'][0], + self.vertices[i].meta['axis'][1], + self.vertices[i].meta['axis'][2], + self.vertices[i].meta['axis_order'], + degrees=True) + # Todo: invert this by applying angle operations in reverse order + self.vertices[i].meta['Cinv'] = np.linalg.inv(self.vertices[i].meta['C']) + + +# Utilities for loading in x,y,z data.
+
[docs]def load_text_data(dataset, directory, centre=True): + """Load in a data set of marker points from the Ohio State University C3D motion capture files (http://accad.osu.edu/research/mocap/mocap_data.htm).""" + + points, point_names = parse_text(os.path.join(directory, dataset + '.txt'))[0:2] + # Remove markers where there is a NaN + present_index = [i for i in range(points[0].shape[1]) if not (np.any(np.isnan(points[0][:, i])) or np.any(np.isnan(points[0][:, i])) or np.any(np.isnan(points[0][:, i])))] + + point_names = point_names[present_index] + for i in range(3): + points[i] = points[i][:, present_index] + if centre: + points[i] = (points[i].T - points[i].mean(axis=1)).T + + # Concatanate the X, Y and Z markers together + Y = np.concatenate((points[0], points[1], points[2]), axis=1) + Y = Y/400. + connect = read_connections(os.path.join(directory, 'connections.txt'), point_names) + return Y, connect +
+
[docs]def parse_text(file_name): + """Parse data from Ohio State University text mocap files (http://accad.osu.edu/research/mocap/mocap_data.htm).""" + + # Read the header + fid = open(file_name, 'r') + point_names = np.array(fid.readline().split())[2:-1:3] + fid.close() + for i in range(len(point_names)): + point_names[i] = point_names[i][0:-2] + + # Read the matrix data + S = np.loadtxt(file_name, skiprows=1) + field = np.uint(S[:, 0]) + times = S[:, 1] + S = S[:, 2:] + + # Set the -9999.99 markers to be not present + S[S==-9999.99] = np.NaN + + # Store x, y and z in different arrays + points = [] + points.append(S[:, 0:-1:3]) + points.append(S[:, 1:-1:3]) + points.append(S[:, 2:-1:3]) + + return points, point_names, times +
+
[docs]def read_connections(file_name, point_names): + """Read a file detailing which markers should be connected to which for motion capture data.""" + + connections = [] + fid = open(file_name, 'r') + line=fid.readline() + while(line): + connections.append(np.array(line.split(','))) + connections[-1][0] = connections[-1][0].strip() + connections[-1][1] = connections[-1][1].strip() + line = fid.readline() + connect = np.zeros((len(point_names), len(point_names)),dtype=bool) + for i in range(len(point_names)): + for j in range(len(point_names)): + for k in range(len(connections)): + if connections[k][0] == point_names[i] and connections[k][1] == point_names[j]: + + connect[i,j]=True + connect[j,i]=True + break + + return connect + + +
+skel = acclaim_skeleton() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/multioutput.html b/doc/_build/html/_modules/GPy/util/multioutput.html new file mode 100644 index 00000000..a4223407 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/multioutput.html @@ -0,0 +1,194 @@ + + + + + + + + GPy.util.multioutput — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.multioutput

+import numpy as np
+import warnings
+import GPy
+
+
+
[docs]def get_slices(input_list): + num_outputs = len(input_list) + _s = [0] + [ _x.shape[0] for _x in input_list ] + _s = np.cumsum(_s) + slices = [slice(a,b) for a,b in zip(_s[:-1],_s[1:])] + return slices +
+
[docs]def build_XY(input_list,output_list=None,index=None): + num_outputs = len(input_list) + if output_list is not None: + assert num_outputs == len(output_list) + Y = np.vstack(output_list) + else: + Y = None + + if index is not None: + assert len(index) == num_outputs + I = np.hstack( [np.repeat(j,_x.shape[0]) for _x,j in zip(input_list,index)] ) + else: + I = np.hstack( [np.repeat(j,_x.shape[0]) for _x,j in zip(input_list,range(num_outputs))] ) + + X = np.vstack(input_list) + X = np.hstack([X,I[:,None]]) + + return X,Y,I[:,None]#slices +
+
[docs]def build_likelihood(Y_list,noise_index,likelihoods_list=None): + Ny = len(Y_list) + if likelihoods_list is None: + likelihoods_list = [GPy.likelihoods.Gaussian(name="Gaussian_noise_%s" %j) for y,j in zip(Y_list,range(Ny))] + else: + assert len(likelihoods_list) == Ny + #likelihood = GPy.likelihoods.mixed_noise.MixedNoise(likelihoods_list=likelihoods_list, noise_index=noise_index) + likelihood = GPy.likelihoods.mixed_noise.MixedNoise(likelihoods_list=likelihoods_list) + return likelihood + +
+
[docs]def ICM(input_dim, num_outputs, kernel, W_rank=1,W=None,kappa=None,name='ICM'): + """ + Builds a kernel for an Intrinsic Coregionalization Model + + :input_dim: Input dimensionality (does not include dimension of indices) + :num_outputs: Number of outputs + :param kernel: kernel that will be multiplied by the coregionalize kernel (matrix B). + :type kernel: a GPy kernel + :param W_rank: number tuples of the corregionalization parameters 'W' + :type W_rank: integer + """ + if kernel.input_dim <> input_dim: + kernel.input_dim = input_dim + warnings.warn("kernel's input dimension overwritten to fit input_dim parameter.") + + K = kernel.prod(GPy.kern.Coregionalize(1, num_outputs, active_dims=[input_dim], rank=W_rank,W=W,kappa=kappa,name='B'),name=name) + return K + +
+
[docs]def LCM(input_dim, num_outputs, kernels_list, W_rank=1,name='ICM'): + """ + Builds a kernel for an Linear Coregionalization Model + + :input_dim: Input dimensionality (does not include dimension of indices) + :num_outputs: Number of outputs + :param kernel: kernel that will be multiplied by the coregionalize kernel (matrix B). + :type kernel: a GPy kernel + :param W_rank: number tuples of the corregionalization parameters 'W' + :type W_rank: integer + """ + Nk = len(kernels_list) + K = ICM(input_dim,num_outputs,kernels_list[0],W_rank,name='%s%s' %(name,0)) + j = 1 + for kernel in kernels_list[1:]: + K += ICM(input_dim,num_outputs,kernel,W_rank,name='%s%s' %(name,j)) + j += 1 + return K + +
+
[docs]def Private(input_dim, num_outputs, kernel, output, kappa=None,name='X'): + """ + Builds a kernel for an Intrinsic Coregionalization Model + + :input_dim: Input dimensionality + :num_outputs: Number of outputs + :param kernel: kernel that will be multiplied by the coregionalize kernel (matrix B). + :type kernel: a GPy kernel + :param W_rank: number tuples of the corregionalization parameters 'W' + :type W_rank: integer + """ + K = ICM(input_dim,num_outputs,kernel,W_rank=1,kappa=kappa,name=name) + K.B.W.fix(0) + _range = range(num_outputs) + _range.pop(output) + for j in _range: + K.B.kappa[j] = 0 + K.B.kappa[j].fix() + return K
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/netpbmfile.html b/doc/_build/html/_modules/GPy/util/netpbmfile.html new file mode 100644 index 00000000..a8745650 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/netpbmfile.html @@ -0,0 +1,425 @@ + + + + + + + + GPy.util.netpbmfile — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.netpbmfile

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# netpbmfile.py
+
+# Copyright (c) 2011-2013, Christoph Gohlke
+# Copyright (c) 2011-2013, The Regents of the University of California
+# Produced at the Laboratory for Fluorescence Dynamics.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# * Neither the name of the copyright holders nor the names of any
+#   contributors may be used to endorse or promote products derived
+#   from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+"""Read and write image data from respectively to Netpbm files.
+
+This implementation follows the Netpbm format specifications at
+http://netpbm.sourceforge.net/doc/. No gamma correction is performed.
+
+The following image formats are supported: PBM (bi-level), PGM (grayscale),
+PPM (color), PAM (arbitrary), XV thumbnail (RGB332, read-only).
+
+:Author:
+  `Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/>`_
+
+:Organization:
+  Laboratory for Fluorescence Dynamics, University of California, Irvine
+
+:Version: 2013.01.18
+
+Requirements
+------------
+* `CPython 2.7, 3.2 or 3.3 <http://www.python.org>`_
+* `Numpy 1.7 <http://www.numpy.org>`_
+* `Matplotlib 1.2 <http://www.matplotlib.org>`_  (optional for plotting)
+
+Examples
+--------
+>>> im1 = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16)
+>>> imsave('_tmp.pgm', im1)
+>>> im2 = imread('_tmp.pgm')
+>>> assert numpy.all(im1 == im2)
+
+"""
+
+from __future__ import division, print_function
+
+import sys
+import re
+import math
+from copy import deepcopy
+
+import numpy
+
+__version__ = '2013.01.18'
+__docformat__ = 'restructuredtext en'
+__all__ = ['imread', 'imsave', 'NetpbmFile']
+
+
+
[docs]def imread(filename, *args, **kwargs): + """Return image data from Netpbm file as numpy array. + + `args` and `kwargs` are arguments to NetpbmFile.asarray(). + + Examples + -------- + >>> image = imread('_tmp.pgm') + + """ + try: + netpbm = NetpbmFile(filename) + image = netpbm.asarray() + finally: + netpbm.close() + return image + +
+
[docs]def imsave(filename, data, maxval=None, pam=False): + """Write image data to Netpbm file. + + Examples + -------- + >>> image = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16) + >>> imsave('_tmp.pgm', image) + + """ + try: + netpbm = NetpbmFile(data, maxval=maxval) + netpbm.write(filename, pam=pam) + finally: + netpbm.close() + +
+
[docs]class NetpbmFile(object): + """Read and write Netpbm PAM, PBM, PGM, PPM, files.""" + + _types = {b'P1': b'BLACKANDWHITE', b'P2': b'GRAYSCALE', b'P3': b'RGB', + b'P4': b'BLACKANDWHITE', b'P5': b'GRAYSCALE', b'P6': b'RGB', + b'P7 332': b'RGB', b'P7': b'RGB_ALPHA'} + + def __init__(self, arg=None, **kwargs): + """Initialize instance from filename, open file, or numpy array.""" + for attr in ('header', 'magicnum', 'width', 'height', 'maxval', + 'depth', 'tupltypes', '_filename', '_fh', '_data'): + setattr(self, attr, None) + if arg is None: + self._fromdata([], **kwargs) + elif isinstance(arg, basestring): + self._fh = open(arg, 'rb') + self._filename = arg + self._fromfile(self._fh, **kwargs) + elif hasattr(arg, 'seek'): + self._fromfile(arg, **kwargs) + self._fh = arg + else: + self._fromdata(arg, **kwargs) + +
[docs] def asarray(self, copy=True, cache=False, **kwargs): + """Return image data from file as numpy array.""" + data = self._data + if data is None: + data = self._read_data(self._fh, **kwargs) + if cache: + self._data = data + else: + return data + return deepcopy(data) if copy else data +
+
[docs] def write(self, arg, **kwargs): + """Write instance to file.""" + if hasattr(arg, 'seek'): + self._tofile(arg, **kwargs) + else: + with open(arg, 'wb') as fid: + self._tofile(fid, **kwargs) +
+
[docs] def close(self): + """Close open file. Future asarray calls might fail.""" + if self._filename and self._fh: + self._fh.close() + self._fh = None +
+ def __del__(self): + self.close() + + def _fromfile(self, fh): + """Initialize instance from open file.""" + fh.seek(0) + data = fh.read(4096) + if (len(data) < 7) or not (b'0' < data[1:2] < b'8'): + raise ValueError("Not a Netpbm file:\n%s" % data[:32]) + try: + self._read_pam_header(data) + except Exception: + try: + self._read_pnm_header(data) + except Exception: + raise ValueError("Not a Netpbm file:\n%s" % data[:32]) + + def _read_pam_header(self, data): + """Read PAM header and initialize instance.""" + regroups = re.search( + b"(^P7[\n\r]+(?:(?:[\n\r]+)|(?:#.*)|" + b"(HEIGHT\s+\d+)|(WIDTH\s+\d+)|(DEPTH\s+\d+)|(MAXVAL\s+\d+)|" + b"(?:TUPLTYPE\s+\w+))*ENDHDR\n)", data).groups() + self.header = regroups[0] + self.magicnum = b'P7' + for group in regroups[1:]: + key, value = group.split() + setattr(self, unicode(key).lower(), int(value)) + matches = re.findall(b"(TUPLTYPE\s+\w+)", self.header) + self.tupltypes = [s.split(None, 1)[1] for s in matches] + + def _read_pnm_header(self, data): + """Read PNM header and initialize instance.""" + bpm = data[1:2] in b"14" + regroups = re.search(b"".join(( + b"(^(P[123456]|P7 332)\s+(?:#.*[\r\n])*", + b"\s*(\d+)\s+(?:#.*[\r\n])*", + b"\s*(\d+)\s+(?:#.*[\r\n])*" * (not bpm), + b"\s*(\d+)\s(?:\s*#.*[\r\n]\s)*)")), data).groups() + (1, ) * bpm + self.header = regroups[0] + self.magicnum = regroups[1] + self.width = int(regroups[2]) + self.height = int(regroups[3]) + self.maxval = int(regroups[4]) + self.depth = 3 if self.magicnum in b"P3P6P7 332" else 1 + self.tupltypes = [self._types[self.magicnum]] + + def _read_data(self, fh, byteorder='>'): + """Return image data from open file as numpy array.""" + fh.seek(len(self.header)) + data = fh.read() + dtype = 'u1' if self.maxval < 256 else byteorder + 'u2' + depth = 1 if self.magicnum == b"P7 332" else self.depth + shape = [-1, self.height, self.width, depth] + size = numpy.prod(shape[1:]) + if self.magicnum in b"P1P2P3": + data = numpy.array(data.split(None, size)[:size], dtype) + data = data.reshape(shape) + elif self.maxval == 1: + shape[2] = int(math.ceil(self.width / 8)) + data = numpy.frombuffer(data, dtype).reshape(shape) + data = numpy.unpackbits(data, axis=-2)[:, :, :self.width, :] + else: + data = numpy.frombuffer(data, dtype) + data = data[:size * (data.size // size)].reshape(shape) + if data.shape[0] < 2: + data = data.reshape(data.shape[1:]) + if data.shape[-1] < 2: + data = data.reshape(data.shape[:-1]) + if self.magicnum == b"P7 332": + rgb332 = numpy.array(list(numpy.ndindex(8, 8, 4)), numpy.uint8) + rgb332 *= [36, 36, 85] + data = numpy.take(rgb332, data, axis=0) + return data + + def _fromdata(self, data, maxval=None): + """Initialize instance from numpy array.""" + data = numpy.array(data, ndmin=2, copy=True) + if data.dtype.kind not in "uib": + raise ValueError("not an integer type: %s" % data.dtype) + if data.dtype.kind == 'i' and numpy.min(data) < 0: + raise ValueError("data out of range: %i" % numpy.min(data)) + if maxval is None: + maxval = numpy.max(data) + maxval = 255 if maxval < 256 else 65535 + if maxval < 0 or maxval > 65535: + raise ValueError("data out of range: %i" % maxval) + data = data.astype('u1' if maxval < 256 else '>u2') + self._data = data + if data.ndim > 2 and data.shape[-1] in (3, 4): + self.depth = data.shape[-1] + self.width = data.shape[-2] + self.height = data.shape[-3] + self.magicnum = b'P7' if self.depth == 4 else b'P6' + else: + self.depth = 1 + self.width = data.shape[-1] + self.height = data.shape[-2] + self.magicnum = b'P5' if maxval > 1 else b'P4' + self.maxval = maxval + self.tupltypes = [self._types[self.magicnum]] + self.header = self._header() + + def _tofile(self, fh, pam=False): + """Write Netbm file.""" + fh.seek(0) + fh.write(self._header(pam)) + data = self.asarray(copy=False) + if self.maxval == 1: + data = numpy.packbits(data, axis=-1) + data.tofile(fh) + + def _header(self, pam=False): + """Return file header as byte string.""" + if pam or self.magicnum == b'P7': + header = "\n".join(( + "P7", + "HEIGHT %i" % self.height, + "WIDTH %i" % self.width, + "DEPTH %i" % self.depth, + "MAXVAL %i" % self.maxval, + "\n".join("TUPLTYPE %s" % unicode(i) for i in self.tupltypes), + "ENDHDR\n")) + elif self.maxval == 1: + header = "P4 %i %i\n" % (self.width, self.height) + elif self.depth == 1: + header = "P5 %i %i %i\n" % (self.width, self.height, self.maxval) + else: + header = "P6 %i %i %i\n" % (self.width, self.height, self.maxval) + if sys.version_info[0] > 2: + header = bytes(header, 'ascii') + return header + + def __str__(self): + """Return information about instance.""" + return unicode(self.header) + +
+if sys.version_info[0] > 2: + basestring = str + unicode = lambda x: str(x, 'ascii') + +if __name__ == "__main__": + # Show images specified on command line or all images in current directory + from glob import glob + from matplotlib import pyplot + files = sys.argv[1:] if len(sys.argv) > 1 else glob('*.p*m') + for fname in files: + try: + pam = NetpbmFile(fname) + img = pam.asarray(copy=False) + if False: + pam.write('_tmp.pgm.out', pam=True) + img2 = imread('_tmp.pgm.out') + assert numpy.all(img == img2) + imsave('_tmp.pgm.out', img) + img2 = imread('_tmp.pgm.out') + assert numpy.all(img == img2) + pam.close() + except ValueError as e: + print(fname, e) + continue + _shape = img.shape + if img.ndim > 3 or (img.ndim > 2 and img.shape[-1] not in (3, 4)): + img = img[0] + cmap = 'gray' if pam.maxval > 1 else 'binary' + pyplot.imshow(img, cmap, interpolation='nearest') + pyplot.title("%s %s %s %s" % (fname, unicode(pam.magicnum), + _shape, img.dtype)) + pyplot.show() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/normalizer.html b/doc/_build/html/_modules/GPy/util/normalizer.html new file mode 100644 index 00000000..89366e59 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/normalizer.html @@ -0,0 +1,139 @@ + + + + + + + + GPy.util.normalizer — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.normalizer

+'''
+Created on Aug 27, 2014
+
+@author: t-mazwie
+'''
+import logging
+import numpy as np
+
+
[docs]class Norm(object): + def __init__(self): + pass +
[docs] def scale_by(self, Y): + """ + Use data matrix Y as normalization space to work in. + """ + raise NotImplementedError
+
[docs] def normalize(self, Y): + """ + Project Y into normalized space + """ + raise NotImplementedError
+
[docs] def inverse_mean(self, X): + """ + Project the normalized object X into space of Y + """ + raise NotImplementedError
+
[docs] def inverse_variance(self, var): + return var
+
[docs] def scaled(self): + """ + Whether this Norm object has been initialized. + """ + raise NotImplementedError
+
[docs]class MeanNorm(Norm): + def __init__(self): + self.mean = None +
[docs] def scale_by(self, Y): + Y = np.ma.masked_invalid(Y, copy=False) + self.mean = Y.mean(0).view(np.ndarray)
+
[docs] def normalize(self, Y): + return Y-self.mean
+
[docs] def inverse_mean(self, X): + return X+self.mean
+
[docs] def scaled(self): + return self.mean is not None
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/parallel.html b/doc/_build/html/_modules/GPy/util/parallel.html new file mode 100644 index 00000000..d09d52b1 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/parallel.html @@ -0,0 +1,135 @@ + + + + + + + + GPy.util.parallel — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.parallel

+"""
+The module of tools for parallelization (MPI)
+"""
+import numpy as np
+try:
+    from mpi4py import MPI
+    def get_id_within_node(comm=MPI.COMM_WORLD):
+        rank = comm.rank
+        nodename =  MPI.Get_processor_name()
+        nodelist = comm.allgather(nodename)
+        return len([i for i in nodelist[:rank] if i==nodename])
+
+    numpy_to_MPI_typemap = {
+        np.dtype(np.float64) : MPI.DOUBLE,
+        np.dtype(np.float32) : MPI.FLOAT,
+        np.dtype(np.int)     : MPI.INT,
+        np.dtype(np.int8)    : MPI.CHAR,
+        np.dtype(np.uint8)   : MPI.UNSIGNED_CHAR,
+        np.dtype(np.int32)   : MPI.INT,
+        np.dtype(np.uint32)  : MPI.UNSIGNED_INT,
+    }
+except:
+    pass
+
+
[docs]def divide_data(datanum, rank, size): + assert rank<size and datanum>0 + + residue = (datanum)%size + datanum_list = np.empty((size),dtype=np.int32) + for i in xrange(size): + if i<residue: + datanum_list[i] = int(datanum/size)+1 + else: + datanum_list[i] = int(datanum/size) + if rank<residue: + size = datanum/size+1 + offset = size*rank + else: + size = datanum/size + offset = size*rank+residue + return offset, offset+size, datanum_list
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/pca.html b/doc/_build/html/_modules/GPy/util/pca.html new file mode 100644 index 00000000..58843ce1 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/pca.html @@ -0,0 +1,235 @@ + + + + + + + + GPy.util.pca — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.pca

+'''
+Created on 10 Sep 2012
+
+@author: Max Zwiessele
+@copyright: Max Zwiessele 2012
+'''
+import numpy
+try:
+    import pylab
+    import matplotlib
+except:
+    pass
+from numpy.linalg.linalg import LinAlgError
+from operator import setitem
+import itertools
+
+
[docs]class PCA(object): + """ + PCA module with automatic primal/dual determination. + """ + def __init__(self, X): + self.mu = None + self.sigma = None + + X = self.center(X) + + # self.X = input + if X.shape[0] >= X.shape[1]: + # print "N >= D: using primal" + self.eigvals, self.eigvectors = self._primal_eig(X) + else: + # print "N < D: using dual" + self.eigvals, self.eigvectors = self._dual_eig(X) + self.sort = numpy.argsort(self.eigvals)[::-1] + self.eigvals = self.eigvals[self.sort] + self.eigvectors = self.eigvectors[:, self.sort] + self.fracs = self.eigvals / self.eigvals.sum() + self.Q = self.eigvals.shape[0] + +
[docs] def center(self, X): + """ + Center `X` in PCA space. + """ + X = X.copy() + inan = numpy.isnan(X) + if self.mu is None: + X_ = numpy.ma.masked_array(X, inan) + self.mu = X_.mean(0).base + self.sigma = X_.std(0).base + reduce(lambda y,x: setitem(x[0], x[1], x[2]), itertools.izip(X.T, inan.T, self.mu), None) + X = X - self.mu + X = X / numpy.where(self.sigma == 0, 1e-30, self.sigma) + return X +
+ def _primal_eig(self, X): + return numpy.linalg.eigh(numpy.einsum('ji,jk->ik',X,X)) + + def _dual_eig(self, X): + dual_eigvals, dual_eigvects = numpy.linalg.eigh(numpy.einsum('ij,kj->ik',X,X)) + relevant_dimensions = numpy.argsort(numpy.abs(dual_eigvals))[-X.shape[1]:] + eigvals = dual_eigvals[relevant_dimensions] + eigvects = dual_eigvects[:, relevant_dimensions] + eigvects = (1. / numpy.sqrt(X.shape[0] * numpy.abs(eigvals))) * X.T.dot(eigvects) + eigvects /= numpy.sqrt(numpy.diag(eigvects.T.dot(eigvects))) + return eigvals, eigvects + +
[docs] def project(self, X, Q=None): + """ + Project X into PCA space, defined by the Q highest eigenvalues. + Y = X dot V + """ + if Q is None: + Q = self.Q + if Q > X.shape[1]: + raise IndexError("requested dimension larger then input dimension") + X = self.center(X) + return X.dot(self.eigvectors[:, :Q]) +
+
[docs] def plot_fracs(self, Q=None, ax=None, fignum=None): + """ + Plot fractions of Eigenvalues sorted in descending order. + """ + from GPy.plotting.matplot_dep import Tango + Tango.reset() + col = Tango.nextMedium() + if ax is None: + fig = pylab.figure(fignum) + ax = fig.add_subplot(111) + if Q is None: + Q = self.Q + ticks = numpy.arange(Q) + bar = ax.bar(ticks - .4, self.fracs[:Q], color=col) + ax.set_xticks(ticks, map(lambda x: r"${}$".format(x), ticks + 1)) + ax.set_ylabel("Eigenvalue fraction") + ax.set_xlabel("PC") + ax.set_ylim(0, ax.get_ylim()[1]) + ax.set_xlim(ticks.min() - .5, ticks.max() + .5) + try: + pylab.tight_layout() + except: + pass + return bar +
+
[docs] def plot_2d(self, X, labels=None, s=20, marker='o', + dimensions=(0, 1), ax=None, colors=None, + fignum=None, cmap=None, # @UndefinedVariable + ** kwargs): + """ + Plot dimensions `dimensions` with given labels against each other in + PC space. Labels can be any sequence of labels of dimensions X.shape[0]. + Labels can be drawn with a subsequent call to legend() + """ + if cmap is None: + cmap = matplotlib.cm.jet + if ax is None: + fig = pylab.figure(fignum) + ax = fig.add_subplot(111) + if labels is None: + labels = numpy.zeros(X.shape[0]) + ulabels = [] + for lab in labels: + if not lab in ulabels: + ulabels.append(lab) + nlabels = len(ulabels) + if colors is None: + colors = iter([cmap(float(i) / nlabels) for i in range(nlabels)]) + else: + colors = iter(colors) + X_ = self.project(X, self.Q)[:,dimensions] + kwargs.update(dict(s=s)) + plots = list() + for i, l in enumerate(ulabels): + kwargs.update(dict(color=colors.next(), marker=marker[i % len(marker)])) + plots.append(ax.scatter(*X_[labels == l, :].T, label=str(l), **kwargs)) + ax.set_xlabel(r"PC$_1$") + ax.set_ylabel(r"PC$_2$") + try: + pylab.tight_layout() + except: + pass + return plots
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/squashers.html b/doc/_build/html/_modules/GPy/util/squashers.html new file mode 100644 index 00000000..28e6b41d --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/squashers.html @@ -0,0 +1,110 @@ + + + + + + + + GPy.util.squashers — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.squashers

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+
+
[docs]def sigmoid(x): + return 1./(1.+np.exp(-x)) +
+
[docs]def softmax(x): + ex = np.exp(x-x.max(1)[:,None]) + return ex/ex.sum(1)[:,np.newaxis] +
+
[docs]def single_softmax(x): + ex = np.exp(x) + return ex/ex.sum() +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/subarray_and_sorting.html b/doc/_build/html/_modules/GPy/util/subarray_and_sorting.html new file mode 100644 index 00000000..1867c5fe --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/subarray_and_sorting.html @@ -0,0 +1,156 @@ + + + + + + + + GPy.util.subarray_and_sorting — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.subarray_and_sorting

+'''
+.. module:: GPy.util.subarray_and_sorting
+
+.. moduleauthor:: Max Zwiessele <ibinbei@gmail.com>
+
+'''
+__updated__ = '2014-05-21'
+
+import numpy as np, logging
+
+
[docs]def common_subarrays(X, axis=0): + """ + Find common subarrays of 2 dimensional X, where axis is the axis to apply the search over. + Common subarrays are returned as a dictionary of <subarray, [index]> pairs, where + the subarray is a tuple representing the subarray and the index is the index + for the subarray in X, where index is the index to the remaining axis. + + :param :class:`np.ndarray` X: 2d array to check for common subarrays in + :param int axis: axis to apply subarray detection over. + When the index is 0, compare rows -- columns, otherwise. + + Examples: + ========= + + In a 2d array: + >>> import numpy as np + >>> X = np.zeros((3,6), dtype=bool) + >>> X[[1,1,1],[0,4,5]] = 1; X[1:,[2,3]] = 1 + >>> X + array([[False, False, False, False, False, False], + [ True, False, True, True, True, True], + [False, False, True, True, False, False]], dtype=bool) + >>> d = common_subarrays(X,axis=1) + >>> len(d) + 3 + >>> X[:, d[tuple(X[:,0])]] + array([[False, False, False], + [ True, True, True], + [False, False, False]], dtype=bool) + >>> d[tuple(X[:,4])] == d[tuple(X[:,0])] == [0, 4, 5] + True + >>> d[tuple(X[:,1])] + [1] + """ + from collections import defaultdict + from itertools import count + from operator import iadd + assert X.ndim == 2 and axis in (0,1), "Only implemented for 2D arrays" + subarrays = defaultdict(list) + cnt = count() + def accumulate(x, s, c): + t = tuple(x) + col = c.next() + iadd(s[t], [col]) + return None + if axis == 0: [accumulate(x, subarrays, cnt) for x in X] + else: [accumulate(x, subarrays, cnt) for x in X.T] + return subarrays +
+if __name__ == '__main__': + import doctest + doctest.testmod() +
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/univariate_Gaussian.html b/doc/_build/html/_modules/GPy/util/univariate_Gaussian.html new file mode 100644 index 00000000..19e1e7e7 --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/univariate_Gaussian.html @@ -0,0 +1,180 @@ + + + + + + + + GPy.util.univariate_Gaussian — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.univariate_Gaussian

+# Copyright (c) 2012, 2013 Ricardo Andrade
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+import numpy as np
+from scipy import weave
+
+
[docs]def std_norm_pdf(x): + """Standard Gaussian density function""" + return 1./np.sqrt(2.*np.pi)*np.exp(-.5*x**2) +
+
[docs]def std_norm_cdf(x): + """ + Cumulative standard Gaussian distribution + Based on Abramowitz, M. and Stegun, I. (1970) + """ + x_shape = np.asarray(x).shape + + if len(x_shape) == 0 or x_shape[0] == 1: + sign = np.sign(x) + x *= sign + x /= np.sqrt(2.) + t = 1.0/(1.0 + 0.3275911*x) + erf = 1. - np.exp(-x**2)*t*(0.254829592 + t*(-0.284496736 + t*(1.421413741 + t*(-1.453152027 + t*(1.061405429))))) + cdf_x = 0.5*(1.0 + sign*erf) + return cdf_x + else: + x = np.atleast_1d(x).copy() + cdf_x = np.zeros_like(x) + sign = np.ones_like(x) + neg_x_ind = x<0 + sign[neg_x_ind] = -1.0 + x[neg_x_ind] = -x[neg_x_ind] + x /= np.sqrt(2.) + t = 1.0/(1.0 + 0.3275911*x) + erf = 1. - np.exp(-x**2)*t*(0.254829592 + t*(-0.284496736 + t*(1.421413741 + t*(-1.453152027 + t*(1.061405429))))) + cdf_x = 0.5*(1.0 + sign*erf) + cdf_x = cdf_x.reshape(x_shape) + return cdf_x +
+
[docs]def std_norm_cdf_weave(x): + """ + Cumulative standard Gaussian distribution + Based on Abramowitz, M. and Stegun, I. (1970) + + A weave implementation of std_norm_cdf, which is faster. this is unused, + because of the difficulties of a weave dependency. (see github issue #94) + + """ + #Generalize for many x + x = np.asarray(x).copy() + cdf_x = np.zeros_like(x) + N = x.size + support_code = "#include <math.h>" + code = """ + + double sign, t, erf; + for (int i=0; i<N; i++){ + sign = 1.0; + if (x[i] < 0.0){ + sign = -1.0; + x[i] = -x[i]; + } + x[i] = x[i]/sqrt(2.0); + + t = 1.0/(1.0 + 0.3275911*x[i]); + + erf = 1. - exp(-x[i]*x[i])*t*(0.254829592 + t*(-0.284496736 + t*(1.421413741 + t*(-1.453152027 + t*(1.061405429))))); + + //return_val = 0.5*(1.0 + sign*erf); + cdf_x[i] = 0.5*(1.0 + sign*erf); + } + """ + weave.inline(code, arg_names=['x', 'cdf_x', 'N'], support_code=support_code) + return cdf_x +
+
[docs]def inv_std_norm_cdf(x): + """ + Inverse cumulative standard Gaussian distribution + Based on Winitzki, S. (2008) + """ + z = 2*x -1 + ln1z2 = np.log(1-z**2) + a = 8*(np.pi -3)/(3*np.pi*(4-np.pi)) + b = 2/(np.pi * a) + ln1z2/2 + inv_erf = np.sign(z) * np.sqrt( np.sqrt(b**2 - ln1z2/a) - b ) + return np.sqrt(2) * inv_erf +
+ +
+
+
+ +
+ + + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/GPy/util/warping_functions.html b/doc/_build/html/_modules/GPy/util/warping_functions.html new file mode 100644 index 00000000..68bf236c --- /dev/null +++ b/doc/_build/html/_modules/GPy/util/warping_functions.html @@ -0,0 +1,376 @@ + + + + + + + + GPy.util.warping_functions — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for GPy.util.warping_functions

+# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
+# Licensed under the BSD 3-clause license (see LICENSE.txt)
+
+
+import numpy as np
+
+
[docs]class WarpingFunction(object): + """ + abstract function for warping + z = f(y) + """ + + def __init__(self): + raise NotImplementedError + +
[docs] def f(self,y,psi): + """function transformation + y is a list of values (GP training data) of shpape [N,1] + """ + raise NotImplementedError +
+
[docs] def fgrad_y(self,y,psi): + """gradient of f w.r.t to y""" + raise NotImplementedError +
+
[docs] def fgrad_y_psi(self,y,psi): + """gradient of f w.r.t to y""" + raise NotImplementedError +
+
[docs] def f_inv(self,z,psi): + """inverse function transformation""" + raise NotImplementedError +
+ def _get_param_names(self): + raise NotImplementedError + +
[docs] def plot(self, psi, xmin, xmax): + y = np.arange(xmin, xmax, 0.01) + f_y = self.f(y, psi) + from matplotlib import pyplot as plt + plt.figure() + plt.plot(y, f_y) + plt.xlabel('y') + plt.ylabel('f(y)') + plt.title('warping function') +
+
[docs]class TanhWarpingFunction(WarpingFunction): + + def __init__(self,n_terms=3): + """n_terms specifies the number of tanh terms to be used""" + self.n_terms = n_terms + self.num_parameters = 3 * self.n_terms + +
[docs] def f(self,y,psi): + """ + transform y with f using parameter vector psi + psi = [[a,b,c]] + ::math::`f = \\sum_{terms} a * tanh(b*(y+c))` + + """ + + #1. check that number of params is consistent + assert psi.shape[0] == self.n_terms, 'inconsistent parameter dimensions' + assert psi.shape[1] == 3, 'inconsistent parameter dimensions' + + #2. exponentiate the a and b (positive!) + mpsi = psi.copy() + + #3. transform data + z = y.copy() + for i in range(len(mpsi)): + a,b,c = mpsi[i] + z += a*np.tanh(b*(y+c)) + return z + +
+
[docs] def f_inv(self, y, psi, iterations = 10): + """ + calculate the numerical inverse of f + + :param iterations: number of N.R. iterations + + """ + + y = y.copy() + z = np.ones_like(y) + + for i in range(iterations): + z -= (self.f(z, psi) - y)/self.fgrad_y(z,psi) + + return z + +
+
[docs] def fgrad_y(self, y, psi, return_precalc = False): + """ + gradient of f w.r.t to y ([N x 1]) + returns: Nx1 vector of derivatives, unless return_precalc is true, + then it also returns the precomputed stuff + """ + + mpsi = psi.copy() + + # vectorized version + + # S = (mpsi[:,1]*(y + mpsi[:,2])).T + S = (mpsi[:,1]*(y[:,:,None] + mpsi[:,2])).T + R = np.tanh(S) + D = 1-R**2 + + # GRAD = (1+(mpsi[:,0:1]*mpsi[:,1:2]*D).sum(axis=0))[:,np.newaxis] + GRAD = (1+(mpsi[:,0:1][:,:,None]*mpsi[:,1:2][:,:,None]*D).sum(axis=0)).T + + if return_precalc: + # return GRAD,S.sum(axis=1),R.sum(axis=1),D.sum(axis=1) + return GRAD, S, R, D + + + return GRAD + +
+
[docs] def fgrad_y_psi(self, y, psi, return_covar_chain = False): + """ + gradient of f w.r.t to y and psi + + returns: NxIx3 tensor of partial derivatives + + """ + + # 1. exponentiate the a and b (positive!) + mpsi = psi.copy() + w, s, r, d = self.fgrad_y(y, psi, return_precalc = True) + + gradients = np.zeros((y.shape[0], y.shape[1], len(mpsi), 3)) + for i in range(len(mpsi)): + a,b,c = mpsi[i] + gradients[:,:,i,0] = (b*(1.0/np.cosh(s[i]))**2).T + gradients[:,:,i,1] = a*(d[i] - 2.0*s[i]*r[i]*(1.0/np.cosh(s[i]))**2).T + gradients[:,:,i,2] = (-2.0*a*(b**2)*r[i]*((1.0/np.cosh(s[i]))**2)).T + + + if return_covar_chain: + covar_grad_chain = np.zeros((y.shape[0], y.shape[1], len(mpsi), 3)) + + for i in range(len(mpsi)): + a,b,c = mpsi[i] + covar_grad_chain[:, :, i, 0] = (r[i]).T + covar_grad_chain[:, :, i, 1] = (a*(y + c) * ((1.0/np.cosh(s[i]))**2).T) + covar_grad_chain[:, :, i, 2] = a*b*((1.0/np.cosh(s[i]))**2).T + + return gradients, covar_grad_chain + + return gradients +
+ def _get_param_names(self): + variables = ['a', 'b', 'c'] + names = sum([['warp_tanh_%s_t%i' % (variables[n],q) for n in range(3)] for q in range(self.n_terms)],[]) + return names + +
+
[docs]class TanhWarpingFunction_d(WarpingFunction): + + def __init__(self,n_terms=3): + """n_terms specifies the number of tanh terms to be used""" + self.n_terms = n_terms + self.num_parameters = 3 * self.n_terms + 1 + +
[docs] def f(self,y,psi): + """ + Transform y with f using parameter vector psi + psi = [[a,b,c]] + + :math:`f = \\sum_{terms} a * tanh(b*(y+c))` + """ + + #1. check that number of params is consistent + # assert psi.shape[0] == self.n_terms, 'inconsistent parameter dimensions' + # assert psi.shape[1] == 4, 'inconsistent parameter dimensions' + mpsi = psi.copy() + d = psi[-1] + mpsi = mpsi[:self.num_parameters-1].reshape(self.n_terms, 3) + + #3. transform data + z = d*y.copy() + for i in range(len(mpsi)): + a,b,c = mpsi[i] + z += a*np.tanh(b*(y+c)) + return z + +
+
[docs] def f_inv(self, z, psi, max_iterations=1000, y=None): + """ + calculate the numerical inverse of f + + :param max_iterations: maximum number of N.R. iterations + + """ + + z = z.copy() + if y is None: + y = np.ones_like(z) + + it = 0 + update = np.inf + + while it == 0 or (np.abs(update).sum() > 1e-10 and it < max_iterations): + update = (self.f(y, psi) - z)/self.fgrad_y(y, psi) + y -= update + it += 1 + if it == max_iterations: + print "WARNING!!! Maximum number of iterations reached in f_inv " + + return y + +
+
[docs] def fgrad_y(self, y, psi, return_precalc = False): + """ + gradient of f w.r.t to y ([N x 1]) + + :returns: Nx1 vector of derivatives, unless return_precalc is true, then it also returns the precomputed stuff + + """ + + + mpsi = psi.copy() + d = psi[-1] + mpsi = mpsi[:self.num_parameters-1].reshape(self.n_terms, 3) + + # vectorized version + + S = (mpsi[:,1]*(y[:,:,None] + mpsi[:,2])).T + R = np.tanh(S) + D = 1-R**2 + + GRAD = (d + (mpsi[:,0:1][:,:,None]*mpsi[:,1:2][:,:,None]*D).sum(axis=0)).T + + if return_precalc: + return GRAD, S, R, D + + + return GRAD + +
+
[docs] def fgrad_y_psi(self, y, psi, return_covar_chain = False): + """ + gradient of f w.r.t to y and psi + + :returns: NxIx4 tensor of partial derivatives + + """ + + mpsi = psi.copy() + mpsi = mpsi[:self.num_parameters-1].reshape(self.n_terms, 3) + + w, s, r, d = self.fgrad_y(y, psi, return_precalc = True) + + gradients = np.zeros((y.shape[0], y.shape[1], len(mpsi), 4)) + for i in range(len(mpsi)): + a,b,c = mpsi[i] + gradients[:,:,i,0] = (b*(1.0/np.cosh(s[i]))**2).T + gradients[:,:,i,1] = a*(d[i] - 2.0*s[i]*r[i]*(1.0/np.cosh(s[i]))**2).T + gradients[:,:,i,2] = (-2.0*a*(b**2)*r[i]*((1.0/np.cosh(s[i]))**2)).T + gradients[:,:,0,3] = 1.0 + + if return_covar_chain: + covar_grad_chain = np.zeros((y.shape[0], y.shape[1], len(mpsi), 4)) + + for i in range(len(mpsi)): + a,b,c = mpsi[i] + covar_grad_chain[:, :, i, 0] = (r[i]).T + covar_grad_chain[:, :, i, 1] = (a*(y + c) * ((1.0/np.cosh(s[i]))**2).T) + covar_grad_chain[:, :, i, 2] = a*b*((1.0/np.cosh(s[i]))**2).T + covar_grad_chain[:, :, 0, 3] = y + + return gradients, covar_grad_chain + + return gradients +
+ def _get_param_names(self): + variables = ['a', 'b', 'c', 'd'] + names = sum([['warp_tanh_%s_t%i' % (variables[n],q) for n in range(3)] for q in range(self.n_terms)],[]) + names.append('warp_tanh_d') + return names
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/index.html b/doc/_build/html/_modules/index.html new file mode 100644 index 00000000..a8f23fd7 --- /dev/null +++ b/doc/_build/html/_modules/index.html @@ -0,0 +1,242 @@ + + + + + + + + Overview: module code — GPy documentation + + + + + + + + + + + + + +
+
+
+
+ +

All modules for which code is available

+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/multiprocessing/synchronize.html b/doc/_build/html/_modules/multiprocessing/synchronize.html new file mode 100644 index 00000000..78161be2 --- /dev/null +++ b/doc/_build/html/_modules/multiprocessing/synchronize.html @@ -0,0 +1,436 @@ + + + + + + + + multiprocessing.synchronize — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for multiprocessing.synchronize

+#
+# Module implementing synchronization primitives
+#
+# multiprocessing/synchronize.py
+#
+# Copyright (c) 2006-2008, R Oudkerk
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. Neither the name of author nor the names of any contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+__all__ = [
+    'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Event'
+    ]
+
+import threading
+import os
+import sys
+
+from time import time as _time, sleep as _sleep
+
+import _multiprocessing
+from multiprocessing.process import current_process
+from multiprocessing.util import Finalize, register_after_fork, debug
+from multiprocessing.forking import assert_spawning, Popen
+
+# Try to import the mp.synchronize module cleanly, if it fails
+# raise ImportError for platforms lacking a working sem_open implementation.
+# See issue 3770
+try:
+    from _multiprocessing import SemLock
+except (ImportError):
+    raise ImportError("This platform lacks a functioning sem_open" +
+                      " implementation, therefore, the required" +
+                      " synchronization primitives needed will not" +
+                      " function, see issue 3770.")
+
+#
+# Constants
+#
+
+RECURSIVE_MUTEX, SEMAPHORE = range(2)
+SEM_VALUE_MAX = _multiprocessing.SemLock.SEM_VALUE_MAX
+
+#
+# Base class for semaphores and mutexes; wraps `_multiprocessing.SemLock`
+#
+
+class SemLock(object):
+
+    def __init__(self, kind, value, maxvalue):
+        sl = self._semlock = _multiprocessing.SemLock(kind, value, maxvalue)
+        debug('created semlock with handle %s' % sl.handle)
+        self._make_methods()
+
+        if sys.platform != 'win32':
+            def _after_fork(obj):
+                obj._semlock._after_fork()
+            register_after_fork(self, _after_fork)
+
+    def _make_methods(self):
+        self.acquire = self._semlock.acquire
+        self.release = self._semlock.release
+
+    def __enter__(self):
+        return self._semlock.__enter__()
+
+    def __exit__(self, *args):
+        return self._semlock.__exit__(*args)
+
+    def __getstate__(self):
+        assert_spawning(self)
+        sl = self._semlock
+        return (Popen.duplicate_for_child(sl.handle), sl.kind, sl.maxvalue)
+
+    def __setstate__(self, state):
+        self._semlock = _multiprocessing.SemLock._rebuild(*state)
+        debug('recreated blocker with handle %r' % state[0])
+        self._make_methods()
+
+#
+# Semaphore
+#
+
+class Semaphore(SemLock):
+
+    def __init__(self, value=1):
+        SemLock.__init__(self, SEMAPHORE, value, SEM_VALUE_MAX)
+
+    def get_value(self):
+        return self._semlock._get_value()
+
+    def __repr__(self):
+        try:
+            value = self._semlock._get_value()
+        except Exception:
+            value = 'unknown'
+        return '<Semaphore(value=%s)>' % value
+
+#
+# Bounded semaphore
+#
+
+class BoundedSemaphore(Semaphore):
+
+    def __init__(self, value=1):
+        SemLock.__init__(self, SEMAPHORE, value, value)
+
+    def __repr__(self):
+        try:
+            value = self._semlock._get_value()
+        except Exception:
+            value = 'unknown'
+        return '<BoundedSemaphore(value=%s, maxvalue=%s)>' % \
+               (value, self._semlock.maxvalue)
+
+#
+# Non-recursive lock
+#
+
+class Lock(SemLock):
+
+    def __init__(self):
+        SemLock.__init__(self, SEMAPHORE, 1, 1)
+
+    def __repr__(self):
+        try:
+            if self._semlock._is_mine():
+                name = current_process().name
+                if threading.current_thread().name != 'MainThread':
+                    name += '|' + threading.current_thread().name
+            elif self._semlock._get_value() == 1:
+                name = 'None'
+            elif self._semlock._count() > 0:
+                name = 'SomeOtherThread'
+            else:
+                name = 'SomeOtherProcess'
+        except Exception:
+            name = 'unknown'
+        return '<Lock(owner=%s)>' % name
+
+#
+# Recursive lock
+#
+
+class RLock(SemLock):
+
+    def __init__(self):
+        SemLock.__init__(self, RECURSIVE_MUTEX, 1, 1)
+
+    def __repr__(self):
+        try:
+            if self._semlock._is_mine():
+                name = current_process().name
+                if threading.current_thread().name != 'MainThread':
+                    name += '|' + threading.current_thread().name
+                count = self._semlock._count()
+            elif self._semlock._get_value() == 1:
+                name, count = 'None', 0
+            elif self._semlock._count() > 0:
+                name, count = 'SomeOtherThread', 'nonzero'
+            else:
+                name, count = 'SomeOtherProcess', 'nonzero'
+        except Exception:
+            name, count = 'unknown', 'unknown'
+        return '<RLock(%s, %s)>' % (name, count)
+
+#
+# Condition variable
+#
+
+class Condition(object):
+
+    def __init__(self, lock=None):
+        self._lock = lock or RLock()
+        self._sleeping_count = Semaphore(0)
+        self._woken_count = Semaphore(0)
+        self._wait_semaphore = Semaphore(0)
+        self._make_methods()
+
+    def __getstate__(self):
+        assert_spawning(self)
+        return (self._lock, self._sleeping_count,
+                self._woken_count, self._wait_semaphore)
+
+    def __setstate__(self, state):
+        (self._lock, self._sleeping_count,
+         self._woken_count, self._wait_semaphore) = state
+        self._make_methods()
+
+    def __enter__(self):
+        return self._lock.__enter__()
+
+    def __exit__(self, *args):
+        return self._lock.__exit__(*args)
+
+    def _make_methods(self):
+        self.acquire = self._lock.acquire
+        self.release = self._lock.release
+
+    def __repr__(self):
+        try:
+            num_waiters = (self._sleeping_count._semlock._get_value() -
+                           self._woken_count._semlock._get_value())
+        except Exception:
+            num_waiters = 'unknown'
+        return '<Condition(%s, %s)>' % (self._lock, num_waiters)
+
+    def wait(self, timeout=None):
+        assert self._lock._semlock._is_mine(), \
+               'must acquire() condition before using wait()'
+
+        # indicate that this thread is going to sleep
+        self._sleeping_count.release()
+
+        # release lock
+        count = self._lock._semlock._count()
+        for i in xrange(count):
+            self._lock.release()
+
+        try:
+            # wait for notification or timeout
+            self._wait_semaphore.acquire(True, timeout)
+        finally:
+            # indicate that this thread has woken
+            self._woken_count.release()
+
+            # reacquire lock
+            for i in xrange(count):
+                self._lock.acquire()
+
+    def notify(self):
+        assert self._lock._semlock._is_mine(), 'lock is not owned'
+        assert not self._wait_semaphore.acquire(False)
+
+        # to take account of timeouts since last notify() we subtract
+        # woken_count from sleeping_count and rezero woken_count
+        while self._woken_count.acquire(False):
+            res = self._sleeping_count.acquire(False)
+            assert res
+
+        if self._sleeping_count.acquire(False): # try grabbing a sleeper
+            self._wait_semaphore.release()      # wake up one sleeper
+            self._woken_count.acquire()         # wait for the sleeper to wake
+
+            # rezero _wait_semaphore in case a timeout just happened
+            self._wait_semaphore.acquire(False)
+
+    def notify_all(self):
+        assert self._lock._semlock._is_mine(), 'lock is not owned'
+        assert not self._wait_semaphore.acquire(False)
+
+        # to take account of timeouts since last notify*() we subtract
+        # woken_count from sleeping_count and rezero woken_count
+        while self._woken_count.acquire(False):
+            res = self._sleeping_count.acquire(False)
+            assert res
+
+        sleepers = 0
+        while self._sleeping_count.acquire(False):
+            self._wait_semaphore.release()        # wake up one sleeper
+            sleepers += 1
+
+        if sleepers:
+            for i in xrange(sleepers):
+                self._woken_count.acquire()       # wait for a sleeper to wake
+
+            # rezero wait_semaphore in case some timeouts just happened
+            while self._wait_semaphore.acquire(False):
+                pass
+
+#
+# Event
+#
+
+class Event(object):
+
+    def __init__(self):
+        self._cond = Condition(Lock())
+        self._flag = Semaphore(0)
+
+    def is_set(self):
+        self._cond.acquire()
+        try:
+            if self._flag.acquire(False):
+                self._flag.release()
+                return True
+            return False
+        finally:
+            self._cond.release()
+
+    def set(self):
+        self._cond.acquire()
+        try:
+            self._flag.acquire(False)
+            self._flag.release()
+            self._cond.notify_all()
+        finally:
+            self._cond.release()
+
+    def clear(self):
+        self._cond.acquire()
+        try:
+            self._flag.acquire(False)
+        finally:
+            self._cond.release()
+
+    def wait(self, timeout=None):
+        self._cond.acquire()
+        try:
+            if self._flag.acquire(False):
+                self._flag.release()
+            else:
+                self._cond.wait(timeout)
+
+            if self._flag.acquire(False):
+                self._flag.release()
+                return True
+            return False
+        finally:
+            self._cond.release()
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_modules/unittest/case.html b/doc/_build/html/_modules/unittest/case.html new file mode 100644 index 00000000..535cf9ec --- /dev/null +++ b/doc/_build/html/_modules/unittest/case.html @@ -0,0 +1,1168 @@ + + + + + + + + unittest.case — GPy documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for unittest.case

+"""Test case implementation"""
+
+import collections
+import sys
+import functools
+import difflib
+import pprint
+import re
+import types
+import warnings
+
+from . import result
+from .util import (
+    strclass, safe_repr, unorderable_list_difference,
+    _count_diff_all_purpose, _count_diff_hashable
+)
+
+
+__unittest = True
+
+
+DIFF_OMITTED = ('\nDiff is %s characters long. '
+                 'Set self.maxDiff to None to see it.')
+
+class SkipTest(Exception):
+    """
+    Raise this exception in a test to skip it.
+
+    Usually you can use TestCase.skipTest() or one of the skipping decorators
+    instead of raising this directly.
+    """
+    pass
+
+class _ExpectedFailure(Exception):
+    """
+    Raise this when a test is expected to fail.
+
+    This is an implementation detail.
+    """
+
+    def __init__(self, exc_info):
+        super(_ExpectedFailure, self).__init__()
+        self.exc_info = exc_info
+
+class _UnexpectedSuccess(Exception):
+    """
+    The test was supposed to fail, but it didn't!
+    """
+    pass
+
+def _id(obj):
+    return obj
+
+def skip(reason):
+    """
+    Unconditionally skip a test.
+    """
+    def decorator(test_item):
+        if not isinstance(test_item, (type, types.ClassType)):
+            @functools.wraps(test_item)
+            def skip_wrapper(*args, **kwargs):
+                raise SkipTest(reason)
+            test_item = skip_wrapper
+
+        test_item.__unittest_skip__ = True
+        test_item.__unittest_skip_why__ = reason
+        return test_item
+    return decorator
+
+def skipIf(condition, reason):
+    """
+    Skip a test if the condition is true.
+    """
+    if condition:
+        return skip(reason)
+    return _id
+
+def skipUnless(condition, reason):
+    """
+    Skip a test unless the condition is true.
+    """
+    if not condition:
+        return skip(reason)
+    return _id
+
+
+def expectedFailure(func):
+    @functools.wraps(func)
+    def wrapper(*args, **kwargs):
+        try:
+            func(*args, **kwargs)
+        except Exception:
+            raise _ExpectedFailure(sys.exc_info())
+        raise _UnexpectedSuccess
+    return wrapper
+
+
+class _AssertRaisesContext(object):
+    """A context manager used to implement TestCase.assertRaises* methods."""
+
+    def __init__(self, expected, test_case, expected_regexp=None):
+        self.expected = expected
+        self.failureException = test_case.failureException
+        self.expected_regexp = expected_regexp
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_value, tb):
+        if exc_type is None:
+            try:
+                exc_name = self.expected.__name__
+            except AttributeError:
+                exc_name = str(self.expected)
+            raise self.failureException(
+                "{0} not raised".format(exc_name))
+        if not issubclass(exc_type, self.expected):
+            # let unexpected exceptions pass through
+            return False
+        self.exception = exc_value # store for later retrieval
+        if self.expected_regexp is None:
+            return True
+
+        expected_regexp = self.expected_regexp
+        if not expected_regexp.search(str(exc_value)):
+            raise self.failureException('"%s" does not match "%s"' %
+                     (expected_regexp.pattern, str(exc_value)))
+        return True
+
+
+class TestCase(object):
+    """A class whose instances are single test cases.
+
+    By default, the test code itself should be placed in a method named
+    'runTest'.
+
+    If the fixture may be used for many test cases, create as
+    many test methods as are needed. When instantiating such a TestCase
+    subclass, specify in the constructor arguments the name of the test method
+    that the instance is to execute.
+
+    Test authors should subclass TestCase for their own tests. Construction
+    and deconstruction of the test's environment ('fixture') can be
+    implemented by overriding the 'setUp' and 'tearDown' methods respectively.
+
+    If it is necessary to override the __init__ method, the base class
+    __init__ method must always be called. It is important that subclasses
+    should not change the signature of their __init__ method, since instances
+    of the classes are instantiated automatically by parts of the framework
+    in order to be run.
+
+    When subclassing TestCase, you can set these attributes:
+    * failureException: determines which exception will be raised when
+        the instance's assertion methods fail; test methods raising this
+        exception will be deemed to have 'failed' rather than 'errored'.
+    * longMessage: determines whether long messages (including repr of
+        objects used in assert methods) will be printed on failure in *addition*
+        to any explicit message passed.
+    * maxDiff: sets the maximum length of a diff in failure messages
+        by assert methods using difflib. It is looked up as an instance
+        attribute so can be configured by individual tests if required.
+    """
+
+    failureException = AssertionError
+
+    longMessage = False
+
+    maxDiff = 80*8
+
+    # If a string is longer than _diffThreshold, use normal comparison instead
+    # of difflib.  See #11763.
+    _diffThreshold = 2**16
+
+    # Attribute used by TestSuite for classSetUp
+
+    _classSetupFailed = False
+
+    def __init__(self, methodName='runTest'):
+        """Create an instance of the class that will use the named test
+           method when executed. Raises a ValueError if the instance does
+           not have a method with the specified name.
+        """
+        self._testMethodName = methodName
+        self._resultForDoCleanups = None
+        try:
+            testMethod = getattr(self, methodName)
+        except AttributeError:
+            raise ValueError("no such test method in %s: %s" %
+                  (self.__class__, methodName))
+        self._testMethodDoc = testMethod.__doc__
+        self._cleanups = []
+
+        # Map types to custom assertEqual functions that will compare
+        # instances of said type in more detail to generate a more useful
+        # error message.
+        self._type_equality_funcs = {}
+        self.addTypeEqualityFunc(dict, 'assertDictEqual')
+        self.addTypeEqualityFunc(list, 'assertListEqual')
+        self.addTypeEqualityFunc(tuple, 'assertTupleEqual')
+        self.addTypeEqualityFunc(set, 'assertSetEqual')
+        self.addTypeEqualityFunc(frozenset, 'assertSetEqual')
+        try:
+            self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual')
+        except NameError:
+            # No unicode support in this build
+            pass
+
+    def addTypeEqualityFunc(self, typeobj, function):
+        """Add a type specific assertEqual style function to compare a type.
+
+        This method is for use by TestCase subclasses that need to register
+        their own type equality functions to provide nicer error messages.
+
+        Args:
+            typeobj: The data type to call this function on when both values
+                    are of the same type in assertEqual().
+            function: The callable taking two arguments and an optional
+                    msg= argument that raises self.failureException with a
+                    useful error message when the two arguments are not equal.
+        """
+        self._type_equality_funcs[typeobj] = function
+
+    def addCleanup(self, function, *args, **kwargs):
+        """Add a function, with arguments, to be called when the test is
+        completed. Functions added are called on a LIFO basis and are
+        called after tearDown on test failure or success.
+
+        Cleanup items are called even if setUp fails (unlike tearDown)."""
+        self._cleanups.append((function, args, kwargs))
+
+    def setUp(self):
+        "Hook method for setting up the test fixture before exercising it."
+        pass
+
+    def tearDown(self):
+        "Hook method for deconstructing the test fixture after testing it."
+        pass
+
+    @classmethod
+    def setUpClass(cls):
+        "Hook method for setting up class fixture before running tests in the class."
+
+    @classmethod
+    def tearDownClass(cls):
+        "Hook method for deconstructing the class fixture after running all tests in the class."
+
+    def countTestCases(self):
+        return 1
+
+    def defaultTestResult(self):
+        return result.TestResult()
+
+    def shortDescription(self):
+        """Returns a one-line description of the test, or None if no
+        description has been provided.
+
+        The default implementation of this method returns the first line of
+        the specified test method's docstring.
+        """
+        doc = self._testMethodDoc
+        return doc and doc.split("\n")[0].strip() or None
+
+
+    def id(self):
+        return "%s.%s" % (strclass(self.__class__), self._testMethodName)
+
+    def __eq__(self, other):
+        if type(self) is not type(other):
+            return NotImplemented
+
+        return self._testMethodName == other._testMethodName
+
+    def __ne__(self, other):
+        return not self == other
+
+    def __hash__(self):
+        return hash((type(self), self._testMethodName))
+
+    def __str__(self):
+        return "%s (%s)" % (self._testMethodName, strclass(self.__class__))
+
+    def __repr__(self):
+        return "<%s testMethod=%s>" % \
+               (strclass(self.__class__), self._testMethodName)
+
+    def _addSkip(self, result, reason):
+        addSkip = getattr(result, 'addSkip', None)
+        if addSkip is not None:
+            addSkip(self, reason)
+        else:
+            warnings.warn("TestResult has no addSkip method, skips not reported",
+                          RuntimeWarning, 2)
+            result.addSuccess(self)
+
+    def run(self, result=None):
+        orig_result = result
+        if result is None:
+            result = self.defaultTestResult()
+            startTestRun = getattr(result, 'startTestRun', None)
+            if startTestRun is not None:
+                startTestRun()
+
+        self._resultForDoCleanups = result
+        result.startTest(self)
+
+        testMethod = getattr(self, self._testMethodName)
+        if (getattr(self.__class__, "__unittest_skip__", False) or
+            getattr(testMethod, "__unittest_skip__", False)):
+            # If the class or method was skipped.
+            try:
+                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
+                            or getattr(testMethod, '__unittest_skip_why__', ''))
+                self._addSkip(result, skip_why)
+            finally:
+                result.stopTest(self)
+            return
+        try:
+            success = False
+            try:
+                self.setUp()
+            except SkipTest as e:
+                self._addSkip(result, str(e))
+            except KeyboardInterrupt:
+                raise
+            except:
+                result.addError(self, sys.exc_info())
+            else:
+                try:
+                    testMethod()
+                except KeyboardInterrupt:
+                    raise
+                except self.failureException:
+                    result.addFailure(self, sys.exc_info())
+                except _ExpectedFailure as e:
+                    addExpectedFailure = getattr(result, 'addExpectedFailure', None)
+                    if addExpectedFailure is not None:
+                        addExpectedFailure(self, e.exc_info)
+                    else:
+                        warnings.warn("TestResult has no addExpectedFailure method, reporting as passes",
+                                      RuntimeWarning)
+                        result.addSuccess(self)
+                except _UnexpectedSuccess:
+                    addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
+                    if addUnexpectedSuccess is not None:
+                        addUnexpectedSuccess(self)
+                    else:
+                        warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures",
+                                      RuntimeWarning)
+                        result.addFailure(self, sys.exc_info())
+                except SkipTest as e:
+                    self._addSkip(result, str(e))
+                except:
+                    result.addError(self, sys.exc_info())
+                else:
+                    success = True
+
+                try:
+                    self.tearDown()
+                except KeyboardInterrupt:
+                    raise
+                except:
+                    result.addError(self, sys.exc_info())
+                    success = False
+
+            cleanUpSuccess = self.doCleanups()
+            success = success and cleanUpSuccess
+            if success:
+                result.addSuccess(self)
+        finally:
+            result.stopTest(self)
+            if orig_result is None:
+                stopTestRun = getattr(result, 'stopTestRun', None)
+                if stopTestRun is not None:
+                    stopTestRun()
+
+    def doCleanups(self):
+        """Execute all cleanup functions. Normally called for you after
+        tearDown."""
+        result = self._resultForDoCleanups
+        ok = True
+        while self._cleanups:
+            function, args, kwargs = self._cleanups.pop(-1)
+            try:
+                function(*args, **kwargs)
+            except KeyboardInterrupt:
+                raise
+            except:
+                ok = False
+                result.addError(self, sys.exc_info())
+        return ok
+
+    def __call__(self, *args, **kwds):
+        return self.run(*args, **kwds)
+
+    def debug(self):
+        """Run the test without collecting errors in a TestResult"""
+        self.setUp()
+        getattr(self, self._testMethodName)()
+        self.tearDown()
+        while self._cleanups:
+            function, args, kwargs = self._cleanups.pop(-1)
+            function(*args, **kwargs)
+
+    def skipTest(self, reason):
+        """Skip this test."""
+        raise SkipTest(reason)
+
+    def fail(self, msg=None):
+        """Fail immediately, with the given message."""
+        raise self.failureException(msg)
+
+    def assertFalse(self, expr, msg=None):
+        """Check that the expression is false."""
+        if expr:
+            msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr))
+            raise self.failureException(msg)
+
+    def assertTrue(self, expr, msg=None):
+        """Check that the expression is true."""
+        if not expr:
+            msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr))
+            raise self.failureException(msg)
+
+    def _formatMessage(self, msg, standardMsg):
+        """Honour the longMessage attribute when generating failure messages.
+        If longMessage is False this means:
+        * Use only an explicit message if it is provided
+        * Otherwise use the standard message for the assert
+
+        If longMessage is True:
+        * Use the standard message
+        * If an explicit message is provided, plus ' : ' and the explicit message
+        """
+        if not self.longMessage:
+            return msg or standardMsg
+        if msg is None:
+            return standardMsg
+        try:
+            # don't switch to '{}' formatting in Python 2.X
+            # it changes the way unicode input is handled
+            return '%s : %s' % (standardMsg, msg)
+        except UnicodeDecodeError:
+            return  '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
+
+
+    def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
+        """Fail unless an exception of class excClass is raised
+           by callableObj when invoked with arguments args and keyword
+           arguments kwargs. If a different type of exception is
+           raised, it will not be caught, and the test case will be
+           deemed to have suffered an error, exactly as for an
+           unexpected exception.
+
+           If called with callableObj omitted or None, will return a
+           context object used like this::
+
+                with self.assertRaises(SomeException):
+                    do_something()
+
+           The context manager keeps a reference to the exception as
+           the 'exception' attribute. This allows you to inspect the
+           exception after the assertion::
+
+               with self.assertRaises(SomeException) as cm:
+                   do_something()
+               the_exception = cm.exception
+               self.assertEqual(the_exception.error_code, 3)
+        """
+        context = _AssertRaisesContext(excClass, self)
+        if callableObj is None:
+            return context
+        with context:
+            callableObj(*args, **kwargs)
+
+    def _getAssertEqualityFunc(self, first, second):
+        """Get a detailed comparison function for the types of the two args.
+
+        Returns: A callable accepting (first, second, msg=None) that will
+        raise a failure exception if first != second with a useful human
+        readable error message for those types.
+        """
+        #
+        # NOTE(gregory.p.smith): I considered isinstance(first, type(second))
+        # and vice versa.  I opted for the conservative approach in case
+        # subclasses are not intended to be compared in detail to their super
+        # class instances using a type equality func.  This means testing
+        # subtypes won't automagically use the detailed comparison.  Callers
+        # should use their type specific assertSpamEqual method to compare
+        # subclasses if the detailed comparison is desired and appropriate.
+        # See the discussion in http://bugs.python.org/issue2578.
+        #
+        if type(first) is type(second):
+            asserter = self._type_equality_funcs.get(type(first))
+            if asserter is not None:
+                if isinstance(asserter, basestring):
+                    asserter = getattr(self, asserter)
+                return asserter
+
+        return self._baseAssertEqual
+
+    def _baseAssertEqual(self, first, second, msg=None):
+        """The default assertEqual implementation, not type specific."""
+        if not first == second:
+            standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second))
+            msg = self._formatMessage(msg, standardMsg)
+            raise self.failureException(msg)
+
+    def assertEqual(self, first, second, msg=None):
+        """Fail if the two objects are unequal as determined by the '=='
+           operator.
+        """
+        assertion_func = self._getAssertEqualityFunc(first, second)
+        assertion_func(first, second, msg=msg)
+
+    def assertNotEqual(self, first, second, msg=None):
+        """Fail if the two objects are equal as determined by the '!='
+           operator.
+        """
+        if not first != second:
+            msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first),
+                                                          safe_repr(second)))
+            raise self.failureException(msg)
+
+
+    def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None):
+        """Fail if the two objects are unequal as determined by their
+           difference rounded to the given number of decimal places
+           (default 7) and comparing to zero, or by comparing that the
+           between the two objects is more than the given delta.
+
+           Note that decimal places (from zero) are usually not the same
+           as significant digits (measured from the most signficant digit).
+
+           If the two objects compare equal then they will automatically
+           compare almost equal.
+        """
+        if first == second:
+            # shortcut
+            return
+        if delta is not None and places is not None:
+            raise TypeError("specify delta or places not both")
+
+        if delta is not None:
+            if abs(first - second) <= delta:
+                return
+
+            standardMsg = '%s != %s within %s delta' % (safe_repr(first),
+                                                        safe_repr(second),
+                                                        safe_repr(delta))
+        else:
+            if places is None:
+                places = 7
+
+            if round(abs(second-first), places) == 0:
+                return
+
+            standardMsg = '%s != %s within %r places' % (safe_repr(first),
+                                                          safe_repr(second),
+                                                          places)
+        msg = self._formatMessage(msg, standardMsg)
+        raise self.failureException(msg)
+
+    def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None):
+        """Fail if the two objects are equal as determined by their
+           difference rounded to the given number of decimal places
+           (default 7) and comparing to zero, or by comparing that the
+           between the two objects is less than the given delta.
+
+           Note that decimal places (from zero) are usually not the same
+           as significant digits (measured from the most signficant digit).
+
+           Objects that are equal automatically fail.
+        """
+        if delta is not None and places is not None:
+            raise TypeError("specify delta or places not both")
+        if delta is not None:
+            if not (first == second) and abs(first - second) > delta:
+                return
+            standardMsg = '%s == %s within %s delta' % (safe_repr(first),
+                                                        safe_repr(second),
+                                                        safe_repr(delta))
+        else:
+            if places is None:
+                places = 7
+            if not (first == second) and round(abs(second-first), places) != 0:
+                return
+            standardMsg = '%s == %s within %r places' % (safe_repr(first),
+                                                         safe_repr(second),
+                                                         places)
+
+        msg = self._formatMessage(msg, standardMsg)
+        raise self.failureException(msg)
+
+    # Synonyms for assertion methods
+
+    # The plurals are undocumented.  Keep them that way to discourage use.
+    # Do not add more.  Do not remove.
+    # Going through a deprecation cycle on these would annoy many people.
+    assertEquals = assertEqual
+    assertNotEquals = assertNotEqual
+    assertAlmostEquals = assertAlmostEqual
+    assertNotAlmostEquals = assertNotAlmostEqual
+    assert_ = assertTrue
+
+    # These fail* assertion method names are pending deprecation and will
+    # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578
+    def _deprecate(original_func):
+        def deprecated_func(*args, **kwargs):
+            warnings.warn(
+                'Please use {0} instead.'.format(original_func.__name__),
+                PendingDeprecationWarning, 2)
+            return original_func(*args, **kwargs)
+        return deprecated_func
+
+    failUnlessEqual = _deprecate(assertEqual)
+    failIfEqual = _deprecate(assertNotEqual)
+    failUnlessAlmostEqual = _deprecate(assertAlmostEqual)
+    failIfAlmostEqual = _deprecate(assertNotAlmostEqual)
+    failUnless = _deprecate(assertTrue)
+    failUnlessRaises = _deprecate(assertRaises)
+    failIf = _deprecate(assertFalse)
+
+    def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
+        """An equality assertion for ordered sequences (like lists and tuples).
+
+        For the purposes of this function, a valid ordered sequence type is one
+        which can be indexed, has a length, and has an equality operator.
+
+        Args:
+            seq1: The first sequence to compare.
+            seq2: The second sequence to compare.
+            seq_type: The expected datatype of the sequences, or None if no
+                    datatype should be enforced.
+            msg: Optional message to use on failure instead of a list of
+                    differences.
+        """
+        if seq_type is not None:
+            seq_type_name = seq_type.__name__
+            if not isinstance(seq1, seq_type):
+                raise self.failureException('First sequence is not a %s: %s'
+                                        % (seq_type_name, safe_repr(seq1)))
+            if not isinstance(seq2, seq_type):
+                raise self.failureException('Second sequence is not a %s: %s'
+                                        % (seq_type_name, safe_repr(seq2)))
+        else:
+            seq_type_name = "sequence"
+
+        differing = None
+        try:
+            len1 = len(seq1)
+        except (TypeError, NotImplementedError):
+            differing = 'First %s has no length.    Non-sequence?' % (
+                    seq_type_name)
+
+        if differing is None:
+            try:
+                len2 = len(seq2)
+            except (TypeError, NotImplementedError):
+                differing = 'Second %s has no length.    Non-sequence?' % (
+                        seq_type_name)
+
+        if differing is None:
+            if seq1 == seq2:
+                return
+
+            seq1_repr = safe_repr(seq1)
+            seq2_repr = safe_repr(seq2)
+            if len(seq1_repr) > 30:
+                seq1_repr = seq1_repr[:30] + '...'
+            if len(seq2_repr) > 30:
+                seq2_repr = seq2_repr[:30] + '...'
+            elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr)
+            differing = '%ss differ: %s != %s\n' % elements
+
+            for i in xrange(min(len1, len2)):
+                try:
+                    item1 = seq1[i]
+                except (TypeError, IndexError, NotImplementedError):
+                    differing += ('\nUnable to index element %d of first %s\n' %
+                                 (i, seq_type_name))
+                    break
+
+                try:
+                    item2 = seq2[i]
+                except (TypeError, IndexError, NotImplementedError):
+                    differing += ('\nUnable to index element %d of second %s\n' %
+                                 (i, seq_type_name))
+                    break
+
+                if item1 != item2:
+                    differing += ('\nFirst differing element %d:\n%s\n%s\n' %
+                                 (i, item1, item2))
+                    break
+            else:
+                if (len1 == len2 and seq_type is None and
+                    type(seq1) != type(seq2)):
+                    # The sequences are the same, but have differing types.
+                    return
+
+            if len1 > len2:
+                differing += ('\nFirst %s contains %d additional '
+                             'elements.\n' % (seq_type_name, len1 - len2))
+                try:
+                    differing += ('First extra element %d:\n%s\n' %
+                                  (len2, seq1[len2]))
+                except (TypeError, IndexError, NotImplementedError):
+                    differing += ('Unable to index element %d '
+                                  'of first %s\n' % (len2, seq_type_name))
+            elif len1 < len2:
+                differing += ('\nSecond %s contains %d additional '
+                             'elements.\n' % (seq_type_name, len2 - len1))
+                try:
+                    differing += ('First extra element %d:\n%s\n' %
+                                  (len1, seq2[len1]))
+                except (TypeError, IndexError, NotImplementedError):
+                    differing += ('Unable to index element %d '
+                                  'of second %s\n' % (len1, seq_type_name))
+        standardMsg = differing
+        diffMsg = '\n' + '\n'.join(
+            difflib.ndiff(pprint.pformat(seq1).splitlines(),
+                          pprint.pformat(seq2).splitlines()))
+        standardMsg = self._truncateMessage(standardMsg, diffMsg)
+        msg = self._formatMessage(msg, standardMsg)
+        self.fail(msg)
+
+    def _truncateMessage(self, message, diff):
+        max_diff = self.maxDiff
+        if max_diff is None or len(diff) <= max_diff:
+            return message + diff
+        return message + (DIFF_OMITTED % len(diff))
+
+    def assertListEqual(self, list1, list2, msg=None):
+        """A list-specific equality assertion.
+
+        Args:
+            list1: The first list to compare.
+            list2: The second list to compare.
+            msg: Optional message to use on failure instead of a list of
+                    differences.
+
+        """
+        self.assertSequenceEqual(list1, list2, msg, seq_type=list)
+
+    def assertTupleEqual(self, tuple1, tuple2, msg=None):
+        """A tuple-specific equality assertion.
+
+        Args:
+            tuple1: The first tuple to compare.
+            tuple2: The second tuple to compare.
+            msg: Optional message to use on failure instead of a list of
+                    differences.
+        """
+        self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple)
+
+    def assertSetEqual(self, set1, set2, msg=None):
+        """A set-specific equality assertion.
+
+        Args:
+            set1: The first set to compare.
+            set2: The second set to compare.
+            msg: Optional message to use on failure instead of a list of
+                    differences.
+
+        assertSetEqual uses ducktyping to support different types of sets, and
+        is optimized for sets specifically (parameters must support a
+        difference method).
+        """
+        try:
+            difference1 = set1.difference(set2)
+        except TypeError, e:
+            self.fail('invalid type when attempting set difference: %s' % e)
+        except AttributeError, e:
+            self.fail('first argument does not support set difference: %s' % e)
+
+        try:
+            difference2 = set2.difference(set1)
+        except TypeError, e:
+            self.fail('invalid type when attempting set difference: %s' % e)
+        except AttributeError, e:
+            self.fail('second argument does not support set difference: %s' % e)
+
+        if not (difference1 or difference2):
+            return
+
+        lines = []
+        if difference1:
+            lines.append('Items in the first set but not the second:')
+            for item in difference1:
+                lines.append(repr(item))
+        if difference2:
+            lines.append('Items in the second set but not the first:')
+            for item in difference2:
+                lines.append(repr(item))
+
+        standardMsg = '\n'.join(lines)
+        self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertIn(self, member, container, msg=None):
+        """Just like self.assertTrue(a in b), but with a nicer default message."""
+        if member not in container:
+            standardMsg = '%s not found in %s' % (safe_repr(member),
+                                                  safe_repr(container))
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertNotIn(self, member, container, msg=None):
+        """Just like self.assertTrue(a not in b), but with a nicer default message."""
+        if member in container:
+            standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
+                                                        safe_repr(container))
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertIs(self, expr1, expr2, msg=None):
+        """Just like self.assertTrue(a is b), but with a nicer default message."""
+        if expr1 is not expr2:
+            standardMsg = '%s is not %s' % (safe_repr(expr1),
+                                             safe_repr(expr2))
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertIsNot(self, expr1, expr2, msg=None):
+        """Just like self.assertTrue(a is not b), but with a nicer default message."""
+        if expr1 is expr2:
+            standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),)
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertDictEqual(self, d1, d2, msg=None):
+        self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
+        self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
+
+        if d1 != d2:
+            standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True))
+            diff = ('\n' + '\n'.join(difflib.ndiff(
+                           pprint.pformat(d1).splitlines(),
+                           pprint.pformat(d2).splitlines())))
+            standardMsg = self._truncateMessage(standardMsg, diff)
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertDictContainsSubset(self, expected, actual, msg=None):
+        """Checks whether actual is a superset of expected."""
+        missing = []
+        mismatched = []
+        for key, value in expected.iteritems():
+            if key not in actual:
+                missing.append(key)
+            elif value != actual[key]:
+                mismatched.append('%s, expected: %s, actual: %s' %
+                                  (safe_repr(key), safe_repr(value),
+                                   safe_repr(actual[key])))
+
+        if not (missing or mismatched):
+            return
+
+        standardMsg = ''
+        if missing:
+            standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in
+                                                    missing)
+        if mismatched:
+            if standardMsg:
+                standardMsg += '; '
+            standardMsg += 'Mismatched values: %s' % ','.join(mismatched)
+
+        self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertItemsEqual(self, expected_seq, actual_seq, msg=None):
+        """An unordered sequence specific comparison. It asserts that
+        actual_seq and expected_seq have the same element counts.
+        Equivalent to::
+
+            self.assertEqual(Counter(iter(actual_seq)),
+                             Counter(iter(expected_seq)))
+
+        Asserts that each element has the same count in both sequences.
+        Example:
+            - [0, 1, 1] and [1, 0, 1] compare equal.
+            - [0, 0, 1] and [0, 1] compare unequal.
+        """
+        first_seq, second_seq = list(expected_seq), list(actual_seq)
+        with warnings.catch_warnings():
+            if sys.py3kwarning:
+                # Silence Py3k warning raised during the sorting
+                for _msg in ["(code|dict|type) inequality comparisons",
+                             "builtin_function_or_method order comparisons",
+                             "comparing unequal types"]:
+                    warnings.filterwarnings("ignore", _msg, DeprecationWarning)
+            try:
+                first = collections.Counter(first_seq)
+                second = collections.Counter(second_seq)
+            except TypeError:
+                # Handle case with unhashable elements
+                differences = _count_diff_all_purpose(first_seq, second_seq)
+            else:
+                if first == second:
+                    return
+                differences = _count_diff_hashable(first_seq, second_seq)
+
+        if differences:
+            standardMsg = 'Element counts were not equal:\n'
+            lines = ['First has %d, Second has %d:  %r' % diff for diff in differences]
+            diffMsg = '\n'.join(lines)
+            standardMsg = self._truncateMessage(standardMsg, diffMsg)
+            msg = self._formatMessage(msg, standardMsg)
+            self.fail(msg)
+
+    def assertMultiLineEqual(self, first, second, msg=None):
+        """Assert that two multi-line strings are equal."""
+        self.assertIsInstance(first, basestring,
+                'First argument is not a string')
+        self.assertIsInstance(second, basestring,
+                'Second argument is not a string')
+
+        if first != second:
+            # don't use difflib if the strings are too long
+            if (len(first) > self._diffThreshold or
+                len(second) > self._diffThreshold):
+                self._baseAssertEqual(first, second, msg)
+            firstlines = first.splitlines(True)
+            secondlines = second.splitlines(True)
+            if len(firstlines) == 1 and first.strip('\r\n') == first:
+                firstlines = [first + '\n']
+                secondlines = [second + '\n']
+            standardMsg = '%s != %s' % (safe_repr(first, True),
+                                        safe_repr(second, True))
+            diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
+            standardMsg = self._truncateMessage(standardMsg, diff)
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertLess(self, a, b, msg=None):
+        """Just like self.assertTrue(a < b), but with a nicer default message."""
+        if not a < b:
+            standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b))
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertLessEqual(self, a, b, msg=None):
+        """Just like self.assertTrue(a <= b), but with a nicer default message."""
+        if not a <= b:
+            standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b))
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertGreater(self, a, b, msg=None):
+        """Just like self.assertTrue(a > b), but with a nicer default message."""
+        if not a > b:
+            standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b))
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertGreaterEqual(self, a, b, msg=None):
+        """Just like self.assertTrue(a >= b), but with a nicer default message."""
+        if not a >= b:
+            standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b))
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertIsNone(self, obj, msg=None):
+        """Same as self.assertTrue(obj is None), with a nicer default message."""
+        if obj is not None:
+            standardMsg = '%s is not None' % (safe_repr(obj),)
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertIsNotNone(self, obj, msg=None):
+        """Included for symmetry with assertIsNone."""
+        if obj is None:
+            standardMsg = 'unexpectedly None'
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertIsInstance(self, obj, cls, msg=None):
+        """Same as self.assertTrue(isinstance(obj, cls)), with a nicer
+        default message."""
+        if not isinstance(obj, cls):
+            standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls)
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertNotIsInstance(self, obj, cls, msg=None):
+        """Included for symmetry with assertIsInstance."""
+        if isinstance(obj, cls):
+            standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls)
+            self.fail(self._formatMessage(msg, standardMsg))
+
+    def assertRaisesRegexp(self, expected_exception, expected_regexp,
+                           callable_obj=None, *args, **kwargs):
+        """Asserts that the message in a raised exception matches a regexp.
+
+        Args:
+            expected_exception: Exception class expected to be raised.
+            expected_regexp: Regexp (re pattern object or string) expected
+                    to be found in error message.
+            callable_obj: Function to be called.
+            args: Extra args.
+            kwargs: Extra kwargs.
+        """
+        if expected_regexp is not None:
+            expected_regexp = re.compile(expected_regexp)
+        context = _AssertRaisesContext(expected_exception, self, expected_regexp)
+        if callable_obj is None:
+            return context
+        with context:
+            callable_obj(*args, **kwargs)
+
+    def assertRegexpMatches(self, text, expected_regexp, msg=None):
+        """Fail the test unless the text matches the regular expression."""
+        if isinstance(expected_regexp, basestring):
+            expected_regexp = re.compile(expected_regexp)
+        if not expected_regexp.search(text):
+            msg = msg or "Regexp didn't match"
+            msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text)
+            raise self.failureException(msg)
+
+    def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None):
+        """Fail the test if the text matches the regular expression."""
+        if isinstance(unexpected_regexp, basestring):
+            unexpected_regexp = re.compile(unexpected_regexp)
+        match = unexpected_regexp.search(text)
+        if match:
+            msg = msg or "Regexp matched"
+            msg = '%s: %r matches %r in %r' % (msg,
+                                               text[match.start():match.end()],
+                                               unexpected_regexp.pattern,
+                                               text)
+            raise self.failureException(msg)
+
+
+class FunctionTestCase(TestCase):
+    """A test case that wraps a test function.
+
+    This is useful for slipping pre-existing test functions into the
+    unittest framework. Optionally, set-up and tidy-up functions can be
+    supplied. As with TestCase, the tidy-up ('tearDown') function will
+    always be called if the set-up ('setUp') function ran successfully.
+    """
+
+    def __init__(self, testFunc, setUp=None, tearDown=None, description=None):
+        super(FunctionTestCase, self).__init__()
+        self._setUpFunc = setUp
+        self._tearDownFunc = tearDown
+        self._testFunc = testFunc
+        self._description = description
+
+    def setUp(self):
+        if self._setUpFunc is not None:
+            self._setUpFunc()
+
+    def tearDown(self):
+        if self._tearDownFunc is not None:
+            self._tearDownFunc()
+
+    def runTest(self):
+        self._testFunc()
+
+    def id(self):
+        return self._testFunc.__name__
+
+    def __eq__(self, other):
+        if not isinstance(other, self.__class__):
+            return NotImplemented
+
+        return self._setUpFunc == other._setUpFunc and \
+               self._tearDownFunc == other._tearDownFunc and \
+               self._testFunc == other._testFunc and \
+               self._description == other._description
+
+    def __ne__(self, other):
+        return not self == other
+
+    def __hash__(self):
+        return hash((type(self), self._setUpFunc, self._tearDownFunc,
+                     self._testFunc, self._description))
+
+    def __str__(self):
+        return "%s (%s)" % (strclass(self.__class__),
+                            self._testFunc.__name__)
+
+    def __repr__(self):
+        return "<%s tec=%s>" % (strclass(self.__class__),
+                                     self._testFunc)
+
+    def shortDescription(self):
+        if self._description is not None:
+            return self._description
+        doc = self._testFunc.__doc__
+        return doc and doc.split("\n")[0].strip() or None
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/doc/_build/html/_sources/GPy.core.parameterization.txt b/doc/_build/html/_sources/GPy.core.parameterization.txt new file mode 100644 index 00000000..4877a06d --- /dev/null +++ b/doc/_build/html/_sources/GPy.core.parameterization.txt @@ -0,0 +1,102 @@ +GPy.core.parameterization package +================================= + +Submodules +---------- + +GPy.core.parameterization.domains module +---------------------------------------- + +.. automodule:: GPy.core.parameterization.domains + :members: + :undoc-members: + :show-inheritance: + +GPy.core.parameterization.index_operations module +------------------------------------------------- + +.. automodule:: GPy.core.parameterization.index_operations + :members: + :undoc-members: + :show-inheritance: + +GPy.core.parameterization.lists_and_dicts module +------------------------------------------------ + +.. automodule:: GPy.core.parameterization.lists_and_dicts + :members: + :undoc-members: + :show-inheritance: + +GPy.core.parameterization.observable_array module +------------------------------------------------- + +.. automodule:: GPy.core.parameterization.observable_array + :members: + :undoc-members: + :show-inheritance: + +GPy.core.parameterization.param module +-------------------------------------- + +.. automodule:: GPy.core.parameterization.param + :members: + :undoc-members: + :show-inheritance: + +GPy.core.parameterization.parameter_core module +----------------------------------------------- + +.. automodule:: GPy.core.parameterization.parameter_core + :members: + :undoc-members: + :show-inheritance: + +GPy.core.parameterization.parameterized module +---------------------------------------------- + +.. automodule:: GPy.core.parameterization.parameterized + :members: + :undoc-members: + :show-inheritance: + +GPy.core.parameterization.priors module +--------------------------------------- + +.. automodule:: GPy.core.parameterization.priors + :members: + :undoc-members: + :show-inheritance: + +GPy.core.parameterization.ties_and_remappings module +---------------------------------------------------- + +.. automodule:: GPy.core.parameterization.ties_and_remappings + :members: + :undoc-members: + :show-inheritance: + +GPy.core.parameterization.transformations module +------------------------------------------------ + +.. automodule:: GPy.core.parameterization.transformations + :members: + :undoc-members: + :show-inheritance: + +GPy.core.parameterization.variational module +-------------------------------------------- + +.. automodule:: GPy.core.parameterization.variational + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.core.parameterization + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.core.txt b/doc/_build/html/_sources/GPy.core.txt new file mode 100644 index 00000000..3c236612 --- /dev/null +++ b/doc/_build/html/_sources/GPy.core.txt @@ -0,0 +1,77 @@ +GPy.core package +================ + +Subpackages +----------- + +.. toctree:: + + GPy.core.parameterization + +Submodules +---------- + +GPy.core.gp module +------------------ + +.. automodule:: GPy.core.gp + :members: + :undoc-members: + :show-inheritance: + +GPy.core.mapping module +----------------------- + +.. automodule:: GPy.core.mapping + :members: + :undoc-members: + :show-inheritance: + +GPy.core.model module +--------------------- + +.. automodule:: GPy.core.model + :members: + :undoc-members: + :show-inheritance: + +GPy.core.sparse_gp module +------------------------- + +.. automodule:: GPy.core.sparse_gp + :members: + :undoc-members: + :show-inheritance: + +GPy.core.sparse_gp_mpi module +----------------------------- + +.. automodule:: GPy.core.sparse_gp_mpi + :members: + :undoc-members: + :show-inheritance: + +GPy.core.svigp module +--------------------- + +.. automodule:: GPy.core.svigp + :members: + :undoc-members: + :show-inheritance: + +GPy.core.symbolic module +------------------------ + +.. automodule:: GPy.core.symbolic + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.core + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.examples.txt b/doc/_build/html/_sources/GPy.examples.txt new file mode 100644 index 00000000..7fc8a123 --- /dev/null +++ b/doc/_build/html/_sources/GPy.examples.txt @@ -0,0 +1,70 @@ +GPy.examples package +==================== + +Submodules +---------- + +GPy.examples.classification module +---------------------------------- + +.. automodule:: GPy.examples.classification + :members: + :undoc-members: + :show-inheritance: + +GPy.examples.coreg_example module +--------------------------------- + +.. automodule:: GPy.examples.coreg_example + :members: + :undoc-members: + :show-inheritance: + +GPy.examples.dimensionality_reduction module +-------------------------------------------- + +.. automodule:: GPy.examples.dimensionality_reduction + :members: + :undoc-members: + :show-inheritance: + +GPy.examples.non_gaussian module +-------------------------------- + +.. automodule:: GPy.examples.non_gaussian + :members: + :undoc-members: + :show-inheritance: + +GPy.examples.regression module +------------------------------ + +.. automodule:: GPy.examples.regression + :members: + :undoc-members: + :show-inheritance: + +GPy.examples.stochastic module +------------------------------ + +.. automodule:: GPy.examples.stochastic + :members: + :undoc-members: + :show-inheritance: + +GPy.examples.tutorials module +----------------------------- + +.. automodule:: GPy.examples.tutorials + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.examples + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.inference.latent_function_inference.txt b/doc/_build/html/_sources/GPy.inference.latent_function_inference.txt new file mode 100644 index 00000000..98d16705 --- /dev/null +++ b/doc/_build/html/_sources/GPy.inference.latent_function_inference.txt @@ -0,0 +1,102 @@ +GPy.inference.latent_function_inference package +=============================================== + +Submodules +---------- + +GPy.inference.latent_function_inference.dtc module +-------------------------------------------------- + +.. automodule:: GPy.inference.latent_function_inference.dtc + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.latent_function_inference.exact_gaussian_inference module +----------------------------------------------------------------------- + +.. automodule:: GPy.inference.latent_function_inference.exact_gaussian_inference + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.latent_function_inference.expectation_propagation module +---------------------------------------------------------------------- + +.. automodule:: GPy.inference.latent_function_inference.expectation_propagation + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.latent_function_inference.expectation_propagation_dtc module +-------------------------------------------------------------------------- + +.. automodule:: GPy.inference.latent_function_inference.expectation_propagation_dtc + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.latent_function_inference.fitc module +--------------------------------------------------- + +.. automodule:: GPy.inference.latent_function_inference.fitc + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.latent_function_inference.inferenceX module +--------------------------------------------------------- + +.. automodule:: GPy.inference.latent_function_inference.inferenceX + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.latent_function_inference.laplace module +------------------------------------------------------ + +.. automodule:: GPy.inference.latent_function_inference.laplace + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.latent_function_inference.posterior module +-------------------------------------------------------- + +.. automodule:: GPy.inference.latent_function_inference.posterior + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.latent_function_inference.var_dtc module +------------------------------------------------------ + +.. automodule:: GPy.inference.latent_function_inference.var_dtc + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.latent_function_inference.var_dtc_gpu module +---------------------------------------------------------- + +.. automodule:: GPy.inference.latent_function_inference.var_dtc_gpu + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.latent_function_inference.var_dtc_parallel module +--------------------------------------------------------------- + +.. automodule:: GPy.inference.latent_function_inference.var_dtc_parallel + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.inference.latent_function_inference + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.inference.mcmc.txt b/doc/_build/html/_sources/GPy.inference.mcmc.txt new file mode 100644 index 00000000..273658b7 --- /dev/null +++ b/doc/_build/html/_sources/GPy.inference.mcmc.txt @@ -0,0 +1,30 @@ +GPy.inference.mcmc package +========================== + +Submodules +---------- + +GPy.inference.mcmc.hmc module +----------------------------- + +.. automodule:: GPy.inference.mcmc.hmc + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.mcmc.samplers module +---------------------------------- + +.. automodule:: GPy.inference.mcmc.samplers + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.inference.mcmc + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.inference.optimization.txt b/doc/_build/html/_sources/GPy.inference.optimization.txt new file mode 100644 index 00000000..a81a8e68 --- /dev/null +++ b/doc/_build/html/_sources/GPy.inference.optimization.txt @@ -0,0 +1,62 @@ +GPy.inference.optimization package +================================== + +Submodules +---------- + +GPy.inference.optimization.conjugate_gradient_descent module +------------------------------------------------------------ + +.. automodule:: GPy.inference.optimization.conjugate_gradient_descent + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.optimization.gradient_descent_update_rules module +--------------------------------------------------------------- + +.. automodule:: GPy.inference.optimization.gradient_descent_update_rules + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.optimization.optimization module +---------------------------------------------- + +.. automodule:: GPy.inference.optimization.optimization + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.optimization.scg module +------------------------------------- + +.. automodule:: GPy.inference.optimization.scg + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.optimization.sgd module +------------------------------------- + +.. automodule:: GPy.inference.optimization.sgd + :members: + :undoc-members: + :show-inheritance: + +GPy.inference.optimization.stochastics module +--------------------------------------------- + +.. automodule:: GPy.inference.optimization.stochastics + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.inference.optimization + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.inference.txt b/doc/_build/html/_sources/GPy.inference.txt new file mode 100644 index 00000000..235f804b --- /dev/null +++ b/doc/_build/html/_sources/GPy.inference.txt @@ -0,0 +1,19 @@ +GPy.inference package +===================== + +Subpackages +----------- + +.. toctree:: + + GPy.inference.latent_function_inference + GPy.inference.mcmc + GPy.inference.optimization + +Module contents +--------------- + +.. automodule:: GPy.inference + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.kern._src.psi_comp.txt b/doc/_build/html/_sources/GPy.kern._src.psi_comp.txt new file mode 100644 index 00000000..d84eeaa0 --- /dev/null +++ b/doc/_build/html/_sources/GPy.kern._src.psi_comp.txt @@ -0,0 +1,62 @@ +GPy.kern._src.psi_comp package +============================== + +Submodules +---------- + +GPy.kern._src.psi_comp.linear_psi_comp module +--------------------------------------------- + +.. automodule:: GPy.kern._src.psi_comp.linear_psi_comp + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.psi_comp.rbf_psi_comp module +------------------------------------------ + +.. automodule:: GPy.kern._src.psi_comp.rbf_psi_comp + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.psi_comp.rbf_psi_gpucomp module +--------------------------------------------- + +.. automodule:: GPy.kern._src.psi_comp.rbf_psi_gpucomp + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.psi_comp.sslinear_psi_comp module +----------------------------------------------- + +.. automodule:: GPy.kern._src.psi_comp.sslinear_psi_comp + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.psi_comp.ssrbf_psi_comp module +-------------------------------------------- + +.. automodule:: GPy.kern._src.psi_comp.ssrbf_psi_comp + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.psi_comp.ssrbf_psi_gpucomp module +----------------------------------------------- + +.. automodule:: GPy.kern._src.psi_comp.ssrbf_psi_gpucomp + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.kern._src.psi_comp + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.kern._src.txt b/doc/_build/html/_sources/GPy.kern._src.txt new file mode 100644 index 00000000..93dc0058 --- /dev/null +++ b/doc/_build/html/_sources/GPy.kern._src.txt @@ -0,0 +1,197 @@ +GPy.kern._src package +===================== + +Subpackages +----------- + +.. toctree:: + + GPy.kern._src.psi_comp + +Submodules +---------- + +GPy.kern._src.ODE_UY module +--------------------------- + +.. automodule:: GPy.kern._src.ODE_UY + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.ODE_UYC module +---------------------------- + +.. automodule:: GPy.kern._src.ODE_UYC + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.ODE_st module +--------------------------- + +.. automodule:: GPy.kern._src.ODE_st + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.ODE_t module +-------------------------- + +.. automodule:: GPy.kern._src.ODE_t + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.add module +------------------------ + +.. automodule:: GPy.kern._src.add + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.brownian module +----------------------------- + +.. automodule:: GPy.kern._src.brownian + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.coregionalize module +---------------------------------- + +.. automodule:: GPy.kern._src.coregionalize + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.hierarchical module +--------------------------------- + +.. automodule:: GPy.kern._src.hierarchical + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.independent_outputs module +---------------------------------------- + +.. automodule:: GPy.kern._src.independent_outputs + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.kern module +------------------------- + +.. automodule:: GPy.kern._src.kern + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.kernel_slice_operations module +-------------------------------------------- + +.. automodule:: GPy.kern._src.kernel_slice_operations + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.linear module +--------------------------- + +.. automodule:: GPy.kern._src.linear + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.mlp module +------------------------ + +.. automodule:: GPy.kern._src.mlp + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.periodic module +----------------------------- + +.. automodule:: GPy.kern._src.periodic + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.poly module +------------------------- + +.. automodule:: GPy.kern._src.poly + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.prod module +------------------------- + +.. automodule:: GPy.kern._src.prod + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.rbf module +------------------------ + +.. automodule:: GPy.kern._src.rbf + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.splitKern module +------------------------------ + +.. automodule:: GPy.kern._src.splitKern + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.static module +--------------------------- + +.. automodule:: GPy.kern._src.static + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.stationary module +------------------------------- + +.. automodule:: GPy.kern._src.stationary + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.symbolic module +----------------------------- + +.. automodule:: GPy.kern._src.symbolic + :members: + :undoc-members: + :show-inheritance: + +GPy.kern._src.trunclinear module +-------------------------------- + +.. automodule:: GPy.kern._src.trunclinear + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.kern._src + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.kern.txt b/doc/_build/html/_sources/GPy.kern.txt new file mode 100644 index 00000000..5a0c61c2 --- /dev/null +++ b/doc/_build/html/_sources/GPy.kern.txt @@ -0,0 +1,17 @@ +GPy.kern package +================ + +Subpackages +----------- + +.. toctree:: + + GPy.kern._src + +Module contents +--------------- + +.. automodule:: GPy.kern + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.likelihoods.txt b/doc/_build/html/_sources/GPy.likelihoods.txt new file mode 100644 index 00000000..323bb609 --- /dev/null +++ b/doc/_build/html/_sources/GPy.likelihoods.txt @@ -0,0 +1,86 @@ +GPy.likelihoods package +======================= + +Submodules +---------- + +GPy.likelihoods.bernoulli module +-------------------------------- + +.. automodule:: GPy.likelihoods.bernoulli + :members: + :undoc-members: + :show-inheritance: + +GPy.likelihoods.exponential module +---------------------------------- + +.. automodule:: GPy.likelihoods.exponential + :members: + :undoc-members: + :show-inheritance: + +GPy.likelihoods.gamma module +---------------------------- + +.. automodule:: GPy.likelihoods.gamma + :members: + :undoc-members: + :show-inheritance: + +GPy.likelihoods.gaussian module +------------------------------- + +.. automodule:: GPy.likelihoods.gaussian + :members: + :undoc-members: + :show-inheritance: + +GPy.likelihoods.likelihood module +--------------------------------- + +.. automodule:: GPy.likelihoods.likelihood + :members: + :undoc-members: + :show-inheritance: + +GPy.likelihoods.link_functions module +------------------------------------- + +.. automodule:: GPy.likelihoods.link_functions + :members: + :undoc-members: + :show-inheritance: + +GPy.likelihoods.mixed_noise module +---------------------------------- + +.. automodule:: GPy.likelihoods.mixed_noise + :members: + :undoc-members: + :show-inheritance: + +GPy.likelihoods.poisson module +------------------------------ + +.. automodule:: GPy.likelihoods.poisson + :members: + :undoc-members: + :show-inheritance: + +GPy.likelihoods.student_t module +-------------------------------- + +.. automodule:: GPy.likelihoods.student_t + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.likelihoods + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.mappings.txt b/doc/_build/html/_sources/GPy.mappings.txt new file mode 100644 index 00000000..c13642cc --- /dev/null +++ b/doc/_build/html/_sources/GPy.mappings.txt @@ -0,0 +1,46 @@ +GPy.mappings package +==================== + +Submodules +---------- + +GPy.mappings.additive module +---------------------------- + +.. automodule:: GPy.mappings.additive + :members: + :undoc-members: + :show-inheritance: + +GPy.mappings.kernel module +-------------------------- + +.. automodule:: GPy.mappings.kernel + :members: + :undoc-members: + :show-inheritance: + +GPy.mappings.linear module +-------------------------- + +.. automodule:: GPy.mappings.linear + :members: + :undoc-members: + :show-inheritance: + +GPy.mappings.mlp module +----------------------- + +.. automodule:: GPy.mappings.mlp + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.mappings + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.models.txt b/doc/_build/html/_sources/GPy.models.txt new file mode 100644 index 00000000..cb043afa --- /dev/null +++ b/doc/_build/html/_sources/GPy.models.txt @@ -0,0 +1,198 @@ +GPy.models package +================== + +Submodules +---------- + +GPy.models.bayesian_gplvm module +-------------------------------- + +.. automodule:: GPy.models.bayesian_gplvm + :members: + :undoc-members: + :show-inheritance: + +GPy.models.bayesian_gplvm_minibatch module +------------------------------------------ + +.. automodule:: GPy.models.bayesian_gplvm_minibatch + :members: + :undoc-members: + :show-inheritance: + +GPy.models.bcgplvm module +------------------------- + +.. automodule:: GPy.models.bcgplvm + :members: + :undoc-members: + :show-inheritance: + +GPy.models.gp_classification module +----------------------------------- + +.. automodule:: GPy.models.gp_classification + :members: + :undoc-members: + :show-inheritance: + +GPy.models.gp_coregionalized_regression module +---------------------------------------------- + +.. automodule:: GPy.models.gp_coregionalized_regression + :members: + :undoc-members: + :show-inheritance: + +GPy.models.gp_heteroscedastic_regression module +----------------------------------------------- + +.. automodule:: GPy.models.gp_heteroscedastic_regression + :members: + :undoc-members: + :show-inheritance: + +GPy.models.gp_kronecker_gaussian_regression module +-------------------------------------------------- + +.. automodule:: GPy.models.gp_kronecker_gaussian_regression + :members: + :undoc-members: + :show-inheritance: + +GPy.models.gp_multioutput_regression module +------------------------------------------- + +.. automodule:: GPy.models.gp_multioutput_regression + :members: + :undoc-members: + :show-inheritance: + +GPy.models.gp_regression module +------------------------------- + +.. automodule:: GPy.models.gp_regression + :members: + :undoc-members: + :show-inheritance: + +GPy.models.gp_var_gauss module +------------------------------ + +.. automodule:: GPy.models.gp_var_gauss + :members: + :undoc-members: + :show-inheritance: + +GPy.models.gplvm module +----------------------- + +.. automodule:: GPy.models.gplvm + :members: + :undoc-members: + :show-inheritance: + +GPy.models.gradient_checker module +---------------------------------- + +.. automodule:: GPy.models.gradient_checker + :members: + :undoc-members: + :show-inheritance: + +GPy.models.mrd module +--------------------- + +.. automodule:: GPy.models.mrd + :members: + :undoc-members: + :show-inheritance: + +GPy.models.sparse_gp_classification module +------------------------------------------ + +.. automodule:: GPy.models.sparse_gp_classification + :members: + :undoc-members: + :show-inheritance: + +GPy.models.sparse_gp_coregionalized_regression module +----------------------------------------------------- + +.. automodule:: GPy.models.sparse_gp_coregionalized_regression + :members: + :undoc-members: + :show-inheritance: + +GPy.models.sparse_gp_minibatch module +------------------------------------- + +.. automodule:: GPy.models.sparse_gp_minibatch + :members: + :undoc-members: + :show-inheritance: + +GPy.models.sparse_gp_multioutput_regression module +-------------------------------------------------- + +.. automodule:: GPy.models.sparse_gp_multioutput_regression + :members: + :undoc-members: + :show-inheritance: + +GPy.models.sparse_gp_regression module +-------------------------------------- + +.. automodule:: GPy.models.sparse_gp_regression + :members: + :undoc-members: + :show-inheritance: + +GPy.models.sparse_gplvm module +------------------------------ + +.. automodule:: GPy.models.sparse_gplvm + :members: + :undoc-members: + :show-inheritance: + +GPy.models.ss_gplvm module +-------------------------- + +.. automodule:: GPy.models.ss_gplvm + :members: + :undoc-members: + :show-inheritance: + +GPy.models.ss_mrd module +------------------------ + +.. automodule:: GPy.models.ss_mrd + :members: + :undoc-members: + :show-inheritance: + +GPy.models.svigp_regression module +---------------------------------- + +.. automodule:: GPy.models.svigp_regression + :members: + :undoc-members: + :show-inheritance: + +GPy.models.warped_gp module +--------------------------- + +.. automodule:: GPy.models.warped_gp + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.models + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.plotting.matplot_dep.latent_space_visualizations.controllers.txt b/doc/_build/html/_sources/GPy.plotting.matplot_dep.latent_space_visualizations.controllers.txt new file mode 100644 index 00000000..71826ed6 --- /dev/null +++ b/doc/_build/html/_sources/GPy.plotting.matplot_dep.latent_space_visualizations.controllers.txt @@ -0,0 +1,30 @@ +GPy.plotting.matplot_dep.latent_space_visualizations.controllers package +======================================================================== + +Submodules +---------- + +GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller module +--------------------------------------------------------------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.latent_space_visualizations.controllers.axis_event_controller + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.latent_space_visualizations.controllers.imshow_controller module +----------------------------------------------------------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.latent_space_visualizations.controllers.imshow_controller + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.plotting.matplot_dep.latent_space_visualizations.controllers + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.plotting.matplot_dep.latent_space_visualizations.txt b/doc/_build/html/_sources/GPy.plotting.matplot_dep.latent_space_visualizations.txt new file mode 100644 index 00000000..6e5cf4bd --- /dev/null +++ b/doc/_build/html/_sources/GPy.plotting.matplot_dep.latent_space_visualizations.txt @@ -0,0 +1,17 @@ +GPy.plotting.matplot_dep.latent_space_visualizations package +============================================================ + +Subpackages +----------- + +.. toctree:: + + GPy.plotting.matplot_dep.latent_space_visualizations.controllers + +Module contents +--------------- + +.. automodule:: GPy.plotting.matplot_dep.latent_space_visualizations + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.plotting.matplot_dep.txt b/doc/_build/html/_sources/GPy.plotting.matplot_dep.txt new file mode 100644 index 00000000..77780708 --- /dev/null +++ b/doc/_build/html/_sources/GPy.plotting.matplot_dep.txt @@ -0,0 +1,141 @@ +GPy.plotting.matplot_dep package +================================ + +Subpackages +----------- + +.. toctree:: + + GPy.plotting.matplot_dep.latent_space_visualizations + +Submodules +---------- + +GPy.plotting.matplot_dep.Tango module +------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.Tango + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.base_plots module +------------------------------------------ + +.. automodule:: GPy.plotting.matplot_dep.base_plots + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.dim_reduction_plots module +--------------------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.dim_reduction_plots + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.img_plots module +----------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.img_plots + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.inference_plots module +----------------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.inference_plots + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.kernel_plots module +-------------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.kernel_plots + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.mapping_plots module +--------------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.mapping_plots + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.maps module +------------------------------------ + +.. automodule:: GPy.plotting.matplot_dep.maps + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.models_plots module +-------------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.models_plots + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.netpbmfile module +------------------------------------------ + +.. automodule:: GPy.plotting.matplot_dep.netpbmfile + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.priors_plots module +-------------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.priors_plots + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.ssgplvm module +--------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.ssgplvm + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.svig_plots module +------------------------------------------ + +.. automodule:: GPy.plotting.matplot_dep.svig_plots + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.variational_plots module +------------------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.variational_plots + :members: + :undoc-members: + :show-inheritance: + +GPy.plotting.matplot_dep.visualize module +----------------------------------------- + +.. automodule:: GPy.plotting.matplot_dep.visualize + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.plotting.matplot_dep + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.plotting.txt b/doc/_build/html/_sources/GPy.plotting.txt new file mode 100644 index 00000000..af035515 --- /dev/null +++ b/doc/_build/html/_sources/GPy.plotting.txt @@ -0,0 +1,17 @@ +GPy.plotting package +==================== + +Subpackages +----------- + +.. toctree:: + + GPy.plotting.matplot_dep + +Module contents +--------------- + +.. automodule:: GPy.plotting + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.testing.txt b/doc/_build/html/_sources/GPy.testing.txt new file mode 100644 index 00000000..45bb307f --- /dev/null +++ b/doc/_build/html/_sources/GPy.testing.txt @@ -0,0 +1,102 @@ +GPy.testing package +=================== + +Submodules +---------- + +GPy.testing.examples_tests module +--------------------------------- + +.. automodule:: GPy.testing.examples_tests + :members: + :undoc-members: + :show-inheritance: + +GPy.testing.fitc module +----------------------- + +.. automodule:: GPy.testing.fitc + :members: + :undoc-members: + :show-inheritance: + +GPy.testing.index_operations_tests module +----------------------------------------- + +.. automodule:: GPy.testing.index_operations_tests + :members: + :undoc-members: + :show-inheritance: + +GPy.testing.inference_tests module +---------------------------------- + +.. automodule:: GPy.testing.inference_tests + :members: + :undoc-members: + :show-inheritance: + +GPy.testing.kernel_tests module +------------------------------- + +.. automodule:: GPy.testing.kernel_tests + :members: + :undoc-members: + :show-inheritance: + +GPy.testing.likelihood_tests module +----------------------------------- + +.. automodule:: GPy.testing.likelihood_tests + :members: + :undoc-members: + :show-inheritance: + +GPy.testing.model_tests module +------------------------------ + +.. automodule:: GPy.testing.model_tests + :members: + :undoc-members: + :show-inheritance: + +GPy.testing.observable_tests module +----------------------------------- + +.. automodule:: GPy.testing.observable_tests + :members: + :undoc-members: + :show-inheritance: + +GPy.testing.parameterized_tests module +-------------------------------------- + +.. automodule:: GPy.testing.parameterized_tests + :members: + :undoc-members: + :show-inheritance: + +GPy.testing.pickle_tests module +------------------------------- + +.. automodule:: GPy.testing.pickle_tests + :members: + :undoc-members: + :show-inheritance: + +GPy.testing.prior_tests module +------------------------------ + +.. automodule:: GPy.testing.prior_tests + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.testing + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.txt b/doc/_build/html/_sources/GPy.txt new file mode 100644 index 00000000..9be6dbec --- /dev/null +++ b/doc/_build/html/_sources/GPy.txt @@ -0,0 +1,26 @@ +GPy package +=========== + +Subpackages +----------- + +.. toctree:: + + GPy.core + GPy.examples + GPy.inference + GPy.kern + GPy.likelihoods + GPy.mappings + GPy.models + GPy.plotting + GPy.testing + GPy.util + +Module contents +--------------- + +.. automodule:: GPy + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/GPy.util.txt b/doc/_build/html/_sources/GPy.util.txt new file mode 100644 index 00000000..e50efdfb --- /dev/null +++ b/doc/_build/html/_sources/GPy.util.txt @@ -0,0 +1,230 @@ +GPy.util package +================ + +Submodules +---------- + +GPy.util.block_matrices module +------------------------------ + +.. automodule:: GPy.util.block_matrices + :members: + :undoc-members: + :show-inheritance: + +GPy.util.caching module +----------------------- + +.. automodule:: GPy.util.caching + :members: + :undoc-members: + :show-inheritance: + +GPy.util.classification module +------------------------------ + +.. automodule:: GPy.util.classification + :members: + :undoc-members: + :show-inheritance: + +GPy.util.config module +---------------------- + +.. automodule:: GPy.util.config + :members: + :undoc-members: + :show-inheritance: + +GPy.util.datasets module +------------------------ + +.. automodule:: GPy.util.datasets + :members: + :undoc-members: + :show-inheritance: + +GPy.util.debug module +--------------------- + +.. automodule:: GPy.util.debug + :members: + :undoc-members: + :show-inheritance: + +GPy.util.decorators module +-------------------------- + +.. automodule:: GPy.util.decorators + :members: + :undoc-members: + :show-inheritance: + +GPy.util.diag module +-------------------- + +.. automodule:: GPy.util.diag + :members: + :undoc-members: + :show-inheritance: + +GPy.util.erfcx module +--------------------- + +.. automodule:: GPy.util.erfcx + :members: + :undoc-members: + :show-inheritance: + +GPy.util.functions module +------------------------- + +.. automodule:: GPy.util.functions + :members: + :undoc-members: + :show-inheritance: + +GPy.util.gpu_init module +------------------------ + +.. automodule:: GPy.util.gpu_init + :members: + :undoc-members: + :show-inheritance: + +GPy.util.initialization module +------------------------------ + +.. automodule:: GPy.util.initialization + :members: + :undoc-members: + :show-inheritance: + +GPy.util.linalg module +---------------------- + +.. automodule:: GPy.util.linalg + :members: + :undoc-members: + :show-inheritance: + +GPy.util.linalg_gpu module +-------------------------- + +.. automodule:: GPy.util.linalg_gpu + :members: + :undoc-members: + :show-inheritance: + +GPy.util.ln_diff_erfs module +---------------------------- + +.. automodule:: GPy.util.ln_diff_erfs + :members: + :undoc-members: + :show-inheritance: + +GPy.util.misc module +-------------------- + +.. automodule:: GPy.util.misc + :members: + :undoc-members: + :show-inheritance: + +GPy.util.mocap module +--------------------- + +.. automodule:: GPy.util.mocap + :members: + :undoc-members: + :show-inheritance: + +GPy.util.mpi module +------------------- + +.. automodule:: GPy.util.mpi + :members: + :undoc-members: + :show-inheritance: + +GPy.util.multioutput module +--------------------------- + +.. automodule:: GPy.util.multioutput + :members: + :undoc-members: + :show-inheritance: + +GPy.util.netpbmfile module +-------------------------- + +.. automodule:: GPy.util.netpbmfile + :members: + :undoc-members: + :show-inheritance: + +GPy.util.normalizer module +-------------------------- + +.. automodule:: GPy.util.normalizer + :members: + :undoc-members: + :show-inheritance: + +GPy.util.parallel module +------------------------ + +.. automodule:: GPy.util.parallel + :members: + :undoc-members: + :show-inheritance: + +GPy.util.pca module +------------------- + +.. automodule:: GPy.util.pca + :members: + :undoc-members: + :show-inheritance: + +GPy.util.squashers module +------------------------- + +.. automodule:: GPy.util.squashers + :members: + :undoc-members: + :show-inheritance: + +GPy.util.subarray_and_sorting module +------------------------------------ + +.. automodule:: GPy.util.subarray_and_sorting + :members: + :undoc-members: + :show-inheritance: + +GPy.util.univariate_Gaussian module +----------------------------------- + +.. automodule:: GPy.util.univariate_Gaussian + :members: + :undoc-members: + :show-inheritance: + +GPy.util.warping_functions module +--------------------------------- + +.. automodule:: GPy.util.warping_functions + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: GPy.util + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/_build/html/_sources/index.txt b/doc/_build/html/_sources/index.txt new file mode 100644 index 00000000..fec4aef1 --- /dev/null +++ b/doc/_build/html/_sources/index.txt @@ -0,0 +1,38 @@ +.. GPy documentation master file, created by + sphinx-quickstart on Fri Jan 18 17:36:01 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to GPy's documentation! +=============================== + +`GPy `_ is a Gaussian Process (GP) framework written in Python, from the Sheffield machine learning group. + +The `GPy homepage `_ contains tutorials for users and further information on the project, including installation instructions. +This documentation is mostly aimed at developers interacting closely with the code-base. + +The code can be found on our `Github project page `_. It is open source and provided under the BSD license. + +.. * `Basic Gaussian process regression `_ +.. * `Interacting with models `_ +.. * `A kernel overview `_ +.. * `Writing new kernels `_ +.. * `Writing new models `_ +.. * `Parameterization handles `_ + +.. You may also be interested by some examples in the GPy/examples folder. + +Contents: + +.. toctree:: + :maxdepth: 2 + + GPy + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/doc/_build/html/_sources/installation.txt b/doc/_build/html/_sources/installation.txt new file mode 100644 index 00000000..35352272 --- /dev/null +++ b/doc/_build/html/_sources/installation.txt @@ -0,0 +1,31 @@ +============== + Installation +============== + + +Linux +============ + + +Windows +====================== +One easy way to get a Python distribution with the required packages is to use the Anaconda environment from Continuum Analytics. + +* Download and install the free version of Anaconda according to your operating system from `their website `_. +* Open a (new) terminal window: + + * Navigate to Applications/Accessories/cmd, or + * open *anaconda Command Prompt* from windows *start* + +You should now be able to launch a Python interpreter by typing *ipython* in the terminal. In the ipython prompt, you can check your installation by importing the libraries we will need later: +:: + $ import numpy + $ import pylab + +To install the latest version of GPy, *git* is required. A *git* client on Windows can be found `here `_. It is recommened to install with the option "*Use Git from the Windows Command Prompt*". Then, GPy can be installed with the following command +:: + pip install git+https://github.com/SheffieldML/GPy.git@devel + +MacOSX +=================================== + diff --git a/doc/_build/html/_sources/kernel_implementation.txt b/doc/_build/html/_sources/kernel_implementation.txt new file mode 100644 index 00000000..c566d21d --- /dev/null +++ b/doc/_build/html/_sources/kernel_implementation.txt @@ -0,0 +1,49 @@ + +*************************** +List of implemented kernels +*************************** + +The following table shows the implemented kernels in GPy and gives the details of the implemented function for each kernel. + +==================== =========== ===== =========== ====== ======= =========== =============== ======= =========== ====== ====== ======= +NAME Dimension ARD get/set K Kdiag dK_dtheta dKdiag_dtheta dK_dX dKdiag_dX psi0 psi1 psi2 +==================== =========== ===== =========== ====== ======= =========== =============== ======= =========== ====== ====== ======= +bias n |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +Brownian 1 |tick| |tick| |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +exponential n yes |tick| |tick| |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +finite_dimensional n |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +linear n yes |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +Matern32 n yes |tick| |tick| |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +Matern52 n yes |tick| |tick| |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +periodic_exponential 1 |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +periodic_Matern32 1 |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +periodic_Matern52 1 |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +rational quadratic 1 |tick| |tick| |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +rbf n yes |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +spline 1 |tick| |tick| |tick| |tick| |tick| |tick| +-------------------- ----------- ----- ----------- ------ ------- ----------- --------------- ------- ----------- ------ ------ ------- +white n |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| |tick| +==================== =========== ===== =========== ====== ======= =========== =============== ======= =========== ====== ====== ======= + +Depending on the use, all functions may not be required + + * ``get/set, K, Kdiag``: compulsory + * ``dK_dtheta``: necessary to optimize the model + * ``dKdiag_dtheta``: sparse models, BGPLVM, GPs with uncertain inputs + * ``dK_dX``: sparse models, GPLVM, BGPLVM, GPs with uncertain inputs + * ``dKdiag_dX``: sparse models, BGPLVM, GPs with uncertain inputs + * ``psi0, psi1, psi2``: BGPLVM, GPs with uncertain inputs + +.. |tick| image:: Figures/tick.png diff --git a/doc/_build/html/_sources/modules.txt b/doc/_build/html/_sources/modules.txt new file mode 100644 index 00000000..9c698ca2 --- /dev/null +++ b/doc/_build/html/_sources/modules.txt @@ -0,0 +1,7 @@ +GPy +=== + +.. toctree:: + :maxdepth: 4 + + GPy diff --git a/doc/_build/html/_sources/tuto_GP_regression.txt b/doc/_build/html/_sources/tuto_GP_regression.txt new file mode 100644 index 00000000..29eefa72 --- /dev/null +++ b/doc/_build/html/_sources/tuto_GP_regression.txt @@ -0,0 +1,142 @@ +************************************* +Gaussian process regression tutorial +************************************* + +We will see in this tutorial the basics for building a 1 dimensional and a 2 dimensional Gaussian process regression model, also known as a kriging model. The code shown in this tutorial can be obtained at GPy/examples/tutorials.py, or by running ``GPy.examples.tutorials.tuto_GP_regression()``. + +We first import the libraries we will need: :: + + import pylab as pb + pb.ion() + import numpy as np + import GPy + +1-dimensional model +=================== + +For this toy example, we assume we have the following inputs and outputs:: + + X = np.random.uniform(-3.,3.,(20,1)) + Y = np.sin(X) + np.random.randn(20,1)*0.05 + +Note that the observations Y include some noise. + +The first step is to define the covariance kernel we want to use for the model. We choose here a kernel based on Gaussian kernel (i.e. rbf or square exponential):: + + kernel = GPy.kern.RBF(input_dim=1, variance=1., lengthscale=1.) + +The parameter ``input_dim`` stands for the dimension of the input space. The parameters ``variance`` and ``lengthscale`` are optional. Many other kernels are implemented such as: + +* linear (:py:class:`~GPy.kern.Linear`) +* exponential kernel (:py:class:`GPy.kern.Exponential`) +* Matern 3/2 (:py:class:`GPy.kern.Matern32`) +* Matern 5/2 (:py:class:`GPy.kern.Matern52`) +* spline (:py:class:`GPy.kern.Spline`) +* and many others... + +The inputs required for building the model are the observations and the kernel:: + + m = GPy.models.GPRegression(X,Y,kernel) + +By default, some observation noise is added to the modle. The functions ``print`` and ``plot`` give an insight of the model we have just build. The code:: + + print m + m.plot() + +gives the following output: :: + + Name : GP regression + Log-likelihood : -22.8178418808 + Number of Parameters : 3 + Parameters: + GP_regression. | Value | Constraint | Prior | Tied to + rbf.variance | 1.0 | +ve | | + rbf.lengthscale | 1.0 | +ve | | + Gaussian_noise.variance | 1.0 | +ve | | + +.. figure:: Figures/tuto_GP_regression_m1.png + :align: center + :height: 350px + + GP regression model before optimization of the parameters. The shaded region corresponds to ~95% confidence intervals (ie +/- 2 standard deviation). + +The default values of the kernel parameters may not be relevant for +the current data (for example, the confidence intervals seems too wide +on the previous figure). A common approach is to find the values of +the parameters that maximize the likelihood of the data. It as easy as +calling ``m.optimize`` in GPy:: + + m.optimize() + +If we want to perform some restarts to try to improve the result of the optimization, we can use the ``optimize_restart`` function:: + + m.optimize_restarts(num_restarts = 10) + +Once again, we can use ``print(m)`` and ``m.plot()`` to look at the resulting model resulting model:: + + Name : GP regression + Log-likelihood : 11.947469082 + Number of Parameters : 3 + Parameters: + GP_regression. | Value | Constraint | Prior | Tied to + rbf.variance | 0.74229417323 | +ve | | + rbf.lengthscale | 1.43020495724 | +ve | | + Gaussian_noise.variance | 0.00325654460991 | +ve | | + +.. figure:: Figures/tuto_GP_regression_m2.png + :align: center + :height: 350px + + GP regression model after optimization of the parameters. + + +2-dimensional example +===================== + +Here is a 2 dimensional example:: + + import pylab as pb + pb.ion() + import numpy as np + import GPy + + # sample inputs and outputs + X = np.random.uniform(-3.,3.,(50,2)) + Y = np.sin(X[:,0:1]) * np.sin(X[:,1:2])+np.random.randn(50,1)*0.05 + + # define kernel + ker = GPy.kern.Matern52(2,ARD=True) + GPy.kern.White(2) + + # create simple GP model + m = GPy.models.GPRegression(X,Y,ker) + + # optimize and plot + m.optimize(max_f_eval = 1000) + m.plot() + print(m) + +The flag ``ARD=True`` in the definition of the Matern kernel specifies that we want one lengthscale parameter per dimension (ie the GP is not isotropic). The output of the last two lines is:: + + Name : GP regression + Log-likelihood : 26.787156248 + Number of Parameters : 5 + Parameters: + GP_regression. | Value | Constraint | Prior | Tied to + add.Mat52.variance | 0.385463739076 | +ve | | + add.Mat52.lengthscale | (2,) | +ve | | + add.white.variance | 0.000835329608514 | +ve | | + Gaussian_noise.variance | 0.000835329608514 | +ve | | + +If you want to see the ``ARD`` parameters explicitly print them +directly:: + + >>> print m.add.Mat52.lengthscale + Index | GP_regression.add.Mat52.lengthscale | Constraint | Prior | Tied to + [0] | 1.9575587 | +ve | | N/A + [1] | 1.9689948 | +ve | | N/A + +.. figure:: Figures/tuto_GP_regression_m3.png + :align: center + :height: 350px + + Contour plot of the best predictor (posterior mean). diff --git a/doc/_build/html/_sources/tuto_creating_new_kernels.txt b/doc/_build/html/_sources/tuto_creating_new_kernels.txt new file mode 100644 index 00000000..a8197596 --- /dev/null +++ b/doc/_build/html/_sources/tuto_creating_new_kernels.txt @@ -0,0 +1,212 @@ +******************** +Creating new kernels +******************** + +We will see in this tutorial how to create new kernels in GPy. We will also give details on how to implement each function of the kernel and illustrate with a running example: the rational quadratic kernel. + +Structure of a kernel in GPy +============================ + +In GPy a kernel object is made of a list of kernpart objects, which correspond to symetric positive definite functions. More precisely, the kernel should be understood as the sum of the kernparts. In order to implement a new covariance, the following steps must be followed + + 1. implement the new covariance as a kernpart object + 2. update the constructors that allow to use the kernpart as a kern object + 3. update the __init__.py file + +Theses three steps are detailed below. + +Implementing a kernpart object +============================== + +We advise the reader to start with copy-pasting an existing kernel and to modify the new file. We will now give a description of the various functions that can be found in a kernpart object. + +**Header** + +The header is similar to all kernels: :: + + from kernpart import kernpart + import numpy as np + + class rational_quadratic(kernpart): + +**__init__(self,input_dim, param1, param2, ...)** + +The implementation of this function in mandatory. + +For all kernparts the first parameter ``input_dim`` corresponds to the dimension of the input space, and the following parameters stand for the parameterization of the kernel. + +You have to call ``super(, self).__init__(input_dim, +name)`` to make sure the input dimension and name of the kernel are +stored in the right place. These attributes are available as +``self.input_dim`` and ``self.name`` at runtime. +.. The following attributes are compulsory: ``self.input_dim`` (the dimension, integer), ``self.name`` (name of the kernel, string), ``self.num_params`` (number of parameters, integer). :: +Parameterization is done by adding +:py:class:``GPy.core.parameter.Param`` objects to ``self`` and use +them as normal numpy ``array-like``s in yout code. The parameters have +to be added by calling +:py:function:``GPy.core.parameterized:Parameterized.add_parameters`` +with the :py:class:``GPy.core.parameter.Param`` objects as arguments. + + def __init__(self,input_dim,variance=1.,lengthscale=1.,power=1.): + super(RationalQuadratic, self).__init__(input_dim, 'rat_quad') + assert input_dim == 1, "For this kernel we assume input_dim=1" + self.variance = Param('variance', variance) + self.lengthscale = Param('lengtscale', lengthscale) + self.power = Param('power', power) + self.add_parameters(self.variance, self.lengthscale, self.power) + +From now on you can use the parameters ``self.variance, +self.lengthscale, self.power`` as normal numpy ``array-like``s in your +code. Updates from the optimization routine will be done +automatically. + +**parameters_changed(self)** + +The implementation of this function is optional. + +This functions deals as a callback for each optimization iteration. If +one optimization step was successfull and the parameters (added by +:py:function:``GPy.core.parameterized:Parameterized.add_parameters``) +this callback function will be called to be able to update any +precomputations for the kernel. + + def parameters_changed(self): + # nothing todo here + + + +.. **_get_params(self)** + +.. The implementation of this function in mandatory. + +.. This function returns a one dimensional array of length ``self.num_params`` containing the value of the parameters. :: + +.. def _get_params(self): +.. return np.hstack((self.variance,self.lengthscale,self.power)) + +.. **_set_params(self,x)** + +.. The implementation of this function in mandatory. + +.. The input is a one dimensional array of length ``self.num_params`` containing the value of the parameters. The function has no output but it updates the values of the attribute associated to the parameters (such as ``self.variance``, ``self.lengthscale``, ...). :: + +.. def _set_params(self,x): +.. self.variance = x[0] +.. self.lengthscale = x[1] +.. self.power = x[2] + +.. **_get_param_names(self)** + +.. The implementation of this function in mandatory. + +.. It returns a list of strings of length ``self.num_params`` corresponding to the parameter names. :: + +.. def _get_param_names(self): +.. return ['variance','lengthscale','power'] + +**K(self,X,X2,target)** + +The implementation of this function in mandatory. + +This function is used to compute the covariance matrix associated with the inputs X, X2 (np.arrays with arbitrary number of line (say :math:`n_1`, :math:`n_2`) and ``self.input_dim`` columns). This function does not returns anything but it adds the :math:`n_1 \times n_2` covariance matrix to the kernpart to the object ``target`` (a :math:`n_1 \times n_2` np.array). This trick allows to compute the covariance matrix of a kernel containing many kernparts with a limited memory use. :: + + def K(self,X,X2,target): + if X2 is None: X2 = X + dist2 = np.square((X-X2.T)/self.lengthscale) + target += self.variance*(1 + dist2/2.)**(-self.power) + +**Kdiag(self,X,target)** + +The implementation of this function in mandatory. + +This function is similar to ``K`` but it computes only the values of the kernel on the diagonal. Thus, ``target`` is a 1-dimensional np.array of length :math:`n_1`. :: + + def Kdiag(self,X,target): + target += self.variance + + +**dK_dtheta(self,dL_dK,X,X2,target)** + +This function is required for the optimization of the parameters. + +Computes the derivative of the likelihood. As previously, the values are added to the object target which is a 1-dimensional np.array of length ``self.input_dim``. For example, if the kernel is parameterized by :math:`\sigma^2,\ \theta`, then :math:`\frac{dL}{d\sigma^2} = \frac{dL}{d K} \frac{dK}{d\sigma^2}` is added to the first element of target and :math:`\frac{dL}{d\theta} = \frac{dL}{d K} \frac{dK}{d\theta}` to the second. :: + + def dK_dtheta(self,dL_dK,X,X2,target): + if X2 is None: X2 = X + dist2 = np.square((X-X2.T)/self.lengthscale) + + dvar = (1 + dist2/2.)**(-self.power) + dl = self.power * self.variance * dist2 * self.lengthscale**(-3) * (1 + dist2/2./self.power)**(-self.power-1) + dp = - self.variance * np.log(1 + dist2/2.) * (1 + dist2/2.)**(-self.power) + + target[0] += np.sum(dvar*dL_dK) + target[1] += np.sum(dl*dL_dK) + target[2] += np.sum(dp*dL_dK) + + +**dKdiag_dtheta(self,dL_dKdiag,X,target)** + +This function is required for BGPLVM, sparse models and uncertain inputs. + +As previously, target is an ``self.num_params`` array and :math:`\frac{dL}{d Kdiag} \frac{dKdiag}{dparam}` is added to each element. :: + + def dKdiag_dtheta(self,dL_dKdiag,X,target): + target[0] += np.sum(dL_dKdiag) + # here self.lengthscale and self.power have no influence on Kdiag so target[1:] are unchanged + +**dK_dX(self,dL_dK,X,X2,target)** + +This function is required for GPLVM, BGPLVM, sparse models and uncertain inputs. + +Computes the derivative of the likelihood with respect to the inputs ``X`` (a :math:`n \times d` np.array). The result is added to target which is a :math:`n \times d` np.array. :: + + def dK_dX(self,dL_dK,X,X2,target): + """derivative of the covariance matrix with respect to X.""" + if X2 is None: X2 = X + dist2 = np.square((X-X2.T)/self.lengthscale) + + dX = -self.variance*self.power * (X-X2.T)/self.lengthscale**2 * (1 + dist2/2./self.lengthscale)**(-self.power-1) + target += np.sum(dL_dK*dX,1)[:,np.newaxis] + +**dKdiag_dX(self,dL_dKdiag,X,target)** + +This function is required for BGPLVM, sparse models and uncertain inputs. As for ``dKdiag_dtheta``, :math:`\frac{dL}{d Kdiag} \frac{dKdiag}{dX}` is added to each element of target. :: + + def dKdiag_dX(self,dL_dKdiag,X,target): + pass + +**Psi statistics** + +The psi statistics and their derivatives are required for BGPLVM and GPS with uncertain inputs. + +The expressions of the psi statistics are: + +TODO + +For the rational quadratic we have: + +TODO + +Update the constructor +====================== + +Once the required functions have been implemented as a kernpart object, the file GPy/kern/constructors.py has to be updated to allow to build a kernel based on the kernpart object. + +The following line should be added in the preamble of the file:: + + from rational_quadratic import rational_quadratic as rational_quadratic_part + +as well as the following block :: + + def rational_quadratic(input_dim,variance=1., lengthscale=1., power=1.): + part = rational_quadraticpart(input_dim,variance, lengthscale, power) + return kern(input_dim, [part]) + + +Update initialization +===================== + +The last step is to update the list of kernels imported from constructor in GPy/kern/__init__.py. + + + diff --git a/doc/_build/html/_sources/tuto_creating_new_models.txt b/doc/_build/html/_sources/tuto_creating_new_models.txt new file mode 100644 index 00000000..07f6194f --- /dev/null +++ b/doc/_build/html/_sources/tuto_creating_new_models.txt @@ -0,0 +1,100 @@ +.. _creating_new_models: + +******************* +Creating new Models +******************* + +In GPy all models inherit from the base class :py:class:`~GPy.core.parameterized.Parameterized`. :py:class:`~GPy.core.parameterized.Parameterized` is a class which allows for parameterization of objects. All it holds is functionality for tying, bounding and fixing of parameters. It also provides the functionality of searching and manipulating parameters by regular expression syntax. See :py:class:`~GPy.core.parameterized.Parameterized` for more information. + +The :py:class:`~GPy.core.model.Model` class provides parameter introspection, objective function and optimization. + +In order to fully use all functionality of +:py:class:`~GPy.core.model.Model` some methods need to be implemented +/ overridden. And the model needs to be told its parameters, such +that it can provide optimized parameter distribution and handling. +In order to explain the functionality of those methods +we will use a wrapper to the numpy ``rosen`` function, which holds +input parameters :math:`\mathbf{X}`. Where +:math:`\mathbf{X}\in\mathbb{R}^{N\times 1}`. + +Obligatory methods +================== + +:py:func:`~GPy.core.model.Model.__init__` : + Initialize the model with the given parameters. These need to + be added to the model by calling + `self.add_parameter()`, where param needs to be a + parameter handle (See parameterized_ for details).:: + + self.X = GPy.Param("input", X) + self.add_parameter(self.X) + +:py:meth:`~GPy.core.model.Model.log_likelihood` : + Returns the log-likelihood of the new model. For our example + this is just the call to ``rosen`` and as we want to minimize + it, we need to negate the objective.:: + + return -scipy.optimize.rosen(self.X) + +:py:meth:`~GPy.core.model.Model.parameters_changed` : + Updates the internal state of the model and sets the gradient of + each parameter handle in the hierarchy with respect to the + log_likelihod. Thus here we need to set the negative derivative of + the rosenbrock function for the parameters. In this case it is the + gradient for self.X.:: + + self.X.gradient = -scipy.optimize.rosen_der(self.X) + + +Here the full code for the `Rosen` class:: + + from GPy import Model, Param + import scipy + class Rosen(Model): + def __init__(self, X, name='rosenbrock'): + super(Rosen, self).__init__(name=name) + self.X = Param("input", X) + self.add_parameter(self.X) + def log_likelihood(self): + return -scipy.optimize.rosen(self.X) + def parameters_changed(self): + self.X.gradient = -scipy.optimize.rosen_der(self.X) + +In order to test the newly created model, we can check the gradients +and optimize a standard rosenbrock run:: + + >>> m = Rosen(np.array([-1,-1])) + >>> print m + Name : rosenbrock + Log-likelihood : -404.0 + Number of Parameters : 2 + Parameters: + rosenbrock. | Value | Constraint | Prior | Tied to + input | (2,) | | | + >>> m.checkgrad(verbose=True) + Name | Ratio | Difference | Analytical | Numerical + ------------------------------------------------------------------------------------------ + rosenbrock.input[[0]] | 1.000000 | 0.000000 | -804.000000 | -804.000000 + rosenbrock.input[[1]] | 1.000000 | 0.000000 | -400.000000 | -400.000000 + >>> m.optimize() + >>> print m + Name : rosenbrock + Log-likelihood : -6.52150088871e-15 + Number of Parameters : 2 + Parameters: + rosenbrock. | Value | Constraint | Prior | Tied to + input | (2,) | | | + >>> print m.input + Index | rosenbrock.input | Constraint | Prior | Tied to + [0] | 0.99999994 | | | N/A + [1] | 0.99999987 | | | N/A + >>> print m.gradient + [ -1.91169809e-06, 1.01852309e-06] + +This is the optimium for the 2D Rosenbrock function, as expected, and +the gradient of the inputs are almost zero. + +Optional methods +================ + +Currently none. diff --git a/doc/_build/html/_sources/tuto_interacting_with_models.txt b/doc/_build/html/_sources/tuto_interacting_with_models.txt new file mode 100644 index 00000000..80b2ac77 --- /dev/null +++ b/doc/_build/html/_sources/tuto_interacting_with_models.txt @@ -0,0 +1,341 @@ +.. _interacting_with_models: + +************************************* +Interacting with models +************************************* + +The GPy model class has a set of features which are +designed to make it simple to explore the parameter +space of the model. By default, the scipy optimisers +are used to fit GPy models (via model.optimize()), +for which we provide mechanisms for 'free' optimisation: +GPy can ensure that naturally positive parameters +(such as variances) remain positive. But these mechanisms +are much more powerful than simple reparameterisation, +as we shall see. + +Along this tutorial we'll use a sparse GP regression model +as example. This example can be in ``GPy.examples.regression``. +All of the examples included in GPy return an instance +of a model class, and therefore they can be called in +the following way: :: + + import numpy as np + import pylab as pb + pb.ion() + import GPy + m = GPy.examples.regression.sparse_GP_regression_1D() + +Examining the model using print +=============================== +To see the current state of the model parameters, +and the model's (marginal) likelihood just print the model :: + + print m + +The first thing displayed on the screen is the log-likelihood +value of the model with its current parameters. Below the +log-likelihood, a table with all the model's parameters +is shown. For each parameter, the table contains the name +of the parameter, the current value, and in case there are +defined: constraints, ties and prior distrbutions associated. :: + + Name : sparse gp + Log-likelihood : 588.947189413 + Number of Parameters : 8 + Parameters: + sparse_gp. | Value | Constraint | Prior | Tied to + inducing inputs | (5, 1) | | | + rbf.variance | 1.91644016819 | +ve | | + rbf.lengthscale | 2.62103621347 | +ve | | + Gaussian_noise.variance | 0.00269870373421 | +ve | | + +In this case the kernel parameters (``rbf.variance``, +``rbf.lengthscale``) as well as +the likelihood noise parameter (``Gaussian_noise.variance``), are constrained +to be positive, while the inducing inputs have no +constraints associated. Also there are no ties or prior defined. + +You can also print all subparts of the model, by printing the +subcomponents individually:: + + print m.rbf + +This will print the details of this particular parameter handle:: + + rbf. | Value | Constraint | Prior | Tied to + variance | 1.91644016819 | +ve | | + lengthscale | 2.62103621347 | +ve | | + +When you want to get a closer look into +multivalue parameters, print them directly:: + + print m.inducing_inputs + + Index | sparse_gp.inducing_inputs | Constraint | Prior | Tied to + [0 0] | 2.7189499 | | | N/A + [1 0] | 0.02006533 | | | N/A + [2 0] | -1.5299386 | | | N/A + [3 0] | -2.7001675 | | | N/A + [4 0] | 1.4654162 | | | N/A + +Interacting with Parameters: +======================= +The preferred way of interacting with parameters is to act on the +parameter handle itself. +Interacting with parameter handles is simple. The names, printed by `print m` +are accessible interactively and programatically. For example try to +set kernels (`rbf`) `lengthscale` to `.2` and print the result:: + + m.rbf.lengthscale = .2 + print m + +You should see this:: + + Name : sparse gp + Log-likelihood : 588.947189413 + Number of Parameters : 8 + Parameters: + sparse_gp. | Value | Constraint | Prior | Tied to + inducing inputs | (5, 1) | | | + rbf.variance | 1.91644016819 | +ve | | + rbf.lengthscale | 0.2 | +ve | | + Gaussian_noise.variance | 0.00269870373421 | +ve | | + +This will already have updated the model's inner state, so you can +plot it or see the changes in the posterior `m.posterior` of the model. + +Regular expressions +---------------- +The model's parameters can also be accessed through regular +expressions, by 'indexing' the model with a regular expression, +matching the parameter name. Through indexing by regular expression, +you can only retrieve leafs of the hierarchy, and you can retrieve the +values matched by calling `values()` on the returned object:: + + >>> print m['.*var'] + Index | sparse_gp.rbf.variance | Constraint | Prior | Tied to + [0] | 2.1500132 | | | N/A + ----- | sparse_gp.Gaussian_noise.variance | ---------- | ---------- | ------- + [0] | 0.0024268215 | | | N/A + >>> print m['.*var'].values() + [ 2.1500132 0.00242682] + >>> print m['rbf'] + Index | sparse_gp.rbf.variance | Constraint | Prior | Tied to + [0] | 2.1500132 | | | N/A + ----- | sparse_gp.rbf.lengthscale | ---------- | ---------- | ------- + [0] | 2.6782803 | | | N/A + +There is access to setting parameters by regular expression, +as well. Here are a few examples of how to set parameters by regular expression:: + + >>> m['.*var'] = .1 + >>> print m['.*var'] + Index | sparse_gp.rbf.variance | Constraint | Prior | Tied to + [0] | 0.1 | | | N/A + ----- | sparse_gp.Gaussian_noise.variance | ---------- | ---------- | ------- + [0] | 0.1 | | | N/A + >>> m['.*var'] = [.1, .2] + >>> print m['.*var'] + Index | sparse_gp.rbf.variance | Constraint | Prior | Tied to + [0] | 0.1 | | | N/A + ----- | sparse_gp.Gaussian_noise.variance | ---------- | ---------- | ------- + [0] | 0.2 | | | N/A + +The fact that only leaf nodes can be accesses we can print all +parameters in a flattened view, by printing the regular expression +match of matching all objects:: + + >>> print m[''] + Index | sparse_gp.inducing_inputs | Constraint | Prior | Tied to + [0 0] | -2.6716041 | | | N/A + [1 0] | -1.4665111 | | | N/A + [2 0] | -0.031010293 | | | N/A + [3 0] | 1.4563711 | | | N/A + [4 0] | 2.6803046 | | | N/A + ----- | sparse_gp.rbf.variance | ---------- | ---------- | ------- + [0] | 0.1 | | | N/A + ----- | sparse_gp.rbf.lengthscale | ---------- | ---------- | ------- + [0] | 2.6782803 | | | N/A + ----- | sparse_gp.Gaussian_noise.variance | ---------- | ---------- | ------- + [0] | 0.2 | | | N/A + +Setting and fetching parameters `parameter_array` +------------------------------------------ +Another way to interact with the model's parameters is through the +`parameter_array`. The Parameter array holds all the parameters of the +model in one place and is editable. It can be accessed through +indexing the model for example you can set all the parameters through +this mechanism:: + + >>> new_params = np.r_[[-4,-2,0,2,4], [.5,2], [.3]] + >>> print new_params + array([-4. , -2. , 0. , 2. , 4. , 0.5, 2. , 0.3]) + >>> m[:] = new_params + >>> print m + Name : sparse gp + Log-likelihood : -147.561160209 + Number of Parameters : 8 + Parameters: + sparse_gp. | Value | Constraint | Prior | Tied to + inducing inputs | (5, 1) | | | + rbf.variance | 0.5 | +sq | | + rbf.lengthscale | 2.0 | +ve | | + Gaussian_noise.variance | 0.3 | +sq | | + +Parameters themselves (leafs of the hierarchy) can be indexed and used +the same way as numpy arrays. First let us set a slice of the +`inducing_inputs`:: + + >>> m.inducing_inputs[2:, 0] = [1,3,5] + >>> print m.inducing_indputs + Index | sparse_gp.inducing_inputs | Constraint | Prior | Tied to + [0 0] | -4 | | | N/A + [1 0] | -2 | | | N/A + [2 0] | 1 | | | N/A + [3 0] | 3 | | | N/A + [4 0] | 5 | | | N/A + +Or you use the parameters as normal numpy arrays for calculations:: + + >>> precision = 1./m.Gaussian_noise.variance + array([ 3.33333333]) + +Getting the model's log likelihood +============================================= +Appart form the printing the model, the marginal +log-likelihood can be obtained by using the function +``log_likelihood()``.:: + + >>> m.log_likelihood() + array([-152.83377316]) + +If you want to ensure the log likelihood as a float, call `float()` +around it:: + + >>> float(m.log_likelihood()) + -152.83377316356177 + +Getting the model parameter's gradients +============================ +The gradients of a model can shed light on understanding the +(possibly hard) optimization process. The gradients of each parameter +handle can be accessed through their `gradient` field.:: + + >>> print m.gradient + [ 5.51170031 9.71735112 -4.20282106 -3.45667035 -1.58828165 + -2.11549358 12.40292787 -627.75467803] + >>> print m.rbf.gradient + [ -2.11549358 12.40292787] + >>> m.optimize() + >>> print m.gradient + [ -5.98046560e-04 -3.64576085e-04 1.98005930e-04 3.43381219e-04 + -6.85685104e-04 -1.28800748e-05 1.08552429e-03 2.74058081e-01] + +Adjusting the model's constraints +================================ +When we initially call the example, it was optimized and hence the +log-likelihood gradients were close to zero. However, since +we have been changing the parameters, the gradients are far from zero now. +Next we are going to show how to optimize the model setting different +restrictions on the parameters. + +Once a constraint has been set on a parameter, it is possible to remove +it with the command ``unconstrain()``, which can be called on any +parameter handle of the model. The methods `constrain()` and +`unconstrain()` return the indices which were actually unconstrained, +relative to the parameter handle the method was called on. This is +particularly handy for reporting which parameters where reconstrained, +when reconstraining a parameter, which was already constrained:: + + >>> m.rbf.variance.unconstrain() + array([0]) + >>>m.unconstrain() + array([6, 7]) + +If you want to unconstrain only a specific constraint, you can pass it +as an argument of ``unconstrain(Transformation)`` (:py:class:`~GPy.constraints.Transformation`), or call +the respective method, such as ``unconstrain_fixed()`` (or +``unfix()``) to only unfix fixed parameters.:: + + >>> m.inducing_input[0].fix() + >>> m.unfix() + >>> m.rbf.constrain_positive() + >>> print m + Name : sparse gp + Log-likelihood : 620.741066698 + Number of Parameters : 8 + Parameters: + sparse_gp. | Value | Constraint | Prior | Tied to + inducing inputs | (5, 1) | | | + rbf.variance | 1.48329711218 | +ve | | + rbf.lengthscale | 2.5430947048 | +ve | | + Gaussian_noise.variance | 0.00229714444128 | | | + +As you can see, ``unfix()`` only unfixed the inducing_input, and did +not change the positive constraint of the kernel. + +The parameter handles come with default constraints, so you will +rarely be needing to adjust the constraints of a model. In the rare +cases of needing to adjust the constraints of a model, or in need of +fixing some parameters, you can do so with the functions +``constrain_{positive|negative|bounded|fixed}()``.:: + + m['.*var'].constrain_positive() + +Available Constraints +============== + +* :py:meth:`~GPy.constraints.Logexp` +* :py:meth:`~GPy.constraints.Exponent` +* :py:meth:`~GPy.constraints.Square` +* :py:meth:`~GPy.constraints.Logistic` +* :py:meth:`~GPy.constraints.LogexpNeg` +* :py:meth:`~GPy.constraints.NegativeExponent` +* :py:meth:`~GPy.constraints.NegativeLogexp` + + +Tying Parameters +============ +Not yet implemented for GPy version 0.6.0 + + +Optimizing the model +==================== + +Once we have finished defining the constraints, +we can now optimize the model with the function +``optimize``.:: + + m.Gaussian_noise.constrain_positive() + m.rbf.constrain_positive() + m.optimize() + +By deafult, GPy uses the lbfgsb optimizer. + +Some optional parameters may be discussed here. + +* ``optimizer``: which optimizer to use, currently there are ``lbfgsb, fmin_tnc, + scg, simplex`` or any unique identifier uniquely identifying an + optimizer. Thus, you can say ``m.optimize('bfgs') for using the + ``lbfgsb`` optimizer +* ``messages``: if the optimizer is verbose. Each optimizer has its + own way of printing, so do not be confused by differing messages of + different optimizers +* ``max_iters``: Maximum number of iterations to take. Some optimizers + see iterations as function calls, others as iterations of the + algorithm. Please be advised to look into ``scipy.optimize`` for + more instructions, if the number of iterations matter, so you can + give the right parameters to ``optimize()`` +* ``gtol``: only for some optimizers. Will determine the convergence + criterion, as the tolerance of gradient to finish the optimization. + +Further Reading +=============== + +All of the mechansiams for dealing +with parameters are baked right into GPy.core.model, from which all of +the classes in GPy.models inherrit. To learn how to construct your own +model, you might want to read :ref:`creating_new_models`. If you want +to learn how to create kernels, please refer to +:ref:`creating_new_kernels` diff --git a/doc/_build/html/_sources/tuto_kernel_overview.txt b/doc/_build/html/_sources/tuto_kernel_overview.txt new file mode 100644 index 00000000..fc93491a --- /dev/null +++ b/doc/_build/html/_sources/tuto_kernel_overview.txt @@ -0,0 +1,285 @@ + +**************************** +tutorial : A kernel overview +**************************** +The aim of this tutorial is to give a better understanding of the kernel objects in GPy and to list the ones that are already implemented. The code shown in this tutorial can be obtained at GPy/examples/tutorials.py or by running ``GPy.examples.tutorials.tuto_kernel_overview()``. + +First we import the libraries we will need :: + + import pylab as pb + import numpy as np + import GPy + pb.ion() + +For most kernels, the dimension is the only mandatory parameter to define a kernel object. However, it is also possible to specify the values of the parameters. For example, the three following commands are valid for defining a squared exponential kernel (ie rbf or Gaussian) :: + + ker1 = GPy.kern.RBF(1) # Equivalent to ker1 = GPy.kern.RBF(input_dim=1, variance=1., lengthscale=1.) + ker2 = GPy.kern.RBF(input_dim=1, variance = .75, lengthscale=2.) + ker3 = GPy.kern.RBF(1, .5, .5) + +A ``print`` and a ``plot`` functions are implemented to represent kernel objects. The commands :: + + print ker2 + + ker1.plot() + ker2.plot() + ker3.plot() + +return:: + + Name | Value | Constraints | Ties + ------------------------------------------------------- + rbf_variance | 0.7500 | | + rbf_lengthscale | 2.0000 | | + +.. figure:: Figures/tuto_kern_overview_basicplot.png + :align: center + :height: 300px + +Implemented kernels +=================== + +Many kernels are already implemented in GPy. The following figure gives a summary of most of them (a comprehensive list can be list can be found `here `_): + +.. figure:: Figures/tuto_kern_overview_allkern.png + :align: center + :height: 800px + +On the other hand, it is possible to use the `sympy` package to build new kernels. This will be the subject of another tutorial. + +Operations to combine kernels +============================= + +In ``GPy``, kernel objects can be added or multiplied. In both cases, two kinds of operations are possible since one can assume that the kernels to add/multiply are defined on the same space or on different subspaces. In other words, it is possible to use two kernels :math:`k_1,\ k_2` over :math:`\mathbb{R} \times \mathbb{R}` to create + + * a kernel over :math:`\mathbb{R} \times \mathbb{R}`: :math:`k(x,y) = k_1(x,y) \times k_2(x,y)`. + +This is available in GPy via the ``add`` and ``prod`` functions. Here is a quick example :: + + k1 = GPy.kern.RBF(1,1.,2.) + k2 = GPy.kern.Matern32(1, 0.5, 0.2) + + # Product of kernels + k_prod = k1.prod(k2) + + # Sum of kernels + k_add = k1.add(k2) + +.. # plots + pb.figure(figsize=(8,8)) + pb.subplot(2,2,1) + k_prod.plot() + pb.title('prod') + pb.subplot(2,2,2) + k_prodtens.plot() + pb.title('prod') + pb.subplot(2,2,3) + k_add.plot() + pb.title('sum') + pb.subplot(2,2,4) + k_addtens.plot() + pb.title('sum') + pb.subplots_adjust(wspace=0.3, hspace=0.3) + +.. figure:: Figures/tuto_kern_overview_multadd.png + :align: center + :height: 500px + +A shortcut for ``add`` and ``prod`` is provided by the usual ``+`` and ``*`` operators. Here is another example where we create a periodic kernel with some decay :: + + k1 = GPy.kern.RBF(1,1.,2) + k2 = GPy.kern.PeriodicMatern52(1,variance=1e3, lengthscale=1, period = 1.5, lower=-5., upper = 5) + + k = k1 * k2 # equivalent to k = k1.prod(k2) + print k + + # Simulate sample paths + X = np.linspace(-5,5,501)[:,None] + Y = np.random.multivariate_normal(np.zeros(501),k.K(X),1) + +.. # plot + pb.figure(figsize=(10,4)) + pb.subplot(1,2,1) + k.plot() + pb.subplot(1,2,2) + pb.plot(X,Y.T) + pb.ylabel("Sample path") + pb.subplots_adjust(wspace=0.3) + +.. figure:: Figures/tuto_kern_overview_multperdecay.png + :align: center + :height: 300px + +In general, ``kern`` objects can be seen as a sum of ``kernparts`` objects, where the later are covariance functions defined on the same space. For example, the following code :: + + k = (k1+k2)*(k1+k2) + print k.parts[0].name, '\n', k.parts[1].name, '\n', k.parts[1].parts[0].name, '\n', k.parts[1].parts[1].name, '\n' + +returns :: + add_1 + add_2 + rbf + periodic_Matern52 + + +Constraining the parameters +=========================== + +Various constrains can be applied to the parameters of a kernel + + * ``constrain_fixed`` to fix the value of a parameter (the value will not be modified during optimisation) + * ``constrain_positive`` to make sure the parameter is greater than 0. + * ``constrain_bounded`` to impose the parameter to be in a given range. + * ``tie_params`` to impose the value of two (or more) parameters to be equal. + +When calling one of these functions, the parameters to constrain can either by specified by a regular expression that matches its name or by a number that corresponds to the rank of the parameter. Here is an example :: + + k1 = GPy.kern.RBF(1) + k2 = GPy.kern.Matern32(1) + k3 = GPy.kern.White(1) + + k = k1 + k2 + k3 + print k + + k.constrain_positive('.*var') + k.constrain_fixed(np.array([1]),1.75) + k.tie_params('.*len') + k.unconstrain('white') + k.constrain_bounded('white',lower=1e-5,upper=.5) + print k + +with output:: + + Name | Value | Constraints | Ties + --------------------------------------------------------- + rbf_variance | 1.0000 | | + rbf_lengthscale | 1.0000 | | + Mat32_variance | 1.0000 | | + Mat32_lengthscale | 1.0000 | | + white_variance | 1.0000 | | + + + Name | Value | Constraints | Ties + ---------------------------------------------------------- + rbf_variance | 1.0000 | (+ve) | + rbf_lengthscale | 1.7500 | Fixed | (0) + Mat32_variance | 1.0000 | (+ve) | + Mat32_lengthscale | 1.7500 | | (0) + white_variance | 0.3655 | (1e-05, 0.5) | + + +Example : Building an ANOVA kernel +================================== + +In two dimensions ANOVA kernels have the following form: + +.. math:: + + k_{ANOVA}(x,y) = \prod_{i=1}^2 (1 + k_i(x_i,y_i)) = 1 + k_1(x_1,y_1) + k_2(x_2,y_2) + k_1(x_1,y_1) \times k_2(x_2,y_2). + +Let us assume that we want to define an ANOVA kernel with a Matern 3/2 kernel for :math:`k_i`. As seen previously, we can define this kernel as follows :: + + k_cst = GPy.kern.Bias(1,variance=1.) + k_mat = GPy.kern.Matern52(1,variance=1.,lengthscale=3) + Kanova = (k_cst + k_mat).prod(k_cst + k_mat) + print Kanova + +Printing the resulting kernel outputs the following :: + + Name | Value | Constraints | Ties + --------------------------------------------------------------------------- + biasbias_bias_variance | 1.0000 | | (0) + biasbias_bias_variance | 1.0000 | | (3) + biasMat52_bias_variance | 1.0000 | | (0) + biasMat52_Mat52_variance | 1.0000 | | (4) + biasMat52_Mat52_lengthscale | 3.0000 | | (5) + Mat52bias_Mat52_variance | 1.0000 | | (1) + Mat52bias_Mat52_lengthscale | 3.0000 | | (2) + Mat52bias_bias_variance | 1.0000 | | (3) + Mat52Mat52_Mat52_variance | 1.0000 | | (1) + Mat52Mat52_Mat52_lengthscale | 3.0000 | | (2) + Mat52Mat52_Mat52_variance | 1.0000 | | (4) + Mat52Mat52_Mat52_lengthscale | 3.0000 | | (5) + +Note the ties between the parameters of ``Kanova`` that reflect the links between the parameters of the kernparts objects. We can illustrate the use of this kernel on a toy example:: + + # sample inputs and outputs + X = np.random.uniform(-3.,3.,(40,2)) + Y = 0.5*X[:,:1] + 0.5*X[:,1:] + 2*np.sin(X[:,:1]) * np.sin(X[:,1:]) + + # Create GP regression model + m = GPy.models.GPRegression(X,Y,Kanova) + m.plot() + +.. figure:: Figures/tuto_kern_overview_mANOVA.png + :align: center + :height: 300px + +As :math:`k_{ANOVA}` corresponds to the sum of 4 kernels, the best predictor can be splited in a sum of 4 functions + +.. math:: + + bp(x) & = k(x)^t K^{-1} Y \\ + & = (1 + k_1(x_1) + k_2(x_2) + k_1(x_1)k_2(x_2))^t K^{-1} Y \\ + & = 1^t K^{-1} Y + k_1(x_1)^t K^{-1} Y + k_2(x_2)^t K^{-1} Y + (k_1(x_1)k_2(x_2))^t K^{-1} Y + +The submodels can be represented with the option ``which_function`` of ``plot``: :: + + pb.figure(figsize=(20,3)) + pb.subplots_adjust(wspace=0.5) + axs = pb.subplot(1,5,1) + m.plot(ax=axs) + pb.subplot(1,5,2) + pb.ylabel("= ",rotation='horizontal',fontsize='30') + axs = pb.subplot(1,5,3) + m.plot(ax=axs, which_parts=[False,True,False,False]) + pb.ylabel("cst +",rotation='horizontal',fontsize='30') + axs = pb.subplot(1,5,4) + m.plot(ax=axs, which_parts=[False,False,True,False]) + pb.ylabel("+ ",rotation='horizontal',fontsize='30') + axs = pb.subplot(1,5,5) + pb.ylabel("+ ",rotation='horizontal',fontsize='30') + m.plot(ax=axs, which_parts=[False,False,False,True]) + +.. pb.savefig('tuto_kern_overview_mANOVAdec.png',bbox_inches='tight') + +.. figure:: Figures/tuto_kern_overview_mANOVAdec.png + :align: center + :height: 250px + + +.. # code + import pylab as pb + import numpy as np + import GPy + pb.ion() + + ker1 = GPy.kern.RBF(D=1) # Equivalent to ker1 = GPy.kern.RBF(D=1, variance=1., lengthscale=1.) + ker2 = GPy.kern.RBF(D=1, variance = .75, lengthscale=3.) + ker3 = GPy.kern.RBF(1, .5, .25) + + ker1.plot() + ker2.plot() + ker3.plot() + #pb.savefig("Figures/tuto_kern_overview_basicdef.png") + + kernels = [GPy.kern.RBF(1), GPy.kern.Exponential(1), GPy.kern.Matern32(1), GPy.kern.Matern52(1), GPy.kern.Brownian(1), GPy.kern.Bias(1), GPy.kern.Linear(1), GPy.kern.PeriodicExponential(1), GPy.kern.PeriodicMatern32(1), GPy.kern.PeriodicMatern52(1), GPy.kern.White(1)] + kernel_names = ["GPy.kern.RBF", "GPy.kern.Exponential", "GPy.kern.Matern32", "GPy.kern.Matern52", "GPy.kern.Brownian", "GPy.kern.Bias", "GPy.kern.Linear", "GPy.kern.PeriodicExponential", "GPy.kern.PeriodicMatern32", "GPy.kern.PeriodicMatern52", "GPy.kern.White"] + + pb.figure(figsize=(16,12)) + pb.subplots_adjust(wspace=.5, hspace=.5) + for i, kern in enumerate(kernels): + pb.subplot(3,4,i+1) + kern.plot(x=7.5,plot_limits=[0.00001,15.]) + pb.title(kernel_names[i]+ '\n') + #pb.axes([.1,.1,.8,.7]) + #pb.figtext(.5,.9,'Foo Bar', fontsize=18, ha='center') + #pb.figtext(.5,.85,'Lorem ipsum dolor sit amet, consectetur adipiscing elit',fontsize=10,ha='center') + + # actual plot for the noise + i = 11 + X = np.linspace(0.,15.,201) + WN = 0*X + WN[100] = 1. + pb.subplot(3,4,i+1) + pb.plot(X,WN,'b') diff --git a/doc/_build/html/_sources/tuto_parameterized.txt b/doc/_build/html/_sources/tuto_parameterized.txt new file mode 100644 index 00000000..507ec109 --- /dev/null +++ b/doc/_build/html/_sources/tuto_parameterized.txt @@ -0,0 +1,23 @@ +.. _parameterized: + +******************* +Parameterization handling +******************* + +Parameterization in GPy is done through so called parameter handles. The parameter handles are handles to parameters of a model of any kind. A parameter handle can be constrained, fixed, randomized and others. All parameters in GPy have a name, with which they can be accessed in the model. The most common way of accesssing a parameter programmatically though, is by variable name. + +Parameter handles +============== + +A parameter handle in GPy is a handle on a parameter, as the name suggests. A parameter can be constrained, fixed, randomized and more (See e.g. `working with models`). This gives the freedom to the model to handle parameter distribution and model updates as efficiently as possible. All parameter handles share a common memory space, which is just a flat numpy array, stored in the highest parent of a model hierarchy. +In the following we will introduce and elucidate the different parameter handles which exist in GPy. + +:py:class:`~GPy.core.parameterization.parameterized.Parameterized` +========== + +A parameterized object itself holds parameter handles and is just a summarization of the parameters below. It can use those parameters to change the internal state of the model and GPy ensures those parameters to allways hold the right value when in an optimization routine or any other update. + +:py:class:`~GPy.core.parameterization.param.Param` +=========== + +The lowest level of parameter is a numpy array. This Param class inherits all functionality of a numpy array and can simply be used as if it where a numpy array. These parameters can be accessed in the same way as a numpy array is indexed. diff --git a/doc/_build/html/_static/ajax-loader.gif b/doc/_build/html/_static/ajax-loader.gif new file mode 100644 index 00000000..61faf8ca Binary files /dev/null and b/doc/_build/html/_static/ajax-loader.gif differ diff --git a/doc/_build/html/_static/basic.css b/doc/_build/html/_static/basic.css new file mode 100644 index 00000000..9fa77d88 --- /dev/null +++ b/doc/_build/html/_static/basic.css @@ -0,0 +1,599 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + width: 170px; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + width: 30px; +} + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable dl, table.indextable dd { + margin-top: 0; + margin-bottom: 0; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- general body styles --------------------------------------------------- */ + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.field-list ul { + padding-left: 1em; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.field-list td, table.field-list th { + border: 0 !important; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, .highlighted { + background-color: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +div.code-block-caption { + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +div.code-block-caption + div > div.highlight > pre { + margin-top: 0; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + padding: 1em 1em 0; +} + +div.literal-block-wrapper div.highlight { + margin: 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/doc/_build/html/_static/classic.css b/doc/_build/html/_static/classic.css new file mode 100644 index 00000000..2da92346 --- /dev/null +++ b/doc/_build/html/_static/classic.css @@ -0,0 +1,261 @@ +/* + * default.css_t + * ~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- default theme. + * + * :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: sans-serif; + font-size: 100%; + background-color: #11303d; + color: #000; + margin: 0; + padding: 0; +} + +div.document { + background-color: #1c4e63; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.body { + background-color: #ffffff; + color: #000000; + padding: 0 20px 30px 20px; +} + +div.footer { + color: #ffffff; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #ffffff; + text-decoration: underline; +} + +div.related { + background-color: #133f52; + line-height: 30px; + color: #ffffff; +} + +div.related a { + color: #ffffff; +} + +div.sphinxsidebar { +} + +div.sphinxsidebar h3 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.4em; + font-weight: normal; + margin: 0; + padding: 0; +} + +div.sphinxsidebar h3 a { + color: #ffffff; +} + +div.sphinxsidebar h4 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} + +div.sphinxsidebar p { + color: #ffffff; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; + color: #ffffff; +} + +div.sphinxsidebar a { + color: #98dbcc; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + + + +/* -- hyperlink styles ------------------------------------------------------ */ + +a { + color: #355f7c; + text-decoration: none; +} + +a:visited { + color: #355f7c; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + + + +/* -- body styles ----------------------------------------------------------- */ + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Trebuchet MS', sans-serif; + background-color: #f2f2f2; + font-weight: normal; + color: #20435c; + border-bottom: 1px solid #ccc; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + text-align: justify; + line-height: 130%; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.admonition p { + margin-bottom: 5px; +} + +div.admonition pre { + margin-bottom: 5px; +} + +div.admonition ul, div.admonition ol { + margin-bottom: 5px; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: #eeffcc; + color: #333333; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +code { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} + +th { + background-color: #ede; +} + +.warning code { + background: #efc2c2; +} + +.note code { + background: #d6d6d6; +} + +.viewcode-back { + font-family: sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} + +div.code-block-caption { + color: #efefef; + background-color: #1c4e63; +} \ No newline at end of file diff --git a/doc/_build/html/_static/comment-bright.png b/doc/_build/html/_static/comment-bright.png new file mode 100644 index 00000000..551517b8 Binary files /dev/null and b/doc/_build/html/_static/comment-bright.png differ diff --git a/doc/_build/html/_static/comment-close.png b/doc/_build/html/_static/comment-close.png new file mode 100644 index 00000000..09b54be4 Binary files /dev/null and b/doc/_build/html/_static/comment-close.png differ diff --git a/doc/_build/html/_static/comment.png b/doc/_build/html/_static/comment.png new file mode 100644 index 00000000..92feb52b Binary files /dev/null and b/doc/_build/html/_static/comment.png differ diff --git a/doc/_build/html/_static/default.css b/doc/_build/html/_static/default.css new file mode 100644 index 00000000..5f1399ab --- /dev/null +++ b/doc/_build/html/_static/default.css @@ -0,0 +1,256 @@ +/* + * default.css_t + * ~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- default theme. + * + * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: sans-serif; + font-size: 100%; + background-color: #11303d; + color: #000; + margin: 0; + padding: 0; +} + +div.document { + background-color: #1c4e63; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.body { + background-color: #ffffff; + color: #000000; + padding: 0 20px 30px 20px; +} + +div.footer { + color: #ffffff; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #ffffff; + text-decoration: underline; +} + +div.related { + background-color: #133f52; + line-height: 30px; + color: #ffffff; +} + +div.related a { + color: #ffffff; +} + +div.sphinxsidebar { +} + +div.sphinxsidebar h3 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.4em; + font-weight: normal; + margin: 0; + padding: 0; +} + +div.sphinxsidebar h3 a { + color: #ffffff; +} + +div.sphinxsidebar h4 { + font-family: 'Trebuchet MS', sans-serif; + color: #ffffff; + font-size: 1.3em; + font-weight: normal; + margin: 5px 0 0 0; + padding: 0; +} + +div.sphinxsidebar p { + color: #ffffff; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; + color: #ffffff; +} + +div.sphinxsidebar a { + color: #98dbcc; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + + + +/* -- hyperlink styles ------------------------------------------------------ */ + +a { + color: #355f7c; + text-decoration: none; +} + +a:visited { + color: #355f7c; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + + + +/* -- body styles ----------------------------------------------------------- */ + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Trebuchet MS', sans-serif; + background-color: #f2f2f2; + font-weight: normal; + color: #20435c; + border-bottom: 1px solid #ccc; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + text-align: justify; + line-height: 130%; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.admonition p { + margin-bottom: 5px; +} + +div.admonition pre { + margin-bottom: 5px; +} + +div.admonition ul, div.admonition ol { + margin-bottom: 5px; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: #eeffcc; + color: #333333; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +tt { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} + +th { + background-color: #ede; +} + +.warning tt { + background: #efc2c2; +} + +.note tt { + background: #d6d6d6; +} + +.viewcode-back { + font-family: sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} \ No newline at end of file diff --git a/doc/_build/html/_static/doctools.js b/doc/_build/html/_static/doctools.js new file mode 100644 index 00000000..c7bfe760 --- /dev/null +++ b/doc/_build/html/_static/doctools.js @@ -0,0 +1,263 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s == 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node) { + if (node.nodeType == 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span = document.createElement("span"); + span.className = className; + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this); + }); + } + } + return this.each(function() { + highlight(this); + }); +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated == 'undefined') + return string; + return (typeof translated == 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated == 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) == 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this == '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/doc/_build/html/_static/down-pressed.png b/doc/_build/html/_static/down-pressed.png new file mode 100644 index 00000000..7c30d004 Binary files /dev/null and b/doc/_build/html/_static/down-pressed.png differ diff --git a/doc/_build/html/_static/down.png b/doc/_build/html/_static/down.png new file mode 100644 index 00000000..f48098a4 Binary files /dev/null and b/doc/_build/html/_static/down.png differ diff --git a/doc/_build/html/_static/file.png b/doc/_build/html/_static/file.png new file mode 100644 index 00000000..254c60bf Binary files /dev/null and b/doc/_build/html/_static/file.png differ diff --git a/doc/_build/html/_static/jquery-1.11.1.js b/doc/_build/html/_static/jquery-1.11.1.js new file mode 100644 index 00000000..d4b67f7e --- /dev/null +++ b/doc/_build/html/_static/jquery-1.11.1.js @@ -0,0 +1,10308 @@ +/*! + * jQuery JavaScript Library v1.11.1 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-05-01T17:42Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var deletedIds = []; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "1.11.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1, IE<9 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( support.ownLast ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1, IE<9 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( indexOf ) { + return indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: function() { + return +( new Date() ); + }, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v1.10.19 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-04-18 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== strundefined && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", function() { + setDocument(); + }); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { + div.innerHTML = "
"; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowclip^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + + } else if ( !(--remaining) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + + +var strundefined = typeof undefined; + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownLast = i !== "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +// Execute ASAP in case we need to set body.style.zoom +jQuery(function() { + // Minified: var a,b,c,d + var val, div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Return for frameset docs that don't have a body + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; + + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; + if ( val ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); +}); + + + + +(function() { + var div = document.createElement( "div" ); + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( elem ) { + var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute("classid") === noData; +}; + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties + noData: { + "applet ": true, + "embed ": true, + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[0], + attrs = elem && elem.attributes; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; +}; +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + // Minified: var a,b,c + var input = document.createElement( "input" ), + div = document.createElement( "div" ), + fragment = document.createDocumentFragment(); + + // Setup + div.innerHTML = "
a"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + div.innerHTML = ""; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + support.noCloneEvent = true; + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } +})(); + + +(function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) + for ( i in { submit: true, change: true, focusin: true }) { + eventName = "on" + i; + + if ( !(support[ i + "Bubbles" ] = eventName in window) ) { + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: IE < 9, Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!support.noCloneEvent || !support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + deletedIds.push( id ); + } + } + } + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "