Skip to content

Commit

Permalink
Merge pull request #591 from abhro/patch-1
Browse files Browse the repository at this point in the history
Minor overhaul of markdown docs and docstrings
  • Loading branch information
mkitti committed May 14, 2024
2 parents c7e2d45 + c86d58e commit 8c25bad
Show file tree
Hide file tree
Showing 30 changed files with 653 additions and 394 deletions.
2 changes: 1 addition & 1 deletion doc/Extrapolation.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ For some of these, extra care needs to be taken in higher dimensions, when decid
| |
----------+---------------+--------
| |
| | ...and here?
| | ...and here?
3 changes: 2 additions & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244"
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"

[compat]
Documenter = "0.27"
Documenter = "1"
41 changes: 32 additions & 9 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
using Documenter, Interpolations
using Documenter
using DocumenterCitations
using Interpolations

DocMeta.setdocmeta!(
Interpolations,
:DocTestSetup,
:(using Interpolations),
recursive = true,
)

bib = CitationBibliography(
joinpath(@__DIR__, "src", "refs.bib"),
style = :authoryear,
)

makedocs(
sitename="Interpolations.jl",
modules=[Interpolations],
format=Documenter.HTML(prettyurls = get(ENV, "CI", nothing)=="true"),
pages=["Home" => "index.md",
sitename = "Interpolations.jl",
modules = [Interpolations],
format = Documenter.HTML(
prettyurls = get(ENV, "CI", nothing)=="true",
),
pages = [
"Home" => "index.md",
"Convenience Constructors" => "convenience-construction.md",
"General usage" => "interpolations.md",
"Interpolation algorithms" => "control.md",
Expand All @@ -13,9 +31,14 @@ pages=["Home" => "index.md",
"Library" => "api.md",
"News and Changes" => "NEWS.md",
"Other Interpolation Packages" => "other_packages.md",
],
strict=true,
"Bilbiography" => "bibliography.md",
],
warnonly = false,
doctest = true,
plugins = [bib],
)

deploydocs(repo="github.com/JuliaMath/Interpolations.jl.git",
push_preview=true)
deploydocs(
repo = "github.com/JuliaMath/Interpolations.jl.git",
push_preview = true,
)
11 changes: 6 additions & 5 deletions docs/src/api.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
## Public API
```@meta
DocTestSetup= quote
using Interpolations
end
```

```@autodocs
Modules = [Interpolations]
Expand All @@ -17,3 +12,9 @@ Modules = [Interpolations]
Public = false
Order = [:function, :type]
```

## Bibliography
```@bibliography
Pages = ["api.md"]
Canonical = false
```
8 changes: 8 additions & 0 deletions docs/src/bibliography.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Bibliography

```@bibliography
```

```@bibliography
*
```
4 changes: 2 additions & 2 deletions docs/src/chainrules.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This enables integration with autodiff libraries like Zygote, enabling
```julia
x = 1:10
y = sin.(x)
itp = interpolate(y,BSpline(Linear()))
itp = interpolate(y, BSpline(Linear()))
Zygote.gradient(itp, 2)
#([-0.7681774187658145],)
```
```
121 changes: 83 additions & 38 deletions docs/src/control.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@

### BSplines

The interpolation type is described in terms of *degree* and, if necessary, *boundary conditions*. There are currently four degrees available: `Constant`, `Linear`, `Quadratic`, and `Cubic` corresponding to B-splines of degree 0, 1, 2, and 3 respectively.

B-splines of quadratic or higher degree require solving an equation system to obtain the interpolation coefficients, and for that you must specify a *boundary condition* that is applied to close the system. The following boundary conditions are implemented: `Flat`, `Line` (alternatively, `Natural`), `Free`, `Periodic` and `Reflect`; their mathematical implications are described in detail in their docstrings.
When specifying these boundary conditions you also have to specify whether they apply at the edge grid point (`OnGrid()`)
or beyond the edge point halfway to the next (fictitious) grid point (`OnCell()`).
The interpolation type is described in terms of *degree* and, if necessary,
*boundary conditions*. There are currently four degrees available: `Constant`,
`Linear`, `Quadratic`, and `Cubic` corresponding to B-splines of degree 0, 1,
2, and 3 respectively.

B-splines of quadratic or higher degree require solving an equation system to
obtain the interpolation coefficients, and for that you must specify a
*boundary condition* that is applied to close the system. The following boundary
conditions are implemented: `Flat`, `Line` (alternatively, `Natural`), `Free`,
`Periodic` and `Reflect`; their mathematical implications are described in
detail in their docstrings.
When specifying these boundary conditions you also have to specify whether they
apply at the edge grid point (`OnGrid()`) or beyond the edge point halfway to
the next (fictitious) grid point (`OnCell()`).

Some examples:
```julia
Expand All @@ -30,7 +39,8 @@ v = itp(3.2, 4.1) # returns 0.9*(0.8*A[3,4]+0.2*A[4,4]) + 0.1*(0.8*A[3,5]+0.2*A
# Quadratic is the lowest order that has continuous gradient
itp = interpolate(A, BSpline(Quadratic(Reflect(OnCell()))))

# Linear interpolation in the first dimension, and no interpolation (just lookup) in the second
# Linear interpolation in the first dimension, and no interpolation
# (just lookup) in the second
itp = interpolate(A, (BSpline(Linear()), NoInterp()))
v = itp(3.65, 5) # returns 0.35*A[3,5] + 0.65*A[4,5]
```
Expand All @@ -43,7 +53,15 @@ which destroys the input `A` but also does not need to allocate as much memory.

### Scaled BSplines

BSplines assume your data is uniformly spaced on the grid `1:N`, or its multidimensional equivalent. If you have data of the form `[f(x) for x in A]`, you need to tell Interpolations about the grid `A`. If `A` is not uniformly spaced, you must use gridded interpolation described below. However, if `A` is a collection of ranges or linspaces, you can use scaled BSplines. This is more efficient because the gridded algorithm does not exploit the uniform spacing. Scaled BSplines can also be used with any spline degree available for BSplines, while gridded interpolation does not currently support quadratic or cubic splines.
BSplines assume your data is uniformly spaced on the grid `1:N`, or its
multidimensional equivalent. If you have data of the form `[f(x) for x in A]`,
you need to tell Interpolations about the grid `A`. If `A` is not uniformly
spaced, you must use gridded interpolation described below. However, if `A` is a
collection of ranges or linspaces, you can use scaled BSplines. This is more
efficient because the gridded algorithm does not exploit the uniform spacing.
Scaled BSplines can also be used with any spline degree available for BSplines,
while gridded interpolation does not currently support quadratic or cubic
splines.

Some examples,
```julia
Expand Down Expand Up @@ -89,8 +107,8 @@ The general syntax is
```julia
itp = interpolate(nodes, A, options...)
```
where `nodes = (xnodes, ynodes, ...)` specifies the positions along
each axis at which the array `A` is sampled for arbitrary ("rectangular") samplings.
where `nodes = (xnodes, ynodes, ...)` specifies the positions along each axis
at which the array `A` is sampled for arbitrary ("rectangular") samplings.

For example:
```julia
Expand All @@ -101,27 +119,30 @@ itp(4,1.2) # approximately A[2,6]
```
One may also mix modes, by specifying a mode vector in the form of an explicit tuple:
```julia
itp = interpolate(nodes, A, (Gridded(Linear()),Gridded(Constant())))
itp = interpolate(nodes, A, (Gridded(Linear()), Gridded(Constant())))
```

Presently there are only three modes for gridded:
```julia
Gridded(Linear())
```
whereby a linear interpolation is applied between nodes,
```julia
Gridded(Constant())
```
whereby nearest neighbor interpolation is used on the applied axis,
```julia
NoInterp()
```
whereby the coordinate of the selected input vector MUST be located on a grid point. Requests for off grid
coordinates results in the throwing of an error.

For [`Constant`](@ref) there are additional parameters. Use `Constant{Previous}()` in order to perform a previous
neighbor interpolation. Use `Constant{Next}()` for a next neighbor interpolation.
Note that rounding can be an issue, see [#473](https://github.com/JuliaMath/Interpolations.jl/issues/473).
- For linear interpolation between nodes
```julia
Gridded(Linear())
```
- For nearest neighbor interpolation on the applied axis
```julia
Gridded(Constant())
```
- For no interpolation. The coordinate of the selected input vector MUST be
located on a grid point. Requests for off grid coordinates results in the
throwing of an error.
```julia
NoInterp()
```

For [`Constant`](@ref) there are additional parameters. Use
`Constant{Previous}()` in order to perform a previous neighbor interpolation.
Use `Constant{Next}()` for a next neighbor interpolation.
Note that rounding can be an issue, see
[issue #473](https://github.com/JuliaMath/Interpolations.jl/issues/473).

`missing` data will naturally propagate through the interpolation,
where some values will become missing. To avoid that, one can
Expand All @@ -131,22 +152,27 @@ For example:
x = 1:6
A = [i == 3 ? missing : i for i in x]
xf = [xi for (xi,a) in zip(x, A) if !ismissing(a)]
Af = [a for a in A if !ismissing(a)]
Af = filter(!ismissing, A)
itp = interpolate((xf, ), Af, Gridded(Linear()))
```

In-place gridded interpolation is also possible:
```julia
```@example
using Interpolations # hide
x = 1:4
y = view(rand(4), :)
itp = interpolate!((x,), y, Gridded(Linear()))
y .= 0
@show itp(2.5) # 0
itp(2.5)
```

## Parametric splines

Given a set a knots with coordinates `x(t)` and `y(t)`, a parametric spline `S(t) = (x(t),y(t))` parametrized by `t in [0,1]` can be constructed with the following code adapted from a [post](http://julia-programming-language.2336112.n4.nabble.com/Parametric-splines-td37794.html#a37818) by Tomas Lycken:
Given a set a knots with coordinates `x(t)` and `y(t)`, a parametric spline
`S(t) = (x(t),y(t))` parametrized by `t` in `[0,1]` can be constructed with the
following code adapted from a
[post](http://julia-programming-language.2336112.n4.nabble.com/Parametric-splines-td37794.html#a37818)
by Tomas Lycken:

```julia
using Interpolations
Expand All @@ -156,7 +182,11 @@ x = sin.(2π*t)
y = cos.(2π*t)
A = hcat(x,y)
itp = Interpolations.scale(interpolate(A, (BSpline(Cubic(Natural(OnGrid()))), NoInterp())), t, 1:2)
itp = Interpolations.scale(
interpolate(A, (BSpline(Cubic(Natural(OnGrid()))), NoInterp())),
t,
1:2
)
tfine = 0:.01:1
xs, ys = [itp(t,1) for t in tfine], [itp(t,2) for t in tfine]
Expand All @@ -174,16 +204,27 @@ plot!(xs, ys, label="spline")

## Monotonic interpolation

When you have some one-dimensional data that is monotonic, many standard interpolation methods may give an interpolating function that it is not monotonic. Monotonic interpolation ensures that the interpolating function is also monotonic.
When you have some one-dimensional data that is monotonic, many standard
interpolation methods may give an interpolating function that it is not
monotonic. Monotonic interpolation ensures that the interpolating function is
also monotonic.

Here is an example of making a cumulative distribution function for some data:

```julia
percentile_values = [0.0, 0.01, 0.1, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0, 99.9, 99.99, 100.0];
percentile_values = [
0.0, 0.01, 0.1, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,
10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0,
91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0,
99.9, 99.99, 100.0
];
y = sort(randn(length(percentile_values))); # some random data
itp_cdf = extrapolate(interpolate(y, percentile_values, SteffenMonotonicInterpolation()), Flat());
itp_cdf = extrapolate(
interpolate(y, percentile_values, SteffenMonotonicInterpolation()),
Flat()
);
t = -3.0:0.01:3.0 # just a range for calculating values of the interpolating function
Expand All @@ -200,7 +241,11 @@ There are a few different monotonic interpolation algorithms. Some guarantee tha
* [`SteffenMonotonicInterpolation`](@ref) -- it does not overshoot.

You can read about monotonic interpolation in the following sources:
```@bibliography
Pages = []
Canonical = false
* Fritsch & Carlson (1980), "Monotone Piecewise Cubic Interpolation", doi:10.1137/0717021.
* Fritsch & Butland (1984), "A Method for Constructing Local Monotone Piecewise Cubic Interpolants", doi:10.1137/0905021.
* Steffen (1990), "A Simple Method for Monotonic Interpolation in One Dimension", [URL](http://adsabs.harvard.edu/abs/1990A%26A...239..443S)
Fritsch1980
Fritsch1984
Steffen1990
```
Loading

0 comments on commit 8c25bad

Please sign in to comment.