Пример #1
0
    def __init__(self, x, xp, y, Sigmay=None, covariance_function='sqexp'):
        """
        :param x: an array of arrays holding inputs i.e. x = [[x_1], [x_2], ..., [x_3]] where x_1 in R^{N_1} etc.
        :param xp: an array of arrays holding targets i.e. xp = [[xp_1], [xp_2], ..., [xp_3]] where xp_1 in R^{Np_1} etc.
        :param y: an array of arrays holding data i.e. y = [[y_1], [y_2], ..., [y_3]] where y_1 in R^{N_1} etc.
        :param Sigmay: an array of arrays holding variances i.e. Sigmay = [[Sigmay_1], [Sigmay_2], ..., [Sigmay_3]] 
                where Sigmay_1 in R^{N_1} etc.
        :param covariance_function: a list holding the covariance functions to use for each dimension
        """
        self.D = x.shape[0]
        self.N = kt.kron_N(x)
        self.x = x
        self.Np = kt.kron_N(xp)
        self.xp = xp
        self.y = y
        if Sigmay is not None:
            self.Sigmay = Sigmay
        else:
            self.Sigmay = None
        self.covariance_function = covariance_function

        # initialise the individual diff square grids
        self.XX = []
        self.XXp = []
        self.XXpp = []
        for i in xrange(self.D):
            self.XX.append(abs_diff.abs_diff(self.x[i], self.x[i]))
            self.XXp.append(abs_diff.abs_diff(self.x[i], self.xp[i]))
            self.XXpp.append(abs_diff.abs_diff(self.xp[i], self.xp[i]))
        self.XX = np.asarray(self.XX)
        self.XXp = np.asarray(self.XXp)
        self.XXpp = np.asarray(self.XXpp)

        # set the kernels
        from GP.kernels import exponential_squared  # only using this one for now
        self.kernels = []
        self.kernels_transformed = []
        for i in xrange(self.D):
            if self.Sigmay is not None:
                self.kernels.append(exponential_squared.sqexp(Sigmay=self.Sigmay[i], mode='kron'))
                #self.kernels_transformed.append(exponential_squared.sqexp(mode='kron'))
            else:
                self.kernels.append(exponential_squared.sqexp(mode='kron'))

        # Instantiate posterior mean, cov and evidence classes
        self.meano = posterior_mean.meanf(self.x, self.xp, self.y, self.kernels, mode="kron",
                                          XX=self.XX, XXp=self.XXp)
        self.meanf = lambda theta: self.meano.give_mean(theta)
        self.covo = posterior_covariance.covf(self.kernels, mode="kron", XX=self.XX, XXp=self.XXp, XXpp=self.XXpp)
        self.covf = lambda theta: self.covo.give_covariance(theta)
        self.logpo = marginal_posterior.evidence(self.x, self.y, self.kernels, mode="kron", XX=self.XX)
        self.logp = lambda theta: self.logpo.logL(theta)
Пример #2
0
 def interp(self, tp, theta, gbar):
     if self.K.solve_mode == "full":
         # get matrix of differences
         from GP.tools import abs_diff
         ttp = abs_diff.abs_diff(self.K.t, tp)
         ttpp = abs_diff.abs_diff(tp, tp)
         # get covariance matrices
         Kp = self.K.kernel.cov_func(theta, ttp, noise=False)
         Kpp = self.K.kernel.cov_func(theta, ttpp, noise=False)
         # get the mean function
         gmean = np.dot(Kp.T, self._idot(gbar))
         gcov = Kpp - Kp.T.dot(self._idot(Kp))
         return gmean, gcov
     else:
         raise NotImplementedError("Still working on faster solve_mode")
Пример #3
0
def draw_samples_ND_grid(x, theta, Nsamps, meanf=None):
    """
    Draw N dimensional samples on a Euclidean grid
    :param meanf: mean function
    :param x: array of arrays containing targets [x_1, x_2, ..., x_D]
    :param theta: array of arrays containing [theta_1, theta_2, ..., theta_D]
    :param Nsamps: number of samples to draw
    :return: array containing samples [Nsamps, N_1, N_2, ..., N_D]
    """

    D = x.shape[0]
    Ns = []
    K = np.empty(D, dtype=object)
    Kcov = expsq.sqexp()
    Ntot = 1
    for i in xrange(D):
        Ns.append(x[i].size)
        XX = abs_diff.abs_diff(x[i], x[i])
        print Ns[i], theta[i], K[i]
        K[i] = Kcov.cov_func(theta[i], XX, noise=False) + 1e-13 * np.eye(Ns[i])
        Ntot *= Ns[i]

    L = kt.kron_cholesky(K)
    samps = np.zeros([Nsamps] + Ns, dtype=np.float64)
    for i in xrange(Nsamps):
        xi = np.random.randn(Ntot)
        if meanf is not None:
            samps[i] = meanf(x) + kt.kron_matvec(L, xi).reshape(Ns)
        else:
            samps[i] = kt.kron_matvec(L, xi).reshape(Ns)
    return samps
