https://github.com/GPflow/GPflow
Tip revision: 768f64426d6129b93f2159ac1ab9eb2cd8844f23 authored by Sergio Diaz on 18 March 2019, 16:13:45 UTC
Merge branch 'sergio_pasc/gpflow-2.0/move-quadrature-tests' of github.com:GPflow/GPflow into sergio_pasc/gpflow-2.0/move-quadrature-tests
Merge branch 'sergio_pasc/gpflow-2.0/move-quadrature-tests' of github.com:GPflow/GPflow into sergio_pasc/gpflow-2.0/move-quadrature-tests
Tip revision: 768f644
sums.py
import itertools
from functools import reduce
import tensorflow as tf
from . import dispatch
from .. import kernels
from .. import mean_functions as mfn
from ..features import InducingPoints
from ..probability_distributions import (DiagonalGaussian, Gaussian,
MarkovGaussian)
from ..util import NoneType
from .expectations import expectation
@dispatch.expectation.register(Gaussian, kernels.Sum, NoneType, NoneType, NoneType)
def _E(p, kern, _, __, ___, nghp=None):
"""
Compute the expectation:
<\Sum_i diag(Ki_{X, X})>_p(X)
- \Sum_i Ki_{.,.} :: Sum kernel
:return: N
"""
exps = [expectation(p, k, nghp=nghp) for k in kern.kernels]
return reduce(tf.add, exps)
@dispatch.expectation.register(Gaussian, kernels.Sum, InducingPoints, NoneType, NoneType)
def _E(p, kern, feat, _, __, nghp=None):
"""
Compute the expectation:
<\Sum_i Ki_{X, Z}>_p(X)
- \Sum_i Ki_{.,.} :: Sum kernel
:return: NxM
"""
exps = [expectation(p, (k, feat), nghp=nghp) for k in kern.kernels]
return reduce(tf.add, exps)
@dispatch.expectation.register(Gaussian,
(mfn.Linear, mfn.Identity, mfn.Constant),
NoneType, kernels.Sum, InducingPoints)
def _E(p, mean, _, kern, feat, nghp=None):
"""
Compute the expectation:
expectation[n] = <m(x_n)^T (\Sum_i Ki_{x_n, Z})>_p(x_n)
- \Sum_i Ki_{.,.} :: Sum kernel
:return: NxQxM
"""
exps = [expectation(p, mean, (k, feat), nghp=nghp) for k in kern.kernels]
return reduce(tf.add, exps)
@dispatch.expectation.register(MarkovGaussian, mfn.Identity, NoneType, kernels.Sum, InducingPoints)
def _E(p, mean, _, kern, feat, nghp=None):
"""
Compute the expectation:
expectation[n] = <x_{n+1} (\Sum_i Ki_{x_n, Z})>_p(x_{n:n+1})
- \Sum_i Ki_{.,.} :: Sum kernel
:return: NxDxM
"""
exps = [expectation(p, mean, (k, feat), nghp=nghp) for k in kern.kernels]
return reduce(tf.add, exps)
@dispatch.expectation.register((Gaussian, DiagonalGaussian), kernels.Sum, InducingPoints, kernels.Sum, InducingPoints)
def _E(p, kern1, feat1, kern2, feat2, nghp=None):
"""
Compute the expectation:
expectation[n] = <(\Sum_i K1_i_{Z1, x_n}) (\Sum_j K2_j_{x_n, Z2})>_p(x_n)
- \Sum_i K1_i_{.,.}, \Sum_j K2_j_{.,.} :: Sum kernels
:return: NxM1xM2
"""
crossexps = []
if kern1 == kern2 and feat1 == feat2: # avoid duplicate computation by using transposes
for i, k1 in enumerate(kern1.kernels):
crossexps.append(expectation(p, (k1, feat1), (k1, feat1), nghp=nghp))
for k2 in kern1.kernels[:i]:
eKK = expectation(p, (k1, feat1), (k2, feat2), nghp=nghp)
eKK += tf.linalg.transpose(eKK)
crossexps.append(eKK)
else:
for k1, k2 in itertools.product(kern1.kernels, kern2.kernels):
crossexps.append(expectation(p, (k1, feat1), (k2, feat2), nghp=nghp))
return reduce(tf.add, crossexps)