Merge kernel source.

This commit is contained in:
Neil Lawrence 2014-04-23 12:21:05 +01:00
commit 643f338337
6 changed files with 70 additions and 59 deletions

View file

@ -12,6 +12,7 @@ from _src.ssrbf import SSRBF # TODO: ZD: did you remove this?
from _src.ODE_UY import ODE_UY from _src.ODE_UY import ODE_UY
# TODO: put this in an init file somewhere # TODO: put this in an init file somewhere
#I'm commenting this out because the files were not added. JH. Remember to add the files before commiting
try: try:
import sympy as sym import sympy as sym
sympy_available=True sympy_available=True
@ -19,8 +20,8 @@ except ImportError:
sympy_available=False sympy_available=False
if sympy_available: if sympy_available:
from _src.symbolic import Symbolic from _src.symbolic2 import Symbolic
from _src.eq import Eq from _src.eq import Eq
from _src.heat_eqinit import Heat_eqinit from _src.heat_eqinit import Heat_eqinit
from _src.ode1_eq_lfm import Ode1_eq_lfm #from _src.ode1_eq_lfm import Ode1_eq_lfm

View file

@ -7,16 +7,17 @@ from student_t import StudentT
from likelihood import Likelihood from likelihood import Likelihood
from mixed_noise import MixedNoise from mixed_noise import MixedNoise
# TODO need to fix this in a config file. # TODO need to fix this in a config file.
try: # TODO need to add the files to the git repo!
import sympy as sym #try:
sympy_available=True #import sympy as sym
except ImportError: #sympy_available=True
sympy_available=False #except ImportError:
if sympy_available: #sympy_available=False
# These are likelihoods that rely on symbolic. #if sympy_available:
from symbolic import Symbolic ## These are likelihoods that rely on symbolic.
from sstudent_t import SstudentT #from symbolic import Symbolic
from negative_binomial import Negative_binomial #from sstudent_t import SstudentT
from skew_normal import Skew_normal #from negative_binomial import Negative_binomial
from skew_exponential import Skew_exponential ##from skew_normal import Skew_normal
#from skew_exponential import Skew_exponential
#from null_category import Null_category #from null_category import Null_category

View file

