11package io .github .mandar2812 .dynaml .kernels
22
3+ import breeze .linalg .DenseMatrix
4+
35/**
4- * @author mandar date: 22/01/2017.
5- *
66 * A kernel formed by multiplication
77 * of two kernels k(.,.) = k1(.,.) * k2(.,.)
8+ * @author mandar date: 22/01/2017.
9+ *
810 * */
911class MultiplicativeCovariance [Index ](
10- firstKernel : LocalScalarKernel [Index ],
11- otherKernel : LocalScalarKernel [Index ])
12+ val firstKernel : LocalScalarKernel [Index ],
13+ val otherKernel : LocalScalarKernel [Index ])
1214 extends CompositeCovariance [Index ] {
1315
1416 val (fID, sID) = (firstKernel.toString.split(" \\ ." ).last, otherKernel.toString.split(" \\ ." ).last)
@@ -17,7 +19,7 @@ class MultiplicativeCovariance[Index](
1719 firstKernel.hyper_parameters.map(h => fID+ " /" + h) ++
1820 otherKernel.hyper_parameters.map(h => sID+ " /" + h)
1921
20- private def getKernelConfigs (config : Map [String , Double ]) = (
22+ protected def getKernelConfigs (config : Map [String , Double ]) = (
2123 config.filter(_._1.contains(fID)).map(CompositeCovariance .truncateHyperParams),
2224 config.filter(_._1.contains(sID)).map(CompositeCovariance .truncateHyperParams)
2325 )
@@ -64,3 +66,45 @@ class MultiplicativeCovariance[Index](
6466 SVMKernel .crossKernelMatrix(dataset1, dataset2, this .evaluate)
6567
6668}
69+
70+ /**
71+ * Implementation of separable stationary kernels as defined in
72+ * http://jmlr.csail.mit.edu/papers/volume2/genton01a/genton01a.pdf
73+ *
74+ * K(x,y) = K1(x)×K2(y)
75+ *
76+ * @tparam I The index set or input domain over which the kernel function is evaluated.
77+ * @tparam Kernel A kernel type which extends [[StationaryKernel ]] as well as [[LocalScalarKernel ]]
78+ * @param firstKernel The kernel given by K1,
79+ * it is assumed that the user inputs a valid stationary kernel of type [[Kernel ]]
80+ * @param otherKernel The kernel given by K2,
81+ * it is assumed that the user inputs a valid stationary kernel of type [[Kernel ]]
82+ * @author mandar2812 date 21/06/2017
83+ * */
84+ class SeparableStationaryKernel [
85+ I , Kernel <: StationaryKernel [I , Double , DenseMatrix [Double ]] with LocalScalarKernel [I ]](
86+ override val firstKernel : Kernel , override val otherKernel : Kernel ) extends
87+ MultiplicativeCovariance [I ](firstKernel, otherKernel) {
88+
89+
90+ override def evaluateAt (config : Map [String , Double ])(x : I , y : I ) = {
91+
92+ val (firstKernelConfig, secondKernelConfig) = getKernelConfigs(config)
93+
94+ firstKernel.evalAt(firstKernelConfig)(x) * otherKernel.evalAt(secondKernelConfig)(y)
95+
96+ }
97+
98+ override def gradientAt (config : Map [String , Double ])(x : I , y : I ) = {
99+
100+ val (firstKernelConfig, secondKernelConfig) = getKernelConfigs(config)
101+
102+ firstKernel.gradientAt(firstKernelConfig)(x, x).map((couple) =>
103+ (fID+ " /" + couple._1, couple._2* otherKernel.evaluateAt(secondKernelConfig)(y,y))
104+ ) ++ otherKernel.gradientAt(secondKernelConfig)(y,y).map((couple) =>
105+ (sID+ " /" + couple._1, couple._2* firstKernel.evaluateAt(firstKernelConfig)(x,x))
106+ )
107+
108+ }
109+ }
110+
0 commit comments