-
Notifications
You must be signed in to change notification settings - Fork 36
Add Piecewise Polynomial Kernel #76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
willtebbutt
merged 19 commits into
JuliaGaussianProcesses:master
from
sharanry:piecewisePolynomial
Apr 9, 2020
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
9b86a8d
Add Piecewise Polynomial Kernel
sharanry 1e4995f
Fix docstring
sharanry 49b5822
Use div instead of floor
sharanry 659a7d3
Make V a parameterized type
sharanry c3afcd5
Apply suggestions from code review by @devmotion
sharanry 9fb7f6f
Update Docstring
sharanry 10b5d13
Add getproperty for v
sharanry e9304ea
Add type parameter V
sharanry 4deaef6
Add _piecewisepolynomial function and add kernel matrix functions
sharanry 49b67ab
Use feature_dim
sharanry 4f8f8d8
Add external constructor
sharanry 4a452de
Cleanup external constructor
sharanry 802da81
Add tests
sharanry d6a9d8c
Add more tests
sharanry ee263fa
Apply suggestions from code review
sharanry 94db1c9
Fix doctring
sharanry f1a9bf4
Merge branch 'master' into piecewisePolynomial
sharanry c7c644f
Modify _f
sharanry d94da63
Fix bug with _kernelmatrix
sharanry File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
""" | ||
PiecewisePolynomialKernel{V}(maha::AbstractMatrix) | ||
|
||
Piecewise Polynomial covariance function with compact support, V = 0,1,2,3. | ||
The kernel functions are 2v times continuously differentiable and the corresponding | ||
processes are hence v times mean-square differentiable. The kernel function is: | ||
```math | ||
κ(x, y) = max(1 - r, 0)^(j + V) * f(r, j) with j = floor(D / 2) + V + 1 | ||
``` | ||
where `r` is the Mahalanobis distance mahalanobis(x,y) with `maha` as the metric. | ||
|
||
""" | ||
struct PiecewisePolynomialKernel{V, A<:AbstractMatrix{<:Real}} <: BaseKernel | ||
maha::A | ||
function PiecewisePolynomialKernel{V}(maha::AbstractMatrix{<:Real}) where V | ||
V in (0, 1, 2, 3) || error("Invalid paramter v=$(V). Should be 0, 1, 2 or 3.") | ||
LinearAlgebra.checksquare(maha) | ||
return new{V,typeof(maha)}(maha) | ||
end | ||
end | ||
|
||
function PiecewisePolynomialKernel(;v::Integer=0, maha::AbstractMatrix{<:Real}) | ||
return PiecewisePolynomialKernel{v}(maha) | ||
end | ||
|
||
_f(κ::PiecewisePolynomialKernel{0}, r, j) = 1 | ||
_f(κ::PiecewisePolynomialKernel{1}, r, j) = 1 + (j + 1) * r | ||
_f(κ::PiecewisePolynomialKernel{2}, r, j) = 1 + (j + 2) * r + (j^2 + 4 * j + 3) / 3 * r.^2 | ||
_f(κ::PiecewisePolynomialKernel{3}, r, j) = 1 + (j + 3) * r + | ||
(6 * j^2 + 36j + 45) / 15 * r.^2 + (j^3 + 9 * j^2 + 23j + 15) / 15 * r.^3 | ||
|
||
function _piecewisepolynomial(κ::PiecewisePolynomialKernel{V}, r, j) where V | ||
return max(1 - r, 0)^(j + V) * _f(κ, r, j) | ||
end | ||
|
||
function kappa( | ||
κ::PiecewisePolynomialKernel{V}, | ||
x::AbstractVector{<:Real}, | ||
y::AbstractVector{<:Real}, | ||
) where {V} | ||
r = evaluate(metric(κ), x, y) | ||
j = div(size(x, 2), 1) + V + 1 | ||
return _piecewisepolynomial(κ, r, j) | ||
end | ||
|
||
function _kernel( | ||
κ::PiecewisePolynomialKernel, | ||
x::AbstractVector, | ||
y::AbstractVector; | ||
obsdim::Int = defaultobs, | ||
) | ||
@assert length(x) == length(y) "x and y don't have the same dimension!" | ||
return kappa(κ,x,y) | ||
end | ||
|
||
function kernelmatrix( | ||
κ::PiecewisePolynomialKernel{V}, | ||
X::AbstractMatrix; | ||
obsdim::Int = defaultobs | ||
) where {V} | ||
j = div(size(X, feature_dim(obsdim)), 2) + V + 1 | ||
return map(r->_piecewisepolynomial(κ, r, j), pairwise(metric(κ), X; dims=obsdim)) | ||
end | ||
|
||
function _kernelmatrix(κ::PiecewisePolynomialKernel{V}, X, Y, obsdim) where {V} | ||
j = div(size(X, feature_dim(obsdim)), 2) + V + 1 | ||
return map(r->_piecewisepolynomial(κ, r, j), pairwise(metric(κ), X, Y; dims=obsdim)) | ||
end | ||
|
||
function kernelmatrix!( | ||
K::AbstractMatrix, | ||
κ::PiecewisePolynomialKernel{V}, | ||
X::AbstractMatrix; | ||
obsdim::Int = defaultobs | ||
) where {V} | ||
@assert obsdim ∈ [1,2] "obsdim should be 1 or 2 (see docs of kernelmatrix))" | ||
if !check_dims(K, X, X, feature_dim(obsdim), obsdim) | ||
throw(DimensionMismatch( | ||
"Dimensions of the target array K $(size(K)) are not consistent with X " * | ||
"$(size(X))", | ||
)) | ||
end | ||
j = div(size(X, feature_dim(obsdim)), 2) + V + 1 | ||
return map!(r->_piecewisepolynomial(κ,r,j), K, pairwise(metric(κ), X; dims=obsdim)) | ||
end | ||
|
||
function kernelmatrix!( | ||
K::AbstractMatrix, | ||
κ::PiecewisePolynomialKernel{V}, | ||
X::AbstractMatrix, | ||
Y::AbstractMatrix; | ||
obsdim::Int = defaultobs, | ||
) where {V} | ||
@assert obsdim ∈ [1,2] "obsdim should be 1 or 2 (see docs of kernelmatrix))" | ||
if !check_dims(K, X, Y, feature_dim(obsdim), obsdim) | ||
throw(DimensionMismatch( | ||
"Dimensions $(size(K)) of the target array K are not consistent with X " * | ||
"($(size(X))) and Y ($(size(Y)))", | ||
)) | ||
end | ||
j = div(size(X, feature_dim(obsdim)), 2) + V + 1 | ||
return map!(r->_piecewisepolynomial(κ,r,j), K, pairwise(metric(κ), X, Y; dims=obsdim)) | ||
end | ||
|
||
metric(κ::PiecewisePolynomialKernel) = Mahalanobis(κ.maha) | ||
|
||
function Base.show(io::IO, κ::PiecewisePolynomialKernel{V}) where {V} | ||
print(io, "Piecewise Polynomial Kernel (v = $(V), size(maha) = $(size(κ.maha))") | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
@testset "piecewisepolynomial" begin | ||
v1 = rand(3) | ||
v2 = rand(3) | ||
m1 = rand(3, 4) | ||
m2 = rand(3, 4) | ||
maha = ones(3, 3) | ||
k = PiecewisePolynomialKernel{3}(maha) | ||
|
||
k2 = PiecewisePolynomialKernel(v=3, maha=maha) | ||
|
||
@test k2(v1, v2) ≈ k(v1, v2) atol=1e-5 | ||
|
||
@test k(v1, v2) ≈ kappa(k, v1, v2) atol=1e-5 | ||
@test typeof(k(v1, v2)) <: Real | ||
@test size(k(m1, m2)) == (4, 4) | ||
@test size(k(m1)) == (4, 4) | ||
|
||
A1 = ones(4, 4) | ||
kernelmatrix!(A1, k, m1, m2) | ||
@test A1 ≈ kernelmatrix(k, m1, m2) atol=1e-5 | ||
|
||
A2 = ones(4, 4) | ||
kernelmatrix!(A2, k, m1) | ||
@test A2 ≈ kernelmatrix(k, m1) atol=1e-5 | ||
|
||
@test size(kerneldiagmatrix(k, m1)) == (4,) | ||
@test kerneldiagmatrix(k, m1) == ones(4) | ||
A3 = ones(4) | ||
kerneldiagmatrix!(A3, k, m1) | ||
@test A3 == kerneldiagmatrix(k, m1) | ||
|
||
@test_throws ErrorException PiecewisePolynomialKernel{4}(maha) | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.