Skip to content

Commit

Permalink
Move Size from StaticArrays.jl (#13)
Browse files Browse the repository at this point in the history
* Move `Size` from StaticArrays.jl

* one more test

* export Size
  • Loading branch information
mateuszbaran authored Sep 21, 2022
1 parent 3024fe6 commit 33f4dad
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "StaticArraysCore"
uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
version = "1.3.0"
version = "1.4.0"

[compat]
julia = "1.6"
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ Interface package for [StaticArrays.jl](https://github.com/JuliaArrays/StaticArr
[![Build Status](https://github.com/JuliaArrays/StaticArraysCore.jl/workflows/CI/badge.svg)](https://github.com/JuliaArrays/StaticArraysCore.jl/actions?query=workflow%3ACI)
[![codecov.io](https://codecov.io/github/JuliaArrays/StaticArraysCore.jl/branch/main/graph/badge.svg)](http://codecov.io/github/JuliaArrays/StaticArraysCore.jl/branch/main)

Contains definitions for the following types:
Contains definitions for the following types and functions:

* immutable: `SArray`, `SVector` and `SMatrix`,
* mutable: `MArray`, `MVector` and `MMatrix`,
* wrapper: `SizedArray`, `SizedVector` and `SizedMatrix`.
* wrapper: `SizedArray`, `SizedVector` and `SizedMatrix`,
* `Size` and `Dynamic`,
* `similar_type`.
82 changes: 82 additions & 0 deletions src/StaticArraysCore.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export SArray, SMatrix, SVector
export MArray, MMatrix, MVector
export SizedArray, SizedMatrix, SizedVector
export FieldArray, FieldMatrix, FieldVector
export Size

"""
abstract type StaticArray{S, T, N} <: AbstractArray{T, N} end
Expand Down Expand Up @@ -411,4 +412,85 @@ if they wish to overload the default behavior.
"""
function similar_type end

"""
Dynamic()
Used to signify that a dimension of an array is not known statically.
"""
struct Dynamic end

const StaticDimension = Union{Int, Dynamic}

"""
Size(dims::Int...)
`Size` is used extensively throughout the `StaticArrays` API to describe _compile-time_
knowledge of the size of an array. The dimensions are stored as a type parameter and are
statically propagated by the compiler, resulting in efficient, type-inferrable code. For
example, to create a static matrix of zeros, use `A = zeros(SMatrix{3,3})`. The static
size of `A` can be obtained by `Size(A)`. (rather than `size(zeros(3,3))`, which returns
`Base.Tuple{2,Int}`).
Note that if dimensions are not known statically (e.g., for standard `Array`s),
[`Dynamic()`](@ref) should be used instead of an `Int`.
Size(a::AbstractArray)
Size(::Type{T<:AbstractArray})
The `Size` constructor can be used to extract static dimension information from a given
array. For example:
```julia-repl
julia> Size(zeros(SMatrix{3, 4}))
Size(3, 4)
julia> Size(zeros(3, 4))
Size(StaticArrays.Dynamic(), StaticArrays.Dynamic())
```
This has multiple uses, including "trait"-based dispatch on the size of a statically-sized
array. For example:
```julia
det(x::StaticMatrix) = _det(Size(x), x)
_det(::Size{(1,1)}, x::StaticMatrix) = x[1,1]
_det(::Size{(2,2)}, x::StaticMatrix) = x[1,1]*x[2,2] - x[1,2]*x[2,1]
# and other definitions as necessary
```
"""
struct Size{S}
function Size{S}() where {S}
new{S::Tuple{Vararg{StaticDimension}}}()
end
end

Base.@pure Size(s::Tuple{Vararg{StaticDimension}}) = Size{s}()
Base.@pure Size(s::StaticDimension...) = Size{s}()
Base.@pure Size(s::Type{<:Tuple}) = Size{tuple(s.parameters...)}()

Base.show(io::IO, ::Size{S}) where {S} = print(io, "Size", S)

function missing_size_error(::Type{SA}) where SA
error("""
The size of type `$SA` is not known.
If you were trying to construct (or `convert` to) a `StaticArray` you
may need to add the size explicitly as a type parameter so its size is
inferrable to the Julia compiler (or performance would be terrible). For
example, you might try
m = zeros(3,3)
SMatrix(m) # this error
SMatrix{3,3}(m) # correct - size is inferrable
SArray{Tuple{3,3}}(m) # correct, note Tuple{3,3}
""")
end

Size(a::T) where {T<:AbstractArray} = Size(T)
Size(::Type{SA}) where {SA <: StaticArray} = missing_size_error(SA)
Size(::Type{SA}) where {SA <: StaticArray{S}} where {S<:Tuple} = @isdefined(S) ? Size(S) : missing_size_error(SA)

Base.@pure Size(::Type{<:AbstractArray{<:Any, N}}) where {N} = Size(ntuple(_ -> Dynamic(), N))

end # module
13 changes: 13 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,16 @@ using StaticArraysCore, Test

@test StaticArraysCore.StaticArrayStyle{1}(Val(2)) === StaticArraysCore.StaticArrayStyle{2}()
end

@testset "Size" begin
M = SArray{Tuple{2,3,4},Int,3}(tuple(rand(Int, 24)...))
@test (@inferred Size(M)) === Size(2, 3, 4)
Ms = Size(M)
@test repr(Ms) == "Size(2, 3, 4)"
@test Size(2, StaticArraysCore.Dynamic(), 5) === Size{(2, StaticArraysCore.Dynamic(), 5)}()
@test Size((2, StaticArraysCore.Dynamic(), 5)) === Size{(2, StaticArraysCore.Dynamic(), 5)}()
@test Size(Tuple{2, StaticArraysCore.Dynamic(), 5}) === Size{(2, StaticArraysCore.Dynamic(), 5)}()
@test Size([2 3; 4 5]) === Size{(StaticArraysCore.Dynamic(), StaticArraysCore.Dynamic())}()

@test_throws ErrorException Size(SArray)
end

5 comments on commit 33f4dad

@hyrodium
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error while trying to register: Register Failed
@hyrodium, it looks like you are not a publicly listed member/owner in the parent organization (JuliaArrays).
If you are a member/owner, you will need to change your membership to public. See GitHub Help

@devmotion
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems registration failed?

@mateuszbaran
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/68724

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.4.0 -m "<description of version>" 33f4dada9a6e19dddc4eb0d65807d4185f4ed9a0
git push origin v1.4.0

Please sign in to comment.