• Stars
    star
    765
  • Rank 59,269 (Top 2 %)
  • Language
    Julia
  • License
    Other
  • Created over 8 years ago
  • Updated 21 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Statically sized arrays for Julia

StaticArrays

Statically sized arrays for Julia

Build Status Coverage Status codecov.io Stable Dev deps version

StaticArrays provides a framework for implementing statically sized arrays in Julia, 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 Arrays with static size information. Further, the abstract FieldVector can be used to make fast StaticVectors out of any uniform Julia "struct". Full documentation can be found here.

Most of the primary array types exported by StaticArrays.jl are defined in the small interface package StaticArraysCore.jl. This includes e.g., the definitions of the abstract type StaticArray and the concrete types SArray, MArray, and SizedArray (as well as their dimension-specific aliases). This enables downstream packages to implement new methods for these types without depending on (and hence loading) the entirety of StaticArrays.jl, and thereby to avoid incurring the full load-time of StaticArrays.jl (which is on the order of 0.6 s for StaticArrays.jl v1.4 on Julia v1.7).

Speed

The speed of small SVectors, SMatrixs and SArrays is often > 10 × faster than Base.Array. For example, here's a microbenchmark showing some common operations.

============================================
    Benchmarks for 3×3 Float64 matrices
============================================
Matrix multiplication               -> 5.9x speedup
Matrix multiplication (mutating)    -> 1.8x speedup
Matrix addition                     -> 33.1x speedup
Matrix addition (mutating)          -> 2.5x speedup
Matrix determinant                  -> 112.9x speedup
Matrix inverse                      -> 67.8x speedup
Matrix symmetric eigendecomposition -> 25.0x speedup
Matrix Cholesky decomposition       -> 8.8x speedup
Matrix LU decomposition             -> 6.1x speedup
Matrix QR decomposition             -> 65.0x speedup

These numbers were generated on an Intel i7-7700HQ using Julia-1.2. As with all synthetic benchmarks, the speedups you see here should only be taken as very roughly indicative of the speedup you may see in real code. When in doubt, benchmark your real application!

Note that in the current implementation, working with large StaticArrays 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.

Quick start

Add StaticArrays from the Pkg REPL, i.e., pkg> add StaticArrays. Then:

using LinearAlgebra
using StaticArrays

# Use the convenience constructor type `SA` to create vectors and matrices
SA[1, 2, 3]      isa SVector{3,Int}
SA_F64[1, 2, 3]  isa SVector{3,Float64}
SA_F32[1, 2, 3]  isa SVector{3,Float32}
SA[1 2; 3 4]     isa SMatrix{2,2,Int}
SA_F64[1 2; 3 4] isa SMatrix{2,2,Float64}

# Create an SVector using various forms, using constructors, functions or macros
v1 = SVector(1, 2, 3)
v1.data === (1, 2, 3) # SVector uses a tuple for internal storage
v2 = SVector{3,Float64}(1, 2, 3) # length 3, eltype Float64
v3 = @SVector [1, 2, 3]
v4 = @SVector [i^2 for i = 1:10] # arbitrary comprehensions (range is evaluated at global scope)
v5 = zeros(SVector{3}) # defaults to Float64
v6 = @SVector zeros(3)
v7 = SVector{3}([1, 2, 3]) # Array conversions must specify size

# Can get size() from instance or type
size(v1) == (3,)
size(typeof(v1)) == (3,)

# Similar constructor syntax for matrices
m1 = SMatrix{2,2}(1, 2, 3, 4) # flat, column-major storage, equal to m2:
m2 = @SMatrix [ 1  3 ;
                2  4 ]
m3 = SMatrix{3,3}(1I)
m4 = @SMatrix randn(4,4)
m5 = SMatrix{2,2}([1 3 ; 2 4]) # Array conversions must specify size

# Higher-dimensional support
a = @SArray randn(2, 2, 2, 2, 2, 2)

# Supports all the common operations of AbstractArray
v7 = v1 + v2
v8 = sin.(v3)
v3 == m3 * v3 # recall that m3 = SMatrix{3,3}(1I)
# map, reduce, broadcast, map!, broadcast!, etc...

# Indexing can also be done using static arrays of integers
v1[1] === 1
v1[SVector(3,2,1)] === @SVector [3, 2, 1]
v1[:] === v1
typeof(v1[[1,2,3]]) <: Vector # Can't determine size from the type of [1,2,3]

# Is (partially) hooked into BLAS, LAPACK, etc:
rand(MMatrix{20,20}) * rand(MMatrix{20,20}) # large matrices can use BLAS
eigen(m3) # eigen(), etc uses specialized algorithms up to 3×3, or else LAPACK

# Static arrays stay statically sized, even when used by Base functions, etc:
typeof(eigen(m3).vectors) == SMatrix{3,3,Float64,9}
typeof(eigen(m3).values) == SVector{3,Float64}