Пример #4
0
def draw_spatio_temporal_samples(meanf, x, t, theta_x, theta_t, Nsamps):
    Nt = t.size
    Nx = x.size  # assumes 1D
    Ntot = Nt * Nx
    XX = abs_diff.abs_diff(x, x)
    TT = abs_diff.abs_diff(t, t)
    Kcov = expsq.sqexp()
    Kx = Kcov.cov_func(theta_x, XX, noise=False) + 1e-13 * np.eye(Nx)
    Kt = Kcov.cov_func(theta_t, TT, noise=False) + 1e-13 * np.eye(Nt)
    K = np.array([Kt, Kx])
    L = kt.kron_cholesky(K)
    samps = np.zeros([Nsamps, Nt, Nx])
    for i in xrange(Nsamps):
        xi = np.random.randn(Ntot)
        samps[i] = meanf + kt.kron_matvec(L, xi).reshape(Nt, Nx)
    return samps
Пример #5
0
    def __init__(self, t, x, tp, xp):
        """

        :param t: T x 1 vector of input times 
        :param x: N x 2 vector of input spatial locations
        """
        self.t = t
        self.T = t.size  # number of time points
        self.x = x
        self.N = x.shape[1]  # number of spatial points
        self.M = self.T * self.N

        # get abs diff of spatial locs and evaluate cov func
        self.XX = abs_diff.abs_diff(x, x)
        self.XXp = abs_diff.abs_diff(xp, x)
        # self.XXpp = self.abs_diff_x(xp, xp)

        # get abs diff of temporal locs and evaluate cov func
        self.TT = abs_diff.abs_diff(t, t)
        self.TTp = abs_diff.abs_diff(tp, t)
Пример #6
0
def test_tensorvec(x, t, z, N):
    Nxp = 10
    xp = np.linspace(-1, 1, Nxp)
    xxp = abs_diff.abs_diff(x, xp)
    Kpx = (kernel.cov_func(thetax, xxp, noise=False)).T

    Ntp = 12
    tp = np.linspace(0, 1, Ntp)
    ttp = abs_diff.abs_diff(t, tp)
    Kpt = (kernel.cov_func(thetat, ttp, noise=False)).T

    Nzp = 14
    zp = np.linspace(-0.5, 1, Nzp)
    zzp = abs_diff.abs_diff(z, zp)
    Kpz = (kernel.cov_func(thetaz, zzp, noise=False)).T

    Ap = np.array([Kpz, Kpx, Kpt])  # note ordering!!!
    Kp = kt.kron_kron(Ap)

    b = np.random.randn(N)
    res1 = Kp.dot(b)
    res2 = kt.kron_tensorvec(Ap, b)
    compare(res1, res2, 'tensorvec')
Пример #7
0
    c = np.append(t, t[np.arange(N)[1:-1][::-1]].conj())
    x_aug = np.append(x, np.zeros([N - 2, M]), axis=0)
    tmp = FFT_circmat(c, x_aug)
    return tmp[0:N, :]


if __name__ == "__main__":
    from GP.tools import abs_diff
    from GP.kernels import exponential_squared

    # get Toeplitz matrix
    kernel = exponential_squared.sqexp()
    Nx = 1024
    thetax = np.array([1.0, 0.5])
    x = np.linspace(-10, 10, Nx)
    xx = abs_diff.abs_diff(x, x)
    Kx = kernel.cov_func(thetax, xx, noise=False)

    # broadcast to circulant row
    row1 = np.append(Kx[0, :], Kx[0, np.arange(Nx)[1:-1][::-1]].conj())

    # create FFTW objects
    FFT = pyfftw.builders.rfft
    iFFT = pyfftw.builders.irfft

    # test 1D FFT
    b = np.random.randn(Nx)

    bhat = FFT(b)
    b2 = iFFT(bhat())
Пример #8
0
def draw_samples(meanf, x, theta, cov_func, N):
    XX = abs_diff.abs_diff(x, x)
    covf = cov_func(XX, theta)
    samps = np.random.multivariate_normal(meanf, covf, N)
    return samps
