### Install and Use StaticArrays Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/quickstart.md Install the StaticArrays package and import it along with LinearAlgebra for array operations. ```julia import Pkg Pkg.add("StaticArrays") # or Pkg.clone("https://github.com/JuliaArrays/StaticArrays.jl") using StaticArrays using LinearAlgebra ``` -------------------------------- ### Example Usage of svectors and svectorscopy Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md Demonstrates the usage of `svectors` (no copy) and `svectorscopy` (with copy) functions on a sample matrix. ```julia M = reshape(collect(1:6), (2,3)) svectors(M, Val{2}()) svectorscopy(M, Val{2}()) ``` -------------------------------- ### Similar and Size Traits Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/quickstart.md Use `similar()` to get a mutable container of the same type and size, and `similar_type()` to get a constructor for a similar static type. The `Size` trait provides compile-time size information. ```julia # 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) ``` -------------------------------- ### SMatrix Constructors and Macros Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md Details on creating statically sized N×M matrices using constructors and the @SMatrix macro. ```APIDOC ## `SMatrix` Statically sized `N×M` matrices are provided by `SMatrix{N,M,T,L}`. Here `L` is the `length` of the matrix, such that `N × M = L`. However, convenience constructors are provided, so that `L`, `T` and even `M` are unnecessary. At minimum, you can type `SMatrix{2}(1,2,3,4)` to create a 2×2 matrix (the total number of elements must divide evenly into `N`). A convenience macro `@SMatrix [1 2; 3 4]` is provided (which also accepts comprehensions and the `zeros()`, `ones()`, `fill()`, `rand()`, `randn()`, and `randexp()` functions). ``` -------------------------------- ### Matrix Constructor Syntax Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/README.md Illustrates various ways to construct static matrices, including flat, column-major, identity, random, and from existing arrays. ```julia 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 ``` -------------------------------- ### Get Size of Static Arrays Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/quickstart.md Retrieve the size of a static array instance or its type. ```julia # Can get size() from instance or type size(v1) == (3,) size(typeof(v1)) == (3,) ``` -------------------------------- ### Create Static Matrices Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/quickstart.md Construct `SMatrix` instances using different syntaxes, including flat initialization, macro-based initialization with explicit layout, and identity matrix creation. ```julia # 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 ``` -------------------------------- ### SVector Constructors and Macros Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md Provides details on creating immutable static vectors of fixed length and type using convenience constructors and the @SVector macro. ```APIDOC ## `SVector` The simplest static array is the type `SVector{N,T}`, which provides an immutable vector of fixed length `N` and type `T`. `SVector` defines a series of convenience constructors, so you can just type e.g. `SVector(1,2,3)`. Alternatively there is an intelligent `@SVector` macro where you can use native Julia array literals syntax, comprehensions, and the `zeros()`, `ones()`, `fill()`, `rand()` and `randn()` functions, such as `@SVector [1,2,3]`, `@SVector Float64[1,2,3]`, `@SVector [f(i) for i = 1:10]`, `@SVector zeros(3)`, `@SVector randn(Float32, 4)`, etc (Note: the range of a comprehension is evaluated at global scope by the macro, and must be made of combinations of literal values, functions, or global variables, but is not limited to just simple ranges. Extending this to (hopefully statically known by type-inference) local-scope variables is hoped for the future. The `zeros()`, `ones()`, `fill()`, `rand()`, `randn()`, and `randexp()` functions do not have this limitation.) ``` -------------------------------- ### SArray Construction Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md Explains how to construct static arrays with an arbitrary number of dimensions using the @SArray macro. ```APIDOC ## `SArray` A container with arbitrarily many dimensions is defined as `struct SArray{Size,T,N,L} <: StaticArray{Size,T,N}`, where `Size = Tuple{S1, S2, ...}` is a tuple of `Int`s. You can easily construct one with the `@SArray` macro, supporting all the features of `@SVector` and `@SMatrix` (but with arbitrary dimension). The main reason `SVector` and `SMatrix` are defined is to make it easier to define the types without the extra tuple characters (compare `SVector{3}` to `SArray{Tuple{3}}`). ``` -------------------------------- ### Create Static Vectors Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/quickstart.md Create `SVector` instances using various methods including direct constructors, functions, and macros. Comprehensions are evaluated at the global scope. ```julia # 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 ``` -------------------------------- ### Higher-Dimensional Static Arrays Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/README.md Shows how to create static arrays for higher dimensions. ```julia a = @SArray randn(2, 2, 2, 2, 2, 2) ``` -------------------------------- ### Indexing with Static Arrays Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/README.md Explains how to index static arrays using integers and static arrays of integers. Note that determining size from a standard array of integers is not possible at compile time. ```julia 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] ``` -------------------------------- ### Create Higher-Dimensional Static Arrays Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/quickstart.md Demonstrates the creation of higher-dimensional static arrays using the `@SArray` macro. ```julia # Higher-dimensional support a = @SArray randn(2, 2, 2, 2, 2, 2) ``` -------------------------------- ### SizedArray Wrapper and Specialized Methods Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/README.md Shows how a standard Array can be wrapped into a `SizedArray` to take advantage of specialized fast methods, such as inversion. ```julia m4 = SizedMatrix{3,3}(rand(3,3)) inv(m4) # Take advantage of specialized fast methods ``` -------------------------------- ### Constructing SMatrix with Literal Values Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md Create statically sized matrices using convenience constructors, specifying at least the number of columns. ```julia SMatrix{2}(1,2,3,4) ``` -------------------------------- ### Create Static Vectors and Matrices with SA Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/quickstart.md Use the convenience constructor type `SA` to create static vectors and matrices with specified element types. ```julia # 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} ``` -------------------------------- ### SA — Literal array constructor Source: https://context7.com/juliaarrays/staticarrays.jl/llms.txt The `SA[...]` macro provides a concise way to construct static arrays. It infers the element type by promotion, or you can explicitly set it with `SA{T}[...]`. It results in an `SVector` for 1-D literals and an `SMatrix` for 2-D literals. ```APIDOC ## SA — Literal array constructor `SA[...]` is the most concise way to construct a static array. The element type is inferred by promotion; use `SA{T}[...]` to fix the element type explicitly. Type aliases `SA_F32` and `SA_F64` are provided for common floating-point types. The resulting array is an `SVector` for a 1-D literal or an `SMatrix` for a 2-D literal. ```julia using StaticArrays # 1-D → SVector v = SA[1, 2, 3] # SVector{3, Int64} vf = SA_F64[1, 2, 3] # SVector{3, Float64} vf32 = SA{Float32}[1, 2, 3] # SVector{3, Float32} # 2-D → SMatrix m = SA[1 2; 3 4] # SMatrix{2, 2, Int64, 4} mf = SA_F64[1 2; 3 4] # SMatrix{2, 2, Float64, 4} # Arithmetic works immediately norm_v = sqrt(sum(v .^ 2)) # 3.7416… rotated = m * v # SVector{2, Int64} ``` ``` -------------------------------- ### Common AbstractArray Operations Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/README.md Demonstrates standard array operations like addition, element-wise sine, and matrix-vector multiplication. ```julia v7 = v1 + v2 v8 = sin.(v3) v3 == m3 * v3 # recall that m3 = SMatrix{3,3}(1I) ``` -------------------------------- ### BLAS and LAPACK Integration Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/README.md Shows how large matrices can leverage BLAS for multiplication and how small matrices can use specialized algorithms for operations like eigen decomposition. ```julia 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 ``` -------------------------------- ### Constructing SMatrix with @SMatrix Macro Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md The @SMatrix macro supports Julia array literal syntax, comprehensions, and generation functions for static matrices. ```julia @SMatrix [1 2; 3 4] ``` -------------------------------- ### Building Static Arrays Iteratively Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md Efficiently construct static arrays by first building an MArray and then converting it to an SArray. Compilers can often elide the allocation for this pattern. ```julia function standard_basis_vector(T, ::Val{I}, ::Val{N}) where {I,N} v = zero(MVector{N,T}) v[I] = one(T) SVector(v) end ``` -------------------------------- ### SMatrix — Immutable Static Matrix Construction Source: https://context7.com/juliaarrays/staticarrays.jl/llms.txt Create immutable N×M matrices stored column-major. The @SMatrix macro supports literals, comprehensions, and initializer functions. Size parameters L and T are inferred. Specialized linear algebra operations are available for small sizes. ```julia using StaticArrays, LinearAlgebra # Construction m1 = SMatrix{2,2}(1, 2, 3, 4) # column-major: [1 3; 2 4] m2 = @SMatrix [1 2; 3 4] # row-literal: [1 2; 3 4] m3 = @SMatrix [i+j for i in 1:3, j in 1:3] # 3×3 comprehension m4 = @SMatrix randn(4, 4) # random 4×4 SMatrix{4,4,Float64,16} identity3 = SMatrix{3,3}(1.0I) # 3×3 identity matrix # Linear algebra — specialized algorithms for small sizes v = SA[1.0, 2.0, 3.0] x = identity3 \ v # SVector{3, Float64} solve d = det(m2) # -2.0 (fast 2×2 formula) i = inv(m2) # SMatrix{2,2,Float64,4} (fast 2×2 inversion) e = eigen(identity3) # Eigen with SVector eigenvalues, SMatrix vectors f = qr(m4) # QR factorization via specialized algorithm # Transpose / adjoint stay statically sized typeof(m2') # Adjoint{Int64, SMatrix{2,2,Int64,4}} typeof(transpose(m2)) # Transpose{Int64, SMatrix{2,2,Int64,4}} ``` -------------------------------- ### Constructing SArray with @SArray Macro Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md Use the @SArray macro for constructing static arrays with an arbitrary number of dimensions, supporting features similar to @SVector and @SMatrix. ```julia @SArray [1,2,3] ``` -------------------------------- ### Benchmark Results for 3x3 Float64 Matrices Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/README.md This benchmark shows performance improvements for various matrix operations using StaticArrays compared to Base.Array. Results are indicative and may vary based on hardware and Julia version. ```text ============================================ 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 ``` -------------------------------- ### BLAS and LAPACK Integration Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/quickstart.md Static arrays can leverage BLAS and LAPACK for performance with large matrices. Specialized algorithms are used for small matrices (e.g., up to 3x3 for `eigen`). ```julia # 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 ``` -------------------------------- ### Size-Based Dispatch for Determinant Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md Implement size-based dispatch for functions like determinant, allowing different methods for matrices of different static sizes. ```julia det(x::StaticMatrix) = _det(Size(x), x) ``` ```julia _det(::Size{(1,1)}, x::StaticMatrix) = x[1,1] ``` ```julia _det(::Size{(2,2)}, x::StaticMatrix) = x[1,1]*x[2,2] - x[1,2]*x[2,1] ``` -------------------------------- ### Static Size Preservation Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/README.md Illustrates that static arrays maintain their static size even when used with Base functions, ensuring type stability. ```julia typeof(eigen(m3).vectors) == SMatrix{3,3,Float64,9} typeof(eigen(m3).values) == SVector{3,Float64} ``` -------------------------------- ### Mutable Static Array Constructors Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md Convenience macros for creating mutable static arrays like MVector, MMatrix, and MArray. These arrays are heap-allocated and support `setindex!`. ```julia @MVector ``` ```julia @MMatrix ``` ```julia @MArray ``` -------------------------------- ### Constructing SVector with @SVector Macro Source: https://github.com/juliaarrays/staticarrays.jl/blob/master/docs/src/api.md The @SVector macro allows using Julia array literal syntax, comprehensions, and generation functions like zeros() and randn() for static vectors. ```julia @SVector [1,2,3] ``` ```julia @SVector Float64[1,2,3] ``` ```julia @SVector [f(i) for i = 1:10] ``` ```julia @SVector zeros(3) ``` ```julia @SVector randn(Float32, 4) ```