@ -16,10 +16,9 @@ def ax_default(fignum, ax):
def meanplot(x, mu, color=Tango.colorsHex['darkBlue'], ax=None, fignum=None, linewidth=2,**kw): def meanplot(x, mu, color=Tango.colorsHex['darkBlue'], ax=None, fignum=None, linewidth=2,**kw):
_, axes = ax_default(fignum, ax) _, axes = ax_default(fignum, ax)
#here's the mean
return axes.plot(x,mu,color=color,linewidth=linewidth,**kw) return axes.plot(x,mu,color=color,linewidth=linewidth,**kw)
def gpplot(x,mu,lower,upper,edgecol=Tango.colorsHex['darkBlue'],fillcol=Tango.colorsHex['lightBlue'],ax=None,fignum=None,xlabel='x',ylabel='y',**kwargs): def gpplot(x, mu, lower, upper, edgecol=Tango.colorsHex['darkBlue'], fillcol=Tango.colorsHex['lightBlue'], ax=None, fignum=None, **kwargs):
_, axes = ax_default(fignum, ax) _, axes = ax_default(fignum, ax)
mu = mu.flatten() mu = mu.flatten()
@ -42,9 +41,6 @@ def gpplot(x,mu,lower,upper,edgecol=Tango.colorsHex['darkBlue'],fillcol=Tango.co
plots.append(meanplot(x, upper,color=edgecol,linewidth=0.2,ax=axes)) plots.append(meanplot(x, upper,color=edgecol,linewidth=0.2,ax=axes))
plots.append(meanplot(x, lower,color=edgecol,linewidth=0.2,ax=axes)) plots.append(meanplot(x, lower,color=edgecol,linewidth=0.2,ax=axes))
axes.set_xlabel(xlabel)
axes.set_ylabel(ylabel)
return plots return plots
@ -53,11 +49,13 @@ def removeRightTicks(ax=None):
for i, line in enumerate(ax.get_yticklines()): for i, line in enumerate(ax.get_yticklines()):
if i%2 == 1: # odd indices if i%2 == 1: # odd indices
line.set_visible(False) line.set_visible(False)
def removeUpperTicks(ax=None): def removeUpperTicks(ax=None):
ax = ax or pb.gca() ax = ax or pb.gca()
for i, line in enumerate(ax.get_xticklines()): for i, line in enumerate(ax.get_xticklines()):
if i%2 == 1: # odd indices if i%2 == 1: # odd indices
line.set_visible(False) line.set_visible(False)
def fewerXticks(ax=None,divideby=2): def fewerXticks(ax=None,divideby=2):
ax = ax or pb.gca() ax = ax or pb.gca()
ax.set_xticks(ax.get_xticks()[::divideby]) ax.set_xticks(ax.get_xticks()[::divideby])

View file

@ -12,6 +12,7 @@ For a quick start, you can have a look at one of the tutorials:
* `A kernel overview <tuto_kernel_overview.html>`_ * `A kernel overview <tuto_kernel_overview.html>`_
* `Writing new kernels <tuto_creating_new_kernels.html>`_ * `Writing new kernels <tuto_creating_new_kernels.html>`_
* `Writing new models <tuto_creating_new_models.html>`_ * `Writing new models <tuto_creating_new_models.html>`_
* `Parameterization handles <tuto_parameterized.html>`_
You may also be interested by some examples in the GPy/examples folder. You may also be interested by some examples in the GPy/examples folder.

View file

@ -8,57 +8,44 @@ In GPy all models inherit from the base class :py:class:`~GPy.core.parameterized
The :py:class:`~GPy.core.model.Model` class provides parameter introspection, objective function and optimization. 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. 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}`. 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 Obligatory methods
================== ==================
:py:meth:`~GPy.core.model.Model.__init__` : :py:meth:`~GPy.core.model.Model.__init__` :
Initialize the model with the given parameters. In our example we have to store shape information of :math:`\mathbf X` and the parameters themselves:: Initialize the model with the given parameters. These need to
be added to the model by calling
`self.add_parameter(<param>)`, where param needs to be a
parameter handle (See parameterized_ for details).::
self.X = X self.X = GPy.core.Param("input", X)
self.num_inputs = self.X.shape[0] self.add_parameter(self.X)
assert self.X.ndim == 1, only vector inputs allowed
:py:meth:`~GPy.core.model.Model._get_params` :
Return parameters of the model as a flattened numpy array-like. So, in our example we have to return the input parameters::
return self.X.flatten()
:py:meth:`~GPy.core.model.Model._set_params` :
Set parameters, which have been fetched through :py:meth:`~GPy.core.model.Model._get_params`. In other words, "invert" the functionality of :py:meth:`~GPy.core.model.Model._get_params`::
self.X = params[:self.num_inputs*self.input_dim].reshape(self.num_inputs)
:py:meth:`~GPy.core.model.Model.log_likelihood` : :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``:: 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) return -scipy.optimize.rosen(self.X)
:py:meth:`~GPy.core.model.Model._log_likelihood_gradients` : :py:meth:`~GPy.core.model.Model.parameters_changed` :
Returns the gradients with respect to all parameters:: 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 put the negative derivative of
the rosenbrock function:
return scipy.optimize.rosen_der(self.X) self.X.gradient = -scipy.optimize.rosen_der(self.X)
Optional methods Optional methods
================ ================
If you want some special functionality please provide the following methods: Currently none.
Using the pickle functionality
------------------------------
To be able to use the pickle functionality ``m.pickle(<path>)`` the methods ``getstate(self)`` and ``setstate(self, state)`` have to be provided. The convention for a ``state`` in ``GPy`` is a list of all parameters, which are needed to restore the model. All classes provided in ``GPy`` follow this convention, thus you can just append to the state of the inherited class and call the inherited class' ``setstate`` with the appropriate state.
:py:meth:`~GPy.core.model.Model.getstate` :
This method returns a state of the model, following the memento pattern. As we are inheriting from :py:class:`~GPy.core.model.Model`, we have to return the state of Model as well. In out example we have `X` and `num_inputs` as state::
return Model.getstate(self) + [self.X, self.num_inputs]
:py:meth:`~GPy.core.model.Model.setstate` :
This method restores this model with the given ``state``::
self.num_inputs = state.pop()
self.X = state.pop()
return Model.setstate(self, state)

View file

@ -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.