Name: OffsetArrays.jl
Owner: JuliaArrays
Description: Fortran-like arrays with arbitrary, zero or negative starting indices.
Created: 2014-01-31 11:13:19.0
Updated: 2018-01-17 00:26:46.0
Pushed: 2018-01-16 08:21:31.0
Size: 132
Language: Julia
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
OffsetArrays provides Julia users with arrays that have arbitrary indices, similar to those found in some other programming languages like Fortran.
a> using OffsetArrays
a> y = OffsetArray{Float64}(uninitialized, -1:1, -7:7, -128:512, -5:5, -1:1, -3:3, -2:2, -1:1);
a> summary(y)
setArrays.OffsetArray{Float64,8,Array{Float64,8}} with indices -1:1×-7:7×-128:512×-5:5×-1:1×-3:3×-2:2×-1:1"
a> y[-1,-7,-128,-5,-1,-3,-2,-1] = 14
a> y[-1,-7,-128,-5,-1,-3,-2,-1] += 5
Support for such arrays is based on new functionality in Julia v0.5, and the modern package is not usable on earlier Julia versions.
During the transition during Julia 0.5 to allowing arrays with
arbitrary indices, certain operations (like size
and length
) are
deliberately unsupported; see the
documentation
describing the reasoning behind this decision. The general
recommendation is to use indices
and linearindices
for most
operations where size
and length
would have formerly been used.
If your package makes use of OffsetArrays, you can also add the following internal convenience definitions:
e(A::AbstractArray) = map(length, indices(A))
e(A) = size(A)
gth(A::AbstractArray) = length(linearindices(A))
gth(A) = length(A)
These versions should work for all types.
Also during Julia 0.5, @inbounds
will not remove the internal
bounds-checking that happens when using an OffsetArray. Until this
changes, you can often accomplish the same task with @unsafe
:
OffsetArray(rand(1000), 0:999)
afe for i in indices(v, 1)
v[i] += 1
With such annotation, OffsetArray
s are as performant as Array
s.
@unsafe
is not as powerful as @inbounds
, and it is possible to set
up situations where it fails to remove bounds checks. However, it
suffices for many uses.
The original purpose of the package was to simplify translation of Fortran codes, say
the codes accompanying the book Numerical Solution of Hyperbolic Partial Differential Equations by prof. John A. Trangenstein Please refer here and here
Clawpack (stands for Conservation Laws Package) by prof. Randall J. LeVeque
see also translation to Julia of Fortran codes from ClawPack
The directory examples of hyperbolic_PDE contains at the moment a translation of explicit upwind finite difference scheme for scalar law advection equation from the book Numerical Solution of Hyperbolic Partial Differential Equations by prof. John A. Trangenstein.
examples/scalar_law/PROGRAM0/main.jl
The original Fortran arrays u(-2:ncells+1), x(0:ncells), flux(0:ncells)
transformed to 1-based Julia arrays by shifting index expressions
= Array(Float64, ncells+4)
= Array(Float64, ncells+1)
= Array(Float64, ncells+1)
examples/scalar_law/PROGRAM0/main_offset_array.jl Exemplary use case of this package
= OffsetArray(Float64, -2:ncells+1)
= OffsetArray(Float64, 0:ncells)
= OffsetArray(Float64, 0:ncells)
Timings for baseline with @unsafe
annotation:
3402 seconds (21 allocations: 235.531 KB)
Timing for OffsetArray
version with @unsafe
annotation:
3987 seconds (16 allocations: 235.094 KB)
Timing for sub
macro version with @unsafe
annotation (doesn't work without @unsafe
):
5967 seconds (217 allocations: 268.094 KB)
Only the 2nd timing after warming up is given.
UPDATE: Added
/m/O/e/s/PROGRAM1] $ julia linaddmain.jl --cells=10000 --runs=3 ms master|? 1?
2295 seconds (42.90 k allocations: 1.990 MB)
9693 seconds (18 allocations: 313.281 KB)
2243 seconds (18 allocations: 313.281 KB)
/m/O/e/s/PROGRAM1] $ julia linaddmain.jl --cells=100000 --runs=3 6134ms master|? 1?
0463 seconds (42.90 k allocations: 4.736 MB)
7485 seconds (18 allocations: 3.053 MB)
8687 seconds (18 allocations: 3.053 MB)
Fortran timing for 100000
number of cells
0m4.781s
0m4.760s
0m0.000s
That is 7.2s for Julia script vs. 4.8s for Fortran.