Source code for pyGPs.Core.cov

#================================================================================
#    Marion Neumann [marion dot neumann at uni-bonn dot de]
#    Daniel Marthaler [dan dot marthaler at gmail dot com]
#    Shan Huang [shan dot huang at iais dot fraunhofer dot de]
#    Kristian Kersting [kristian dot kersting at cs dot tu-dortmund dot de]
#
#    This file is part of pyGPs.
#    The software package is released under the BSD 2-Clause (FreeBSD) License.
#
#    Copyright (c) by
#    Marion Neumann, Daniel Marthaler, Shan Huang & Kristian Kersting, 18/02/2014
#================================================================================
# covariance functions to be use by Gaussian process functions. There are two
# different kinds of covariance functions: simple and composite:
#
# simple cov functions:
#
# Gabor         - Gabor covariance function
# SM            - Spectral Mixture covariance function
# Poly          - Polynomial covariance function
# PiecePoly     - Piecewise polynomial kernel with compact support.
# RBF           - Squared Exponential kernel.
# RBFunit       - Squared Exponential kernel with unit magnitude.
# RBFard        - Squared Exponential kernel with Automatic Relevance Determination.
# Const         - Constant kernel.
# Linear        - Linear kernel.
# LINard        - Linear covariance function with Automatic Relevance Detemination.
# Matern        - Matern covariance function.
# Periodic      - Stationary kernel for a smooth periodic function.
# Noise         - Independent covariance function, i.e "white noise".
# RQ            - Rational Quadratic covariance function with isotropic distance measure.
# RQard         - Rational Quadratic covariance function with ARD distance measure.
# Pre           - Precomputed kernel matrix.
#
# composite covariance functions:
#
#   ScaleOfKernel     - scaled version of a covariance function
#   ProductOfKernel   - products of covariance functions
#   SumOfKernel       - sums of covariance functions
#   FITCOfKernel      - Covariance function to be used together with the FITC approximation
#
#
# This is a object-oriented python implementation of gpml functionality
# (Copyright (c) by Carl Edward Rasmussen and Hannes Nickisch, 2011-02-18).
# based on the functional-version of python implementation
# (Copyright (c) by Marion Neumann and Daniel Marthaler, 20/05/2013)
#
# Copyright (c) by Marion Neumann and Shan Huang, 30/09/2013


import numpy as np
import math
import scipy.spatial.distance as spdist

