mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-06-02 14:45:15 +02:00
add missing file
This commit is contained in:
parent
0e01474aec
commit
f221a3b1fa
1 changed files with 92 additions and 0 deletions
92
GPy/kern/_src/psi_comp/gaussherm.py
Normal file
92
GPy/kern/_src/psi_comp/gaussherm.py
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||||
|
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||||
|
|
||||||
|
"""
|
||||||
|
An approximated psi-statistics implementation based on Gauss-Hermite Quadrature
|
||||||
|
"""
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from GPy.util.caching import Cache_this
|
||||||
|
from ....util.linalg import tdot
|
||||||
|
from ....core.parameterization.parameter_core import Pickleable
|
||||||
|
|
||||||
|
class PSICOMP_GH(Pickleable):
|
||||||
|
|
||||||
|
def __init__(self, degree=5, cache_K=True):
|
||||||
|
self.degree = degree
|
||||||
|
self.cache_K = cache_K
|
||||||
|
self.locs, self.weights = np.polynomial.hermite.hermgauss(degree)
|
||||||
|
self.locs *= np.sqrt(2.)
|
||||||
|
self.weights*= 1./np.sqrt(np.pi)
|
||||||
|
self.Xs = None
|
||||||
|
|
||||||
|
def _setup_observers(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@Cache_this(limit=10, ignore_args=(0,))
|
||||||
|
def comp_K(self, Z, qX):
|
||||||
|
if self.Xs is None or self.Xs.shape != qX.mean.shape:
|
||||||
|
from ....core.parameterization import ObsAr
|
||||||
|
self.Xs = ObsAr(np.empty((self.degree,)+qX.mean.shape))
|
||||||
|
mu, S = qX.mean.values, qX.variance.values
|
||||||
|
S_sq = np.sqrt(S)
|
||||||
|
for i in xrange(self.degree):
|
||||||
|
self.Xs[i] = self.locs[i]*S_sq+mu
|
||||||
|
return self.Xs
|
||||||
|
|
||||||
|
@Cache_this(limit=10, ignore_args=(0,))
|
||||||
|
def psicomputations(self, kern, Z, qX):
|
||||||
|
mu, S = qX.mean.values, qX.variance.values
|
||||||
|
N,M,Q = mu.shape[0],Z.shape[0],mu.shape[1]
|
||||||
|
if self.cache_K: Xs = self.comp_K(Z, qX)
|
||||||
|
else: S_sq = np.sqrt(S)
|
||||||
|
|
||||||
|
psi0 = np.zeros((N,))
|
||||||
|
psi1 = np.zeros((N,M))
|
||||||
|
psi2 = np.zeros((M,M))
|
||||||
|
for i in xrange(self.degree):
|
||||||
|
if self.cache_K:
|
||||||
|
X = Xs[i]
|
||||||
|
else:
|
||||||
|
X = self.locs[i]*S_sq+mu
|
||||||
|
psi0 += self.weights[i]* kern.Kdiag(X)
|
||||||
|
Kfu = kern.K(X,Z)
|
||||||
|
psi1 += self.weights[i]* Kfu
|
||||||
|
psi2 += self.weights[i]* tdot(Kfu.T)
|
||||||
|
return psi0, psi1, psi2
|
||||||
|
|
||||||
|
@Cache_this(limit=10, ignore_args=(0, 2,3,4))
|
||||||
|
def psiDerivativecomputations(self, kern, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, qX):
|
||||||
|
mu, S = qX.mean.values, qX.variance.values
|
||||||
|
if self.cache_K: Xs = self.comp_K(Z, qX)
|
||||||
|
S_sq = np.sqrt(S)
|
||||||
|
|
||||||
|
dtheta_old = kern.gradient.copy()
|
||||||
|
dtheta = np.zeros_like(kern.gradient)
|
||||||
|
dZ = np.zeros_like(Z.values)
|
||||||
|
dmu = np.zeros_like(mu)
|
||||||
|
dS = np.zeros_like(S)
|
||||||
|
for i in xrange(self.degree):
|
||||||
|
if self.cache_K:
|
||||||
|
X = Xs[i]
|
||||||
|
else:
|
||||||
|
X = self.locs[i]*S_sq+mu
|
||||||
|
dL_dpsi0_i = dL_dpsi0*self.weights[i]
|
||||||
|
kern.update_gradients_diag(dL_dpsi0_i, X)
|
||||||
|
dtheta += kern.gradient
|
||||||
|
dX = kern.gradients_X_diag(dL_dpsi0_i, X)
|
||||||
|
Kfu = kern.K(X,Z)
|
||||||
|
dL_dkfu = (dL_dpsi1+ 2.*Kfu.dot(dL_dpsi2))*self.weights[i]
|
||||||
|
kern.update_gradients_full(dL_dkfu, X, Z)
|
||||||
|
dtheta += kern.gradient
|
||||||
|
dX += kern.gradients_X(dL_dkfu, X, Z)
|
||||||
|
dZ += kern.gradients_X(dL_dkfu.T, Z, X)
|
||||||
|
dmu += dX
|
||||||
|
dS += dX*self.locs[i]/(2.*S_sq)
|
||||||
|
kern.gradient[:] = dtheta_old
|
||||||
|
return dtheta, dZ, dmu, dS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue