Skip to content

Commit 2303079

Browse files
committed
Added separable stationary kernels
1 parent 01d8944 commit 2303079

File tree

3 files changed

+55
-11
lines changed

3 files changed

+55
-11
lines changed

dynaml-core/src/main/scala-2.11/io/github/mandar2812/dynaml/kernels/AdditiveCovariance.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package io.github.mandar2812.dynaml.kernels
22

33
/**
4-
* @author mandar date: 22/01/2017.
5-
*
64
* A kernel formed by addition
75
* of two kernels k(.,.) = k1(.,.) + k2(.,.)
8-
*/
6+
* @author mandar date: 22/01/2017.
7+
*
8+
* */
99
class AdditiveCovariance[Index](
10-
firstKernel: LocalScalarKernel[Index],
11-
otherKernel: LocalScalarKernel[Index]) extends
10+
val firstKernel: LocalScalarKernel[Index],
11+
val otherKernel: LocalScalarKernel[Index]) extends
1212
CompositeCovariance[Index] {
1313

1414
val (fID, sID) = (firstKernel.toString.split("\\.").last, otherKernel.toString.split("\\.").last)

dynaml-core/src/main/scala-2.11/io/github/mandar2812/dynaml/kernels/DecomposableCovariance.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import io.github.mandar2812.dynaml.pipes._
88
* of base kernels over a subset of the input space.
99
*
1010
* for example K((x1, y1), (x1, y2)) = k1(x1,x2) + k2(y1,y2)
11-
*/
11+
* */
1212
class DecomposableCovariance[S](kernels: LocalScalarKernel[S]*)(
1313
implicit encoding: Encoder[S, Array[S]],
1414
reducer: Reducer = Reducer.:+:) extends CompositeCovariance[S] {

dynaml-core/src/main/scala-2.11/io/github/mandar2812/dynaml/kernels/MultiplicativeCovariance.scala

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package 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
* */
911
class 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

Comments
 (0)