[docs]class Kernel(object): """ This is a base class of Kernel functions there is no computation in this class, it just defines rules about a kernel class should have each covariance function will inherit it and implement its own behaviour """ def __init__(self): self.hyp = [] self.para = [] def __repr__(self): strvalue =str(type(self))+': to get the kernel matrix or kernel derviatives use: \n'+\ 'model.covfunc.getCovMatrix()\n'+\ 'model.covfunc.getDerMatrix()' return strvalue
[docs] def getCovMatrix(self,x=None,z=None,mode=None): ''' Return the specific covariance matrix according to input mode :param x: training data :param z: test data :param str mode: 'self_test' return self covariance matrix of test data(test by 1). 'train' return training covariance matrix(train by train). 'cross' return cross covariance matrix between x and z(train by test) :return: the corresponding covariance matrix ''' pass
[docs] def getDerMatrix(self,x=None,z=None,mode=None,der=None): ''' Compute derivatives wrt. hyperparameters according to input mode :param x: training data :param z: test data :param str mode: 'self_test' return self derivative matrix of test data(test by 1). 'train' return training derivative matrix(train by train). 'cross' return cross derivative matrix between x and z(train by test) :param int der: index of hyperparameter whose derivative to be computed :return: the corresponding derivative matrix ''' pass
[docs] def checkInputGetCovMatrix(self,x,z,mode): ''' Check validity of inputs for the method getCovMatrix() :param x: training data :param z: test data :param str mode: 'self_test' return self derivative matrix of test data(test by 1). 'train' return training derivative matrix(train by train). 'cross' return cross derivative matrix between x and z(train by test) ''' if mode is None: raise Exception("Specify the mode: 'train' or 'cross'") if x is None and z is None: raise Exception("Specify at least one: training input (x) or test input (z) or both.") if mode == 'cross': if x is None or z is None: raise Exception("Specify both: training input (x) and test input (z) for cross covariance.")
[docs] def checkInputGetDerMatrix(self,x,z,mode,der): ''' Check validity of inputs for the method getDerMatrix() :param x: training data :param z: test data :param str mode: 'self_test' return self derivative matrix of test data(test by 1). 'train' return training derivative matrix(train by train). 'cross' return cross derivative matrix between x and z(train by test) :param int der: index of hyperparameter whose derivative to be computed ''' if mode is None: raise Exception("Specify the mode: 'train' or 'cross'") if x is None and z is None: raise Exception("Specify at least one: training input (x) or test input (z) or both.") if mode == 'cross': if x is None or z is None: raise Exception("Specify both: training input (x) and test input (z) for cross covariance.") if der is None: raise Exception("Specify the index of parameters of the derivatives.") # overloading
def __add__(self,cov): ''' Overloading + operator. :param cov: covariance function :return: an instance of SumOfKernel ''' return SumOfKernel(self,cov) # overloading def __mul__(self,other): ''' Overloading * operator. Using * for both multiplication with scalar and product of kernels depending on the type of the two objects. :param other: covariance function as product or int/float as scalar :return: an instance of ScaleOfKernel or ProductOfKernel ''' if isinstance(other, int) or isinstance(other, float): return ScaleOfKernel(self,other) elif isinstance(other, Kernel): return ProductOfKernel(self,other) else: print "only numbers and Kernels are supported operand types for *" # overloading __rmul__ = __mul__
[docs] def fitc(self,inducingInput): ''' Covariance function to be used together with the FITC approximation. Setting FITC gp model will implicitly call this method. :return: an instance of FITCOfKernel ''' return FITCOfKernel(self,inducingInput) # can be replaced by spdist from scipy
def _sq_dist(self, a, b=None): '''Compute a matrix of all pairwise squared distances between two sets of vectors, stored in the row of the two matrices: a (of size n by D) and b (of size m by D).''' n = a.shape[0] D = a.shape[1] m = n if b is None: b = a.transpose() else: m = b.shape[0] b = b.transpose() C = np.zeros((n,m)) for d in range(0,D): tt = a[:,d] tt = tt.reshape(n,1) tem = np.kron(np.ones((1,m)), tt) tem = tem - np.kron(np.ones((n,1)), b[d,:]) C = C + tem * tem return C
[docs]class ProductOfKernel(Kernel): '''Product of two kernel function.''' def __init__(self,cov1,cov2): self.cov1 = cov1 self.cov2 = cov2 self._hyp = cov1.hyp + cov2.hyp def _setHyp(self,hyp): assert len(hyp) == len(self._hyp) len1 = len(self.cov1.hyp) self._hyp = hyp self.cov1.hyp = self._hyp[:len1] self.cov2.hyp = self._hyp[len1:] def _getHyp(self): return self._hyp hyp = property(_getHyp,_setHyp) def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) A = self.cov1.getCovMatrix(x,z,mode) * self.cov2.getCovMatrix(x,z,mode) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) if der < len(self.cov1.hyp): A = self.cov1.getDerMatrix(x,z,mode,der) * self.cov2.getCovMatrix(x,z,mode) elif der < len(self.hyp): der2 = der - len(self.cov1.hyp) A = self.cov2.getDerMatrix(x,z,mode,der2) * self.cov1.getCovMatrix(x,z,mode) else: raise Exception("Error: der out of range for covProduct") return A
[docs]class SumOfKernel(Kernel): '''Sum of two kernel function.''' def __init__(self,cov1,cov2): self.cov1 = cov1 self.cov2 = cov2 self._hyp = cov1.hyp + cov2.hyp def _setHyp(self,hyp): assert len(hyp) == len(self._hyp) len1 = len(self.cov1.hyp) self._hyp = hyp self.cov1.hyp = self._hyp[:len1] self.cov2.hyp = self._hyp[len1:] def _getHyp(self): return self._hyp hyp = property(_getHyp,_setHyp) def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) A = self.cov1.getCovMatrix(x,z,mode) + self.cov2.getCovMatrix(x,z,mode) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) if der < len(self.cov1.hyp): A = self.cov1.getDerMatrix(x,z,mode,der) elif der < len(self.hyp): der2 = der - len(self.cov1.hyp) A = self.cov2.getDerMatrix(x,z,mode,der2) else: raise Exception("Error: der out of range for covSum") return A
[docs]class ScaleOfKernel(Kernel): '''Scale of a kernel function.''' def __init__(self,cov,scalar): self.cov = cov if cov.hyp: self._hyp = [scalar] + cov.hyp else: self._hyp = [scalar] def _setHyp(self,hyp): assert len(hyp) == len(self._hyp) self._hyp = hyp self.cov.hyp = self._hyp[1:] def _getHyp(self): return self._hyp hyp = property(_getHyp,_setHyp) def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) sf2 = np.exp(self.hyp[0]) # scale parameter A = sf2 * self.cov.getCovMatrix(x,z,mode) # accumulate cov return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) sf2 = np.exp(self.hyp[0]) # scale parameter if der == 0: # compute derivative w.r.t. sf2 A = 2. * sf2 * self.cov.getCovMatrix(x,z,mode) else: A = sf2 * self.cov.getDerMatrix(x,z,mode,der-1) return A
[docs]class FITCOfKernel(Kernel): ''' Covariance function to be used together with the FITC approximation. The function allows for more than one output argument and does not respect the interface of a proper covariance function. Instead of outputing the full covariance, it returns cross-covariances between the inputs x, z and the inducing inputs xu as needed by infFITC ''' def __init__(self,cov,inducingInput): self.inducingInput = inducingInput self.covfunc = cov self._hyp = cov.hyp def _getHyp(self): return self._hyp def _setHyp(self, hyp): self._hyp = hyp self.covfunc.hyp = hyp hyp = property(_getHyp,_setHyp) def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) xu = self.inducingInput if not x is None: try: assert(xu.shape[1] == x.shape[1]) except AssertionError: raise Exception('Dimensionality of inducing inputs must match training inputs') if mode == 'self_test': # self covariances for the test cases K = self.covfunc.getCovMatrix(z=z,mode='self_test') return K elif mode == 'train': # compute covariance matix for training set K = self.covfunc.getCovMatrix(z=x,mode='self_test') Kuu = self.covfunc.getCovMatrix(x=xu,mode='train') Ku = self.covfunc.getCovMatrix(x=xu,z=x,mode='cross') return K, Kuu, Ku elif mode == 'cross': # compute covariance between data sets x and z K = self.covfunc.getCovMatrix(x=xu,z=z,mode='cross') return K def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) xu = self.inducingInput if not x is None: try: assert(xu.shape[1] == x.shape[1]) except AssertionError: raise Exception('Dimensionality of inducing inputs must match training inputs') if mode == 'self_test': # self covariances for the test cases K = self.covfunc.getDerMatrix(z=z,mode='self_test',der=der) return K elif mode == 'train': # compute covariance matix for training set K = self.covfunc.getDerMatrix(z=x,mode='self_test',der=der) Kuu = self.covfunc.getDerMatrix(x=xu,mode='train',der=der) Ku = self.covfunc.getDerMatrix(x=xu,z=x,mode='cross',der=der) return K, Kuu, Ku elif mode == 'cross': # compute covariance between data sets x and z K = self.covfunc.getDerMatrix(x=xu,z=z,mode='cross',der=der) return K
[docs]class Gabor(Kernel): ''' Gabor covariance function with length scale ell and period p. The covariance function is parameterized as: k(x,z) = h( ||x-z|| ) with h(t) = exp(-t^2/(2*ell^2))*cos(2*pi*t/p). The hyperparameters are: hyp = [log(ell), log(p)] Note that SM covariance implements a weighted sum of Gabor covariance functions, but using an alternative (spectral) parameterization. :param log_ell: characteristic length scale. :param log_p: period. ''' def __init__(self, log_ell=0., log_p=0.): self.hyp = [log_ell, log_p] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) ell = np.exp(self.hyp[0]) # characteristic length scale p = np.exp(2. * self.hyp[1]) # period if mode == 'self_test': # self covariances for the test cases nn, D = z.shape A = np.zeros((nn, 1)) elif mode == 'train': # compute covariance matix for dataset x A = spdist.cdist(x / ell, x / ell, 'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z A = spdist.cdist(x / ell, z / ell, 'sqeuclidean') dp = 2 * np.pi * np.sqrt(A) * ell / p A = np.exp(-0.5 * A) * np.cos(dp) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) ell = np.exp(self.hyp[0]) # characteristic length scale p = np.exp(2. * self.hyp[1]) # period if mode == 'self_test': # self covariances for the test cases nn, D = z.shape A = np.zeros((nn, 1)) elif mode == 'train': # compute covariance matix for dataset x A = spdist.cdist(x / ell, x / ell, 'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z A = spdist.cdist(x / ell, z / ell, 'sqeuclidean') dp = 2 * np.pi * np.sqrt(A) * ell / p if der == 0: # compute derivative matrix wrt 1st parameter A = np.exp(-0.5 * A) * np.cos(dp) A = dp * A elif der == 1: # compute derivative matrix wrt 2nd parameter A = np.exp(-0.5 * A) * np.cos(dp) A = np.tan(dp) * dp * A else: raise Exception("Wrong derivative entry in Gabor") return A
[docs]class SM(Kernel): ''' Gaussian Spectral Mixture covariance function. The covariance function is parameterized as: k(x^p,x^q) = w'*prod( exp(-2*pi^2*d^2*v)*cos(2*pi*d*m), 2), d = |x^p,x^q| where m(DxQ), v(DxQ) are the means and variances of the spectral mixture components and w are the mixture weights. The hyperparameters are: hyp = [ log(w), log(m(:)), log(sqrt(v(:))) ] Copyright (c) by Andrew Gordon Wilson and Hannes Nickisch, 2013-10-09. For more details, see 1) Gaussian Process Kernels for Pattern Discovery and Extrapolation, ICML, 2013, by Andrew Gordon Wilson and Ryan Prescott Adams. 2) GPatt: Fast Multidimensional Pattern Extrapolation with Gaussian Processes, arXiv 1310.5288, 2013, by Andrew Gordon Wilson, Elad Gilboa, Arye Nehorai and John P. Cunningham, and http://mlg.eng.cam.ac.uk/andrew/pattern :param log_w: weight coefficients. :param log_m: spectral means (frequencies). :param log_v: spectral variances. ''' def __init__(self, Q=0, hyps=[], D=None): if D: self.hyp = np.random.random(Q*(1+2*D)) else: self.hyp = hyps self.para = [Q] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) Q = self.para[0] if mode == 'self_test': nn, D = z.shape else: nn, D = x.shape assert Q == len(self.hyp) / (1 + 2 * D) w = np.exp(self.hyp[:Q]) m = np.exp(np.reshape(self.hyp[Q:Q + Q * D], (D, Q))) v = np.exp(2 * np.reshape(self.hyp[Q + Q * D:], (D, Q))) if mode == 'self_test': # self covariances for the test cases d2 = np.zeros((nn, 1, D)) elif mode == 'train': # compute covariance matix for dataset x d2 = np.zeros((nn, nn, D)) for j in range(D): xslice = np.atleast_2d(x[:, j]).T d2[:, :, j] = spdist.cdist(xslice, xslice, 'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z d2 = np.zeros((nn, z.shape[0], D)) for j in range(D): xslice = np.atleast_2d(x[:, j]).T zslice = np.atleast_2d(z[:, j]).T d2[:, :, j] = spdist.cdist(xslice, zslice, 'sqeuclidean') d = np.sqrt(d2) k = lambda (d2v, dm): np.exp(-2 * np.pi ** 2 * d2v) * np.cos(2* np.pi * dm) # evaluation of the covariance km = lambda dm: -2 * np.pi * np.tan(2 * np.pi * dm) * dm # remainder when differentiating w.r.t. m kv = lambda d2v: -d2v * (2 * np.pi) ** 2 # remainder when differentiating w.r.t. v A = 0. c = 1. qq = range(Q) for q in qq: C = w[q] * c for j in range(D): C = C * k((d2[:, :, j] * v[j, q], d[:, :, j] * m[j, q])) A = A + C return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) Q = self.para[0] if mode == 'self_test': nn, D = z.shape else: nn, D = x.shape assert Q == len(self.hyp) / (1 + 2 * D) w = np.exp(self.hyp[:Q]) m = np.exp(np.reshape(self.hyp[Q:Q + Q * D], (D, Q))) v = np.exp(2 * np.reshape(self.hyp[Q + Q * D:], (D, Q))) if mode == 'self_test': # self covariances for the test cases d2 = np.zeros((nn, 1, D)) elif mode == 'train': # compute covariance matix for dataset x d2 = np.zeros((nn, nn, D)) for j in range(D): xslice = np.atleast_2d(x[:, j]).T d2[:, :, j] = spdist.cdist(xslice, xslice, 'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z d2 = np.zeros((nn, z.shape[0], D)) for j in range(D): xslice = np.atleast_2d(x[:, j]).T zslice = np.atleast_2d(z[:, j]).T d2[:, :, j] = spdist.cdist(xslice, zslice, 'sqeuclidean') d = np.sqrt(d2) k = lambda (d2v, dm): np.exp(-2 * np.pi ** 2 * d2v) * np.cos(2* np.pi * dm) # evaluation of the covariance km = lambda dm: -2 * np.pi * np.tan(2 * np.pi * dm) * dm # remainder when differentiating w.r.t. m kv = lambda d2v: -d2v * (2 * np.pi) ** 2 # remainder when differentiating w.r.t. v A = 0. c = 1. qq = range(Q) if der < Q: # compute derivative matrix wrt w c = 1 qq = [der] elif der < Q + Q * D: # compute derivative matrix wrt sig p = (der - Q) % D q = (der - Q - p) / D c = km(d[:, :, p] * m[p, q]) qq = [q] elif der < 2 * Q * D + Q: # compute derivative matrix wrt mu p = (der - (D + 1) * Q) % D q = (der - (D + 1) * Q - p) / D c = kv(d2[:, :, p] * v[p, q]) qq = [q] else: raise Exception("Wrong derivative entry in SM") for q in qq: C = w[q] * c for j in range(D): C = C * k((d2[:, :, j] * v[j, q], d[:, :, j] * m[j, q])) A = A + C return A
[docs]class Poly(Kernel): ''' Polynomial covariance function. hyp = [ log_c, log_sigma ] :param log_c: inhomogeneous offset. :param log_sigma: signal deviation. :param d: degree of polynomial (not treated as hyperparameter, i.e. will not be trained). ''' def __init__(self, log_c=0., d=2, log_sigma=0. ): self.hyp = [log_c, log_sigma] self.para = [d] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) c = np.exp(self.hyp[0]) # inhomogeneous offset sf2 = np.exp(2.*self.hyp[1]) # signal variance ord = self.para[0] # order of polynomial if np.abs(ord-np.round(ord)) < 1e-8: # remove numerical error from format of parameter ord = int(round(ord)) assert(ord >= 1.) # only nonzero integers for ord ord = int(ord) if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.reshape(np.sum(z*z,1), (nn,1)) elif mode == 'train': # compute covariance matix for dataset x n,D = x.shape A = np.dot(x,x.T) + np.eye(n)*1e-10 elif mode == 'cross': # compute covariance between data sets x and z A = np.dot(x,z.T) A = sf2 * (c + A)**ord return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) c = np.exp(self.hyp[0]) # inhomogeneous offset sf2 = np.exp(2.*self.hyp[1]) # signal variance ord = self.para[0] # order of polynomial if np.abs(ord-np.round(ord)) < 1e-8: # remove numerical error from format of parameter ord = int(round(ord)) assert(ord >= 1.) # only nonzero integers for ord ord = int(ord) if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.reshape(np.sum(z*z,1), (nn,1)) elif mode == 'train': # compute covariance matix for dataset x A = np.dot(x,x.T) elif mode == 'cross': # compute covariance between data sets x and z A = np.dot(x,z.T) if der == 0: # compute derivative matrix wrt 1st parameter A = c * ord * sf2 * (c+A)**(ord-1) elif der == 1: # compute derivative matrix wrt 2nd parameter A = 2. * sf2 * (c + A)**ord elif der == 2: # no derivative wrt 3rd parameter A = np.zeros_like(A) # do nothing (d is not learned) else: raise Exception("Wrong derivative entry in Poly") return A
[docs]class PiecePoly(Kernel): ''' Piecewise polynomial kernel with compact support. hyp = [log_ell, log_sigma] :param log_ell: characteristic length scale. :param log_sigma: signal deviation. :param v: degree v will be rounded to 0,1,2,or 3. (not treated as hyperparameter, i.e. will not be trained). ''' def __init__(self, log_ell=0., v=2, log_sigma=0. ): self.hyp = [log_ell, log_sigma] self.para = [v] def ppmax(self,A,B): return np.maximum(A,B*np.ones_like(A)) def func(self,v,r,j): if v == 0: return 1 elif v == 1: return ( 1. + (j+1) * r ) elif v == 2: return ( 1. + (j+2)*r + (j*j + 4.*j+ 3)/3.*r*r ) elif v == 3: return ( 1. + (j+3)*r + (6.*j*j+36.*j+45.)/15.*r*r + (j*j*j+9.*j*j+23.*j+15.)/15.*r*r*r ) else: raise Exception (["Wrong degree in PiecePoly. Should be 0,1,2 or 3, is " + str(v)]) def dfunc(self,v,r,j): if v == 0: return 0 elif v == 1: return ( j+1 ) elif v == 2: return ( (j+2) + 2.*(j*j+ 4.*j+ 3.)/3.*r ) elif v == 3: return ( (j+3) + 2.*(6.*j*j+36.*j+45.)/15.*r + (j*j*j+9.*j*j+23.*j+15.)/5.*r*r ) else: raise Exception (["Wrong degree in PiecePoly. Should be 0,1,2 or 3, is " + str(v)]) def pp(self,r,j,v,func): return func(v,r,j)*(self.ppmax(1-r,0)**(j+v)) def dpp(self,r,j,v,func,dfunc): return self.ppmax(1-r,0)**(j+v-1) * r * ( (j+v)*self.func(v,r,j) - self.ppmax(1-r,0) * self.dfunc(v,r,j) ) def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) if not x is None: n, D = x.shape if not z is None: nn, D = z.shape ell = np.exp(self.hyp[0]) # characteristic length scale sf2 = np.exp(2.*self.hyp[1]) # signal variance v = self.para[0] # degree (v = 0,1,2 or 3 only) if np.abs(v-np.round(v)) < 1e-8: # remove numerical error from format of parameter v = int(round(v)) assert(int(v) in range(4)) # Only allowed degrees: 0,1,2 or 3 v = int(v) j = np.floor(0.5*D) + v + 1 if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x A = np.sqrt( spdist.cdist(x/ell, x/ell, 'sqeuclidean') ) elif mode == 'cross': # compute covariance between data sets x and z A = np.sqrt( spdist.cdist(x/ell, z/ell, 'sqeuclidean') ) A = sf2 * self.pp(A,j,v,self.func) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) if not x is None: n, D = x.shape if not z is None: nn, D = z.shape ell = np.exp(self.hyp[0]) # characteristic length scale sf2 = np.exp(2.*self.hyp[1]) # signal variance v = self.para[0] # degree (v = 0,1,2 or 3 only) if np.abs(v-np.round(v)) < 1e-8: # remove numerical error from format of parameter v = int(round(v)) assert(int(v) in range(4)) # Only allowed degrees: 0,1,2 or 3 v = int(v) j = np.floor(0.5*D) + v + 1 if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x A = np.sqrt( spdist.cdist(x/ell, x/ell, 'sqeuclidean') ) elif mode == 'cross': # compute covariance between data sets x and z A = np.sqrt( spdist.cdist(x/ell, z/ell, 'sqeuclidean') ) if der == 0: # compute derivative matrix wrt 1st parameter A = sf2 * self.dpp(A,j,v,self.func,self.dfunc) elif der == 1: # compute derivative matrix wrt 2nd parameter A = 2. * sf2 * self.pp(A,j,v,self.func) elif der == 2: # wants to compute derivative wrt order A = np.zeros_like(A) else: raise Exception("Wrong derivative entry in PiecePoly") return A
[docs]class RBF(Kernel): ''' Squared Exponential kernel with isotropic distance measure. hyp = [log_ell, log_sigma] :param log_ell: characteristic length scale. :param log_sigma: signal deviation. ''' def __init__(self, log_ell=0., log_sigma=0.): self.hyp = [log_ell, log_sigma] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) ell = np.exp(self.hyp[0]) # characteristic length scale sf2 = np.exp(2.*self.hyp[1]) # signal variance if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for training set A = spdist.cdist(x/ell,x/ell,'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z A = spdist.cdist(x/ell,z/ell,'sqeuclidean') A = sf2 * np.exp(-0.5*A) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) ell = np.exp(self.hyp[0]) # characteristic length scale sf2 = np.exp(2.*self.hyp[1]) # signal variance if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x A = spdist.cdist(x/ell,x/ell,'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z A = spdist.cdist(x/ell,z/ell,'sqeuclidean') if der == 0: # compute derivative matrix wrt 1st parameter A = sf2 * np.exp(-0.5*A) * A elif der == 1: # compute derivative matrix wrt 2nd parameter A = 2. * sf2 * np.exp(-0.5*A) else: raise Exception("Calling for a derivative in RBF that does not exist") return A
[docs]class RBFunit(Kernel): ''' Squared Exponential kernel with isotropic distance measure with unit magnitude. i.e signal variance is always 1. hyp = [ log_ell ] :param log_ell: characteristic length scale. ''' def __init__(self, log_ell=0.): self.hyp = [log_ell] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) ell = np.exp(self.hyp[0]) # characteristic length scale if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x A = spdist.cdist(x/ell,x/ell,'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z A = spdist.cdist(x/ell,z/ell,'sqeuclidean') A = np.exp(-0.5*A) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) ell = np.exp(self.hyp[0]) # characteristic length scale if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x A = spdist.cdist(x/ell,x/ell,'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z A = spdist.cdist(x/ell,z/ell,'sqeuclidean') if der == 0: # compute derivative matrix wrt 1st parameter A = np.exp(-0.5*A) * A else: raise Exception("Wrong derivative index in RDFunit") return A
[docs]class RBFard(Kernel): ''' Squared Exponential kernel with Automatic Relevance Determination. hyp = log_ell_list + [log_sigma] :param D: dimension of pattern. set if you want default ell, which is 1 for each dimension. :param log_ell_list: characteristic length scale for each dimension. :param log_sigma: signal deviation. ''' def __init__(self, D=None, log_ell_list=None, log_sigma=0.): if log_ell_list is None: self.hyp = [0. for i in xrange(D)] + [log_sigma] else: self.hyp = log_ell_list + [log_sigma] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) if not x is None: n, D = x.shape if not z is None: nn, D = z.shape ell = 1./np.exp(self.hyp[0:D]) # characteristic length scale sf2 = np.exp(2.*self.hyp[D]) # signal variance if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x tem = np.dot(np.diag(ell),x.T).T A = spdist.cdist(tem,tem,'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z A = spdist.cdist(np.dot(np.diag(ell),x.T).T,np.dot(np.diag(ell),z.T).T,'sqeuclidean') A = sf2*np.exp(-0.5*A) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) if not x is None: n, D = x.shape if not z is None: nn, D = z.shape ell = 1./np.exp(self.hyp[0:D]) # characteristic length scale sf2 = np.exp(2.*self.hyp[D]) # signal variance if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x tem = np.dot(np.diag(ell),x.T).T A = spdist.cdist(tem,tem,'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z A = spdist.cdist(np.dot(np.diag(ell),x.T).T,np.dot(np.diag(ell),z.T).T,'sqeuclidean') A = sf2*np.exp(-0.5*A) if der < D: # compute derivative matrix wrt length scale parameters if mode == 'self_test': A = A*0 elif mode == 'train': tem = np.atleast_2d(x[:,der])/ell[der] A *= spdist.cdist(tem,tem,'sqeuclidean') elif mode == 'cross': A *= spdist.cdist(np.atleast_2d(x[:,der]).T/ell[der],np.atleast_2d(z[:,der]).T/ell[der],'sqeuclidean') elif der == D: # compute derivative matrix wrt magnitude parameter A = 2.*A else: raise Exception("Wrong derivative index in RDFard") return A
[docs]class Const(Kernel): ''' Constant kernel. hyp = [ log_sigma ] :param log_sigma: signal deviation. ''' def __init__(self, log_sigma=0.): self.hyp = [log_sigma] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) sf2 = np.exp(self.hyp[0]) # s2 if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = sf2 * np.ones((nn,1)) elif mode == 'train': # compute covariance matix for dataset x n,D = x.shape A = sf2 * np.ones((n,n)) + np.eye(n)*1e-10 elif mode == 'cross': # compute covariance between data sets x and z n,D = x.shape nn,D = z.shape A = sf2 * np.ones((n,nn)) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) sf2 = np.exp(self.hyp[0]) # s2 if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = sf2 * np.ones((nn,1)) elif mode == 'train': # compute covariance matix for dataset x n,D = x.shape A = sf2 * np.ones((n,n)) elif mode == 'cross': # compute covariance between data sets x and z n,D = x.shape nn,D = z.shape A = sf2 * np.ones((n,nn)) if der == 0: # compute derivative matrix wrt sf2 A = 2. * A else: raise Exception("Wrong derivative entry in covConst") return A
[docs]class Linear(Kernel): ''' Linear kernel. hyp = [ log_sigma ]. :param log_sigma: signal deviation. ''' def __init__(self, log_sigma=0.): self.hyp = [ log_sigma ] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) sf2 = np.exp(self.hyp[0]) # s2 if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.reshape(np.sum(z*z,1), (nn,1)) elif mode == 'train': # compute covariance matix for dataset x n,D = x.shape A = np.dot(x,x.T) + np.eye(n)*1e-10 # required for numerical accuracy elif mode == 'cross': # compute covariance between data sets x and z A = np.dot(x,z.T) A = sf2 * A return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) sf2 = np.exp(self.hyp[0]) # s2 if der == 0: if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.reshape(np.sum(z*z,1), (nn,1)) elif mode == 'train': # compute covariance matix for dataset x n,D = x.shape A = np.dot(x,x.T) + np.eye(n)*1e-16 # required for numerical accuracy elif mode == 'cross': # compute covariance between data sets x and z A = np.dot(x,z.T) A = 2 * sf2 * A else: raise Exception("Wrong derivative index in covLinear") return A
[docs]class LINard(Kernel): ''' Linear covariance function with Automatic Relevance Detemination. hyp = log_ell_list :param D: dimension of training data. Set if you want default ell, which is 1 for each dimension. :param log_ell_list: characteristic length scale for each dimension. ''' def __init__(self, D=None, log_ell_list=None): if log_ell_list is None: self.hyp = [0. for i in xrange(D)] else: self.hyp = log_ell_list def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) ell = np.exp(self.hyp) # ARD parameters if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.reshape(np.sum(z*z,1), (nn,1)) elif mode == 'train': # compute covariance matix for dataset x n, D = x.shape A = np.dot(x,x.T)+ np.eye(n)*1e-10 elif mode == 'cross': # compute covariance between data sets x and z z = np.dot(z,np.diag(1./ell)) A = np.dot(x,z.T) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) ell = np.exp(self.hyp) # ARD parameters if not x is None: n, D = x.shape if not z is None: nn, D = z.shape if der < D: if mode == 'self_test': tem = np.atleast_2d(z[:,der]).T A = -2.* tem * tem elif mode == 'train': A = -2.*np.dot(np.atleast_2d(x[:,der]).T,np.atleast_2d(x[:,der])) elif mode == 'cross': z = np.dot(z,np.diag(1./ell)) A = -2.*np.dot(np.atleast_2d(x[:,der]).T, np.atleast_2d(z[:,der])) # cross covariances else: raise Exception("Wrong derivative index in covLINard") return A
[docs]class Matern(Kernel): ''' Matern covariance function with nu = d/2 and isotropic distance measure. For d=1 the function is also known as the exponential covariance function or the Ornstein-Uhlenbeck covariance in 1d. d will be rounded to 1, 3, 5 or 7 hyp = [ log_ell, log_sigma] :param d: d is 2 times nu. Can only be 1,3, 5, or 7 :param log_ell: characteristic length scale. :param log_sigma: signal deviation. ''' def __init__(self, log_ell=0., d=3, log_sigma=0. ): self.hyp = [ log_ell, log_sigma ] self.para = [d] def func(self,d,t): if d == 1: return 1 elif d == 3: return 1 + t elif d == 5: return 1 + t + t*t/3. elif d == 7: return 1 + t + 2.*t*t/5. + t*t*t/15. else: raise Exception("Wrong value for d in Matern") def dfunc(self,d,t): # Note, this is func - d func/dt if d == 1: return 1 elif d == 3: return t elif d == 5: return (1./3.)*(t + t*t) elif d == 7: return (1./15.)*(t + 3.*t*t + t*t*t) else: raise Exception("Wrong value for d in Matern") def mfunc(self,d,t): return self.func(d,t)*np.exp(-1.*t) def dmfunc(self,d,t): return self.dfunc(d,t)*t*np.exp(-1.*t) def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) ell = np.exp(self.hyp[0]) # characteristic length scale sf2 = np.exp(2.* self.hyp[1]) # signal variance d = self.para[0] # 2 times nu if np.abs(d-np.round(d)) < 1e-8: # remove numerical error from format of parameter d = int(round(d)) d = int(d) try: assert(d in [1,3,5,7]) # check for valid values of d except AssertionError: print "Warning: You specified d to be neither 1,3,5 nor 7. We set it to d=3. " d = 3 if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x x = np.sqrt(d)*x/ell A = np.sqrt(spdist.cdist(x, x, 'sqeuclidean')) elif mode == 'cross': # compute covariance between data sets x and z x = np.sqrt(d)*x/ell z = np.sqrt(d)*z/ell A = np.sqrt(spdist.cdist(x, z, 'sqeuclidean')) A = sf2 * self.mfunc(d,A) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) ell = np.exp(self.hyp[0]) # characteristic length scale sf2 = np.exp(2.* self.hyp[1]) # signal variance d = self.para[0] # 2 times nu if np.abs(d-np.round(d)) < 1e-8: # remove numerical error from format of parameter d = int(round(d)) d = int(d) try: assert(d in [1,3,5,7]) # check for valid values of d except AssertionError: print "Warning: You specified d to be neither 1,3,5 nor 7. We set to d=3. " d = 3 if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x x = np.sqrt(d)*x/ell A = np.sqrt(spdist.cdist(x, x, 'sqeuclidean')) elif mode == 'cross': # compute covariance between data sets x and z x = np.sqrt(d)*x/ell z = np.sqrt(d)*z/ell A = np.sqrt(spdist.cdist(x, z, 'sqeuclidean')) A = sf2 * self.mfunc(d,A) if der == 0: # compute derivative matrix wrt 1st parameter A = sf2 * self.dmfunc(d,A) elif der == 1: # compute derivative matrix wrt 2nd parameter A = 2 * sf2 * self.mfunc(d,A) elif der == 2: # no derivative wrt 3rd parameter A = np.zeros_like(A) # do nothing (d is not learned) else: raise Exception("Wrong derivative value in Matern") return A
[docs]class Periodic(Kernel): ''' Stationary kernel for a smooth periodic function. hyp = [ log_ell, log_p, log_sigma] :param log_p: period. :param log_ell: characteristic length scale. :param log_sigma: signal deviation. ''' def __init__(self, log_ell=0., log_p=0., log_sigma=0. ): self.hyp = [ log_ell, log_p, log_sigma] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) if not x is None: assert x.shape[1]==1, 'periodic covariance can only be used for 1d data' if not z is None: assert z.shape[1]==1, 'periodic covariance can only be used for 1d data' ell = np.exp(self.hyp[0]) # characteristic length scale p = np.exp(self.hyp[1]) # period sf2 = np.exp(2.*self.hyp[2]) # signal variance if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x A = np.sqrt(spdist.cdist(x, x, 'sqeuclidean')) elif mode == 'cross': # compute covariance between data sets x and z A = np.sqrt(spdist.cdist(x, z, 'sqeuclidean')) A = np.pi*A/p A = np.sin(A)/ell A = A * A A = sf2 *np.exp(-2.*A) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) if not x is None: assert x.shape[1]==1, 'periodic covariance can only be used for 1d data' if not z is None: assert z.shape[1]==1, 'periodic covariance can only be used for 1d data' ell = np.exp(self.hyp[0]) # characteristic length scale p = np.exp(self.hyp[1]) # period sf2 = np.exp(2.*self.hyp[2]) # signal variance if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x A = np.sqrt(spdist.cdist(x, x, 'sqeuclidean')) elif mode == 'cross': # compute covariance between data sets x and z A = np.sqrt(spdist.cdist(x, z, 'sqeuclidean')) A = np.pi*A/p if der == 0: # compute derivative matrix wrt 1st parameter A = np.sin(A)/ell A = A * A A = 4. *sf2 *np.exp(-2.*A) * A elif der == 1: # compute derivative matrix wrt 2nd parameter R = np.sin(A)/ell A = 4 * sf2/ell * np.exp(-2.*R*R)*R*np.cos(A)*A elif der == 2: # compute derivative matrix wrt 3rd parameter A = np.sin(A)/ell A = A * A A = 2. * sf2 * np.exp(-2.*A) else: raise Exception("Wrong derivative index in covPeriodic") return A
[docs]class Noise(Kernel): ''' Independent covariance function, i.e "white noise", with specified variance. Normally NOT used anymore since noise is now added in liklihood. hyp = [ log_sigma ] :param log_sigma: signal deviation. ''' def __init__(self, log_sigma=0.): self.hyp = [log_sigma] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) tol = 1.e-9 # Tolerance for declaring two vectors "equal" s2 = np.exp(2.*self.hyp[0]) # noise variance if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x n,D = x.shape A = np.eye(n) elif mode == 'cross': # compute covariance between data sets x and z M = spdist.cdist(x, z, 'sqeuclidean') A = np.zeros_like(M,dtype=np.float) A[M < tol] = 1. A = s2*A return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) tol = 1.e-9 # Tolerance for declaring two vectors "equal" s2 = np.exp(2.*self.hyp[0]) # noise variance if mode == 'self_test': # self covariances for the test cases nn,D = z.shape A = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x n,D = x.shape A = np.eye(n) elif mode == 'cross': # compute covariance between data sets x and z M = spdist.cdist(x, z, 'sqeuclidean') A = np.zeros_like(M,dtype=np.float) A[M < tol] = 1. if der == 0: A = 2.*s2*A else: raise Exception("Wrong derivative index in covNoise") return A
[docs]class RQ(Kernel): ''' Rational Quadratic covariance function with isotropic distance measure. hyp = [ log_ell, log_sigma, log_alpha ] :param log_ell: characteristic length scale. :param log_sigma: signal deviation. :param log_alpha: shape parameter for the RQ covariance. ''' def __init__(self, log_ell=0., log_sigma=0., log_alpha=0.): self.hyp = [ log_ell, log_sigma, log_alpha ] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) ell = np.exp(self.hyp[0]) # characteristic length scale sf2 = np.exp(2.*self.hyp[1]) # signal variance alpha = np.exp(self.hyp[2]) if mode == 'self_test': # self covariances for the test cases nn,D = z.shape D2 = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x D2 = spdist.cdist(x/ell, x/ell, 'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z D2 = spdist.cdist(x/ell, z/ell, 'sqeuclidean') A = sf2 * ( ( 1.0 + 0.5*D2/alpha )**(-alpha) ) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) ell = np.exp(self.hyp[0]) # characteristic length scale sf2 = np.exp(2.*self.hyp[1]) # signal variance alpha = np.exp(self.hyp[2]) if mode == 'self_test': # self covariances for the test cases nn,D = z.shape D2 = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x D2 = spdist.cdist(x/ell, x/ell, 'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z D2 = spdist.cdist(x/ell, z/ell, 'sqeuclidean') if der == 0: # compute derivative matrix wrt 1st parameter A = sf2 * ( 1.0 + 0.5*D2/alpha )**(-alpha-1) * D2 elif der == 1: # compute derivative matrix wrt 2nd parameter A = 2.* sf2 * ( ( 1.0 + 0.5*D2/alpha )**(-alpha) ) elif der == 2: # compute derivative matrix wrt 3rd parameter K = ( 1.0 + 0.5*D2/alpha ) A = sf2 * K**(-alpha) * (0.5*D2/K - alpha*np.log(K) ) else: raise Exception("Wrong derivative index in covRQ") return A
[docs]class RQard(Kernel): ''' Rational Quadratic covariance function with Automatic Relevance Detemination (ARD) distance measure. hyp = log_ell_list + [ log_sigma, log_alpha ] :param D: dimension of pattern. set if you want default ell, which is 0.5 for each dimension. :param log_ell_list: characteristic length scale for each dimension. :param log_sigma: signal deviation. :param log_alpha: shape parameter for the RQ covariance. ''' def __init__(self, D=None, log_ell_list=None, log_sigma=0., log_alpha=0.): if log_ell_list is None: self.hyp = [0. for i in xrange(D)] + [ log_sigma, log_alpha ] else: self.hyp = log_ell_list + [ log_sigma, log_alpha ] def getCovMatrix(self,x=None,z=None,mode=None): self.checkInputGetCovMatrix(x,z,mode) if not x is None: n, D = x.shape if not z is None: nn, D = z.shape ell = 1./np.exp(self.hyp[0:D]) # characteristic length scale sf2 = np.exp(2.*self.hyp[D]) # signal variance alpha = np.exp(self.hyp[D+1]) if mode == 'self_test': # self covariances for the test cases nn,D = z.shape D2 = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x tmp = np.dot(np.diag(ell),x.T).T D2 = spdist.cdist(tmp, tmp, 'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z D2 = spdist.cdist(np.dot(np.diag(ell),x.T).T, np.dot(np.diag(ell),z.T).T, 'sqeuclidean') A = sf2 * ( ( 1.0 + 0.5*D2/alpha )**(-alpha) ) return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): self.checkInputGetDerMatrix(x,z,mode,der) if not x is None: n, D = x.shape if not z is None: nn, D = z.shape ell = 1./np.exp(self.hyp[0:D]) # characteristic length scale sf2 = np.exp(2.*self.hyp[D]) # signal variance alpha = np.exp(self.hyp[D+1]) if mode == 'self_test': # self covariances for the test cases nn,D = z.shape D2 = np.zeros((nn,1)) elif mode == 'train': # compute covariance matix for dataset x tmp = np.dot(np.diag(ell),x.T).T D2 = spdist.cdist(tmp, tmp, 'sqeuclidean') elif mode == 'cross': # compute covariance between data sets x and z D2 = spdist.cdist(np.dot(np.diag(ell),x.T).T, np.dot(np.diag(ell),z.T).T, 'sqeuclidean') if der < D: if mode == 'self_test': A = D2*0 elif mode == 'train': tmp = np.atleast_2d(x[:,der])/ell[der] A = sf2 * ( 1.0 + 0.5*D2/alpha )**(-alpha-1) * spdist.cdist(tmp, tmp, 'sqeuclidean') elif mode == 'cross': A = sf2 * ( 1.0 + 0.5*D2/alpha )**(-alpha-1) * spdist.cdist(np.atleast_2d(x[:,der]).T/ell[der], np.atleast_2d(z[:,der]).T/ell[der], 'sqeuclidean') elif der==D: # compute derivative matrix wrt magnitude parameter A = 2. * sf2 * ( ( 1.0 + 0.5*D2/alpha )**(-alpha) ) elif der==(D+1): # compute derivative matrix wrt magnitude parameter K = ( 1.0 + 0.5*D2/alpha ) A = sf2 * K**(-alpha) * ( 0.5*D2/K - alpha*np.log(K) ) else: raise Exception("Wrong derivative index in covRQard") return A
[docs]class Pre(Kernel): ''' Precomputed kernel matrix. No hyperparameters and thus nothing will be optimised. :param M1: cross covariances matrix(train+1 by test). last row is self covariances (diagonal of test by test) :param M2: training set covariance matrix (train by train) ''' def __init__(self,M1,M2): self.M1 = M1 self.M2 = M2 self.hyp = [] def getCovMatrix(self,x=None,z=None,mode=None): if mode == 'self_test': # diagonal covariance between test_test A = self.M1[-1,:] # self covariances for the test cases (last row) A = np.reshape(A, (A.shape[0],1)) elif mode == 'train': # covariance between train_train A = self.M2 elif mode == 'cross': # covariance between train_test A = self.M1[:-1,:] return A def getDerMatrix(self,x=None,z=None,mode=None,der=None): if not der is None: raise Exception("Error: NO optimization in precomputed kernel matrix") return 0
if __name__ == '__main__': pass