Пример #9
0
    def reset_targets(self, xp):
        try:
            self.Np, D = xp.shape
        except:
            self.Np = xp.size
            D = 1
            xp = np.reshape(xp, (self.Np, D))

        self.xp = xp
        if self.mode == "Full":
            from GP.tools import abs_diff
            self.XXp = abs_diff.abs_diff(self.x, self.xp)
            self.XXpp = abs_diff.abs_diff(self.xp, self.xp)
            # Instantiate posterior mean, cov and evidence classes
            self.meano = posterior_mean.meanf(self.x,
                                              self.xp,
                                              self.y,
                                              self.kernel,
                                              mode=self.mode,
                                              prior_mean=self.prior_mean,
                                              XX=self.XX,
                                              XXp=self.XXp)
            self.meanf = lambda theta: self.meano.give_mean(theta)
            self.covo = posterior_covariance.covf(self.kernel,
                                                  mode=self.mode,
                                                  XX=self.XX,
                                                  XXp=self.XXp,
                                                  XXpp=self.XXpp)
            self.covf = lambda theta: self.covo.give_covariance(theta)
        elif self.mode == "RR":
            from GP.tools import make_basis
            # Construct the basis functions
            if self.basis == "Rect":
                from GP.basisfuncs import rectangular
                self.Phip = make_basis.get_eigenvectors(
                    self.xp, self.M, self.L, rectangular.phi)
            else:
                print "%s basis functions not supported yet" % self.basis

            self.meano = posterior_mean.meanf(self.x,
                                              self.xp,
                                              self.y,
                                              self.kernel,
                                              mode=self.mode,
                                              Phi=self.Phi,
                                              Phip=self.Phip,
                                              PhiTPhi=self.PhiTPhi,
                                              s=self.s,
                                              prior_mean=self.prior_mean,
                                              grid_regular=self.grid_regular)
            self.meanf = lambda theta: self.meano.give_mean(theta)
            self.covo = posterior_covariance.covf(
                self.kernel,
                mode=self.mode,
                Phi=self.Phi,
                Phip=self.Phip,
                PhiTPhi=self.PhiTPhi,
                s=self.s,
                grid_regular=self.grid_regular)
            self.covf = lambda theta: self.covo.give_covariance(theta)
        else:
            raise Exception('Mode %s not supported yet' % self.mode)
