Skip to content

Commit f31cb23

Browse files
authored
Add Basic Structure (#3)
* Basic Structure * Update Project.toml * Address review suggestions * Modify julia compat * Update Project.toml * Add likelihood * Add test and fix typo * Add trainable * Update .travis.yml * Remove logpdf for likelihood and fix params and trainable issue. * CHange TravisCI documentation's required Julia version to 1 * Add Poisson Likelihood * Fix bug * Remove lambda parameter for Poisson likelihood * Add randf and randy and remove trainable default * Rename \Phi to lik * Move different likelihoods into directories * Remove custom rand functions * Use Functors, remove Requires and Flux dependency * Minor style fixes * Remove Likelihood type * Address code review by @devmotion * Setup test/Project.toml
1 parent 435c2bf commit f31cb23

File tree

12 files changed

+183
-11
lines changed

12 files changed

+183
-11
lines changed

.github/workflows/CompatHelper.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: CompatHelper
2+
3+
on:
4+
schedule:
5+
- cron: '00 00 * * *'
6+
7+
jobs:
8+
CompatHelper:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Pkg.add("CompatHelper")
12+
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
13+
- name: CompatHelper.main()
14+
env:
15+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16+
run: julia -e 'using CompatHelper; CompatHelper.main(; subdirs = ["", "test", "docs"])'

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ os:
44
- linux
55
- osx
66
julia:
7-
- 1.0
7+
- 1
88
- nightly
99
notifications:
1010
email: false
@@ -16,7 +16,7 @@ jobs:
1616
fast_finish: true
1717
include:
1818
- stage: Documentation
19-
julia: 1.0
19+
julia: 1
2020
script: julia --project=docs -e '
2121
using Pkg;
2222
Pkg.develop(PackageSpec(path=pwd()));

Project.toml

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@ uuid = "45b822f7-b0f9-4a40-9473-dffa0412f8e7"
33
authors = ["willtebbutt <[email protected]>"]
44
version = "0.1.0"
55

6-
[compat]
7-
julia = "1"
8-
9-
[extras]
10-
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
6+
[deps]
7+
AbstractGPs = "99985d1d-32ba-4be9-9821-2ec096f28918"
8+
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
9+
Functors = "d9f16b24-f501-4c13-a1f2-28368ffc5196"
10+
KernelFunctions = "ec8451be-7e33-11e9-00cf-bbf324bd1392"
11+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
12+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
13+
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1114

12-
[targets]
13-
test = ["Test"]
15+
[compat]
16+
AbstractGPs = "0.1.1"
17+
Distributions = "0.19, 0.20, 0.21, 0.22, 0.23"
18+
Functors = "0.1"
19+
KernelFunctions = "0.4"
20+
julia = "1.3"

src/LatentGPs.jl

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
module LatentGPs
22

3-
greet() = print("Hello World!")
3+
using Distributions
4+
using KernelFunctions
5+
using AbstractGPs
6+
using LinearAlgebra
7+
using Random
8+
using Functors
9+
10+
import Statistics
11+
import Distributions
12+
13+
export LatentGP
14+
15+
export logpdf, rand
16+
17+
export GaussianLikelihood, PoissonLikelihood
18+
19+
20+
include("latent_gp.jl")
21+
22+
# Likelihoods
23+
include("likelihoods/gaussian.jl")
24+
include("likelihoods/poisson.jl")
425

526
end # module

src/latent_gp.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""
2+
LatentGP(f<:GP, lik)
3+
4+
- `fx` is a `FiniteGP`.
5+
- `lik` is the log likelihood function which maps sample from f to corresposing
6+
conditional likelihood distributions.
7+
8+
"""
9+
struct LatentGP{T<:AbstractGPs.FiniteGP, S}
10+
fx::T
11+
lik::S
12+
end
13+
14+
function Distributions.rand(rng::AbstractRNG, lgp::LatentGP)
15+
f = rand(rng, lgp.fx)
16+
y = rand(rng, lgp.lik(f))
17+
return (f=f, y=y)
18+
end
19+
20+
"""
21+
logpdf(lgp::LatentGP, y::NamedTuple{(:f, :y)})
22+
23+
```math
24+
log p(y, f; x)
25+
```
26+
Returns the joint log density of the gaussian process output `f` and real output `y`.
27+
"""
28+
function Distributions.logpdf(lgp::LatentGP, y::NamedTuple{(:f, :y)})
29+
return logpdf(lgp.fx, y.f) + logpdf(lgp.lik(y.f), y.y)
30+
end

src/likelihoods/gaussian.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""
2+
GaussianLikelihood(σ²)
3+
4+
Gaussian likelihood with `σ²` variance. This is to be used if we assume that the
5+
uncertainity associated with the data follows a Gaussian distribution.
6+
7+
```math
8+
p(y|f) = Normal(y | f, σ²)
9+
```
10+
On calling, this would return a normal distribution with mean `f` and variance σ².
11+
"""
12+
struct GaussianLikelihood{T<:Real}
13+
σ²::T
14+
end
15+
16+
GaussianLikelihood() = GaussianLikelihood(1e-6)
17+
18+
@functor GaussianLikelihood
19+
20+
(l::GaussianLikelihood)(f::Real) = Normal(f, sqrt(l.σ²))
21+
22+
(l::GaussianLikelihood)(fs::AbstractVector{<:Real}) = MvNormal(fs, sqrt(l.σ²))

src/likelihoods/poisson.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"""
2+
PoissonLikelihood()
3+
4+
Poisson likelihood with rate as exponential of samples from GP `f`. This is to be used if
5+
we assume that the uncertainity associated with the data follows a Poisson distribution.
6+
"""
7+
struct PoissonLikelihood end
8+
9+
(l::PoissonLikelihood)(f::Real) = Poisson(exp(f))
10+
11+
(l::PoissonLikelihood)(fs::AbstractVector{<:Real}) = Product(Poisson.(exp.(fs)))

test/Project.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[deps]
2+
AbstractGPs = "99985d1d-32ba-4be9-9821-2ec096f28918"
3+
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
4+
Functors = "d9f16b24-f501-4c13-a1f2-28368ffc5196"
5+
KernelFunctions = "ec8451be-7e33-11e9-00cf-bbf324bd1392"
6+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
7+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
8+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
9+
10+
[compat]
11+
AbstractGPs = "0.1.1"
12+
Distributions = "0.19, 0.20, 0.21, 0.22, 0.23"
13+
KernelFunctions = "0.4"
14+
julia = "1.3"

test/latent_gp.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@testset "latent_gp" begin
2+
gp = GP(SqExponentialKernel())
3+
x = rand(10)
4+
y = rand(10)
5+
fx = gp(x, 1e-5)
6+
7+
lik = GaussianLikelihood(1e-5)
8+
9+
lgp = LatentGP(fx, lik)
10+
@test typeof(lgp) <: LatentGP
11+
@test typeof(lgp.fx) <: AbstractGPs.FiniteGP
12+
f = rand(10)
13+
@test typeof(logpdf(lgp, (f=f, y=y))) <: Real
14+
@test typeof(rand(lgp)) <: NamedTuple{(:f, :y)}
15+
end

test/likelihoods/gaussian.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@testset "GaussianLikelihood" begin
2+
gp = GP(SqExponentialKernel())
3+
x = rand(10)
4+
y = rand(10)
5+
fx = gp(x, 1e-5)
6+
lik = GaussianLikelihood(first(fx.Σy))
7+
lgp = LatentGP(fx, lik)
8+
9+
@test typeof(lik(rand(fx))) <: Distribution
10+
@test length(rand(lik(rand(fx)))) == 10
11+
@test keys(Functors.functor(lik)[1]) == (:σ²,)
12+
end

0 commit comments

Comments
 (0)