# Source code for pyro.contrib.gp.kernels.brownian

from __future__ import absolute_import, division, print_function

import torch
from torch.distributions import constraints
from torch.nn import Parameter

from .kernel import Kernel

[docs]class Brownian(Kernel):
r"""
This kernel correponds to a two-sided Brownion motion (Wiener process):

:math:k(x,z)=\begin{cases}\sigma^2\min(|x|,|z|),& \text{if } x\cdot z\ge 0\\
0, & \text{otherwise}. \end{cases}

Note that the input dimension of this kernel must be 1.

Reference:

[1] Theory and Statistical Applications of Stochastic Processes,
Yuliya Mishura, Georgiy Shevchenko
"""

def __init__(self, input_dim, variance=None, active_dims=None, name="Brownian"):
if input_dim != 1:
raise ValueError("Input dimensional for Brownian kernel must be 1.")
super(Brownian, self).__init__(input_dim, active_dims, name)

if variance is None:
variance = torch.tensor(1.)
self.variance = Parameter(variance)
self.set_constraint("variance", constraints.positive)

[docs]    def forward(self, X, Z=None, diag=False):
variance = self.get_param("variance")

if Z is None:
Z = X
X = self._slice_input(X)
if diag:
return variance * X.abs().squeeze(1)

Z = self._slice_input(Z)
if X.shape[1] != Z.shape[1]:
raise ValueError("Inputs must have the same number of features.")

Zt = Z.t()