Skip to content

Commit 15b712b

Browse files
committed
Add Documenter docs
1 parent 1e7b1e8 commit 15b712b

File tree

12 files changed

+296
-79
lines changed

12 files changed

+296
-79
lines changed

.travis.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,14 @@ notifications:
1515
after_success:
1616
# push coverage results to Codecov
1717
- julia -e 'using Pkg, OffsetArrays; cd(joinpath(dirname(pathof(OffsetArrays)), "..")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
18+
19+
jobs:
20+
include:
21+
- stage: "Documentation"
22+
julia: 1
23+
os: linux
24+
script:
25+
- julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd()));
26+
Pkg.instantiate()'
27+
- julia --project=docs/ docs/make.jl
28+
after_success: skip

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "OffsetArrays"
22
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
3-
version = "1.0.0"
3+
version = "1.0.1"
44

55
[compat]
66
julia = "0.7, 1"

README.md

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -48,73 +48,6 @@ OA[-1, 0] = 1
4848
OA[1, 4] = 15
4949
```
5050

51-
OffsetArrays works for arbitrary dimensionality:
52-
53-
```julia
54-
julia> using OffsetArrays
55-
56-
julia> y = OffsetArray{Float64}(undef, -1:1, -7:7, -128:512, -5:5, -1:1, -3:3, -2:2, -1:1);
57-
58-
julia> summary(y)
59-
"OffsetArrays.OffsetArray{Float64,8,Array{Float64,8}} with indices -1:1×-7:7×-128:512×-5:5×-1:1×-3:3×-2:2×-1:1"
60-
61-
julia> y[-1,-7,-128,-5,-1,-3,-2,-1] = 14
62-
14
63-
64-
julia> y[-1,-7,-128,-5,-1,-3,-2,-1] += 5
65-
19.0
66-
```
67-
68-
## Example: Relativistic Notation
69-
Suppose we have a position vector `r = [:x, :y, :z]` which is naturally one-based, ie. `r[1] == :x`, `r[2] == :y`, `r[3] == :z` and we also want to construct a relativistic position vector which includes time as the 0th component. This can be done with OffsetArrays like
70-
71-
```julia
72-
julia> using OffsetArrays
73-
74-
julia> r = [:x, :y, :z];
75-
76-
julia> x = OffsetVector([:t, r...], 0:3)
77-
OffsetArray(::Array{Symbol,1}, 0:3) with eltype Symbol with indices 0:3:
78-
:t
79-
:x
80-
:y
81-
:z
82-
83-
julia> x[0]
84-
:t
85-
86-
julia> x[1:3]
87-
3-element Array{Symbol,1}:
88-
:x
89-
:y
90-
:z
91-
```
92-
93-
## Example: Polynomials
94-
Suppose one wants to represent the Laurent polynomial
95-
```
96-
6/x + 5 - 2*x + 3*x^2 + x^3
97-
```
98-
in julia. The coefficients of this polynomial are a naturally `-1` based list, since the `n`th element of the list
99-
(counting from `-1`) `6, 5, -2, 3, 1` is the coefficient corresponding to the `n`th power of `x`. This Laurent polynomial can be evaluated at say `x = 2` as follows.
100-
```julia
101-
julia> using OffsetArrays
102-
103-
julia> coeffs = OffsetVector([6, 5, -2, 3, 1], -1:3)
104-
OffsetArray(::Array{Int64,1}, -1:3) with eltype Int64 with indices -1:3:
105-
6
106-
5
107-
-2
108-
3
109-
1
110-
111-
julia> polynomial(x, coeffs) = sum(coeffs[n]*x^n for n in eachindex(coeffs))
112-
polynomial (generic function with 1 method)
113-
114-
julia> polynomial(2.0, coeffs)
115-
24.0
116-
```
117-
Notice our use of the `eachindex` function which does not assume that the given array starts at `1`.
11851

11952
## Notes on supporting OffsetArrays
12053

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
environment:
22
matrix:
33
- julia_version: 1.0
4-
- julia_version: 1.3
4+
- julia_version: 1
55
- julia_version: nightly
66

77
platform:

docs/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build/
2+
site/

docs/Project.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[deps]
2+
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
4+
[compat]
5+
Documenter = "0.24"

docs/make.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Documenter
2+
using OffsetArrays
3+
4+
makedocs(
5+
sitename = "OffsetArrays",
6+
format = Documenter.HTML(prettyurls = get(ENV, "CI", nothing) == "true"),
7+
pages = ["index.md", "internals.md", "reference.md"],
8+
modules = [OffsetArrays],
9+
doctestfilters = [r"at \./.*", r"at /home.*", r"top-level scope.*", r"\[\d*\]\s*$"], # for backtraces
10+
)
11+
12+
deploydocs(
13+
repo = "github.com:JuliaArrays/OffsetArrays.jl.git"
14+
)

docs/src/index.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# OffsetArrays.jl
2+
3+
OffsetArrays provides Julia users with arrays that have arbitrary
4+
indices, similar to those found in some other programming languages
5+
like Fortran. Below is the basic usage found in the README, followed
6+
by a couple of short examples illustrating circumstances in which
7+
OffsetArrays can be useful. For a lengthier discussion, see
8+
[this blog post](https://julialang.org/blog/2017/04/offset-arrays/).
9+
10+
## Usage
11+
12+
You can construct such arrays as follows:
13+
14+
```julia
15+
OA = OffsetArray(A, axis1, axis2, ...)
16+
```
17+
18+
where you want `OA` to have axes `(axis1, axis2, ...)` and be indexed by values that
19+
fall within these axis ranges. Example:
20+
21+
```julia
22+
using OffsetArrays
23+
A = Float64.(reshape(1:15, 3, 5))
24+
println("Here is A:")
25+
display(A)
26+
OA = OffsetArray(A, -1:1, 0:4) # OA will have axes (-1:1, 0:4)
27+
println("Here is OA:")
28+
display(OA)
29+
@show OA[-1,0] OA[1,4]
30+
```
31+
32+
gives the output
33+
34+
```julia
35+
here is A:
36+
3×5 Array{Float64,2}:
37+
1.0 4.0 7.0 10.0 13.0
38+
2.0 5.0 8.0 11.0 14.0
39+
3.0 6.0 9.0 12.0 15.0
40+
here is OA:
41+
3×5 OffsetArray(::Array{Float64,2}, -1:1, 0:4) with eltype Float64 with indices -1:1×0:4:
42+
1.0 4.0 7.0 10.0 13.0
43+
2.0 5.0 8.0 11.0 14.0
44+
3.0 6.0 9.0 12.0 15.0
45+
OA[-1, 0] = 1.0
46+
OA[1, 4] = 15.0
47+
```
48+
49+
OffsetArrays works for arbitrary dimensionality:
50+
51+
```julia
52+
julia> using OffsetArrays
53+
54+
julia> y = OffsetArray{Float64}(undef, -1:1, -7:7, -128:512, -5:5, -1:1, -3:3, -2:2, -1:1);
55+
56+
julia> summary(y)
57+
"OffsetArrays.OffsetArray{Float64,8,Array{Float64,8}} with indices -1:1×-7:7×-128:512×-5:5×-1:1×-3:3×-2:2×-1:1"
58+
59+
julia> y[-1,-7,-128,-5,-1,-3,-2,-1] = 14
60+
14
61+
62+
julia> y[-1,-7,-128,-5,-1,-3,-2,-1] += 5
63+
19.0
64+
```
65+
66+
You can use `OffsetArrays.no_offset_view(A)` if you want to return a view of the data in `A` but where indexing starts at 1.
67+
68+
## Example: Relativistic Notation
69+
70+
Suppose we have a position vector `r = [:x, :y, :z]` which is naturally one-based, ie. `r[1] == :x`, `r[2] == :y`, `r[3] == :z` and we also want to construct a relativistic position vector which includes time as the 0th component. This can be done with OffsetArrays like
71+
72+
```jldoctest
73+
julia> using OffsetArrays
74+
75+
julia> r = [:x, :y, :z];
76+
77+
julia> x = OffsetVector([:t, r...], 0:3)
78+
4-element OffsetArray(::Array{Symbol,1}, 0:3) with eltype Symbol with indices 0:3:
79+
:t
80+
:x
81+
:y
82+
:z
83+
84+
julia> x[0]
85+
:t
86+
87+
julia> x[1:3]
88+
3-element Array{Symbol,1}:
89+
:x
90+
:y
91+
:z
92+
```
93+
94+
## Example: Polynomials
95+
96+
Suppose one wants to represent the Laurent polynomial
97+
```
98+
6/x + 5 - 2*x + 3*x^2 + x^3
99+
```
100+
in julia. The coefficients of this polynomial are a naturally `-1` based list, since the `n`th element of the list
101+
(counting from `-1`) `6, 5, -2, 3, 1` is the coefficient corresponding to the `n`th power of `x`. This Laurent polynomial can be evaluated at say `x = 2` as follows.
102+
103+
```jldoctest
104+
julia> using OffsetArrays
105+
106+
julia> coeffs = OffsetVector([6, 5, -2, 3, 1], -1:3)
107+
5-element OffsetArray(::Array{Int64,1}, -1:3) with eltype Int64 with indices -1:3:
108+
6
109+
5
110+
-2
111+
3
112+
1
113+
114+
julia> polynomial(x, coeffs) = sum(coeffs[n]*x^n for n in eachindex(coeffs))
115+
polynomial (generic function with 1 method)
116+
117+
julia> polynomial(2.0, coeffs)
118+
24.0
119+
```
120+
121+
Notice our use of the `eachindex` function which does not assume that the given array starts at `1`.

docs/src/internals.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# For developers
2+
3+
Writing code that supports OffsetArrays is generally fairly straightforward.
4+
The majority of cases can be handled with these tips:
5+
6+
- replace many uses of `size` with `axes`
7+
- replace `1:length(A)` with `eachindex(A)`, or if you need an integer index with `LinearIndices(A)`
8+
- replace explicit allocations like `Array{Int}(undef, size(B))` with `similar(Array{Int}, axes(B))`
9+
10+
More information can be found in [Julia's developer documentation](https://docs.julialang.org/en/v1.0/devdocs/offset-arrays/).
11+
The most subtle issues tend to arise around the axes, and further detail specific to
12+
OffsetArrays.jl follows below.
13+
14+
## Internals
15+
16+
How does OffsetArrays work? The fundamental principle is very simple:
17+
an `OffsetArray` is just a wrapper around a "parent" array, together
18+
with an index offset:
19+
20+
```jldoctest oa; setup=:(using OffsetArrays)
21+
julia> oa = OffsetArray([1 2; 3 4], 0:1, 5:6)
22+
2×2 OffsetArray(::Array{Int64,2}, 0:1, 5:6) with eltype Int64 with indices 0:1×5:6:
23+
1 2
24+
3 4
25+
26+
julia> parent(oa)
27+
2×2 Array{Int64,2}:
28+
1 2
29+
3 4
30+
31+
julia> oa.offsets
32+
(-1, 4)
33+
```
34+
35+
So `parent(oa)` is the original array we constructed it with, and `oa.offsets` is a tuple,
36+
each entry encoding the index-shift to be applied along the corresponding axis.
37+
When you index `oa[i,j]`, it "translates" the `i,j` indexes back to the parent array's
38+
indexes and then returns the value in the parent.
39+
40+
## The axes of OffsetArrays
41+
42+
```jldoctest oa
43+
julia> axes(oa)
44+
(0:1, 5:6)
45+
```
46+
47+
This looks straightforward, but if you dive deeper you'll notice some complexities:
48+
49+
```jldoctest oa
50+
julia> ax = axes(oa, 2)
51+
5:6
52+
53+
julia> typeof(ax)
54+
OffsetArrays.IdOffsetRange{Int64,Base.OneTo{Int64}}
55+
56+
julia> ax[1]
57+
ERROR: BoundsError: attempt to access 2-element Base.OneTo{Int64} at index [-3]
58+
Stacktrace:
59+
[1] throw_boundserror(::Base.OneTo{Int64}, ::Int64) at ./abstractarray.jl:538
60+
[2] getindex at ./range.jl:625 [inlined]
61+
[3] getindex(::OffsetArrays.IdOffsetRange{Int64,Base.OneTo{Int64}}, ::Int64) at /home/tim/.julia/dev/OffsetArrays/src/axes.jl:139
62+
[4] top-level scope at none:0
63+
64+
julia> ax[5]
65+
5
66+
```
67+
68+
The axes are of type [`OffsetArrays.IdOffsetRange`](@ref).
69+
`IdOffsetRange`s are essentially OffsetArrays specialized for ranges, with the additional
70+
property that they tend to be their own axes:
71+
72+
```jldoctest oa
73+
julia> ax
74+
5:6
75+
76+
julia> axes(ax)
77+
(5:6,)
78+
79+
julia> axes(ax[ax])
80+
(5:6,)
81+
```
82+
83+
This example of indexing is [idempotent](https://en.wikipedia.org/wiki/Idempotence).
84+
This is a useful characteristic for ensuring the "fundamental axiom" of generalized indexing,
85+
that `a[rng][i] == a[rng[i]]`:
86+
87+
```jldoctest; setup=:(using OffsetArrays)
88+
julia> oa2 = OffsetArray([5, 10, 15, 20], 0:3)
89+
4-element OffsetArray(::Array{Int64,1}, 0:3) with eltype Int64 with indices 0:3:
90+
5
91+
10
92+
15
93+
20
94+
95+
julia> ax2 = axes(oa2, 1)
96+
0:3
97+
98+
julia> oa2[2]
99+
15
100+
101+
julia> oa2[ax2][2]
102+
15
103+
104+
julia> oa2[ax2[2]]
105+
15
106+
```
107+
108+
`IdOffsetRange`s apply the offset both to the values and the indices of the range, and otherwise preserve the parent range.

docs/src/reference.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Reference
2+
3+
```@docs
4+
OffsetArray
5+
OffsetArrays.IdOffsetRange
6+
OffsetArrays.no_offset_view
7+
```

0 commit comments

Comments
 (0)