Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Size to StaticArraysCore.jl #1094

Merged
merged 1 commit into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "StaticArrays"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.5.7"
version = "1.5.8"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand All @@ -10,7 +10,7 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[compat]
julia = "1.6"
StaticArraysCore = "~1.3.0"
StaticArraysCore = "~1.4.0"

[extras]
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
Expand Down
3 changes: 2 additions & 1 deletion src/StaticArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ using StaticArraysCore: StaticArraysCore, StaticArray, StaticScalar, StaticVecto
tuple_minimum, size_to_tuple, require_one_based_indexing
using StaticArraysCore: FieldArray, FieldMatrix, FieldVector
using StaticArraysCore: StaticArrayStyle
using StaticArraysCore: Dynamic, StaticDimension
import StaticArraysCore: SArray, SVector, SMatrix
import StaticArraysCore: MArray, MVector, MMatrix
import StaticArraysCore: SizedArray, SizedVector, SizedMatrix
import StaticArraysCore: check_array_parameters, convert_ntuple
import StaticArraysCore: similar_type
import StaticArraysCore: similar_type, Size

# end of StaticArraysCore imports
# StaticArraysCore exports
Expand Down
80 changes: 0 additions & 80 deletions src/traits.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
"""
Dynamic()

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

const StaticDimension = Union{Int, Dynamic}

"""
dimmatch(x::StaticDimension, y::StaticDimension)
Expand All @@ -19,85 +11,13 @@ function dimmatch end
@inline dimmatch(x::Int, y::Int) = x === y
@inline dimmatch(x::StaticDimension, y::StaticDimension) = true

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

@pure Size(s::Tuple{Vararg{StaticDimension}}) = Size{s}()
@pure Size(s::StaticDimension...) = Size{s}()
@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)

Size(::Type{Adjoint{T, A}}) where {T, A <: AbstractVecOrMat{T}} = Size(Size(A)[2], Size(A)[1])
Size(::Type{Transpose{T, A}}) where {T, A <: AbstractVecOrMat{T}} = Size(Size(A)[2], Size(A)[1])
Size(::Type{Symmetric{T, A}}) where {T, A <: AbstractMatrix{T}} = Size(A)
Size(::Type{Hermitian{T, A}}) where {T, A <: AbstractMatrix{T}} = Size(A)
Size(::Type{Diagonal{T, A}}) where {T, A <: AbstractVector{T}} = Size(Size(A)[1], Size(A)[1])
Size(::Type{<:LinearAlgebra.AbstractTriangular{T, A}}) where {T,A} = Size(A)
Comment on lines 14 to 19
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be moved to StaticArraysCore as well? Technically it is type piracy.

Copy link
Contributor

Choose a reason for hiding this comment

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

There are some additional definitions below with types from base.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

StaticArraysCore currently doesn't import LinearAlgebra so that's why I didn't more them. Is there a use for these methods in StaticArraysCore without StaticArrays?

I know this is type piracy but it should be harmless since StaticArrays in practice "owns" Size.

Copy link
Contributor

Choose a reason for hiding this comment

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

I know this is type piracy but it should be harmless since StaticArrays in practice "owns" Size.

That's why I assumed it is mostly technical. It would only become an issue if some other package wants to use these Size functionalities without depending on StaticArrays itself.

Some of the definitions below don't even use LinearAlgebra (or some other standard library), e.g., Base.prod or definitions for Tuples.

Generally, I would assume that it's fine for StaticArraysCore to depend on LinearAlgebra as it is a standard library and I think usually any package with StaticArraysCore in the dependency tree will have LinearAlgebra in the dependency tree anyway.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Since the PR to core is already merged and tagged, let's leave that to a new PR.

Copy link
Member

Choose a reason for hiding this comment

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

Basically all of StaticArrays is type piracy, e.g. *(::SMatrix, ::SVector) is type piracy since StaticArrays owns neither the function nor the types.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this might actually not only be a theoretical problem but cause issues with generated functions: JuliaDiff/ForwardDiff.jl#599 (comment)


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

struct Length{L}
function Length{L}() where L
check_length(L)
Expand Down