Name: StaticArrays.jl
Owner: JuliaArrays
Description: Statically sized arrays for Julia
Created: 2016-05-16 12:45:37.0
Updated: 2017-12-20 15:46:05.0
Pushed: 2018-01-17 19:54:12.0
Size: 845
Language: Julia
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
Statically sized arrays for Julia
StaticArrays provides a framework for implementing statically sized arrays
in Julia (? 0.5), using the abstract type StaticArray{Size,T,N} <: AbstractArray{T,N}
.
Subtypes of StaticArray
will provide fast implementations of common array and
linear algebra operations. Note that here “statically sized” means that the
size can be determined from the type, and “static” does not necessarily
imply immutable
.
The package also provides some concrete static array types: SVector
, SMatrix
and SArray
, which may be used as-is (or else embedded in your own type).
Mutable versions MVector
, MMatrix
and MArray
are also exported, as well
as SizedArray
for annotating standard Array
s with static size information.
Further, the abstract FieldVector
can be used to make fast StaticVector
s
out of any uniform Julia “struct”.
Full documentation can be found here.
The speed of small SVector
s, SMatrix
s and SArray
s is often > 10 × faster
than Base.Array
. See this simplified benchmark (or see the full results here):
========================================
Benchmarks for 3×3 Float64 matrices
========================================
ix multiplication -> 8.2x speedup
ix multiplication (mutating) -> 3.1x speedup
ix addition -> 45x speedup
ix addition (mutating) -> 5.1x speedup
ix determinant -> 170x speedup
ix inverse -> 125x speedup
ix symmetric eigendecomposition -> 82x speedup
ix Cholesky decomposition -> 23.6x speedup
These results improve significantly when using julia -O3
with immutable static
arrays, as the extra optimization results in surprisingly good SIMD code.
Note that in the current implementation, working with large StaticArray
s puts a
lot of stress on the compiler, and becomes slower than Base.Array
as the size
increases. A very rough rule of thumb is that you should consider using a
normal Array
for arrays larger than 100 elements. For example, the performance
crossover point for a matrix multiply microbenchmark seems to be about 11x11 in
julia 0.5 with default optimizations.
add("StaticArrays") # or Pkg.clone("https://github.com/JuliaArrays/StaticArrays.jl")
g StaticArrays
eate an SVector using various forms, using constructors, functions or macros
SVector(1, 2, 3)
ata === (1, 2, 3) # SVector uses a tuple for internal storage
SVector{3,Float64}(1, 2, 3) # length 3, eltype Float64
@SVector [1, 2, 3]
@SVector [i^2 for i = 1:10] # arbitrary comprehensions (range is evaluated at global scope)
zeros(SVector{3}) # defaults to Float64
@SVector zeros(3)
SVector{3}([1, 2, 3]) # Array conversions must specify size
n get size() from instance or type
(v1) == (3,)
(typeof(v1)) == (3,)
milar constructor syntax for matrices
SMatrix{2,2}(1, 2, 3, 4) # flat, column-major storage, equal to m2:
@SMatrix [ 1 3 ;
2 4 ]
eye(SMatrix{3,3})
@SMatrix randn(4,4)
SMatrix{2,2}([1 3 ; 2 4]) # Array conversions must specify size
gher-dimensional support
@SArray randn(2, 2, 2, 2, 2, 2)
pports all the common operations of AbstractArray
v1 + v2
sin.(v3)
= m3 * v3 # recall that m3 = eye(SMatrix{3,3})
p, reduce, broadcast, map!, broadcast!, etc...
dexing can also be done using static arrays of integers
] === 1
Vector(3,2,1)] === @SVector [3, 2, 1]
] === v1
of(v1[[1,2,3]]) <: Vector # Can't determine size from the type of [1,2,3]
(partially) hooked into BLAS, LAPACK, etc:
(MMatrix{20,20}) * rand(MMatrix{20,20}) # large matrices can use BLAS
m3) # eig(), etc uses specialized algorithms up to 3×3, or else LAPACK
atic arrays stay statically sized, even when used by Base functions, etc:
of(eig(m3)) == Tuple{SVector{3,Float64}, SMatrix{3,3,Float64,9}}
milar() returns a mutable container, while similar_type() returns a constructor:
of(similar(m3)) == MMatrix{3,3,Float64,9} # (final parameter is length = 9)
lar_type(m3) == SMatrix{3,3,Float64,9}
e Size trait is a compile-time constant representing the size
(m3) === Size(3,3)
standard Array can be wrapped into a SizedArray
Size(3,3)(rand(3,3))
m4) # Take advantage of specialized fast methods
shape() uses Size() or types to specify size:
ape([1,2,3,4], Size(2,2)) == @SMatrix [ 1 3 ;
2 4 ]
of(reshape([1,2,3,4], Size(2,2))) === SizedArray{(2, 2),Int64,2,1}
The package provides a range of different useful built-in StaticArray
types,
which include mutable and immutable arrays based upon tuples, arrays based upon
structs, and wrappers of Array
. There is a relatively simple interface for
creating your own, custom StaticArray
types, too.
This package also provides methods for a wide range of AbstractArray
functions,
specialized for (potentially immutable) StaticArray
s. Many of Julia's
built-in method definitions inherently assume mutability, and further
performance optimizations may be made when the size of the array is known to the
compiler. One example of this is by loop unrolling, which has a substantial
effect on small arrays and tends to automatically trigger LLVM's SIMD
optimizations. Another way performance is boosted is by providing specialized
methods for det
, inv
, eig
and chol
where the algorithm depends on the
precise dimensions of the input. In combination with intelligent fallbacks to
the methods in Base, we seek to provide a comprehensive support for statically
sized arrays, large or small, that hopefully “just works”.
Several existing packages for statically sized arrays have been developed for Julia, noteably FixedSizeArrays and ImmutableArrays which provided signficant inspiration for this package. Upon consultation, it has been decided to move forward with StaticArrays which has found a new home in the JuliaArrays github organization. It is recommended that new users use this package, and that existing dependent packages consider switching to StaticArrays sometime during the life-cycle of Julia v0.5.
You can try using StaticArrays.FixedSizeArrays
to add some compatibility
wrappers for the most commonly used features of the FixedSizeArrays package,
such as Vec
, Mat
, Point
and @fsa
. These wrappers do not provide a
perfect interface, but may help in trying out StaticArrays with pre-existing
code.
Furthermore, using StaticArrays.ImmutableArrays
will let you use the typenames
from the ImmutableArrays package, which does not include the array size as a
type parameter (e.g. Vector3{T}
and Matrix3x3{T}
).