Revision 6c35a7a8544dfecfe92ef9b559b90fcb40b364eb authored by Mark van der Wilk on 20 November 2017, 17:43:17 UTC, committed by GitHub on 20 November 2017, 17:43:17 UTC
* Add Features base classes

* Convert SGPR and SVGP models to use InducingFeatures (including backwards compatibility)

* Fix tests

* Added Multiscale feature.
To show the generality of the inter-domain code.

* Fixed py2 metaclass issue, as per John Bradshaw's suggestion.

* Improve docstrings, register Multiscale feature

* Change SGPR models to determine feature length dynamically [but feature.__len__() still needs to be made dynamic as well!]

* Bits and pieces missed in the merge.

* Add features to __init__.

* Fixed incorrect parameter dtype assignment on compile.

* Two bugfixs.
- Static assignment of len(feature)
- Upper bound mixin referred to Z.

* Fixed bugs in multiscale & added features.

* Added tests for `Multiscale` inducing features.

* Updated `RELEASE.md`, and small changes for tests.

* add test for len(feature)

* Deprecation property for `Z`, relative imports, improved test.

* `SGPMC` has inducing features now + better docstrings.

* Fixed `SGPMC`.

* Testing now uses tf1.4.

* `feat` now `feature` + other changes.

* Update _version.py

* change exception
1 parent 0741f86
Raw File
quadrature.py
from __future__ import print_function, absolute_import
import itertools

import tensorflow as tf
import numpy as np

from . import settings


def hermgauss(n):
    x, w = np.polynomial.hermite.hermgauss(n)
    x, w = x.astype(settings.np_float), w.astype(settings.np_float)
    return x, w


def mvhermgauss(H, D):
    """
    Return the evaluation locations 'xn', and weights 'wn' for a multivariate
    Gauss-Hermite quadrature.

    The outputs can be used to approximate the following type of integral:
    int exp(-x)*f(x) dx ~ sum_i w[i,:]*f(x[i,:])

    :param H: Number of Gauss-Hermite evaluation points.
    :param D: Number of input dimensions. Needs to be known at call-time.
    :return: eval_locations 'x' (H**DxD), weights 'w' (H**D)
    """
    gh_x, gh_w = hermgauss(H)
    x = np.array(list(itertools.product(*(gh_x,) * D)))  # H**DxD
    w = np.prod(np.array(list(itertools.product(*(gh_w,) * D))), 1)  # H**D
    return x, w


def mvnquad(func, means, covs, H, Din, Dout=()):
    """
    Computes N Gaussian expectation integrals of a single function 'f'
    using Gauss-Hermite quadrature.
    :param f: integrand function. Takes one input of shape ?xD.
    :param means: NxD
    :param covs: NxDxD
    :param H: Number of Gauss-Hermite evaluation points.
    :param Din: Number of input dimensions. Needs to be known at call-time.
    :param Dout: Number of output dimensions. Defaults to (). Dout is assumed
    to leave out the item index, i.e. f actually maps (?xD)->(?x*Dout).
    :return: quadratures (N,*Dout)
    """
    xn, wn = mvhermgauss(H, Din)
    N = tf.shape(means)[0]

    # transform points based on Gaussian parameters
    cholXcov = tf.cholesky(covs)  # NxDxD
    Xt = tf.matmul(cholXcov, tf.tile(xn[None, :, :], (N, 1, 1)), transpose_b=True)  # NxDxH**D
    X = 2.0 ** 0.5 * Xt + tf.expand_dims(means, 2)  # NxDxH**D
    Xr = tf.reshape(tf.transpose(X, [2, 0, 1]), (-1, Din))  # (H**D*N)xD

    # perform quadrature
    fX = tf.reshape(func(Xr), (H ** Din, N,) + Dout)
    wr = np.reshape(wn * np.pi ** (-Din * 0.5),
                    (-1,) + (1,) * (1 + len(Dout)))
    return tf.reduce_sum(fX * wr, 0)
back to top