From af8612b9179512bfb0d50669dd1a13305a008b96 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Wed, 29 Mar 2017 23:59:40 +0000 Subject: [PATCH 1/2] RFC: Unify SArray,SMatrix,SVector After the recent refactor something that used to be an SMatrix became a two dimensional SArray (or vice versa - who can keep track). That situation seems unfortunate and unnecessary, so this is an attempt to unify them. This is decently breaking, because it requires the SArray dimension tuple to be e.g. `Tuple{1,2}` rather than `(1,2)`, but should allow us to avoid quite a bit of duplication. These are just the minimal changes to get this running. I would imagine, we could remove some further duplication in follow up patches. --- src/SArray.jl | 96 +++++++++++++++++++++++++++---------------- src/SMatrix.jl | 30 +------------- src/SVector.jl | 12 +----- src/StaticArrays.jl | 4 +- src/abstractarray.jl | 4 +- src/traits.jl | 1 + test/SArray.jl | 92 ++++++++++++++++++++--------------------- test/abstractarray.jl | 14 +++---- test/arraymath.jl | 4 +- test/indexing.jl | 4 +- 10 files changed, 125 insertions(+), 136 deletions(-) diff --git a/src/SArray.jl b/src/SArray.jl index 7ba59368..661b1bd5 100644 --- a/src/SArray.jl +++ b/src/SArray.jl @@ -19,56 +19,82 @@ immutable SArray{Size, T, N, L} <: StaticArray{T, N} data::NTuple{L,T} function (::Type{SArray{Size,T,N,L}}){Size,T,N,L}(x::NTuple{L,T}) - check_sarray_parameters(Val{Size}, T, Val{N}, Val{L}) + check_sarray_parameters(Size, T, Val{N}, Val{L}) new{Size,T,N,L}(x) end function (::Type{SArray{Size,T,N,L}}){Size,T,N,L}(x::NTuple{L,Any}) - check_sarray_parameters(Val{Size}, T, Val{N}, Val{L}) + check_sarray_parameters(Size, T, Val{N}, Val{L}) new{Size,T,N,L}(convert_ntuple(T, x)) end end -@generated function check_sarray_parameters{Size,T,N,L}(::Type{Val{Size}}, ::Type{T}, ::Type{Val{N}}, ::Type{Val{L}}) - if !(isa(Size, Tuple{Vararg{Int}})) - error("SArray parameter Size must be a tuple of Ints (e.g. `SArray{(3,3)}`)") +@pure tuple_length(T) = length(T.parameters) +@pure tuple_prod(T) = *(T.parameters...) +@pure tuple_minimum(T) = minimum(tuple(T.parameters...)) + +# Something doesn't match up type wise +function check_sarray_parameters(Size, T, N, L) + (!isa(Size, DataType) || (Size.name !== Tuple.name)) && throw(ArgumentError("SArray parameter Size must be a Tuple type, got $Size")) + !isa(T, Type) && throw(ArgumentError("SArray parameter T must be a type, got $T")) + !isa(N.parameters[1], Int) && throw(ArgumenError("SArray parameter N must be an integer, got $(N.parameters[1])")) + !isa(L.parameters[1], Int) && throw(ArgumentError("SArray parameter L must be an integer, got $(L.parameters[1])")) + # shouldn't reach here. Anything else should have made it to the function below + error("Internal error. Please file a bug") +end + +@generated function check_sarray_parameters{Size,T,N,L}(::Type{Size}, ::Type{T}, ::Type{Val{N}}, ::Type{Val{L}}) + if !all(x->isa(x, Int), Size.parameters) + throw(ArgumentError("SArray parameter Size must be a tuple of Ints (e.g. `SArray{Tuple{3,3}}` or `SMatrix{3,3}`).")) end - if L != prod(Size) || L < 0 || minimum(Size) < 0 || length(Size) != N - error("Size mismatch in SArray parameters. Got size $Size, dimension $N and length $L.") + if L != tuple_prod(Size) || L < 0 || tuple_minimum(Size) < 0 || tuple_length(Size) != N + throw(ArgumentError("Size mismatch in SArray parameters. Got size $Size, dimension $N and length $L.")) end return nothing end -@generated function (::Type{SArray{Size,T,N}}){Size,T,N}(x::Tuple) +@generated function (::Type{SArray{Size,T,N}}){Size <: Tuple,T,N}(x::Tuple) return quote $(Expr(:meta, :inline)) - SArray{Size,T,N,$(prod(Size))}(x) + SArray{Size,T,N,$(tuple_prod(Size))}(x) end end -@generated function (::Type{SArray{Size,T}}){Size,T}(x::Tuple) +@generated function (::Type{SArray{Size,T}}){Size <: Tuple,T}(x::Tuple) return quote $(Expr(:meta, :inline)) - SArray{Size,T,$(length(Size)),$(prod(Size))}(x) + SArray{Size,T,$(tuple_length(Size)),$(tuple_prod(Size))}(x) end end -@generated function (::Type{SArray{Size}}){Size, T <: Tuple}(x::T) +function SArray{Size,T,N}(x::Tuple) where {Size, T, N} + Base.depwarn("SArray{(dim1,dim2,...),...} is deprecated, use SArray{Tuple{dim1, dim2, ...}, ...}", :SArray) + SArray{Tuple{Size...},T,N}(x) +end +function SArray{Size,T}(x::Tuple) where {Size, T} + Base.depwarn("SArray{(dim1,dim2,...),...} is deprecated, use SArray{Tuple{dim1, dim2, ...}, ...}", :SArray) + SArray{Tuple{Size...},T}(x) +end +function SArray{Size}(x::Tuple) where {Size} + Base.depwarn("SArray{(dim1,dim2,...),...} is deprecated, use SArray{Tuple{dim1, dim2, ...}, ...}", :SArray) + SArray{Tuple{Size...}}(x) +end +@generated function (::Type{SArray{Size}}){Size <: Tuple, T <: Tuple}(x::T) return quote $(Expr(:meta, :inline)) - SArray{Size,$(promote_tuple_eltype(T)),$(length(Size)),$(prod(Size))}(x) + SArray{Size,$(promote_tuple_eltype(T)),$(tuple_length(Size)),$(tuple_prod(Size))}(x) end end -@inline SArray(a::StaticArray) = SArray{size(typeof(a))}(Tuple(a)) +@inline SArray(a::StaticArray) = SArray{size_tuple(a)}(Tuple(a)) # Some more advanced constructor-like functions -@inline one(::Type{SArray{S}}) where {S} = one(SArray{S,Float64,length(S)}) -@inline eye(::Type{SArray{S}}) where {S} = eye(SArray{S,Float64,length(S)}) -@inline one(::Type{SArray{S,T}}) where {S,T} = one(SArray{S,T,length(S)}) -@inline eye(::Type{SArray{S,T}}) where {S,T} = eye(SArray{S,T,length(S)}) +@inline one(::Type{SArray{S}}) where {S} = one(SArray{S,Float64,tuple_length(S)}) +@inline eye(::Type{SArray{S}}) where {S} = eye(SArray{S,Float64,tuple_length(S)}) +@inline one(::Type{SArray{S,T}}) where {S,T} = one(SArray{S,T,tuple_length(S)}) +@inline eye(::Type{SArray{S,T}}) where {S,T} = eye(SArray{S,T,tuple_length(S)}) #################### ## SArray methods ## @@ -97,17 +123,17 @@ macro SArray(ex) end if ex.head == :vect # vector - return esc(Expr(:call, SArray{(length(ex.args),)}, Expr(:tuple, ex.args...))) + return esc(Expr(:call, SArray{Tuple{length(ex.args)}}, Expr(:tuple, ex.args...))) elseif ex.head == :ref # typed, vector - return esc(Expr(:call, Expr(:curly, :SArray, ((length(ex.args)-1),), ex.args[1]), Expr(:tuple, ex.args[2:end]...))) + return esc(Expr(:call, Expr(:curly, :SArray, Tuple{length(ex.args)-1}, ex.args[1]), Expr(:tuple, ex.args[2:end]...))) elseif ex.head == :hcat # 1 x n s1 = 1 s2 = length(ex.args) - return esc(Expr(:call, SArray{(s1, s2)}, Expr(:tuple, ex.args...))) + return esc(Expr(:call, SArray{Tuple{s1, s2}}, Expr(:tuple, ex.args...))) elseif ex.head == :typed_hcat # typed, 1 x n s1 = 1 s2 = length(ex.args) - 1 - return esc(Expr(:call, Expr(:curly, :SArray, (s1, s2), ex.args[1]), Expr(:tuple, ex.args[2:end]...))) + return esc(Expr(:call, Expr(:curly, :SArray, Tuple{s1, s2}, ex.args[1]), Expr(:tuple, ex.args[2:end]...))) elseif ex.head == :vcat if isa(ex.args[1], Expr) && ex.args[1].head == :row # n x m # Validate @@ -119,9 +145,9 @@ macro SArray(ex) end exprs = [ex.args[i].args[j] for i = 1:s1, j = 1:s2] - return esc(Expr(:call, SArray{(s1, s2)}, Expr(:tuple, exprs...))) + return esc(Expr(:call, SArray{Tuple{s1, s2}}, Expr(:tuple, exprs...))) else # n x 1 - return esc(Expr(:call, SArray{(length(ex.args), 1)}, Expr(:tuple, ex.args...))) + return esc(Expr(:call, SArray{Tuple{length(ex.args), 1}}, Expr(:tuple, ex.args...))) end elseif ex.head == :typed_vcat if isa(ex.args[2], Expr) && ex.args[2].head == :row # typed, n x m @@ -134,9 +160,9 @@ macro SArray(ex) end exprs = [ex.args[i+1].args[j] for i = 1:s1, j = 1:s2] - return esc(Expr(:call, Expr(:curly, :SArray, (s1, s2), ex.args[1]), Expr(:tuple, exprs...))) + return esc(Expr(:call, Expr(:curly, :SArray, Tuple{s1, s2}, ex.args[1]), Expr(:tuple, exprs...))) else # typed, n x 1 - return esc(Expr(:call, Expr(:curly, :SArray, (length(ex.args)-1, 1), ex.args[1]), Expr(:tuple, ex.args[2:end]...))) + return esc(Expr(:call, Expr(:curly, :SArray, Tuple{length(ex.args)-1, 1}, ex.args[1]), Expr(:tuple, ex.args[2:end]...))) end elseif isa(ex, Expr) && ex.head == :comprehension if length(ex.args) != 1 || !isa(ex.args[1], Expr) || ex.args[1].head != :generator @@ -174,7 +200,7 @@ macro SArray(ex) return quote $(esc(f_expr)) - $(esc(Expr(:call, Expr(:curly, :SArray, (rng_lengths...)), Expr(:tuple, exprs...)))) + $(esc(Expr(:call, Expr(:curly, :SArray, Tuple{rng_lengths...}), Expr(:tuple, exprs...)))) end elseif isa(ex, Expr) && ex.head == :typed_comprehension if length(ex.args) != 2 || !isa(ex.args[2], Expr) || ex.args[2].head != :generator @@ -213,7 +239,7 @@ macro SArray(ex) return quote $(esc(f_expr)) - $(esc(Expr(:call, Expr(:curly, :SArray, (rng_lengths...), T), Expr(:tuple, exprs...)))) + $(esc(Expr(:call, Expr(:curly, :SArray, Tuple{rng_lengths...}, T), Expr(:tuple, exprs...)))) end elseif isa(ex, Expr) && ex.head == :call if ex.args[1] == :zeros || ex.args[1] == :ones || ex.args[1] == :rand || ex.args[1] == :randn @@ -222,9 +248,9 @@ macro SArray(ex) else return quote if isa($(esc(ex.args[2])), DataType) - $(ex.args[1])($(esc(Expr(:curly, SArray, Expr(:tuple, ex.args[3:end]...), ex.args[2])))) + $(ex.args[1])($(esc(Expr(:curly, SArray, Expr(:curly, Tuple, ex.args[3:end]...), ex.args[2])))) else - $(ex.args[1])($(esc(Expr(:curly, SArray, Expr(:tuple, ex.args[2:end]...))))) + $(ex.args[1])($(esc(Expr(:curly, SArray, Expr(:curly, Tuple, ex.args[2:end]...))))) end end end @@ -235,26 +261,26 @@ macro SArray(ex) error("@SArray got bad expression: $(ex.args[1])($(ex.args[2]))") else return quote - $(esc(ex.args[1]))($(esc(ex.args[2])), SArray{$(esc(Expr(:tuple, ex.args[3:end]...)))}) + $(esc(ex.args[1]))($(esc(ex.args[2])), SArray{$(esc(Expr(:curly, Tuple, ex.args[3:end]...)))}) end end elseif ex.args[1] == :eye if length(ex.args) == 2 return quote - eye(SArray{($(esc(ex.args[2])), $(esc(ex.args[2])))}) + eye(SArray{Tuple{$(esc(ex.args[2])), $(esc(ex.args[2]))}}) end elseif length(ex.args) == 3 # We need a branch, depending if the first argument is a type or a size. return quote if isa($(esc(ex.args[2])), DataType) - eye(SArray{($(esc(ex.args[3])), $(esc(ex.args[3]))), $(esc(ex.args[2]))}) + eye(SArray{Tuple{$(esc(ex.args[3])), $(esc(ex.args[3]))}, $(esc(ex.args[2]))}) else - eye(SArray{($(esc(ex.args[2])), $(esc(ex.args[3])))}) + eye(SArray{Tuple{$(esc(ex.args[2])), $(esc(ex.args[3]))}}) end end elseif length(ex.args) == 4 return quote - eye(SArray{($(esc(ex.args[3])), $(esc(ex.args[4]))), $(esc(ex.args[2]))}) + eye(SArray{Tuple{$(esc(ex.args[3])), $(esc(ex.args[4]))}, $(esc(ex.args[2]))}) end else error("Bad eye() expression for @SArray") diff --git a/src/SMatrix.jl b/src/SMatrix.jl index af78162d..27168372 100644 --- a/src/SMatrix.jl +++ b/src/SMatrix.jl @@ -14,35 +14,7 @@ Construct a statically-sized matrix of dimensions `S1 × S2` using the data from `mat`. The parameters `S1` and `S2` are mandatory since the size of `mat` is unknown to the compiler (the element type may optionally also be specified). """ -immutable SMatrix{S1, S2, T, L} <: StaticMatrix{T} - data::NTuple{L, T} - - function (::Type{SMatrix{S1,S2,T,L}}){S1,S2,T,L}(d::NTuple{L,T}) - check_smatrix_params(Val{S1}, Val{S2}, T, Val{L}) - new{S1,S2,T,L}(d) - end - - function (::Type{SMatrix{S1,S2,T,L}}){S1,S2,T,L}(d::NTuple{L,Any}) - check_smatrix_params(Val{S1}, Val{S2}, T, Val{L}) - new{S1,S2,T,L}(convert_ntuple(T, d)) - end -end - -function check_smatrix_params(::Type{Val{S1}}, ::Type{Val{S2}}, T, ::Type{Val{L}}) where {S1,S2,L} - throw(ArgumentError("SMatrix: Parameter T must be a Type. Got $T")) -end - -@generated function check_smatrix_params(::Type{Val{S1}}, ::Type{Val{S2}}, ::Type{T}, ::Type{Val{L}}) where {S1,S2,L,T} - if !isa(S1, Int) || !isa(S2, Int) || !isa(L, Int) || S1 < 0 || S2 < 0 || L < 0 - throw(ArgumentError("SMatrix: Sizes must be positive integers. Got $S1 × $S2 ($L elements)")) - end - - if S1*S2 == L - return nothing - else - throw(ArgumentError("Size mismatch in SMatrix. S1 = $S1, S2 = $S2, but recieved $L elements")) - end -end +const SMatrix{S1, S2, T, L} = SArray{Tuple{S1, S2}, T, 2, L} @generated function (::Type{SMatrix{S1}}){S1,L}(x::NTuple{L,Any}) S2 = div(L, S1) diff --git a/src/SVector.jl b/src/SVector.jl index c69152fe..415b75d1 100644 --- a/src/SVector.jl +++ b/src/SVector.jl @@ -13,17 +13,7 @@ Construct a statically-sized vector of length `S` using the data from `vec`. The parameter `S` is mandatory since the length of `vec` is unknown to the compiler (the element type may optionally also be specified). """ -immutable SVector{S, T} <: StaticVector{T} - data::NTuple{S, T} - - function (::Type{SVector{S, T}}){S, T}(x::NTuple{S,T}) - new{S, T}(x) - end - - function (::Type{SVector{S, T}}){S, T}(x::NTuple{S,Any}) - new{S, T}(convert_ntuple(T, x)) - end -end +const SVector{S, T} = SArray{Tuple{S}, T, 1, S} @inline (::Type{SVector}){S}(x::NTuple{S,Any}) = SVector{S}(x) @inline (::Type{SVector{S}}){S, T}(x::NTuple{S,T}) = SVector{S,T}(x) diff --git a/src/StaticArrays.jl b/src/StaticArrays.jl index 39ad7e16..59029cdf 100644 --- a/src/StaticArrays.jl +++ b/src/StaticArrays.jl @@ -70,10 +70,10 @@ include("convert.jl") include("SUnitRange.jl") include("Scalar.jl") -include("SVector.jl") include("FieldVector.jl") -include("SMatrix.jl") include("SArray.jl") +include("SMatrix.jl") +include("SVector.jl") include("MVector.jl") include("MMatrix.jl") include("MArray.jl") diff --git a/src/abstractarray.jl b/src/abstractarray.jl index 129ac3ff..f4dc134a 100644 --- a/src/abstractarray.jl +++ b/src/abstractarray.jl @@ -57,7 +57,7 @@ similar_type{A<:AbstractArray,T,S}(::Type{A},::Type{T},s::Size{S}) = default_sim default_similar_type{T,S}(::Type{T}, s::Size{S}, ::Type{Val{0}}) = Scalar{T} default_similar_type{T,S}(::Type{T}, s::Size{S}, ::Type{Val{1}}) = SVector{S[1],T} default_similar_type{T,S}(::Type{T}, s::Size{S}, ::Type{Val{2}}) = SMatrix{S[1],S[2],T,prod(s)} -default_similar_type{T,S,D}(::Type{T}, s::Size{S}, ::Type{Val{D}}) = SArray{S,T,D,prod(s)} +default_similar_type{T,S,D}(::Type{T}, s::Size{S}, ::Type{Val{D}}) = SArray{Tuple{S...},T,D,prod(s)} # should mutable things stay mutable? #similar_type{SA<:Union{MVector,MMatrix,MArray},T,S}(::Type{SA},::Type{T},s::Size{S}) = mutable_similar_type(T,s,length_val(s)) @@ -71,7 +71,7 @@ mutable_similar_type{T,S,D}(::Type{T}, s::Size{S}, ::Type{Val{D}}) = MArray{S,T, #similar_type{SA<:SizedArray,T,S}(::Type{SA},::Type{T},s::Size{S}) = sizedarray_similar_type(T,s,length_val(s)) #similar_type{A<:Array,T,S}(::Type{A},::Type{T},s::Size{S}) = sizedarray_similar_type(T,s,length_val(s)) -sizedarray_similar_type{T,S,D}(::Type{T},s::Size{S},::Type{Val{D}}) = SizedArray{S,T,D,D} +sizedarray_similar_type{T,S,D}(::Type{T},s::Size{S},::Type{Val{D}}) = SizedArray{Tuple{S...},T,D,D} # Field vectors are user controlled, and currently default to SVector, etc diff --git a/src/traits.jl b/src/traits.jl index 79712fa6..04ce6565 100644 --- a/src/traits.jl +++ b/src/traits.jl @@ -33,6 +33,7 @@ check_size(S) = error("Size was expected to be a tuple of `Int`s") @pure Size(s::Tuple{Vararg{Int}}) = Size{s}() @pure Size(s::Int...) = Size{s}() +@pure Size(s::Type{<:Tuple}) = Size{tuple(s.parameters...)}() Size(a::StaticArray) = Size(typeof(a)) diff --git a/test/SArray.jl b/test/SArray.jl index 35a7544b..f9b19bf5 100644 --- a/test/SArray.jl +++ b/test/SArray.jl @@ -1,61 +1,61 @@ @testset "SArray" begin @testset "Inner Constructors" begin - @test SArray{(1,),Int,1,1}((1,)).data === (1,) - @test SArray{(1,),Float64,1,1}((1,)).data === (1.0,) - @test SArray{(2,2),Float64,2,4}((1, 1.0, 1, 1)).data === (1.0, 1.0, 1.0, 1.0) + @test SArray{Tuple{1},Int,1,1}((1,)).data === (1,) + @test SArray{Tuple{1},Float64,1,1}((1,)).data === (1.0,) + @test SArray{Tuple{2,2},Float64,2,4}((1, 1.0, 1, 1)).data === (1.0, 1.0, 1.0, 1.0) # Bad input - @test_throws Exception SArray{(1,),Int,1,1}() - @test_throws Exception SArray{(2,),Int,1,2}((1,)) - @test_throws Exception SArray{(1,),Int,1,1}(()) + @test_throws Exception SArray{Tuple{1},Int,1,1}() + @test_throws Exception SArray{Tuple{2},Int,1,2}((1,)) + @test_throws Exception SArray{Tuple{1},Int,1,1}(()) # Bad parameters - @test_throws Exception SArray{(1,),Int,1,2}((1,)) - @test_throws Exception SArray{(1,),Int,2,1}((1,)) - @test_throws Exception SArray{(1,),1,1,1}((1,)) - @test_throws Exception SArray{(2,),Int,1,1}((1,)) + @test_throws Exception SArray{Tuple{1},Int,1,2}((1,)) + @test_throws Exception SArray{Tuple{1},Int,2,1}((1,)) + @test_throws Exception SArray{Tuple{1},1,1,1}((1,)) + @test_throws Exception SArray{Tuple{2},Int,1,1}((1,)) end @testset "Outer constructors and macro" begin - @test SArray{(1,),Int,1}((1,)).data === (1,) - @test SArray{(1,),Int}((1,)).data === (1,) - @test SArray{(1,)}((1,)).data === (1,) - - @test SArray{(2,2),Int,2}((1,2,3,4)).data === (1,2,3,4) - @test SArray{(2,2),Int}((1,2,3,4)).data === (1,2,3,4) - @test SArray{(2,2)}((1,2,3,4)).data === (1,2,3,4) - - @test ((@SArray [1])::SArray{(1,)}).data === (1,) - @test ((@SArray [1,2])::SArray{(2,)}).data === (1,2) - @test ((@SArray Float64[1,2,3])::SArray{(3,)}).data === (1.0, 2.0, 3.0) - @test ((@SArray [1 2])::SArray{(1,2)}).data === (1, 2) - @test ((@SArray Float64[1 2])::SArray{(1,2)}).data === (1.0, 2.0) - @test ((@SArray [1 ; 2])::SArray{(2,1)}).data === (1, 2) - @test ((@SArray Float64[1 ; 2])::SArray{(2,1)}).data === (1.0, 2.0) - @test ((@SArray [1 2 ; 3 4])::SArray{(2,2)}).data === (1, 3, 2, 4) - @test ((@SArray Float64[1 2 ; 3 4])::SArray{(2,2)}).data === (1.0, 3.0, 2.0, 4.0) - - @test ((@SArray [i*j*k for i = 1:2, j = 2:3, k = 3:4])::SArray{(2,2,2)}).data === (6, 12, 9, 18, 8, 16, 12, 24) - @test ((@SArray Float64[i*j*k for i = 1:2, j = 2:3, k =3:4])::SArray{(2,2,2)}).data === (6.0, 12.0, 9.0, 18.0, 8.0, 16.0, 12.0, 24.0) + @test SArray{Tuple{1},Int,1}((1,)).data === (1,) + @test SArray{Tuple{1},Int}((1,)).data === (1,) + @test SArray{Tuple{1}}((1,)).data === (1,) + + @test SArray{Tuple{2,2},Int,2}((1,2,3,4)).data === (1,2,3,4) + @test SArray{Tuple{2,2},Int}((1,2,3,4)).data === (1,2,3,4) + @test SArray{Tuple{2,2}}((1,2,3,4)).data === (1,2,3,4) + + @test ((@SArray [1])::SArray{Tuple{1}}).data === (1,) + @test ((@SArray [1,2])::SArray{Tuple{2}}).data === (1,2) + @test ((@SArray Float64[1,2,3])::SArray{Tuple{3}}).data === (1.0, 2.0, 3.0) + @test ((@SArray [1 2])::SArray{Tuple{1,2}}).data === (1, 2) + @test ((@SArray Float64[1 2])::SArray{Tuple{1,2}}).data === (1.0, 2.0) + @test ((@SArray [1 ; 2])::SArray{Tuple{2,1}}).data === (1, 2) + @test ((@SArray Float64[1 ; 2])::SArray{Tuple{2,1}}).data === (1.0, 2.0) + @test ((@SArray [1 2 ; 3 4])::SArray{Tuple{2,2}}).data === (1, 3, 2, 4) + @test ((@SArray Float64[1 2 ; 3 4])::SArray{Tuple{2,2}}).data === (1.0, 3.0, 2.0, 4.0) + + @test ((@SArray [i*j*k for i = 1:2, j = 2:3, k = 3:4])::SArray{Tuple{2,2,2}}).data === (6, 12, 9, 18, 8, 16, 12, 24) + @test ((@SArray Float64[i*j*k for i = 1:2, j = 2:3, k =3:4])::SArray{Tuple{2,2,2}}).data === (6.0, 12.0, 9.0, 18.0, 8.0, 16.0, 12.0, 24.0) @test (ex = macroexpand(:(@SArray [1 2; 3])); isa(ex, Expr) && ex.head == :error) - @test ((@SArray zeros(2,2,1))::SArray{(2,2,1), Float64}).data === (0.0, 0.0, 0.0, 0.0) - @test ((@SArray ones(2,2,1))::SArray{(2,2,1), Float64}).data === (1.0, 1.0, 1.0, 1.0) - @test ((@SArray eye(2))::SArray{(2,2), Float64}).data === (1.0, 0.0, 0.0, 1.0) - @test ((@SArray eye(2,2))::SArray{(2,2), Float64}).data === (1.0, 0.0, 0.0, 1.0) - @test isa(@SArray(rand(2,2,1)), SArray{(2,2,1), Float64}) - @test isa(@SArray(randn(2,2,1)), SArray{(2,2,1), Float64}) + @test ((@SArray zeros(2,2,1))::SArray{Tuple{2,2,1}, Float64}).data === (0.0, 0.0, 0.0, 0.0) + @test ((@SArray ones(2,2,1))::SArray{Tuple{2,2,1}, Float64}).data === (1.0, 1.0, 1.0, 1.0) + @test ((@SArray eye(2))::SArray{Tuple{2,2}, Float64}).data === (1.0, 0.0, 0.0, 1.0) + @test ((@SArray eye(2,2))::SArray{Tuple{2,2}, Float64}).data === (1.0, 0.0, 0.0, 1.0) + @test isa(@SArray(rand(2,2,1)), SArray{Tuple{2,2,1}, Float64}) + @test isa(@SArray(randn(2,2,1)), SArray{Tuple{2,2,1}, Float64}) - @test ((@SArray zeros(Float32, 2, 2, 1))::SArray{(2,2,1),Float32}).data === (0.0f0, 0.0f0, 0.0f0, 0.0f0) - @test ((@SArray ones(Float32, 2, 2, 1))::SArray{(2,2,1),Float32}).data === (1.0f0, 1.0f0, 1.0f0, 1.0f0) - @test ((@SArray eye(Float32, 2))::SArray{(2,2), Float32}).data === (1.0f0, 0.0f0, 0.0f0, 1.0f0) - @test ((@SArray eye(Float32, 2, 2))::SArray{(2,2), Float32}).data === (1.0f0, 0.0f0, 0.0f0, 1.0f0) - @test isa(@SArray(rand(Float32, 2, 2, 1)), SArray{(2,2,1), Float32}) - @test isa(@SArray(randn(Float32, 2, 2, 1)), SArray{(2,2,1), Float32}) + @test ((@SArray zeros(Float32, 2, 2, 1))::SArray{Tuple{2,2,1},Float32}).data === (0.0f0, 0.0f0, 0.0f0, 0.0f0) + @test ((@SArray ones(Float32, 2, 2, 1))::SArray{Tuple{2,2,1},Float32}).data === (1.0f0, 1.0f0, 1.0f0, 1.0f0) + @test ((@SArray eye(Float32, 2))::SArray{Tuple{2,2}, Float32}).data === (1.0f0, 0.0f0, 0.0f0, 1.0f0) + @test ((@SArray eye(Float32, 2, 2))::SArray{Tuple{2,2}, Float32}).data === (1.0f0, 0.0f0, 0.0f0, 1.0f0) + @test isa(@SArray(rand(Float32, 2, 2, 1)), SArray{Tuple{2,2,1}, Float32}) + @test isa(@SArray(randn(Float32, 2, 2, 1)), SArray{Tuple{2,2,1}, Float32}) m = [1 2; 3 4] - @test SArray{(2,2)}(m) === @SArray [1 2; 3 4] + @test SArray{Tuple{2,2}}(m) === @SArray [1 2; 3 4] # Non-square comprehensions built from SVectors - see #76 @test @SArray([1 for x = SVector(1,2), y = SVector(1,2,3)]) == ones(2,3) @@ -75,9 +75,9 @@ @test size(m) === (2, 2) @test size(typeof(m)) === (2, 2) - @test size(SArray{(2,2),Int,2}) === (2, 2) - @test size(SArray{(2,2),Int}) === (2, 2) - @test size(SArray{(2,2)}) === (2, 2) + @test size(SArray{Tuple{2,2},Int,2}) === (2, 2) + @test size(SArray{Tuple{2,2},Int}) === (2, 2) + @test size(SArray{Tuple{2,2}}) === (2, 2) @test size(m, 1) === 2 @test size(m, 2) === 2 diff --git a/test/abstractarray.jl b/test/abstractarray.jl index c77447fd..48cfb1df 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -20,9 +20,9 @@ @test @inferred(similar_type(SVector{2,Int}, Size(3,3))) == SMatrix{3, 3, Int, 9} @test @inferred(similar_type(SVector{2,Int}, Float64, Size(3,3))) == SMatrix{3, 3, Float64, 9} - @test @inferred(similar_type(SArray{(4,4,4),Int,3,64}, Float64)) == SArray{(4,4,4), Float64, 3, 64} - @test @inferred(similar_type(SVector{2,Int}, Size(3,3,3))) == SArray{(3,3,3), Int, 3, 27} - @test @inferred(similar_type(SVector{2,Int}, Float64, Size(3,3,3))) == SArray{(3,3,3), Float64, 3, 27} + @test @inferred(similar_type(SArray{Tuple{4,4,4},Int,3,64}, Float64)) == SArray{Tuple{4,4,4}, Float64, 3, 64} + @test @inferred(similar_type(SVector{2,Int}, Size(3,3,3))) == SArray{Tuple{3,3,3}, Int, 3, 27} + @test @inferred(similar_type(SVector{2,Int}, Float64, Size(3,3,3))) == SArray{Tuple{3,3,3}, Float64, 3, 27} # Some specializations for the mutable case @test @inferred(similar_type(MVector{3,Int}, Float64)) == SVector{3,Float64} @@ -34,15 +34,15 @@ @test @inferred(similar_type(MVector{2,Int}, Size(3,3))) == SMatrix{3, 3, Int, 9} @test @inferred(similar_type(MVector{2,Int}, Float64, Size(3,3))) == SMatrix{3, 3, Float64, 9} - @test @inferred(similar_type(MArray{(4,4,4),Int,3,64}, Float64)) == SArray{(4,4,4), Float64, 3, 64} - @test @inferred(similar_type(MVector{2,Int}, Size(3,3,3))) == SArray{(3,3,3), Int, 3, 27} - @test @inferred(similar_type(MVector{2,Int}, Float64, Size(3,3,3))) == SArray{(3,3,3), Float64, 3, 27} + @test @inferred(similar_type(MArray{(4,4,4),Int,3,64}, Float64)) == SArray{Tuple{4,4,4}, Float64, 3, 64} + @test @inferred(similar_type(MVector{2,Int}, Size(3,3,3))) == SArray{Tuple{3,3,3}, Int, 3, 27} + @test @inferred(similar_type(MVector{2,Int}, Float64, Size(3,3,3))) == SArray{Tuple{3,3,3}, Float64, 3, 27} end @testset "similar" begin sv = @SVector [1,2,3] sm = @SMatrix [1 2; 3 4] - sa = SArray{(1,1,1),Int,3,1}((1,)) + sa = SArray{Tuple{1,1,1},Int,3,1}((1,)) @test isa(@inferred(similar(sv)), MVector{3,Int}) @test isa(@inferred(similar(sv, Float64)), MVector{3,Float64}) diff --git a/test/arraymath.jl b/test/arraymath.jl index d28b1cff..5aa27858 100644 --- a/test/arraymath.jl +++ b/test/arraymath.jl @@ -39,14 +39,14 @@ @test @inferred(zeros(SVector{3})) === @SVector [0.0, 0.0, 0.0] @test @inferred(zeros(SMatrix{2,2})) === @SMatrix [0.0 0.0; 0.0 0.0] - @test @inferred(zeros(SArray{(1,1,1)})) === SArray{(1,1,1)}((0.0,)) + @test @inferred(zeros(SArray{Tuple{1,1,1}})) === SArray{Tuple{1,1,1}}((0.0,)) @test @inferred(zeros(MVector{3}))::MVector == @MVector [0.0, 0.0, 0.0] @test @inferred(zeros(MMatrix{2,2}))::MMatrix == @MMatrix [0.0 0.0; 0.0 0.0] @test @inferred(zeros(MArray{(1,1,1)}))::MArray == MArray{(1,1,1)}((0.0,)) @test @inferred(ones(SVector{3})) === @SVector [1.0, 1.0, 1.0] @test @inferred(ones(SMatrix{2,2})) === @SMatrix [1.0 1.0; 1.0 1.0] - @test @inferred(ones(SArray{(1,1,1)})) === SArray{(1,1,1)}((1.0,)) + @test @inferred(ones(SArray{Tuple{1,1,1}})) === SArray{Tuple{1,1,1}}((1.0,)) @test @inferred(ones(MVector{3}))::MVector == @MVector [1.0, 1.0, 1.0] @test @inferred(ones(MMatrix{2,2}))::MMatrix == @MMatrix [1.0 1.0; 1.0 1.0] @test @inferred(ones(MArray{(1,1,1)}))::MArray == MArray{(1,1,1)}((1.0,)) diff --git a/test/indexing.jl b/test/indexing.jl index 6cb36384..23ff5197 100644 --- a/test/indexing.jl +++ b/test/indexing.jl @@ -66,7 +66,7 @@ end @testset "3D scalar indexing" begin - sa = SArray{(2,2,2), Int}([i*j*k for i = 1:2, j = 2:3, k=3:4]) + sa = SArray{Tuple{2,2,2}, Int}([i*j*k for i = 1:2, j = 2:3, k=3:4]) @test sa[1,1,2] === 8 @test sa[1,2,1] === 9 @@ -79,7 +79,7 @@ end @testset "4D scalar indexing" begin - sa = SArray{(2,2,2,2), Int}([i*j*k*l for i = 1:2, j = 2:3, k=3:4, l=4:5]) + sa = SArray{Tuple{2,2,2,2}, Int}([i*j*k*l for i = 1:2, j = 2:3, k=3:4, l=4:5]) @test sa[1,1,1,2] === 30 @test sa[1,1,2,1] === 32 From 594150d66e09e33a273cd83c6b719065e0e5e4ea Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sat, 1 Apr 2017 00:39:44 +0000 Subject: [PATCH 2/2] Bring Scalar/MArray into the fold --- src/MArray.jl | 72 +++++++++++++------------------ src/MMatrix.jl | 35 +-------------- src/MVector.jl | 20 +-------- src/SArray.jl | 42 +----------------- src/Scalar.jl | 19 ++++---- src/StaticArrays.jl | 4 +- src/abstractarray.jl | 2 +- src/util.jl | 32 ++++++++++++++ test/MArray.jl | 96 ++++++++++++++++++++--------------------- test/abstractarray.jl | 10 ++--- test/arraymath.jl | 4 +- test/indexing.jl | 4 +- test/matrix_multiply.jl | 4 +- 13 files changed, 136 insertions(+), 208 deletions(-) diff --git a/src/MArray.jl b/src/MArray.jl index 8f223982..1383fe38 100644 --- a/src/MArray.jl +++ b/src/MArray.jl @@ -20,75 +20,63 @@ type MArray{Size, T, N, L} <: StaticArray{T, N} data::NTuple{L,T} function (::Type{MArray{Size,T,N,L}}){Size,T,N,L}(x::NTuple{L,T}) - check_marray_parameters(Val{Size}, T, Val{N}, Val{L}) + check_array_parameters(Size, T, Val{N}, Val{L}) new{Size,T,N,L}(x) end function (::Type{MArray{Size,T,N,L}}){Size,T,N,L}(x::NTuple{L,Any}) - check_marray_parameters(Val{Size}, T, Val{N}, Val{L}) + check_array_parameters(Size, T, Val{N}, Val{L}) new{Size,T,N,L}(convert_ntuple(T, x)) end function (::Type{MArray{Size,T,N,L}}){Size,T,N,L}() - check_marray_parameters(Val{Size}, T, Val{N}, Val{L}) + check_array_parameters(Size, T, Val{N}, Val{L}) new{Size,T,N,L}() end end -@generated function check_marray_parameters{Size,T,N,L}(::Type{Val{Size}}, ::Type{T}, ::Type{Val{N}}, ::Type{Val{L}}) - if !(isa(Size, Tuple{Vararg{Int}})) - error("MArray parameter Size must be a tuple of Ints (e.g. `MArray{(3,3)}`)") - end - - if L != prod(Size) || L < 0 || minimum(Size) < 0 || length(Size) != N - error("Size mismatch in MArray parameters. Got size $Size, dimension $N and length $L.") - end - - return nothing -end - @generated function (::Type{MArray{Size,T,N}}){Size,T,N}(x::Tuple) return quote $(Expr(:meta, :inline)) - MArray{Size,T,N,$(prod(Size))}(x) + MArray{Size,T,N,$(tuple_prod(Size))}(x) end end @generated function (::Type{MArray{Size,T}}){Size,T}(x::Tuple) return quote $(Expr(:meta, :inline)) - MArray{Size,T,$(length(Size)),$(prod(Size))}(x) + MArray{Size,T,$(tuple_length(Size)),$(tuple_prod(Size))}(x) end end @generated function (::Type{MArray{Size}}){Size, T <: Tuple}(x::T) return quote $(Expr(:meta, :inline)) - MArray{Size,$(promote_tuple_eltype(T)),$(length(Size)),$(prod(Size))}(x) + MArray{Size,$(promote_tuple_eltype(T)),$(tuple_length(Size)),$(tuple_prod(Size))}(x) end end @generated function (::Type{MArray{Size,T,N}}){Size,T,N}() return quote $(Expr(:meta, :inline)) - MArray{Size, T, N, $(prod(Size))}() + MArray{Size, T, N, $(tuple_prod(Size))}() end end @generated function (::Type{MArray{Size,T}}){Size,T}() return quote $(Expr(:meta, :inline)) - MArray{Size, T, $(length(Size)), $(prod(Size))}() + MArray{Size, T, $(tuple_length(Size)), $(tuple_prod(Size))}() end end -@inline MArray(a::StaticArray) = MArray{size(typeof(a))}(Tuple(a)) +@inline MArray(a::StaticArray) = MArray{size_tuple(typeof(a))}(Tuple(a)) # Some more advanced constructor-like functions -@inline one(::Type{MArray{S}}) where {S} = one(MArray{S,Float64,length(S)}) -@inline eye(::Type{MArray{S}}) where {S} = eye(MArray{S,Float64,length(S)}) -@inline one(::Type{MArray{S,T}}) where {S,T} = one(MArray{S,T,length(S)}) -@inline eye(::Type{MArray{S,T}}) where {S,T} = eye(MArray{S,T,length(S)}) +@inline one(::Type{MArray{S}}) where {S} = one(MArray{S,Float64,tuple_length(S)}) +@inline eye(::Type{MArray{S}}) where {S} = eye(MArray{S,Float64,tuple_length(S)}) +@inline one(::Type{MArray{S,T}}) where {S,T} = one(MArray{S,T,tuple_length(S)}) +@inline eye(::Type{MArray{S,T}}) where {S,T} = eye(MArray{S,T,tuple_length(S)}) #################### ## MArray methods ## @@ -133,17 +121,17 @@ macro MArray(ex) end if ex.head == :vect # vector - return esc(Expr(:call, MArray{(length(ex.args),)}, Expr(:tuple, ex.args...))) + return esc(Expr(:call, MArray{Tuple{length(ex.args)}}, Expr(:tuple, ex.args...))) elseif ex.head == :ref # typed, vector - return esc(Expr(:call, Expr(:curly, :MArray, ((length(ex.args)-1),), ex.args[1]), Expr(:tuple, ex.args[2:end]...))) + return esc(Expr(:call, Expr(:curly, :MArray, Tuple{length(ex.args)-1}, ex.args[1]), Expr(:tuple, ex.args[2:end]...))) elseif ex.head == :hcat # 1 x n s1 = 1 s2 = length(ex.args) - return esc(Expr(:call, MArray{(s1, s2)}, Expr(:tuple, ex.args...))) + return esc(Expr(:call, MArray{Tuple{s1, s2}}, Expr(:tuple, ex.args...))) elseif ex.head == :typed_hcat # typed, 1 x n s1 = 1 s2 = length(ex.args) - 1 - return esc(Expr(:call, Expr(:curly, :MArray, (s1, s2), ex.args[1]), Expr(:tuple, ex.args[2:end]...))) + return esc(Expr(:call, Expr(:curly, :MArray, Tuple{s1, s2}, ex.args[1]), Expr(:tuple, ex.args[2:end]...))) elseif ex.head == :vcat if isa(ex.args[1], Expr) && ex.args[1].head == :row # n x m # Validate @@ -155,9 +143,9 @@ macro MArray(ex) end exprs = [ex.args[i].args[j] for i = 1:s1, j = 1:s2] - return esc(Expr(:call, MArray{(s1, s2)}, Expr(:tuple, exprs...))) + return esc(Expr(:call, MArray{Tuple{s1, s2}}, Expr(:tuple, exprs...))) else # n x 1 - return esc(Expr(:call, MArray{(length(ex.args), 1)}, Expr(:tuple, ex.args...))) + return esc(Expr(:call, MArray{Tuple{length(ex.args), 1}}, Expr(:tuple, ex.args...))) end elseif ex.head == :typed_vcat if isa(ex.args[2], Expr) && ex.args[2].head == :row # typed, n x m @@ -170,9 +158,9 @@ macro MArray(ex) end exprs = [ex.args[i+1].args[j] for i = 1:s1, j = 1:s2] - return esc(Expr(:call, Expr(:curly, :MArray, (s1, s2), ex.args[1]), Expr(:tuple, exprs...))) + return esc(Expr(:call, Expr(:curly, :MArray, Tuple{s1, s2}, ex.args[1]), Expr(:tuple, exprs...))) else # typed, n x 1 - return esc(Expr(:call, Expr(:curly, :MArray, (length(ex.args)-1, 1), ex.args[1]), Expr(:tuple, ex.args[2:end]...))) + return esc(Expr(:call, Expr(:curly, :MArray, Tuple{length(ex.args)-1, 1}, ex.args[1]), Expr(:tuple, ex.args[2:end]...))) end elseif isa(ex, Expr) && ex.head == :comprehension if length(ex.args) != 1 || !isa(ex.args[1], Expr) || ex.args[1].head != :generator @@ -210,7 +198,7 @@ macro MArray(ex) return quote $(esc(f_expr)) - $(esc(Expr(:call, Expr(:curly, :MArray, (rng_lengths...)), Expr(:tuple, exprs...)))) + $(esc(Expr(:call, Expr(:curly, :MArray, Tuple{rng_lengths...}), Expr(:tuple, exprs...)))) end elseif isa(ex, Expr) && ex.head == :typed_comprehension if length(ex.args) != 2 || !isa(ex.args[2], Expr) || ex.args[2].head != :generator @@ -249,7 +237,7 @@ macro MArray(ex) return quote $(esc(f_expr)) - $(esc(Expr(:call, Expr(:curly, :MArray, (rng_lengths...), T), Expr(:tuple, exprs...)))) + $(esc(Expr(:call, Expr(:curly, :MArray, Tuple{rng_lengths...}, T), Expr(:tuple, exprs...)))) end elseif isa(ex, Expr) && ex.head == :call if ex.args[1] == :zeros || ex.args[1] == :ones || ex.args[1] == :rand || ex.args[1] == :randn @@ -258,9 +246,9 @@ macro MArray(ex) else return quote if isa($(esc(ex.args[2])), DataType) - $(ex.args[1])($(esc(Expr(:curly, MArray, Expr(:tuple, ex.args[3:end]...), ex.args[2])))) + $(ex.args[1])($(esc(Expr(:curly, MArray, Expr(:curly, Tuple, ex.args[3:end]...), ex.args[2])))) else - $(ex.args[1])($(esc(Expr(:curly, MArray, Expr(:tuple, ex.args[2:end]...))))) + $(ex.args[1])($(esc(Expr(:curly, MArray, Expr(:curly, Tuple, ex.args[2:end]...))))) end end end @@ -271,26 +259,26 @@ macro MArray(ex) error("@MArray got bad expression: $(ex.args[1])($(ex.args[2]))") else return quote - $(esc(ex.args[1]))($(esc(ex.args[2])), MArray{$(esc(Expr(:tuple, ex.args[3:end]...)))}) + $(esc(ex.args[1]))($(esc(ex.args[2])), MArray{$(esc(Expr(:curly, Tuple, ex.args[3:end]...)))}) end end elseif ex.args[1] == :eye if length(ex.args) == 2 return quote - eye(MArray{($(esc(ex.args[2])), $(esc(ex.args[2])))}) + eye(MArray{Tuple{$(esc(ex.args[2])), $(esc(ex.args[2]))}}) end elseif length(ex.args) == 3 # We need a branch, depending if the first argument is a type or a size. return quote if isa($(esc(ex.args[2])), DataType) - eye(MArray{($(esc(ex.args[3])), $(esc(ex.args[3]))), $(esc(ex.args[2]))}) + eye(MArray{Tuple{$(esc(ex.args[3])), $(esc(ex.args[3]))}, $(esc(ex.args[2]))}) else - eye(MArray{($(esc(ex.args[2])), $(esc(ex.args[3])))}) + eye(MArray{Tuple{$(esc(ex.args[2])), $(esc(ex.args[3]))}}) end end elseif length(ex.args) == 4 return quote - eye(MArray{($(esc(ex.args[3])), $(esc(ex.args[4]))), $(esc(ex.args[2]))}) + eye(MArray{Tuple{$(esc(ex.args[3])), $(esc(ex.args[4]))}, $(esc(ex.args[2]))}) end else error("Bad eye() expression for @MArray") diff --git a/src/MMatrix.jl b/src/MMatrix.jl index 0125bc53..6570c0b3 100644 --- a/src/MMatrix.jl +++ b/src/MMatrix.jl @@ -15,40 +15,7 @@ Construct a statically-sized, mutable matrix of dimensions `S1 × S2` using the `mat`. The parameters `S1` and `S2` are mandatory since the size of `mat` is unknown to the compiler (the element type may optionally also be specified). """ -type MMatrix{S1, S2, T, L} <: StaticMatrix{T} - data::NTuple{L, T} - - function (::Type{MMatrix{S1,S2,T,L}}){S1,S2,T,L}(d::NTuple{L,T}) - check_MMatrix_params(Val{S1}, Val{S2}, T, Val{L}) - new{S1,S2,T,L}(d) - end - - function (::Type{MMatrix{S1,S2,T,L}}){S1,S2,T,L}(d::NTuple{L,Any}) - check_MMatrix_params(Val{S1}, Val{S2}, T, Val{L}) - new{S1,S2,T,L}(convert_ntuple(T, d)) - end - - function (::Type{MMatrix{S1,S2,T,L}}){S1,S2,T,L}() - check_MMatrix_params(Val{S1}, Val{S2}, T, Val{L}) - new{S1,S2,T,L}() - end -end - -function check_MMatrix_params(::Type{Val{S1}}, ::Type{Val{S2}}, T, ::Type{Val{L}}) where {S1,S2,L} - throw(ArgumentError("MMatrix: Parameter T must be a Type. Got $T")) -end - -@generated function check_MMatrix_params(::Type{Val{S1}}, ::Type{Val{S2}}, ::Type{T}, ::Type{Val{L}}) where {S1,S2,L,T} - if !isa(S1, Int) || !isa(S2, Int) || !isa(L, Int) || S1 < 0 || S2 < 0 || L < 0 - throw(ArgumentError("MMatrix: Sizes must be positive integers. Got $S1 × $S2 ($L elements)")) - end - - if S1*S2 == L - return nothing - else - throw(ArgumentError("Size mismatch in MMatrix. S1 = $S1, S2 = $S2, but recieved $L elements")) - end -end +const MMatrix{S1, S2, T, L} = MArray{Tuple{S1, S2}, T, 2, L} @generated function (::Type{MMatrix{S1}}){S1,L}(x::NTuple{L}) S2 = div(L, S1) diff --git a/src/MVector.jl b/src/MVector.jl index 704e9f3e..402840a1 100644 --- a/src/MVector.jl +++ b/src/MVector.jl @@ -14,25 +14,7 @@ Construct a statically-sized, mutable vector of length `S` using the data from `vec`. The parameter `S` is mandatory since the length of `vec` is unknown to the compiler (the element type may optionally also be specified). """ -type MVector{S, T} <: StaticVector{T} - data::NTuple{S, T} - - function (::Type{MVector{S,T}}){S,T}(in::NTuple{S, T}) - new{S,T}(in) - end - - function (::Type{MVector{S,T}}){S,T}(in::NTuple{S, Any}) - new{S,T}(convert_ntuple(T,in)) - end - - function (::Type{MVector{S,T}}){S,T}(in::T) - new{S,T}((in,)) - end - - function (::Type{MVector{S,T}}){S,T}() - new{S,T}() - end -end +const MVector{S, T} = MArray{Tuple{S}, T, 1, S} @inline (::Type{MVector}){S}(x::NTuple{S,Any}) = MVector{S}(x) @inline (::Type{MVector{S}}){S, T}(x::NTuple{S,T}) = MVector{S,T}(x) diff --git a/src/SArray.jl b/src/SArray.jl index 661b1bd5..f90ab93d 100644 --- a/src/SArray.jl +++ b/src/SArray.jl @@ -19,42 +19,16 @@ immutable SArray{Size, T, N, L} <: StaticArray{T, N} data::NTuple{L,T} function (::Type{SArray{Size,T,N,L}}){Size,T,N,L}(x::NTuple{L,T}) - check_sarray_parameters(Size, T, Val{N}, Val{L}) + check_array_parameters(Size, T, Val{N}, Val{L}) new{Size,T,N,L}(x) end function (::Type{SArray{Size,T,N,L}}){Size,T,N,L}(x::NTuple{L,Any}) - check_sarray_parameters(Size, T, Val{N}, Val{L}) + check_array_parameters(Size, T, Val{N}, Val{L}) new{Size,T,N,L}(convert_ntuple(T, x)) end end -@pure tuple_length(T) = length(T.parameters) -@pure tuple_prod(T) = *(T.parameters...) -@pure tuple_minimum(T) = minimum(tuple(T.parameters...)) - -# Something doesn't match up type wise -function check_sarray_parameters(Size, T, N, L) - (!isa(Size, DataType) || (Size.name !== Tuple.name)) && throw(ArgumentError("SArray parameter Size must be a Tuple type, got $Size")) - !isa(T, Type) && throw(ArgumentError("SArray parameter T must be a type, got $T")) - !isa(N.parameters[1], Int) && throw(ArgumenError("SArray parameter N must be an integer, got $(N.parameters[1])")) - !isa(L.parameters[1], Int) && throw(ArgumentError("SArray parameter L must be an integer, got $(L.parameters[1])")) - # shouldn't reach here. Anything else should have made it to the function below - error("Internal error. Please file a bug") -end - -@generated function check_sarray_parameters{Size,T,N,L}(::Type{Size}, ::Type{T}, ::Type{Val{N}}, ::Type{Val{L}}) - if !all(x->isa(x, Int), Size.parameters) - throw(ArgumentError("SArray parameter Size must be a tuple of Ints (e.g. `SArray{Tuple{3,3}}` or `SMatrix{3,3}`).")) - end - - if L != tuple_prod(Size) || L < 0 || tuple_minimum(Size) < 0 || tuple_length(Size) != N - throw(ArgumentError("Size mismatch in SArray parameters. Got size $Size, dimension $N and length $L.")) - end - - return nothing -end - @generated function (::Type{SArray{Size,T,N}}){Size <: Tuple,T,N}(x::Tuple) return quote $(Expr(:meta, :inline)) @@ -69,18 +43,6 @@ end end end -function SArray{Size,T,N}(x::Tuple) where {Size, T, N} - Base.depwarn("SArray{(dim1,dim2,...),...} is deprecated, use SArray{Tuple{dim1, dim2, ...}, ...}", :SArray) - SArray{Tuple{Size...},T,N}(x) -end -function SArray{Size,T}(x::Tuple) where {Size, T} - Base.depwarn("SArray{(dim1,dim2,...),...} is deprecated, use SArray{Tuple{dim1, dim2, ...}, ...}", :SArray) - SArray{Tuple{Size...},T}(x) -end -function SArray{Size}(x::Tuple) where {Size} - Base.depwarn("SArray{(dim1,dim2,...),...} is deprecated, use SArray{Tuple{dim1, dim2, ...}, ...}", :SArray) - SArray{Tuple{Size...}}(x) -end @generated function (::Type{SArray{Size}}){Size <: Tuple, T <: Tuple}(x::T) return quote $(Expr(:meta, :inline)) diff --git a/src/Scalar.jl b/src/Scalar.jl index 6a5a0a9c..5c483fff 100644 --- a/src/Scalar.jl +++ b/src/Scalar.jl @@ -4,27 +4,24 @@ Construct a statically-sized 0-dimensional array that contains a single element, `x`. This type is particularly useful for influencing broadcasting operations. """ -immutable Scalar{T} <: StaticArray{T,0} - data::T - - Scalar{T}(x::AbstractArray) where {T} = new{T}(convert(T,x)) - Scalar{T}(x::Tuple{T2}) where {T, T2} = new{T}(convert(T,x[1])) - Scalar{T}(x) where {T} = new{T}(convert(T, x)) -end +const Scalar{T} = SArray{Tuple{},T,0,1} @inline Scalar(x::Tuple{T}) where {T} = Scalar{T}(x[1]) -@inline Scalar(a::AbstractArray) = Scalar{typeof(a)}(a) -@inline Scalar(a::AbstractScalar) = Scalar{eltype(a)}(a[]) # Do we want this to convert or wrap? +@inline Scalar(a::AbstractArray) = Scalar{typeof(a)}((a,)) +@inline Scalar(a::AbstractScalar) = Scalar{eltype(a)}((a[],)) # Do we want this to convert or wrap? +@inline function convert(::Type{SA}, a::AbstractArray) where {SA <: Scalar} + return SA((a,)) +end @pure Size(::Type{Scalar}) = Size() @pure Size{T}(::Type{Scalar{T}}) = Size() -getindex(v::Scalar) = v.data +getindex(v::Scalar) = v.data[1] @inline function getindex(v::Scalar, i::Int) @boundscheck if i != 1 error("Attempt to index Scalar at index $i") end - v.data + v.data[1] end @inline Tuple(v::Scalar) = (v.data,) diff --git a/src/StaticArrays.jl b/src/StaticArrays.jl index 59029cdf..407a6a4d 100644 --- a/src/StaticArrays.jl +++ b/src/StaticArrays.jl @@ -69,14 +69,14 @@ include("traits.jl") include("convert.jl") include("SUnitRange.jl") -include("Scalar.jl") include("FieldVector.jl") include("SArray.jl") include("SMatrix.jl") include("SVector.jl") +include("MArray.jl") include("MVector.jl") +include("Scalar.jl") include("MMatrix.jl") -include("MArray.jl") include("SizedArray.jl") include("abstractarray.jl") diff --git a/src/abstractarray.jl b/src/abstractarray.jl index f4dc134a..575a0c06 100644 --- a/src/abstractarray.jl +++ b/src/abstractarray.jl @@ -65,7 +65,7 @@ default_similar_type{T,S,D}(::Type{T}, s::Size{S}, ::Type{Val{D}}) = SArray{Tupl mutable_similar_type{T,S}(::Type{T}, s::Size{S}, ::Type{Val{0}}) = SizedArray{(),T,0,0} mutable_similar_type{T,S}(::Type{T}, s::Size{S}, ::Type{Val{1}}) = MVector{S[1],T} mutable_similar_type{T,S}(::Type{T}, s::Size{S}, ::Type{Val{2}}) = MMatrix{S[1],S[2],T,prod(s)} -mutable_similar_type{T,S,D}(::Type{T}, s::Size{S}, ::Type{Val{D}}) = MArray{S,T,D,prod(s)} +mutable_similar_type{T,S,D}(::Type{T}, s::Size{S}, ::Type{Val{D}}) = MArray{Tuple{S...},T,D,prod(s)} # Should `SizedArray` stay the same, and also take over an `Array`? #similar_type{SA<:SizedArray,T,S}(::Type{SA},::Type{T},s::Size{S}) = sizedarray_similar_type(T,s,length_val(s)) diff --git a/src/util.jl b/src/util.jl index c2cbccda..a472e256 100644 --- a/src/util.jl +++ b/src/util.jl @@ -27,3 +27,35 @@ end $t end end + +# The ::Tuple variants exist to make sure that anything that calls with a tuple +# instead of a Tuple gets through to the constructor, so the user gets a nice +# error message +@pure tuple_length(T::Type{<:Tuple}) = length(T.parameters) +@pure tuple_length(T::Tuple) = length(T) +@pure tuple_prod(T::Type{<:Tuple}) = length(T.parameters) == 0 ? 1 : *(T.parameters...) +@pure tuple_prod(T::Tuple) = prod(T) +@pure tuple_minimum(T::Type{<:Tuple}) = length(T.parameters) == 0 ? 0 : minimum(tuple(T.parameters...)) +@pure tuple_minimum(T::Tuple) = minimum(T) + +# Something doesn't match up type wise +function check_array_parameters(Size, T, N, L) + (!isa(Size, DataType) || (Size.name !== Tuple.name)) && throw(ArgumentError("Static Array parameter Size must be a Tuple type, got $Size")) + !isa(T, Type) && throw(ArgumentError("Static Array parameter T must be a type, got $T")) + !isa(N.parameters[1], Int) && throw(ArgumenError("Static Array parameter N must be an integer, got $(N.parameters[1])")) + !isa(L.parameters[1], Int) && throw(ArgumentError("Static Array parameter L must be an integer, got $(L.parameters[1])")) + # shouldn't reach here. Anything else should have made it to the function below + error("Internal error. Please file a bug") +end + +@generated function check_array_parameters{Size,T,N,L}(::Type{Size}, ::Type{T}, ::Type{Val{N}}, ::Type{Val{L}}) + if !all(x->isa(x, Int), Size.parameters) + throw(ArgumentError("Static Array parameter Size must be a tuple of Ints (e.g. `SArray{Tuple{3,3}}` or `SMatrix{3,3}`).")) + end + + if L != tuple_prod(Size) || L < 0 || tuple_minimum(Size) < 0 || tuple_length(Size) != N + throw(ArgumentError("Size mismatch in Static Array parameters. Got size $Size, dimension $N and length $L.")) + end + + return nothing +end diff --git a/test/MArray.jl b/test/MArray.jl index a888b626..f4f8a815 100644 --- a/test/MArray.jl +++ b/test/MArray.jl @@ -1,63 +1,63 @@ @testset "MArray" begin @testset "Inner Constructors" begin - @test MArray{(1,),Int,1,1}((1,)).data === (1,) - @test MArray{(1,),Float64,1,1}((1,)).data === (1.0,) - @test MArray{(2,2),Float64,2,4}((1, 1.0, 1, 1)).data === (1.0, 1.0, 1.0, 1.0) - @test isa(MArray{(1,),Int,1,1}(), MArray{(1,),Int,1,1}) - @test isa(MArray{(1,),Int,1}(), MArray{(1,),Int,1,1}) - @test isa(MArray{(1,),Int}(), MArray{(1,),Int,1,1}) + @test MArray{Tuple{1},Int,1,1}((1,)).data === (1,) + @test MArray{Tuple{1},Float64,1,1}((1,)).data === (1.0,) + @test MArray{Tuple{2,2},Float64,2,4}((1, 1.0, 1, 1)).data === (1.0, 1.0, 1.0, 1.0) + @test isa(MArray{Tuple{1},Int,1,1}(), MArray{Tuple{1},Int,1,1}) + @test isa(MArray{Tuple{1},Int,1}(), MArray{Tuple{1},Int,1,1}) + @test isa(MArray{Tuple{1},Int}(), MArray{Tuple{1},Int,1,1}) # Bad input - @test_throws Exception MArray{(2,),Int,1,2}((1,)) - @test_throws Exception MArray{(1,),Int,1,1}(()) + @test_throws Exception MArray{Tuple{2},Int,1,2}((1,)) + @test_throws Exception MArray{Tuple{1},Int,1,1}(()) # Bad parameters - @test_throws Exception MArray{(1,),Int,1,2}((1,)) - @test_throws Exception MArray{(1,),Int,2,1}((1,)) - @test_throws Exception MArray{(1,),1,1,1}((1,)) - @test_throws Exception MArray{(2,),Int,1,1}((1,)) + @test_throws Exception MArray{Tuple{1},Int,1,2}((1,)) + @test_throws Exception MArray{Tuple{1},Int,2,1}((1,)) + @test_throws Exception MArray{Tuple{1},1,1,1}((1,)) + @test_throws Exception MArray{Tuple{2},Int,1,1}((1,)) end @testset "Outer constructors and macro" begin - @test MArray{(1,),Int,1}((1,)).data === (1,) - @test MArray{(1,),Int}((1,)).data === (1,) - @test MArray{(1,)}((1,)).data === (1,) - - @test MArray{(2,2),Int,2}((1,2,3,4)).data === (1,2,3,4) - @test MArray{(2,2),Int}((1,2,3,4)).data === (1,2,3,4) - @test MArray{(2,2)}((1,2,3,4)).data === (1,2,3,4) - - @test ((@MArray [1])::MArray{(1,)}).data === (1,) - @test ((@MArray [1,2])::MArray{(2,)}).data === (1,2) - @test ((@MArray Float64[1,2,3])::MArray{(3,)}).data === (1.0, 2.0, 3.0) - @test ((@MArray [1 2])::MArray{(1,2)}).data === (1, 2) - @test ((@MArray Float64[1 2])::MArray{(1,2)}).data === (1.0, 2.0) - @test ((@MArray [1 ; 2])::MArray{(2,1)}).data === (1, 2) - @test ((@MArray Float64[1 ; 2])::MArray{(2,1)}).data === (1.0, 2.0) - @test ((@MArray [1 2 ; 3 4])::MArray{(2,2)}).data === (1, 3, 2, 4) - @test ((@MArray Float64[1 2 ; 3 4])::MArray{(2,2)}).data === (1.0, 3.0, 2.0, 4.0) - - @test ((@MArray [i*j*k for i = 1:2, j = 2:3, k = 3:4])::MArray{(2,2,2)}).data === (6, 12, 9, 18, 8, 16, 12, 24) - @test ((@MArray Float64[i*j*k for i = 1:2, j = 2:3, k =3:4])::MArray{(2,2,2)}).data === (6.0, 12.0, 9.0, 18.0, 8.0, 16.0, 12.0, 24.0) + @test MArray{Tuple{1},Int,1}((1,)).data === (1,) + @test MArray{Tuple{1},Int}((1,)).data === (1,) + @test MArray{Tuple{1}}((1,)).data === (1,) + + @test MArray{Tuple{2,2},Int,2}((1,2,3,4)).data === (1,2,3,4) + @test MArray{Tuple{2,2},Int}((1,2,3,4)).data === (1,2,3,4) + @test MArray{Tuple{2,2}}((1,2,3,4)).data === (1,2,3,4) + + @test ((@MArray [1])::MArray{Tuple{1}}).data === (1,) + @test ((@MArray [1,2])::MArray{Tuple{2}}).data === (1,2) + @test ((@MArray Float64[1,2,3])::MArray{Tuple{3}}).data === (1.0, 2.0, 3.0) + @test ((@MArray [1 2])::MArray{Tuple{1,2}}).data === (1, 2) + @test ((@MArray Float64[1 2])::MArray{Tuple{1,2}}).data === (1.0, 2.0) + @test ((@MArray [1 ; 2])::MArray{Tuple{2,1}}).data === (1, 2) + @test ((@MArray Float64[1 ; 2])::MArray{Tuple{2,1}}).data === (1.0, 2.0) + @test ((@MArray [1 2 ; 3 4])::MArray{Tuple{2,2}}).data === (1, 3, 2, 4) + @test ((@MArray Float64[1 2 ; 3 4])::MArray{Tuple{2,2}}).data === (1.0, 3.0, 2.0, 4.0) + + @test ((@MArray [i*j*k for i = 1:2, j = 2:3, k = 3:4])::MArray{Tuple{2,2,2}}).data === (6, 12, 9, 18, 8, 16, 12, 24) + @test ((@MArray Float64[i*j*k for i = 1:2, j = 2:3, k =3:4])::MArray{Tuple{2,2,2}}).data === (6.0, 12.0, 9.0, 18.0, 8.0, 16.0, 12.0, 24.0) @test (ex = macroexpand(:(@MArray [1 2; 3])); isa(ex, Expr) && ex.head == :error) - @test ((@MArray zeros(2,2,1))::MArray{(2,2,1), Float64}).data === (0.0, 0.0, 0.0, 0.0) - @test ((@MArray ones(2,2,1))::MArray{(2,2,1), Float64}).data === (1.0, 1.0, 1.0, 1.0) - @test ((@MArray eye(2))::MArray{(2,2), Float64}).data === (1.0, 0.0, 0.0, 1.0) - @test ((@MArray eye(2,2))::MArray{(2,2), Float64}).data === (1.0, 0.0, 0.0, 1.0) - @test isa(@MArray(rand(2,2,1)), MArray{(2,2,1), Float64}) - @test isa(@MArray(randn(2,2,1)), MArray{(2,2,1), Float64}) + @test ((@MArray zeros(2,2,1))::MArray{Tuple{2,2,1}, Float64}).data === (0.0, 0.0, 0.0, 0.0) + @test ((@MArray ones(2,2,1))::MArray{Tuple{2,2,1}, Float64}).data === (1.0, 1.0, 1.0, 1.0) + @test ((@MArray eye(2))::MArray{Tuple{2,2}, Float64}).data === (1.0, 0.0, 0.0, 1.0) + @test ((@MArray eye(2,2))::MArray{Tuple{2,2}, Float64}).data === (1.0, 0.0, 0.0, 1.0) + @test isa(@MArray(rand(2,2,1)), MArray{Tuple{2,2,1}, Float64}) + @test isa(@MArray(randn(2,2,1)), MArray{Tuple{2,2,1}, Float64}) - @test ((@MArray zeros(Float32, 2, 2, 1))::MArray{(2,2,1),Float32}).data === (0.0f0, 0.0f0, 0.0f0, 0.0f0) - @test ((@MArray ones(Float32, 2, 2, 1))::MArray{(2,2,1),Float32}).data === (1.0f0, 1.0f0, 1.0f0, 1.0f0) - @test ((@MArray eye(Float32, 2))::MArray{(2,2), Float32}).data === (1.0f0, 0.0f0, 0.0f0, 1.0f0) - @test ((@MArray eye(Float32, 2, 2))::MArray{(2,2), Float32}).data === (1.0f0, 0.0f0, 0.0f0, 1.0f0) - @test isa(@MArray(rand(Float32, 2, 2, 1)), MArray{(2,2,1), Float32}) - @test isa(@MArray(randn(Float32, 2, 2, 1)), MArray{(2,2,1), Float32}) + @test ((@MArray zeros(Float32, 2, 2, 1))::MArray{Tuple{2,2,1},Float32}).data === (0.0f0, 0.0f0, 0.0f0, 0.0f0) + @test ((@MArray ones(Float32, 2, 2, 1))::MArray{Tuple{2,2,1},Float32}).data === (1.0f0, 1.0f0, 1.0f0, 1.0f0) + @test ((@MArray eye(Float32, 2))::MArray{Tuple{2,2}, Float32}).data === (1.0f0, 0.0f0, 0.0f0, 1.0f0) + @test ((@MArray eye(Float32, 2, 2))::MArray{Tuple{2,2}, Float32}).data === (1.0f0, 0.0f0, 0.0f0, 1.0f0) + @test isa(@MArray(rand(Float32, 2, 2, 1)), MArray{Tuple{2,2,1}, Float32}) + @test isa(@MArray(randn(Float32, 2, 2, 1)), MArray{Tuple{2,2,1}, Float32}) m = [1 2; 3 4] - @test MArray{(2,2)}(m) == @MArray [1 2; 3 4] + @test MArray{Tuple{2,2}}(m) == @MArray [1 2; 3 4] end @testset "Methods" begin @@ -74,9 +74,9 @@ @test size(m) === (2, 2) @test size(typeof(m)) === (2, 2) - @test size(MArray{(2,2),Int,2}) === (2, 2) - @test size(MArray{(2,2),Int}) === (2, 2) - @test size(MArray{(2,2)}) === (2, 2) + @test size(MArray{Tuple{2,2},Int,2}) === (2, 2) + @test size(MArray{Tuple{2,2},Int}) === (2, 2) + @test size(MArray{Tuple{2,2}}) === (2, 2) @test size(m, 1) === 2 @test size(m, 2) === 2 diff --git a/test/abstractarray.jl b/test/abstractarray.jl index 48cfb1df..41300ce7 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -34,7 +34,7 @@ @test @inferred(similar_type(MVector{2,Int}, Size(3,3))) == SMatrix{3, 3, Int, 9} @test @inferred(similar_type(MVector{2,Int}, Float64, Size(3,3))) == SMatrix{3, 3, Float64, 9} - @test @inferred(similar_type(MArray{(4,4,4),Int,3,64}, Float64)) == SArray{Tuple{4,4,4}, Float64, 3, 64} + @test @inferred(similar_type(MArray{Tuple{4,4,4},Int,3,64}, Float64)) == SArray{Tuple{4,4,4}, Float64, 3, 64} @test @inferred(similar_type(MVector{2,Int}, Size(3,3,3))) == SArray{Tuple{3,3,3}, Int, 3, 27} @test @inferred(similar_type(MVector{2,Int}, Float64, Size(3,3,3))) == SArray{Tuple{3,3,3}, Float64, 3, 27} end @@ -54,10 +54,10 @@ @test isa(@inferred(similar(sv, Size(3,3))), MMatrix{3,3,Int,9}) @test isa(@inferred(similar(sv, Float64, Size(3,3))), MMatrix{3,3,Float64,9}) - @test isa(@inferred(similar(sa)), MArray{(1,1,1),Int,3,1}) - @test isa(@inferred(similar(sa, Float64)), MArray{(1,1,1),Float64,3,1}) - @test isa(@inferred(similar(sv, Size(3,3,3))), MArray{(3,3,3),Int,3,27}) - @test isa(@inferred(similar(sv, Float64, Size(3,3,3))), MArray{(3,3,3),Float64,3,27}) + @test isa(@inferred(similar(sa)), MArray{Tuple{1,1,1},Int,3,1}) + @test isa(@inferred(similar(sa, Float64)), MArray{Tuple{1,1,1},Float64,3,1}) + @test isa(@inferred(similar(sv, Size(3,3,3))), MArray{Tuple{3,3,3},Int,3,27}) + @test isa(@inferred(similar(sv, Float64, Size(3,3,3))), MArray{Tuple{3,3,3},Float64,3,27}) end @testset "reshape" begin diff --git a/test/arraymath.jl b/test/arraymath.jl index 5aa27858..9c8cd689 100644 --- a/test/arraymath.jl +++ b/test/arraymath.jl @@ -42,14 +42,14 @@ @test @inferred(zeros(SArray{Tuple{1,1,1}})) === SArray{Tuple{1,1,1}}((0.0,)) @test @inferred(zeros(MVector{3}))::MVector == @MVector [0.0, 0.0, 0.0] @test @inferred(zeros(MMatrix{2,2}))::MMatrix == @MMatrix [0.0 0.0; 0.0 0.0] - @test @inferred(zeros(MArray{(1,1,1)}))::MArray == MArray{(1,1,1)}((0.0,)) + @test @inferred(zeros(MArray{Tuple{1,1,1}}))::MArray == MArray{Tuple{1,1,1}}((0.0,)) @test @inferred(ones(SVector{3})) === @SVector [1.0, 1.0, 1.0] @test @inferred(ones(SMatrix{2,2})) === @SMatrix [1.0 1.0; 1.0 1.0] @test @inferred(ones(SArray{Tuple{1,1,1}})) === SArray{Tuple{1,1,1}}((1.0,)) @test @inferred(ones(MVector{3}))::MVector == @MVector [1.0, 1.0, 1.0] @test @inferred(ones(MMatrix{2,2}))::MMatrix == @MMatrix [1.0 1.0; 1.0 1.0] - @test @inferred(ones(MArray{(1,1,1)}))::MArray == MArray{(1,1,1)}((1.0,)) + @test @inferred(ones(MArray{Tuple{1,1,1}}))::MArray == MArray{Tuple{1,1,1}}((1.0,)) end @testset "zero()" begin diff --git a/test/indexing.jl b/test/indexing.jl index 23ff5197..e9d2e87a 100644 --- a/test/indexing.jl +++ b/test/indexing.jl @@ -72,7 +72,7 @@ @test sa[1,2,1] === 9 @test sa[2,1,1] === 12 - ma = MArray{(2,2,2), Int}() + ma = MArray{Tuple{2,2,2}, Int}() @test (ma[1,1,2] = 8; ma[1,1,2] === 8) @test (ma[1,2,1] = 9; ma[1,2,1] === 9) @test (ma[2,1,1] = 12; ma[2,1,1] === 12) @@ -86,7 +86,7 @@ @test sa[1,2,1,1] === 36 @test sa[2,1,1,1] === 48 - ma = MArray{(2,2,2,2), Int}() + ma = MArray{Tuple{2,2,2,2}, Int}() @test (ma[1,1,1,2] = 30; ma[1,1,1,2] === 30) @test (ma[1,1,2,1] = 32; ma[1,1,2,1] === 32) @test (ma[1,2,1,1] = 36; ma[1,2,1,1] === 36) diff --git a/test/matrix_multiply.jl b/test/matrix_multiply.jl index cda5c033..18e6eb14 100644 --- a/test/matrix_multiply.jl +++ b/test/matrix_multiply.jl @@ -164,9 +164,9 @@ At_mul_Bt!(a, m, n) @test a::MMatrix{2,2,Int,4} == @MMatrix [11 19; 16 28] - a2 = MArray{(2,2),Int,2,4}() + a2 = MArray{Tuple{2,2},Int,2,4}() A_mul_B!(a2, m, n) - @test a2::MArray{(2,2),Int,2,4} == @MArray [10 13; 22 29] + @test a2::MArray{Tuple{2,2},Int,2,4} == @MArray [10 13; 22 29] # Alternative builtin method used for n > 8 m_array_2 = rand(1:10, 10, 10)