-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy pathpolynomial.jl
More file actions
122 lines (90 loc) · 3.55 KB
/
polynomial.jl
File metadata and controls
122 lines (90 loc) · 3.55 KB
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
112
113
114
115
116
117
118
119
120
121
122
"""
LinearKernel(; c::Real=0.0)
Linear kernel with constant offset `c`.
# Definition
For inputs ``x, x' \\in \\mathbb{R}^d``, the linear kernel with constant offset
``c \\geq 0`` is defined as
```math
k(x, x'; c) = x^\\top x' + c.
```
See also: [`PolynomialKernel`](@ref)
"""
struct LinearKernel{Tc<:Real} <: SimpleKernel
c::Vector{Tc}
function LinearKernel(c::Real; check_args::Bool=true)
@check_args(LinearKernel, (c, c >= zero(c), "c ≥ 0"))
return new{typeof(c)}([c])
end
end
LinearKernel(; c::Real=0.0, check_args::Bool=true) = LinearKernel(c; check_args)
@functor LinearKernel
__linear_kappa(c::Real, xᵀy::Real) = xᵀy + c
kappa(κ::LinearKernel, xᵀy::Real) = __linear_kappa(only(κ.c), xᵀy)
metric(::LinearKernel) = DotProduct()
function kernelmatrix(k::LinearKernel, x::AbstractVector, y::AbstractVector)
return __linear_kappa.(only(k.c), pairwise(metric(k), x, y))
end
function kernelmatrix(k::LinearKernel, x::AbstractVector)
return __linear_kappa.(only(k.c), pairwise(metric(k), x))
end
function kernelmatrix_diag(k::LinearKernel, x::AbstractVector, y::AbstractVector)
return __linear_kappa.(only(k.c), colwise(metric(k), x, y))
end
function kernelmatrix_diag(k::LinearKernel, x::AbstractVector)
return __linear_kappa.(only(k.c), colwise(metric(k), x))
end
Base.show(io::IO, κ::LinearKernel) = print(io, "Linear Kernel (c = ", only(κ.c), ")")
"""
PolynomialKernel(; degree::Int=2, c::Real=0.0)
Polynomial kernel of degree `degree` with constant offset `c`.
# Definition
For inputs ``x, x' \\in \\mathbb{R}^d``, the polynomial kernel of degree
``\\nu \\in \\mathbb{N}`` with constant offset ``c \\geq 0`` is defined as
```math
k(x, x'; c, \\nu) = (x^\\top x' + c)^\\nu.
```
See also: [`LinearKernel`](@ref)
"""
struct PolynomialKernel{Tc<:Real} <: SimpleKernel
degree::Int
c::Vector{Tc}
function PolynomialKernel{Tc}(
degree::Int, c::Vector{Tc}; check_args::Bool=true
) where {Tc}
@check_args(
PolynomialKernel,
(degree, degree >= one(degree), "degree ≥ 1"),
(c, only(c) >= zero(Tc), "c ≥ 0")
)
return new{Tc}(degree, c)
end
end
function PolynomialKernel(; degree::Int=2, c::Real=0.0, check_args::Bool=true)
return PolynomialKernel{typeof(c)}(degree, [c]; check_args)
end
# The degree of the polynomial kernel is a fixed discrete parameter
function Functors.functor(::Type{<:PolynomialKernel}, x)
reconstruct_polynomialkernel(xs) = PolynomialKernel{typeof(xs.c)}(x.degree, xs.c)
return (c=x.c,), reconstruct_polynomialkernel
end
struct _PolynomialKappa
degree::Int
end
(κ::_PolynomialKappa)(c::Real, xᵀy::Real) = (xᵀy + c)^κ.degree
kappa(κ::PolynomialKernel, xᵀy::Real) = _PolynomialKappa(κ.degree)(only(κ.c), xᵀy)
metric(::PolynomialKernel) = DotProduct()
function kernelmatrix(k::PolynomialKernel, x::AbstractVector, y::AbstractVector)
return _PolynomialKappa(k.degree).(only(k.c), pairwise(metric(k), x, y))
end
function kernelmatrix(k::PolynomialKernel, x::AbstractVector)
return _PolynomialKappa(k.degree).(only(k.c), pairwise(metric(k), x))
end
function kernelmatrix_diag(k::PolynomialKernel, x::AbstractVector, y::AbstractVector)
return _PolynomialKappa(k.degree).(only(k.c), colwise(metric(k), x, y))
end
function kernelmatrix_diag(k::PolynomialKernel, x::AbstractVector)
return _PolynomialKappa(k.degree).(only(k.c), colwise(metric(k), x))
end
function Base.show(io::IO, κ::PolynomialKernel)
return print(io, "Polynomial Kernel (c = ", only(κ.c), ", degree = ", κ.degree, ")")
end