Giter Club home page Giter Club logo

staticarrays.jl's Introduction

StaticArrays

Statically sized arrays for Julia

StaticArrays StaticArrays Build Status Build status Coverage Status codecov.io

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 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.

Speed

The speed of small SVectors, SMatrixs and SArrays is often > 10 × faster than Base.Array. See this simplified benchmark (or see the full results here):

============================================
    Benchmarks for 3×3 Float64 matrices
============================================

Matrix multiplication               -> 8.2x speedup
Matrix multiplication (mutating)    -> 3.1x speedup
Matrix addition                     -> 45x speedup
Matrix addition (mutating)          -> 5.1x speedup
Matrix determinant                  -> 170x speedup
Matrix inverse                      -> 125x speedup
Matrix symmetric eigendecomposition -> 82x speedup
Matrix 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 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. For example, the performance crossover point for a matrix multiply microbenchmark seems to be about 11x11 in julia 0.5 with default optimizations.

Quick start

Pkg.add("StaticArrays")  # or Pkg.clone("https://github.com/JuliaArrays/StaticArrays.jl")
using StaticArrays
using LinearAlgebra

# 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)) == Eigen{Float64,Float64,SArray{Tuple{3,3},Float64,2,9},SArray{Tuple{3},Float64,1,3}}

# 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 = Size(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, 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".

Relationship to FixedSizeArrays and ImmutableArrays

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}).

staticarrays.jl's People

Contributors

andreasnoack avatar andyferris avatar antoine-levitt avatar beastyblacksmith avatar bshall avatar c42f avatar chethega avatar chrisrackauckas avatar denius avatar fredrikekre avatar godisemo avatar goggle avatar jw3126 avatar kleinschmidt avatar kshyatt avatar marius311 avatar martinholters avatar mschauer avatar pablosanjose avatar rafaqz avatar rdeits avatar schmrlng avatar simonbyrne avatar simondanisch avatar timholy avatar tkoolen avatar tsurherman avatar wsshin avatar yingboma avatar zygmuntszpak avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.