1# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
2# Licensed under the BSD 3-clause license (see LICENSE.txt)
3
4from .kern import Kern
5from ...core.parameterization import Param
6from paramz.transformations import Logexp
7import numpy as np
8
9class Brownian(Kern):
10    """
11    Brownian motion in 1D only.
12
13    Negative times are treated as a separate (backwards!) Brownian motion.
14
15    :param input_dim: the number of input dimensions
16    :type input_dim: int
17    :param variance:
18    :type variance: float
19    """
20    def __init__(self, input_dim=1, variance=1., active_dims=None, name='Brownian'):
21        assert input_dim==1, "Brownian motion in 1D only"
22        super(Brownian, self).__init__(input_dim, active_dims, name)
23
24        self.variance = Param('variance', variance, Logexp())
25        self.link_parameters(self.variance)
26
27    def to_dict(self):
28        """
29        Convert the object into a json serializable dictionary.
30        Note: It uses the private method _save_to_input_dict of the parent.
31        :return dict: json serializable dictionary containing the needed information to instantiate the object
32        """
33
34        input_dict = super(RBF, self)._save_to_input_dict()
35        input_dict["class"] = "GPy.kern.Brownian"
36        return input_dict
37
38    def K(self,X,X2=None):
39        if X2 is None:
40            X2 = X
41        return self.variance*np.where(np.sign(X)==np.sign(X2.T),np.fmin(np.abs(X),np.abs(X2.T)), 0.)
42
43    def Kdiag(self,X):
44        return self.variance*np.abs(X.flatten())
45
46    def update_gradients_full(self, dL_dK, X, X2=None):
47        if X2 is None:
48            X2 = X
49        self.variance.gradient = np.sum(dL_dK * np.where(np.sign(X)==np.sign(X2.T),np.fmin(np.abs(X),np.abs(X2.T)), 0.))
50
51    #def update_gradients_diag(self, dL_dKdiag, X):
52        #self.variance.gradient = np.dot(np.abs(X.flatten()), dL_dKdiag)
53
54    #def gradients_X(self, dL_dK, X, X2=None):
55        #if X2 is None:
56            #return np.sum(self.variance*dL_dK*np.abs(X),1)[:,None]
57        #else:
58            #return np.sum(np.where(np.logical_and(np.abs(X)<np.abs(X2.T), np.sign(X)==np.sign(X2)), self.variance*dL_dK,0.),1)[:,None]
59
60
61
62