# similar() returns a mutable container, while similar_type() returns a constructor:
typeof(similar(m3)) == MArray{Tuple{3,3},Int64,2,9} # (final parameter is length = 9)
similar_type(m3) == SArray{Tuple{3,3},Int64,2,9}

# The Size trait is a compile-time constant representing the size
Size(m3) === Size(3,3)

# A standard Array can be wrapped into a SizedArray
m4 = SizedMatrix{3,3}(rand(3,3))
inv(m4) # Take advantage of specialized fast methods

# reshape() uses Size() or types to specify size:
reshape([1,2,3,4], Size(2,2)) == @SMatrix [ 1  3 ;
                                            2  4 ]
typeof(reshape([1,2,3,4], Size(2,2))) === SizedArray{Tuple{2, 2},Int64,2,1}

Approach

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) StaticArrays. 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, eigen and cholesky 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".

More Repositories

1

StructArrays.jl

Efficient implementation of struct arrays in Julia
Julia
307
star
2

LazyArrays.jl

Lazy arrays and linear algebra in Julia
Julia
278
star
3

AxisArrays.jl

Performant arrays where each dimension can have a named axis with values
Julia
200
star
4

OffsetArrays.jl

Fortran-like arrays with arbitrary, zero or negative starting indices.
Julia
193
star
5

BlockArrays.jl

BlockArrays for Julia
Julia
193
star
6

FillArrays.jl

Julia package for lazily representing matrices filled with a single entry
Julia
177
star
7

ArrayInterface.jl

Designs for new Base array interface primitives, used widely through scientific machine learning (SciML) and other organizations
Julia
134
star
8

MappedArrays.jl

Lazy in-place transformations of arrays
Julia
82
star
9

TiledIteration.jl

Julia package to facilitate writing mulithreaded, multidimensional, cache-efficient code
Julia
79
star
10

InfiniteArrays.jl

A Julia package for representing infinite-dimensional arrays
Julia
72
star
11

ElasticArrays.jl

Resizeable multi-dimensional arrays for Julia
Julia
59
star
12

HybridArrays.jl

Arrays with both statically and dynamically sized axes in Julia
Julia
55
star
13

ShiftedArrays.jl

Lazy shifted arrays for data analysis in Julia
Julia
49
star
14

PaddedViews.jl

Add virtual padding to the edges of an array
Julia
48
star
15

StructsOfArrays.jl

Structures of Arrays that behave like Arrays of Structures
Julia
48
star
16

BlockDiagonals.jl

Functionality for working efficiently with block diagonal matrices.
Julia
47
star
17

ArraysOfArrays.jl

Efficient storage and handling of nested arrays in Julia
Julia
41
star
18

UnsafeArrays.jl

Stack-allocated pointer-based array views
Julia
39
star
19

MosaicViews.jl

Julia package for lazily viewing a 3D or 4D array as an expanded 2D array in the form of a mosaic of matrix slices
Julia
23
star
20

EndpointRanges.jl

Julia package for doing arithmetic on endpoints in array indexing
Julia
23
star
21

FFTViews.jl

Julia package for fast fourier transforms and periodic views
Julia
20
star
22

StackViews.jl

no more 🐱🐱
Julia
19
star
23

IndirectArrays.jl

Julia implementation of indexed or "lookup" arrays
Julia
19
star
24

ArrayViews.jl

A Julia package to explore a new system of array views
Julia
19
star
25

StaticArraysCore.jl

Interface package for StaticArrays.jl
Julia
16
star
26

StaticArrayInterface.jl

Interface designs for enforcing static computations in array functions with Julia
Julia
14
star
27

FixedSizeArrays.jl

Fixed-size multidimensional arrays. An Array-like type with less indirection at the cost of resizing capability.
Julia
14
star
28

LazyGrids.jl

A Julia package for representing multi-dimensional grids
Julia
13
star
29

ShowItLikeYouBuildIt.jl

Compact display of type information by leveraging constructor syntax
Julia
11
star
30

MetadataArrays.jl

Julia
10
star
31

CustomUnitRanges.jl

Package-specific AbstractUnitRange types for julia
Julia
9
star
32

GetindexArrays.jl

Lazy arrays with arbitrary user-defined transformations
Julia
8
star
33

SpatioTemporalTraits.jl

Traits for arrays that live in space and time
Julia
7
star
34

UnalignedVectors.jl

Create arrays from memory buffers that lack appropriate alignment
Julia
5
star
35

CatIndices.jl

Julia package for indices-aware array concatenation and growth
Julia
4
star
36

AbstractArraysOfArrays.jl

[WIP] Abstract types and interface for nested arrays
4
star
37

RangeArrays.jl

Efficient and convenient array data structures where the columns of the arrays are generated (on the fly) by Ranges.
Julia
4
star
38

IdentityRanges.jl

Ranges that preserve indices of views
Julia
3
star
39

Ranges.jl

Support for LinSpace in Julia 0.5
Julia
3
star
40

OneTwoMany.jl

Tools for element access in Julia
Julia
2
star