Пример #10
0
    def __init__(self,
                 x,
                 xp,
                 y,
                 Sigmay=None,
                 prior_mean=None,
                 covariance_function='sqexp',
                 mode="Full",
                 nu=2.5,
                 basis="Rect",
                 M=12,
                 L=5.0,
                 grid_regular=False):
        """
        :param x: vector of inputs
        :param xp: vector of targets
        :param y: vector of data
        :param prior_mean: a prior mean function (must be callable)
        :param covariance_function: the kind of covariance function to use (currently 'sqexp' or 'mattern')
        :param mode: whether to do a full GPR or a reduced rank GPR (currently "Full" or "RR")
        :param nu: specifies the kind of Mattern function to use (must be a half integer)
        :param basis: specifies the class of basis functions to use (currently only "Rect")
        :param M: integer specifying the number of basis functions to use
        :param L: float specifying the boundary of the domain 
        """
        # set inputs and targets enforcing correct sizes
        self.N = x.shape[0]
        try:
            self.D = x.shape[1]
            self.x = x
        except:
            self.D = 1
            self.x = x.reshape(self.N, self.D)
        if self.D > 1:
            raise Exception("Must pass 1D input to temporal_GP")
        self.Np = xp.size
        self.xp = xp.reshape(self.Np, self.D)
        self.y = y.reshape(self.N, self.D)

        # check that prior mean is callable and set it
        try:
            ym = prior_mean(self.x)
            self.prior_mean = prior_mean
            del ym
        except:
            raise Exception("Prior mean function must be callable")

        # set covariance
        if covariance_function == "sqexp":
            from GP.kernels import exponential_squared
            # Initialise kernel
            self.kernel = exponential_squared.sqexp(Sigmay=Sigmay)
        elif covariance_function == "mattern":
            from GP.kernels import mattern
            # Initialise kernel
            self.kernel = mattern.mattern(p=int(nu))
        else:
            raise Exception('Kernel %s not supported yet' %
                            covariance_function)

        # Get inputs required to evaluate covariance function
        self.mode = mode
        if mode == "Full":  # here we need the differences squared
            from GP.tools import abs_diff
            # Initialise absolute differences
            self.XX = abs_diff.abs_diff(self.x, self.x)
            self.XXp = abs_diff.abs_diff(self.x, xp)
            self.XXpp = abs_diff.abs_diff(xp, xp)
            # Instantiate posterior mean, cov and evidence classes
            self.meano = posterior_mean.meanf(self.x,
                                              self.xp,
                                              self.y,
                                              self.kernel,
                                              mode=self.mode,
                                              prior_mean=self.prior_mean,
                                              XX=self.XX,
                                              XXp=self.XXp)
            self.meanf = lambda theta: self.meano.give_mean(theta)
            self.covo = posterior_covariance.covf(self.kernel,
                                                  mode=self.mode,
                                                  XX=self.XX,
                                                  XXp=self.XXp,
                                                  XXpp=self.XXpp)
            self.covf = lambda theta: self.covo.give_covariance(theta)
            self.logpo = marginal_posterior.evidence(self.x,
                                                     self.y,
                                                     self.kernel,
                                                     mode=self.mode,
                                                     XX=self.XX)
            self.logp = lambda theta: self.logpo.logL(theta)
        elif mode == "RR":  # here we need to evaluate the basis functions
            from GP.tools import make_basis
            # check consistency of inputs
            if np.asarray(M).size == 1:  # 1D so only a single value allowed
                self.M = np.array([
                    M
                ])  # cast as array to make it compatible with make_basis class
            else:
                raise Exception(
                    'Inconsistent dimensions specified for M. Must be 1D.')
            if np.asarray(L).size == 1:  # 1D so only a single value allowed
                self.L = np.array([
                    L
                ])  # cast as array to make it compatible with make_basis class
            else:
                raise Exception(
                    'Inconsistent dimensions specified for L. Must be 1D.')
            # Construct the basis functions
            self.basis = basis
            if self.basis == "Rect":
                from GP.basisfuncs import rectangular
                self.Phi = make_basis.get_eigenvectors(self.x, self.M, self.L,
                                                       rectangular.phi)
                self.Phip = make_basis.get_eigenvectors(
                    self.xp, self.M, self.L, rectangular.phi)
                self.Lambda = make_basis.get_eigenvals(self.M, self.L,
                                                       rectangular.Lambda)
            else:
                print "%s basis functions not supported yet" % basis

            # Precompute some terms that never change
            # If inputs are on a regular grid we only need the diagonal
            self.grid_regular = grid_regular
            if self.grid_regular:
                self.PhiTPhi = np.einsum(
                    'ij,ji->i', self.Phi.T,
                    self.Phi)  # computes only the diagonal entries
            else:
                self.PhiTPhi = np.dot(self.Phi.T, self.Phi)
            self.s = np.sqrt(self.Lambda)

            self.meano = posterior_mean.meanf(self.x,
                                              self.xp,
                                              self.y,
                                              self.kernel,
                                              mode=self.mode,
                                              Phi=self.Phi,
                                              Phip=self.Phip,
                                              PhiTPhi=self.PhiTPhi,
                                              s=self.s,
                                              grid_regular=self.grid_regular,
                                              prior_mean=self.prior_mean)
            self.meanf = lambda theta: self.meano.give_mean(theta)
            self.covo = posterior_covariance.covf(
                self.kernel,
                mode=self.mode,
                Phi=self.Phi,
                Phip=self.Phip,
                PhiTPhi=self.PhiTPhi,
                s=self.s,
                grid_regular=self.grid_regular)
            self.covf = lambda theta: self.covo.give_covariance(theta)
            self.logpo = marginal_posterior.evidence(
                self.x,
                self.y,
                self.kernel,
                mode=self.mode,
                Phi=self.Phi,
                PhiTPhi=self.PhiTPhi,
                s=self.s,
                grid_regular=self.grid_regular)
            self.logp = lambda theta: self.logpo.logL(theta)
        else:
            raise Exception('Mode %s not supported yet' % mode)

        self.has_posterior = False  #flag to indicate if the posterior has been computed
Пример #11
0
import numpy as np
from GP.kernels import exponential_squared
from GP.tools import make_basis
from GP.basisfuncs import rectangular

