Skip to content
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

Improve docs #103

Merged
merged 3 commits into from
Jan 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 0 additions & 57 deletions doc/latex/Interpolations.bbl

This file was deleted.

13 changes: 0 additions & 13 deletions doc/latex/Interpolations.bib

This file was deleted.

Binary file removed doc/latex/Interpolations.pdf
Binary file not shown.
283 changes: 0 additions & 283 deletions doc/latex/Interpolations.tex

This file was deleted.

Binary file removed doc/latex/figures/periodic-data.pdf
Binary file not shown.
21 changes: 21 additions & 0 deletions src/b-splines/constant.jl
Original file line number Diff line number Diff line change
@@ -1,20 +1,41 @@
immutable Constant <: Degree{0} end

"""
Constant b-splines are *nearest-neighbor* interpolations, and effectively
return `A[round(Int,x)]` when interpolating
"""
Constant

"""
`define_indices_d` for a constant b-spline calculates `ix_d = round(Int,x_d)`
"""
function define_indices_d(::Type{BSpline{Constant}}, d, pad)
symix, symx = symbol("ix_",d), symbol("x_",d)
:($symix = clamp(round(Int, $symx), 1, size(itp, $d)))
end

"""
`coefficients` for a constant b-spline simply sets `c_d = 1` for compatibility
with the general b-spline framework
"""
function coefficients(::Type{BSpline{Constant}}, N, d)
sym, symx = symbol("c_",d), symbol("x_",d)
:($sym = 1)
end

"""
`gradient_coefficients` for a constant b-spline simply sets `c_d = 0` for
compatibility with the general b-spline framework
"""
function gradient_coefficients(::Type{BSpline{Constant}}, d)
sym, symx = symbol("c_",d), symbol("x_",d)
:($sym = 0)
end

"""
`hessian_coefficients` for a constant b-spline simply sets `c_d = 0` for
compatibility with the general b-spline framework
"""
function hessian_coefficients(::Type{BSpline{Constant}}, d)
sym = symbol("c_",d)
:($sym = 0)
Expand Down
91 changes: 64 additions & 27 deletions src/b-splines/cubic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ Cubic{BC<:Flag}(::BC) = Cubic{BC}()
Assuming uniform knots with spacing 1, the `i`th piece of cubic spline
implemented here is defined as follows.

y_i(x) = ϕm p(x-i) + ϕ q(x-i) + ϕp q(1- (x-i)) + ϕpp p(1 - (x-i))
y_i(x) = cm p(x-i) + c q(x-i) + cp q(1- (x-i)) + cpp p(1 - (x-i))

where

p() = 1/6 * (1-)^3
q() = 2/3 - ^2 + 1/2 ^3
p(δx) = 1/6 * (1-δx)^3
q(δx) = 2/3 - δx^2 + 1/2 δx^3

and the values `ϕX` for `X {m, _, p, pp}` are the pre-filtered coefficients.
and the values `cX` for `X {m, _, p, pp}` are the pre-filtered coefficients.

For future reference, this expands out to the following polynomial:

