Skip to content

Commit 57c82be

Browse files
committed
[WIP] Adding Warped Gaussian Process model
1 parent b676e8c commit 57c82be

File tree

6 files changed

+123
-9
lines changed

6 files changed

+123
-9
lines changed

Diff for: dynaml-core/src/main/scala-2.11/io/github/mandar2812/dynaml/analysis/PushforwardMap.scala

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ under the License.
1818
* */
1919
package io.github.mandar2812.dynaml.analysis
2020

21+
import io.github.mandar2812.dynaml.models.ContinuousProcess
2122
import io.github.mandar2812.dynaml.pipes.{DataPipe, Encoder}
2223
import io.github.mandar2812.dynaml.probability.{ContinuousDistrRV, MeasurableDistrRV}
2324
import spire.algebra.Field
@@ -43,6 +44,8 @@ abstract class PushforwardMap[
4344
def ->[R <: ContinuousDistrRV[Source]](r: R): MeasurableDistrRV[Source, Destination, Jacobian] =
4445
new MeasurableDistrRV[Source, Destination, Jacobian](r)(self)
4546

47+
//def ->[P <: ContinuousProcess[_, _, ]]
48+
4649
/**
4750
* Return the implementation used for calculating
4851
* determinant of the inverse function's Jacobian

Diff for: dynaml-core/src/main/scala-2.11/io/github/mandar2812/dynaml/models/Model.scala

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ trait Model[T, Q, R] {
4545
* */
4646
protected val g: T
4747

48+
def data = g
49+
4850
/**
4951
* Predict the value of the
5052
* target variable given a
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,118 @@
11
package io.github.mandar2812.dynaml.models.gp
22

3-
import io.github.mandar2812.dynaml.kernels.LocalScalarKernel
3+
import breeze.linalg.{DenseMatrix, det, diag}
4+
import io.github.mandar2812.dynaml.algebra.{PartitionedMatrix, PartitionedVector}
5+
import io.github.mandar2812.dynaml.analysis.{DifferentiableMap, PartitionedVectorField, PushforwardMap}
6+
import io.github.mandar2812.dynaml.models.{ContinuousProcess, SecondOrderProcess}
7+
import io.github.mandar2812.dynaml.optimization.GloballyOptWithGrad
8+
import io.github.mandar2812.dynaml.pipes.DataPipe
9+
import io.github.mandar2812.dynaml.probability.{E, MeasurableDistrRV}
10+
import io.github.mandar2812.dynaml.utils
411

512
import scala.reflect.ClassTag
613

714
/**
815
* Created by mandar on 02/01/2017.
916
*/
10-
abstract class WarpedGP[T, I](
11-
cov: LocalScalarKernel[I], n: LocalScalarKernel[I],
12-
data: T, num: Int)(implicit ev: ClassTag[I]) extends
13-
AbstractGPRegressionModel[T, I](cov, n, data, num) {
17+
abstract class WarpedGP[T, I](p: AbstractGPRegressionModel[T, I])(
18+
wFuncT: PushforwardMap[Double, Double, Double])(
19+
implicit ev: ClassTag[I], pf: PartitionedVectorField)
20+
extends ContinuousProcess[
21+
T, I, Double,
22+
MeasurableDistrRV[PartitionedVector, PartitionedVector, PartitionedMatrix]]
23+
with SecondOrderProcess[
24+
T, I, Double, Double, DenseMatrix[Double],
25+
MeasurableDistrRV[PartitionedVector, PartitionedVector, PartitionedMatrix]]
26+
with GloballyOptWithGrad {
1427

28+
29+
//Define the default determinant implementation
30+
implicit val detImpl = DataPipe(
31+
(m: PartitionedMatrix) => m.filterBlocks(c => c._1 == c._2).map(c => det(c._2)).product)
32+
33+
//Define the push forward map for the multivariate case
34+
val wFuncPredDistr: PushforwardMap[PartitionedVector, PartitionedVector, PartitionedMatrix] =
35+
PushforwardMap(
36+
DataPipe((v: PartitionedVector) => v.map(c => (c._1, c._2.map(wFuncT.run)))),
37+
DifferentiableMap(
38+
(v: PartitionedVector) => v.map(c => (c._1, c._2.map(wFuncT.i.run))),
39+
(v: PartitionedVector) => new PartitionedMatrix(
40+
v._data.map(l => ((l._1, l._1), diag(l._2.map(wFuncT.i.J)))) ++
41+
utils.combine(Seq((0 until v.rowBlocks.toInt).toList, (0 until v.rowBlocks.toInt).toList))
42+
.map(c =>
43+
(c.head.toLong, c.last.toLong))
44+
.filter(c => c._2 != c._1)
45+
.map(c => (c, DenseMatrix.zeros[Double](v.rows.toInt/v.rowBlocks.toInt, v.rows.toInt/v.rowBlocks.toInt)))
46+
.toStream, num_cols = v.rows, num_rows = v.rows))
47+
)
48+
49+
/**
50+
* Draw three predictions from the posterior predictive distribution
51+
* 1) Mean or MAP estimate Y
52+
* 2) Y- : The lower error bar estimate (mean - sigma*stdDeviation)
53+
* 3) Y+ : The upper error bar. (mean + sigma*stdDeviation)
54+
**/
55+
override def predictionWithErrorBars[U <: Seq[I]](testData: U, sigma: Int) = ???
56+
57+
/**
58+
* Mean Function: Takes a member of the index set (input)
59+
* and returns the corresponding mean of the distribution
60+
* corresponding to input.
61+
**/
62+
override val mean = p.mean
63+
/**
64+
* Underlying covariance function of the
65+
* Gaussian Processes.
66+
**/
67+
override val covariance = p.covariance
68+
/**
69+
* Stores the names of the hyper-parameters
70+
**/
71+
override protected var hyper_parameters: List[String] = p._hyper_parameters
72+
/**
73+
* A Map which stores the current state of
74+
* the system.
75+
**/
76+
override protected var current_state: Map[String, Double] = p._current_state
77+
78+
/**
79+
* Calculates the energy of the configuration,
80+
* in most global optimization algorithms
81+
* we aim to find an approximate value of
82+
* the hyper-parameters such that this function
83+
* is minimized.
84+
*
85+
* @param h The value of the hyper-parameters in the configuration space
86+
* @param options Optional parameters about configuration
87+
* @return Configuration Energy E(h)
88+
**/
89+
override def energy(h: Map[String, Double], options: Map[String, String]) = p.energy(h, options)
90+
91+
/** Calculates posterior predictive distribution for
92+
* a particular set of test data points.
93+
*
94+
* @param test A Sequence or Sequence like data structure
95+
* storing the values of the input patters.
96+
**/
97+
override def predictiveDistribution[U <: Seq[I]](test: U) = wFuncPredDistr -> p.predictiveDistribution(test)
98+
99+
/**
100+
* Convert from the underlying data structure to
101+
* Seq[(I, Y)] where I is the index set of the GP
102+
* and Y is the value/label type.
103+
**/
104+
override def dataAsSeq(data: T) = p.dataAsSeq(data)
105+
106+
/**
107+
* The training data
108+
**/
109+
override protected val g: T = p.data
110+
111+
/**
112+
* Predict the value of the
113+
* target variable given a
114+
* point.
115+
*
116+
**/
117+
override def predict(point: I) = wFuncT(p.predictionWithErrorBars(Seq(point), 1).head._2)
15118
}

Diff for: dynaml-core/src/main/scala-2.11/io/github/mandar2812/dynaml/optimization/GloballyOptimizable.scala

+4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ trait GloballyOptimizable {
3939
* */
4040
protected var current_state: Map[String, Double]
4141

42+
def _current_state = current_state
43+
44+
def _hyper_parameters = hyper_parameters
45+
4246
/**
4347
* Calculates the energy of the configuration,
4448
* in most global optimization algorithms

Diff for: dynaml-core/src/main/scala-2.11/io/github/mandar2812/dynaml/probability/GaussianRV.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@ import io.github.mandar2812.dynaml.probability.distributions.BlockedMultiVariate
88
import spire.implicits._
99
import spire.algebra.Field
1010

11+
abstract class AbstractGaussianRV[T, V] extends ContinuousDistrRV[T]
12+
1113
/**
1214
* Created by mandar on 26/7/16.
1315
*/
14-
case class GaussianRV(mu: Double, sigma: Double) extends ContinuousDistrRV[Double] {
16+
case class GaussianRV(mu: Double, sigma: Double) extends AbstractGaussianRV[Double, Double] {
1517
override val underlyingDist = new Gaussian(mu, sigma)
1618
}
1719

1820
case class MultGaussianRV(
1921
mu: DenseVector[Double], covariance: DenseMatrix[Double])(
2022
implicit ev: Field[DenseVector[Double]])
21-
extends ContinuousDistrRV[DenseVector[Double]] {
23+
extends AbstractGaussianRV[DenseVector[Double], DenseMatrix[Double]] {
2224

2325
override val underlyingDist = MultivariateGaussian(mu, covariance)
2426

@@ -39,7 +41,7 @@ object MultGaussianRV {
3941

4042
case class MultGaussianPRV(mu: PartitionedVector, covariance: PartitionedPSDMatrix)(
4143
implicit ev: Field[PartitionedVector])
42-
extends ContinuousDistrRV[PartitionedVector] {
44+
extends AbstractGaussianRV[PartitionedVector, PartitionedPSDMatrix] {
4345

4446
override val underlyingDist: ContinuousDistr[PartitionedVector] = BlockedMultiVariateGaussian(mu, covariance)
4547

Diff for: dynaml-core/src/main/scala-2.11/io/github/mandar2812/dynaml/probability/MeasurableFunction.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ object RealValuedMeasurableFunction {
7777
class MeasurableDistrRV[Domain1, Domain2, Jacobian](
7878
baseRV: ContinuousDistrRV[Domain1])(p: PushforwardMap[Domain1, Domain2, Jacobian])
7979
extends MeasurableFunction[Domain1, Domain2](baseRV)(p)
80-
with RandomVarWithDistr[Domain2, ContinuousDistr[Domain2]] {
80+
with ContinuousDistrRV[Domain2] {
8181

8282
override val underlyingDist = new ContinuousDistr[Domain2] {
8383
override def unnormalizedLogPdf(x: Domain2) =

0 commit comments

Comments
 (0)