if __name__=="__main__":
    # set params and get matrix of differences
    N = 100
    Np = 250
    tmin = 0.0
    tmax = 1.0
    t = tmin + (tmax - tmin)*np.sort(np.random.random(N))
    tp = np.linspace(tmin, tmax, Np)
    from GP.tools import abs_diff
    tt = abs_diff.abs_diff(t, t)
    # ttp = abs_diff.abs_diff(t, tp)
    # ttpp = abs_diff.abs_diff(tp, tp)

    # instantiate kernel
    kernel = exponential_squared.sqexp()

    # get some random values of theta to compare RR to full
    sigfm = 1.0
    lm = 0.5
    signm = 1.0
    thetam = np.array([sigfm, lm, signm])

    Ntheta = 10
    theta = np.zeros([Ntheta, 3])
    deltheta = 1.0e-1
Пример #12
0
    def __init__(self,
                 x,
                 xp,
                 covariance_function='sqexp',
                 mode="Full",
                 nu=2.5,
                 basis="Rect",
                 M=12,
                 L=5.0):
        """
        :param x: vector of inputs
        :param xp: vector of targets
        :param covariance_function: the kind of covariance function to use (currently 'sqexp' or 'mattern')
        :param mode: whether to do a full GPR or a reduced rank GPR (currently "Full" or "RR")
        :param nu: specifies the kind of Mattern function to use (must be a half integer)
        :param basis: specifies the class of basis functions to use (currently only "Rect")
        """
        # set inputs and targets
        try:
            self.N, self.D = x.shape
            self.Np = xp.shape[0]
        except:
            self.N = x.size
            self.D = 1
            self.Np = xp.size
        self.x = x
        self.xp = xp

        # set covariance
        if covariance_function == "sqexp":
            from GP.kernels import exponential_squared
            # Initialise kernel
            self.kernel = exponential_squared.sqexp()
        elif covariance_function == "mattern":
            from GP.kernels import mattern
            # Initialise kernel
            self.kernel = mattern.mattern(p=int(nu))

        # Get inputs required to evaluate covariance function
        self.mode = mode
        if mode == "Full":  # here we need the differences squared
            from GP.tools import abs_diff
            # Initialise absolute differences
            self.XX = abs_diff.abs_diff(x, x)
            self.XXp = abs_diff.abs_diff(x, xp)
            self.XXpp = abs_diff.abs_diff(xp, xp)
        elif mode == "RR":  # here we need to evaluate the basis functions
            from GP.tools import make_basis
            # check consistency of inputs
            if np.asarray(
                    M
            ).size == 1:  # if single value is specified for M we use the same number of basis functions for each dimension
                self.M = np.tile(M, self.D)
            elif np.asarray(M).size == self.D:
                self.M = M
            else:
                raise Exception('Inconsistent dimensions specified for M')
            if np.asarray(
                    L
            ).size == 1:  # if single value is specified for L we use square domain (hopefully also circular in future)
                self.L = np.tile(L, self.D)
            elif np.asarray(L).size == self.D:
                self.L = L
            else:
                raise Exception('Inconsistent dimensions specified for L')
            # Construct the basis functions
            if basis == "Rect":
                from GP.basisfuncs import rectangular
                self.Phi = make_basis.get_eigenvectors(self.x, self.M, self.L,
                                                       rectangular.phi)
                self.Phip = make_basis.get_eigenvectors(
                    self.xp, self.M, self.L, rectangular.phi)
                self.Lambda = make_basis.get_eigenvals(self.M, self.L,
                                                       rectangular.Lambda)
            else:
                print "%s basis functions not supported yet" % basis

            # Precompute some terms that never change
            self.PhiTPhi = np.dot(self.Phi.T, self.Phi)
            self.s = np.sqrt(self.Lambda)
Пример #13
0
def test_Kyopinv(Kyop, K, Sigmay, b):
    Ky = K + np.diag(Sigmay)
    res1 = np.linalg.solve(Ky, b)
    res2 = Kyop.idot(b)
    compare(res1, res2, "Kyopinv")


if __name__ == "__main__":
    kernel = exponential_squared.sqexp()
    Nx = 17
    sigmaf = 1.0
    lx = 0.5
    thetax = np.array([sigmaf, lx])
    x = np.linspace(-1, 1, Nx)
    xx = abs_diff.abs_diff(x, x)
    Kx = kernel.cov_func(thetax, xx, noise=False)

    Nt = 19
    lt = 0.5
    thetat = np.array([sigmaf, lt])
    t = np.linspace(-1, 1, Nt)
    tt = abs_diff.abs_diff(t, t)
    Kt = kernel.cov_func(thetat, tt, noise=False)

    Nz = 21
    lz = 0.5
    thetaz = np.array([sigmaf, lz])
    z = np.linspace(-1, 1, Nz)
    zz = abs_diff.abs_diff(z, z)
    Kz = kernel.cov_func(thetaz, zz, noise=False)