Expand All @@ -24,6 +24,11 @@ When we derive boundary conditions we will use derivatives `y_0'(x)` and
"""
Cubic

"""
`define_indices_d` for a cubic b-spline calculates `ix_d = floor(x_d)` and
`fx_d = x_d - ix_d` (corresponding to `i` `and `δx` in the docstring for
`Cubic`), as well as auxiliary quantities `ixm_d`, `ixp_d` and `ixpp_d`
"""
function define_indices_d{BC}(::Type{BSpline{Cubic{BC}}}, d, pad)
symix, symixm, symixp = symbol("ix_",d), symbol("ixm_",d), symbol("ixp_",d)
symixpp, symx, symfx = symbol("ixpp_",d), symbol("x_",d), symbol("fx_",d)
Expand All @@ -39,6 +44,14 @@ function define_indices_d{BC}(::Type{BSpline{Cubic{BC}}}, d, pad)
end
end

"""
`define_indices_d` for a cubic, periodic b-spline calculates `ix_d = floor(x_d)`
and `fx_d = x_d - ix_d` (corresponding to `i` and `δx` in the docstring entry
for `Cubic`), as well as auxiliary quantities `ixm_d`, `ixp_d` and `ixpp_d`.

If any `ixX_d` for `x ∈ {m, p, pp}` (note: not `c_d`) should fall outside of
the data interval, they wrap around.
"""
function define_indices_d(::Type{BSpline{Cubic{Periodic}}}, d, pad)
symix, symixm, symixp = symbol("ix_",d), symbol("ixm_",d), symbol("ixp_",d)
symixpp, symx, symfx = symbol("ixpp_",d), symbol("x_",d), symbol("fx_",d)
Expand All @@ -55,15 +68,16 @@ padding{BC<:Flag}(::Type{BSpline{Cubic{BC}}}) = Val{1}()
padding(::Type{BSpline{Cubic{Periodic}}}) = Val{0}()

"""
In this function we assume that `fx_d = x-ix_d` and we produce `cX_d` for
`X ⋹ {m, _, p, pp}` such that
In `coefficients` for a cubic b-spline we assume that `fx_d = x-ix_d`
and we define `cX_d` for `X ⋹ {m, _, p, pp}` such that

cm_d = p(fx_d)
c_d = q(fx_d)
cp_d = q(1-fx_d)
cpp_d = p(1-fx_d)

where `p` and `q` are defined in the docstring entry for `Cubic`.
where `p` and `q` are defined in the docstring entry for `Cubic`, and
`fx_d` in the docstring entry for `define_indices_d`.
"""
function coefficients{C<:Cubic}(::Type{BSpline{C}}, N, d)
symm, sym = symbol("cm_",d), symbol("c_",d)
Expand All @@ -82,15 +96,16 @@ function coefficients{C<:Cubic}(::Type{BSpline{C}}, N, d)
end

"""
In this function we assume that `fx_d = x-ix_d` and we produce `cX_d` for
`X ⋹ {m, _, p, pp}` such that
In `gradient_coefficients` for a cubic b-spline we assume that `fx_d = x-ix_d`
and we define `cX_d` for `X ⋹ {m, _, p, pp}` such that

cm_d = p'(fx_d)
c_d = q'(fx_d)
cp_d = q'(1-fx_d)
cpp_d = p'(1-fx_d)

where `p` and `q` are defined in the docstring for `Cubic`.
where `p` and `q` are defined in the docstring entry for `Cubic`, and
`fx_d` in the docstring entry for `define_indices_d`.
"""
function gradient_coefficients{C<:Cubic}(::Type{BSpline{C}}, d)
symm, sym, symp, sympp = symbol("cm_",d), symbol("c_",d), symbol("cp_",d), symbol("cpp_",d)
Expand Down Expand Up @@ -147,6 +162,14 @@ end
# Prefiltering #
# ------------ #

"""
`Cubic`: continuity in function value, first and second derivatives yields

2/3 1/6
1/6 2/3 1/6
1/6 2/3 1/6
⋱ ⋱ ⋱
"""
function inner_system_diags{T,C<:Cubic}(::Type{T}, n::Int, ::Type{C})
du = fill(convert(T, SimpleRatio(1, 6)), n-1)
d = fill(convert(T, SimpleRatio(2, 3)), n)
Expand All @@ -155,8 +178,8 @@ function inner_system_diags{T,C<:Cubic}(::Type{T}, n::Int, ::Type{C})
end

"""
`Flat` `OnGrid` amounts to setting `y_0'(x) = 0` at `x = 0`. Applying this
condition gives:
`Cubic{Flat}` `OnGrid` amounts to setting `y_1'(x) = 0` at `x = 1`.
Applying this condition yields

-cm + cp = 0
"""
Expand All @@ -173,10 +196,18 @@ function prefiltering_system{T,TC}(::Type{T}, ::Type{TC}, n::Int,
end

"""
`Flat` `OnCell` amounts to setting `y_0'(x) = 0` at `x = -1/2`. Applying this
condition gives:
`Cubic{Flat}`, `OnCell` amounts to setting `y_1'(x) = 0` at `x = 1/2`.
Applying this condition yields

-9/8 cm + 11/8 c - 3/8 cp + 1/8 cpp = 0

or, equivalently,

-9 cm + 11 c -3 cp + 1 cpp = 0

(Note that we use `y_1'(x)` although it is strictly not valid in this domain; if we
were to use `y_0'(x)` we would have to introduce new coefficients, so that would not
close the system. Instead, we extend the outermost polynomial for an extra half-cell.)
"""
function prefiltering_system{T,TC}(::Type{T}, ::Type{TC}, n::Int,
::Type{Cubic{Flat}}, ::Type{OnCell})
Expand All @@ -198,10 +229,14 @@ function prefiltering_system{T,TC}(::Type{T}, ::Type{TC}, n::Int,
end

"""
`Line` `OnCell` amounts to setting `y_0''(x) = 0` at `x = -1/2`. Applying this
condition gives:
`Cubic{Line}` `OnCell` amounts to setting `y_1''(x) = 0` at `x = 1/2`.
Applying this condition yields

3 cm -7 c + 5 cp -1 cpp = 0

(Note that we use `y_1'(x)` although it is strictly not valid in this domain; if we
were to use `y_0'(x)` we would have to introduce new coefficients, so that would not
close the system. Instead, we extend the outermost polynomial for an extra half-cell.)
"""
function prefiltering_system{T,TC}(::Type{T}, ::Type{TC}, n::Int,
::Type{Cubic{Line}}, ::Type{OnCell})
Expand All @@ -223,13 +258,10 @@ function prefiltering_system{T,TC}(::Type{T}, ::Type{TC}, n::Int,
end

"""
`Line` `OnGrid` amounts to setting `y_0''(x) = 0` at `x = 0`. Applying this
`Cubic{Line}` `OnGrid` amounts to setting `y_1''(x) = 0` at `x = 1`. Applying this
condition gives:

1 cm -2 c + 1 cp = 0 = 0

This is the same system as `Quadratic{Line}`, `OnGrid` so we reuse the
implementation
1 cm -2 c + 1 cp = 0
"""
function prefiltering_system{T,TC}(::Type{T}, ::Type{TC}, n::Int,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we decide not to rely on the Quadratic{Line}, OnGrid implementation here? and for Free below?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I realized when documenting this that the systems aren't the same after all. prefiltering_system relies on inner_system_diags, which will yield different coefficients for quadratic and cubic (of course), and we lose that information if we just forward the call.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh man ok. Good catch. Sounds good, it's nice to have it below he description also

::Type{Cubic{Line}}, ::Type{OnGrid})
Expand All @@ -247,6 +279,14 @@ function prefiltering_system{T,TC}(::Type{T}, ::Type{TC}, n::Int,
Woodbury(lufact!(Tridiagonal(dl, d, du), Val{false}), specs...), zeros(TC, n)
end

"""
`Cubic{Periodic}` `OnGrid` closes the system by looking at the coefficients themselves
as periodic, yielding

c0 = c(N+1)

where `N` is the number of data points.
"""
function prefiltering_system{T,TC,GT<:GridType}(::Type{T}, ::Type{TC}, n::Int,
::Type{Cubic{Periodic}}, ::Type{GT})
dl, d, du = inner_system_diags(T,n,Cubic{Periodic})
Expand All @@ -260,14 +300,11 @@ function prefiltering_system{T,TC,GT<:GridType}(::Type{T}, ::Type{TC}, n::Int,
end

"""
The free boundary condition for either `OnGrid` or `OnCell` makes sure the
interpoland has a continuous third derivative at the second-to-outermost cell
boundary: `y_0'''(1) = y_1'''(1)` and `y_{n-1}'''(n) = y_n'''(n)`. Applying this
condition gives:
`Cubic{Free}` `OnGrid` and `Cubic{Free}` `OnCell` amount to requiring an extra
continuous derivative at the second-to-last cell boundary; this means
`y_1'''(2) = y_2'''(2)`, yielding

1 cm -3 c + 3 cp -1 cpp = 0

This is the same system as `Quadratic{Free}` so we reuse the implementation
"""
function prefiltering_system{T,TC,GT<:GridType}(::Type{T}, ::Type{TC}, n::Int,
::Type{Cubic{Free}}, ::Type{GT})
Expand Down
56 changes: 56 additions & 0 deletions src/b-splines/linear.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
immutable Linear <: Degree{1} end

"""
Assuming uniform knots with spacing 1, the `i`th peice of linear b-spline
implemented here is defined as follows.

y_i(x) = c p(x) + cp p(1-x)

where

p(δx) = x

and the values `cX` for `X ∈ {_, p}` are the coefficients.

Linear b-splines are naturally interpolating, and require no prefiltering;
there is therefore no need for boundary conditions to be provided.

Also, although the implementation is slightly different in order to re-use
the framework built for general b-splines, the resulting interpolant is just
a piecewise linear function connecting each pair of neighboring data points.
"""
Linear

"""
`define_indices_d` for a linear b-spline calculates `ix_d = floor(x_d)` and
`fx_d = x_d - ix_d` (corresponding to `i` and `δx` in the docstring for
`Linear`), as well as the auxiliary quantity `ixp_d`
"""
function define_indices_d(::Type{BSpline{Linear}}, d, pad)
symix, symixp, symfx, symx = symbol("ix_",d), symbol("ixp_",d), symbol("fx_",d), symbol("x_",d)
quote
Expand All @@ -9,6 +35,16 @@ function define_indices_d(::Type{BSpline{Linear}}, d, pad)
end
end

"""
In `coefficients` for a linear b-spline we assume that `fx_d = x-ix-d` and
we define `cX_d` for `X ∈ {_, p}` such that

c_d = p(fx_d)
cp_d = p(1-fx_d)

where `p` is defined in the docstring entry for `Linear` and `fx_d` in the
docstring entry for `define_indices_d`.
"""
function coefficients(::Type{BSpline{Linear}}, N, d)
sym, symp, symfx = symbol("c_",d), symbol("cp_",d), symbol("fx_",d)
quote
Expand All @@ -17,6 +53,16 @@ function coefficients(::Type{BSpline{Linear}}, N, d)
end
end

"""
In `gradient_coefficients` for a linear b-spline we assume that `fx_d = x-ix_d`
and we define `cX_d` for `X ⋹ {_, p}` such that

c_d = p'(fx_d)
cp_d = p'(1-fx_d)

where `p` is defined in the docstring entry for `Linear`, and `fx_d` in the
docstring entry for `define_indices_d`.
"""
function gradient_coefficients(::Type{BSpline{Linear}}, d)
sym, symp, symfx = symbol("c_",d), symbol("cp_",d), symbol("fx_",d)
quote
Expand All @@ -25,6 +71,16 @@ function gradient_coefficients(::Type{BSpline{Linear}}, d)
end
end

"""
In `hessian_coefficients` for a linear b-spline we assume that `fx_d = x-ix_d`
and we define `cX_d` for `X ⋹ {_, p}` such that

c_d = p''(fx_d)
cp_d = p''(1-fx_d)

where `p` is defined in the docstring entry for `Linear`, and `fx_d` in the
docstring entry for `define_indices_d`. (These are both ≡ 0.)
"""
function hessian_coefficients(::Type{BSpline{Linear}}, d)
sym, symp = symbol("c_",d), symbol("cp_",d)
quote
Expand Down
Loading