/
sm.jl
111 lines (94 loc) · 4.05 KB
/
sm.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
"""
spectral_mixture_kernel(
h::Kernel=SqExponentialKernel(),
αs::AbstractVector{<:Real},
γs::AbstractMatrix{<:Real},
ωs::AbstractMatrix{<:Real},
)
where αs are the weights of dimension (A, ), γs is the covariance matrix of
dimension (D, A) and ωs are the mean vectors and is of dimension (D, A).
Here, D is input dimension and A is the number of spectral components.
`h` is the kernel, which defaults to [`SqExponentialKernel`](@ref) if not specified.
!!! warning
If you want to make sure that the constructor is type-stable, you should
provide [`StaticArrays`](https://github.com/JuliaArrays/StaticArrays.jl) arguments:
`αs` as a `StaticVector`, `γs` and `ωs` as `StaticMatrix`.
Generalised Spectral Mixture kernel function. This family of functions is dense
in the family of stationary real-valued kernels with respect to the pointwise convergence.[1]
```math
κ(x, y) = αs' (h(-(γs' * t)^2) .* cos(π * ωs' * t), t = x - y
```
# References:
[1] Generalized Spectral Kernels, by Yves-Laurent Kom Samo and Stephen J. Roberts
[2] SM: Gaussian Process Kernels for Pattern Discovery and Extrapolation,
ICML, 2013, by Andrew Gordon Wilson and Ryan Prescott Adams,
[3] Covariance kernels for fast automatic pattern discovery and extrapolation
with Gaussian processes, Andrew Gordon Wilson, PhD Thesis, January 2014.
http://www.cs.cmu.edu/~andrewgw/andrewgwthesis.pdf
[4] http://www.cs.cmu.edu/~andrewgw/pattern/.
"""
function spectral_mixture_kernel(
h::Kernel,
αs::AbstractVector{<:Real},
γs::AbstractMatrix{<:Real},
ωs::AbstractMatrix{<:Real},
)
if !(size(αs, 1) == size(γs, 2) == size(ωs, 2))
throw(DimensionMismatch("The dimensions of αs, γs, ans ωs do not match"))
end
if size(γs) != size(ωs)
throw(DimensionMismatch("The dimensions of γs ans ωs do not match"))
end
kernels = map(zip(αs, eachcol(γs), eachcol(ωs))) do (α, γ, ω)
a = TransformedKernel(h, LinearTransform(γ'))
b = TransformedKernel(CosineKernel(), LinearTransform(ω'))
return α * a * b
end
return sum(kernels)
end
function spectral_mixture_kernel(
αs::AbstractVector{<:Real}, γs::AbstractMatrix{<:Real}, ωs::AbstractMatrix{<:Real}
)
return spectral_mixture_kernel(SqExponentialKernel(), αs, γs, ωs)
end
"""
spectral_mixture_product_kernel(
h::Kernel=SqExponentialKernel(),
αs::AbstractMatrix{<:Real},
γs::AbstractMatrix{<:Real},
ωs::AbstractMatrix{<:Real},
)
where αs are the weights of dimension (D, A), γs is the covariance matrix of
dimension (D, A) and ωs are the mean vectors and is of dimension (D, A).
Here, D is input dimension and A is the number of spectral components.
Spectral Mixture Product Kernel. With enough components A, the SMP kernel
can model any product kernel to arbitrary precision, and is flexible even
with a small number of components [1]
`h` is the kernel, which defaults to [`SqExponentialKernel`](@ref) if not specified.
```math
κ(x, y) = Πᵢ₌₁ᴷ Σ(αsᵢᵀ .* (h(-(γsᵢᵀ * tᵢ)²) .* cos(ωsᵢᵀ * tᵢ))), tᵢ = xᵢ - yᵢ
```
# References:
[1] GPatt: Fast Multidimensional Pattern Extrapolation with GPs,
arXiv 1310.5288, 2013, by Andrew Gordon Wilson, Elad Gilboa,
Arye Nehorai and John P. Cunningham
"""
function spectral_mixture_product_kernel(
h::Kernel,
αs::AbstractMatrix{<:Real},
γs::AbstractMatrix{<:Real},
ωs::AbstractMatrix{<:Real},
)
if !(size(αs) == size(γs) == size(ωs))
throw(DimensionMismatch("The dimensions of αs, γs, ans ωs do not match"))
end
return KernelTensorProduct(
spectral_mixture_kernel(h, α, reshape(γ, 1, :), reshape(ω, 1, :)) for
(α, γ, ω) in zip(eachrow(αs), eachrow(γs), eachrow(ωs))
)
end
function spectral_mixture_product_kernel(
αs::AbstractMatrix{<:Real}, γs::AbstractMatrix{<:Real}, ωs::AbstractMatrix{<:Real}
)
return spectral_mixture_product_kernel(SqExponentialKernel(), αs, γs, ωs)
end