Skip to content

Commit b935326

Browse files
authored
Julia 0.6 rewrite (#121)
Rewritten for compatibility with Julia v0.6. Improvements: * Full multidimensional APL indexing should now be implemented. * Similarly, broadcast, broadcast!, map and map! now support arbitrary many static array inputs. * Universal use of the Size trait for dispatch * A Length trait and related pure functions * Reorganized files a little, tried to upgrade most code to the new v0.6 syntax and be more consistent with formatting and expression munging. * Started some work on static ranges - the eventual goal here is to upgrade from talking about sizes to talking about indices, so we can have static arrays with index ranges other than 1:n. (However, this wasn't exported.) We have this breaking change: * similar_type defaults to SVector, etc - it does not preserve immutability. This helps e.g. with things like m[i, SVector(1,2,3)] where m::Matrix, and should generally be beneficial for speed. We have this regression * Mixed static array - standard array operations like SMatrix * Vector have been removed. We can add these back in, if they are popular, but until we have inlined non-isbits immutables, we shouldn't do the simple thing here and wrap them in a SizedArray (well, we could, but it might cost more to allocate a pointer to the heap + gc, than to perform the actual operation).
1 parent 24a08f1 commit b935326

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1335
-2608
lines changed

.travis.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ os:
44
- linux
55
- osx
66
julia:
7-
- 0.5
7+
- 0.6
88
- nightly
99
notifications:
1010
email: false
11-
matrix:
12-
allow_failures:
11+
# matrix:
12+
# allow_failures:
1313
# - julia: nightly
14-
- os: osx
14+
# - os: osx
1515
# uncomment the following lines to override the default test script
1616
#script:
1717
# - if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
1818
# - julia -e 'Pkg.clone(pwd()); Pkg.build("StaticArrays"); Pkg.test("StaticArrays"; coverage=true)'
1919
after_success:
20-
- if [ $TRAVIS_JULIA_VERSION = "0.5" ] && [ $TRAVIS_OS_NAME = "linux" ]; then
20+
- if [ $TRAVIS_JULIA_VERSION = "0.6" ] && [ $TRAVIS_OS_NAME = "linux" ]; then
2121
julia -e 'cd(Pkg.dir("StaticArrays")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())';
2222
fi

REQUIRE

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
julia 0.5
2-
Compat 0.19.0

appveyor.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
environment:
22
matrix:
3-
- JULIAVERSION: "julialang/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe"
4-
- JULIAVERSION: "julialang/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
3+
# - JULIAVERSION: "julialang/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe"
4+
# - JULIAVERSION: "julialang/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe"
55
- JULIAVERSION: "julianightlies/bin/winnt/x86/julia-latest-win32.exe"
66
- JULIAVERSION: "julianightlies/bin/winnt/x64/julia-latest-win64.exe"
77

src/FieldVector.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ For example:
1515
z::Float64
1616
end
1717
"""
18-
@compat abstract type FieldVector{T} <: StaticVector{T} end
18+
abstract type FieldVector{T} <: StaticVector{T} end
1919

2020
# Is this a good idea?? Should people just define constructors that accept tuples?
2121
@inline (::Type{FV}){FV<:FieldVector}(x::Tuple) = FV(x...)
2222

2323
@pure Size{FV<:FieldVector}(::Type{FV}) = Size(nfields(FV))
2424

25-
@inline getindex(v::FieldVector, i::Integer) = getfield(v, i)
26-
@inline setindex!(v::FieldVector, x, i::Integer) = setfield!(v, i, x)
25+
@inline getindex(v::FieldVector, i::Int) = getfield(v, i)
26+
@inline setindex!(v::FieldVector, x, i::Int) = setfield!(v, i, x)
2727

2828
# See #53
2929
Base.cconvert{T}(::Type{Ptr{T}}, v::FieldVector) = Ref(v)

src/ImmutableArrays.jl

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,31 @@
11
module ImmutableArrays
22

33
using ..StaticArrays
4-
using Compat
5-
6-
@compat Vector1{T} = SVector{1,T}
7-
@compat Vector2{T} = SVector{2,T}
8-
@compat Vector3{T} = SVector{3,T}
9-
@compat Vector4{T} = SVector{4,T}
10-
11-
@compat Matrix1x1{T} = SMatrix{1,1,T,1}
12-
@compat Matrix1x2{T} = SMatrix{1,2,T,2}
13-
@compat Matrix1x3{T} = SMatrix{1,3,T,3}
14-
@compat Matrix1x4{T} = SMatrix{1,4,T,4}
15-
16-
@compat Matrix2x1{T} = SMatrix{2,1,T,2}
17-
@compat Matrix2x2{T} = SMatrix{2,2,T,4}
18-
@compat Matrix2x3{T} = SMatrix{2,3,T,6}
19-
@compat Matrix2x4{T} = SMatrix{2,4,T,8}
20-
21-
@compat Matrix3x1{T} = SMatrix{3,1,T,3}
22-
@compat Matrix3x2{T} = SMatrix{3,2,T,6}
23-
@compat Matrix3x3{T} = SMatrix{3,3,T,9}
24-
@compat Matrix3x4{T} = SMatrix{3,4,T,12}
25-
26-
@compat Matrix4x1{T} = SMatrix{4,1,T,4}
27-
@compat Matrix4x2{T} = SMatrix{4,2,T,8}
28-
@compat Matrix4x3{T} = SMatrix{4,3,T,12}
29-
@compat Matrix4x4{T} = SMatrix{4,4,T,16}
4+
5+
Vector1{T} = SVector{1,T}
6+
Vector2{T} = SVector{2,T}
7+
Vector3{T} = SVector{3,T}
8+
Vector4{T} = SVector{4,T}
9+
10+
Matrix1x1{T} = SMatrix{1,1,T,1}
11+
Matrix1x2{T} = SMatrix{1,2,T,2}
12+
Matrix1x3{T} = SMatrix{1,3,T,3}
13+
Matrix1x4{T} = SMatrix{1,4,T,4}
14+
15+
Matrix2x1{T} = SMatrix{2,1,T,2}
16+
Matrix2x2{T} = SMatrix{2,2,T,4}
17+
Matrix2x3{T} = SMatrix{2,3,T,6}
18+
Matrix2x4{T} = SMatrix{2,4,T,8}
19+
20+
Matrix3x1{T} = SMatrix{3,1,T,3}
21+
Matrix3x2{T} = SMatrix{3,2,T,6}
22+
Matrix3x3{T} = SMatrix{3,3,T,9}
23+
Matrix3x4{T} = SMatrix{3,4,T,12}
24+
25+
Matrix4x1{T} = SMatrix{4,1,T,4}
26+
Matrix4x2{T} = SMatrix{4,2,T,8}
27+
Matrix4x3{T} = SMatrix{4,3,T,12}
28+
Matrix4x4{T} = SMatrix{4,4,T,16}
3029

3130
export Vector1, Vector2, Vector3, Vector4,
3231
Matrix1x1, Matrix1x2, Matrix1x3, Matrix1x4,

src/MArray.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ end
8585
@inline MArray(a::StaticArray) = MArray{size(typeof(a))}(Tuple(a))
8686

8787
# Some more advanced constructor-like functions
88-
@inline eye{Size}(::Type{MArray{Size}}) = eye(MArray{Size,Float64})
89-
@inline zeros{Size}(::Type{MArray{Size}}) = zeros(MArray{Size,Float64})
90-
@inline ones{Size}(::Type{MArray{Size}}) = ones(MArray{Size,Float64})
91-
88+
@inline one(::Type{MArray{S}}) where {S} = one(MArray{S,Float64,length(S)})
89+
@inline eye(::Type{MArray{S}}) where {S} = eye(MArray{S,Float64,length(S)})
90+
@inline one(::Type{MArray{S,T}}) where {S,T} = one(MArray{S,T,length(S)})
91+
@inline eye(::Type{MArray{S,T}}) where {S,T} = eye(MArray{S,T,length(S)})
9292

9393
####################
9494
## MArray methods ##
@@ -99,13 +99,13 @@ end
9999
@pure Size{S,T,N}(::Type{MArray{S,T,N}}) = Size(S)
100100
@pure Size{S,T,N,L}(::Type{MArray{S,T,N,L}}) = Size(S)
101101

102-
function getindex(v::MArray, i::Integer)
102+
function getindex(v::MArray, i::Int)
103103
Base.@_inline_meta
104104
v.data[i]
105105
end
106106

107-
@propagate_inbounds setindex!{S,T}(v::MArray{S,T}, val, i::Integer) = setindex!(v, convert(T, val), i)
108-
@inline function setindex!{S,T}(v::MArray{S,T}, val::T, i::Integer)
107+
@propagate_inbounds setindex!{S,T}(v::MArray{S,T}, val, i::Int) = setindex!(v, convert(T, val), i)
108+
@inline function setindex!{S,T}(v::MArray{S,T}, val::T, i::Int)
109109
@boundscheck if i < 1 || i > length(v)
110110
throw(BoundsError())
111111
end

src/MMatrix.jl

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,26 @@ type MMatrix{S1, S2, T, L} <: StaticMatrix{T}
3434
end
3535
end
3636

37-
@generated function check_MMatrix_params{S1,S2,L}(::Type{Val{S1}}, ::Type{Val{S2}}, T, ::Type{Val{L}})
38-
if !(T <: DataType) # I think the way types are handled in generated fnctions might have changed in 0.5?
39-
return :(error("MMatrix: Parameter T must be a DataType. Got $T"))
40-
end
37+
function check_MMatrix_params(::Type{Val{S1}}, ::Type{Val{S2}}, T, ::Type{Val{L}}) where {S1,S2,L}
38+
throw(ArgumentError("MMatrix: Parameter T must be a Type. Got $T"))
39+
end
4140

41+
@generated function check_MMatrix_params(::Type{Val{S1}}, ::Type{Val{S2}}, ::Type{T}, ::Type{Val{L}}) where {S1,S2,L,T}
4242
if !isa(S1, Int) || !isa(S2, Int) || !isa(L, Int) || S1 < 0 || S2 < 0 || L < 0
43-
return :(error("MMatrix: Sizes must be positive integers. Got $S1 × $S2 ($L elements)"))
43+
throw(ArgumentError("MMatrix: Sizes must be positive integers. Got $S1 × $S2 ($L elements)"))
4444
end
4545

4646
if S1*S2 == L
4747
return nothing
4848
else
49-
str = "Size mismatch in MMatrix. S1 = $S1, S2 = $S2, but recieved $L elements"
50-
return :(error($str))
49+
throw(ArgumentError("Size mismatch in MMatrix. S1 = $S1, S2 = $S2, but recieved $L elements"))
5150
end
5251
end
5352

5453
@generated function (::Type{MMatrix{S1}}){S1,L}(x::NTuple{L})
5554
S2 = div(L, S1)
5655
if S1*S2 != L
57-
error("Incorrect matrix sizes. $S1 does not divide $L elements")
56+
throw(DimensionMismatch("Incorrect matrix sizes. $S1 does not divide $L elements"))
5857
end
5958
T = promote_tuple_eltype(x)
6059

@@ -90,13 +89,9 @@ end
9089
@inline convert{S1,S2,T}(::Type{MMatrix{S1,S2}}, a::StaticArray{T}) = MMatrix{S1,S2,T}(Tuple(a))
9190
@inline MMatrix(a::StaticMatrix) = MMatrix{size(typeof(a),1),size(typeof(a),2)}(Tuple(a))
9291

93-
9492
# Some more advanced constructor-like functions
9593
@inline one{N}(::Type{MMatrix{N}}) = one(MMatrix{N,N})
9694
@inline eye{N}(::Type{MMatrix{N}}) = eye(MMatrix{N,N})
97-
@inline eye{N,M}(::Type{MMatrix{N,M}}) = eye(MMatrix{N,M,Float64})
98-
@inline zeros{N,M}(::Type{MMatrix{N,M}}) = zeros(MMatrix{N,M,Float64})
99-
@inline ones{N,M}(::Type{MMatrix{N,M}}) = ones(MMatrix{N,M,Float64})
10095

10196
#####################
10297
## MMatrix methods ##
@@ -106,7 +101,7 @@ end
106101
@pure Size{S1,S2,T}(::Type{MMatrix{S1,S2,T}}) = Size(S1, S2)
107102
@pure Size{S1,S2,T,L}(::Type{MMatrix{S1,S2,T,L}}) = Size(S1, S2)
108103

109-
@propagate_inbounds function getindex{S1,S2,T}(m::MMatrix{S1,S2,T}, i::Integer)
104+
@propagate_inbounds function getindex{S1,S2,T}(m::MMatrix{S1,S2,T}, i::Int)
110105
#@boundscheck if i < 1 || i > length(m)
111106
# throw(BoundsError(m,i))
112107
#end
@@ -121,8 +116,8 @@ end
121116
end
122117
end
123118

124-
@propagate_inbounds setindex!{S1,S2,T}(m::MMatrix{S1,S2,T}, val, i::Integer) = setindex!(m, convert(T, val), i)
125-
@propagate_inbounds function setindex!{S1,S2,T}(m::MMatrix{S1,S2,T}, val::T, i::Integer)
119+
@propagate_inbounds setindex!{S1,S2,T}(m::MMatrix{S1,S2,T}, val, i::Int) = setindex!(m, convert(T, val), i)
120+
@propagate_inbounds function setindex!{S1,S2,T}(m::MMatrix{S1,S2,T}, val::T, i::Int)
126121
#@boundscheck if i < 1 || i > length(m)
127122
# throw(BoundsError(m,i))
128123
#end

src/MVector.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ end
4949
@pure Size{S}(::Type{MVector{S}}) = Size(S)
5050
@pure Size{S,T}(::Type{MVector{S,T}}) = Size(S)
5151

52-
@propagate_inbounds function getindex(v::MVector, i::Integer)
52+
@propagate_inbounds function getindex(v::MVector, i::Int)
5353
v.data[i]
5454
end
5555

5656
# Mutating setindex!
57-
@propagate_inbounds setindex!{S,T}(v::MVector{S,T}, val, i::Integer) = setindex!(v, convert(T, val), i)
58-
@inline function setindex!{S,T}(v::MVector{S,T}, val::T, i::Integer)
57+
@propagate_inbounds setindex!{S,T}(v::MVector{S,T}, val, i::Int) = setindex!(v, convert(T, val), i)
58+
@inline function setindex!{S,T}(v::MVector{S,T}, val::T, i::Int)
5959
@boundscheck if i < 1 || i > length(v)
6060
throw(BoundsError())
6161
end

src/SArray.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ end
6565
@inline SArray(a::StaticArray) = SArray{size(typeof(a))}(Tuple(a))
6666

6767
# Some more advanced constructor-like functions
68-
@inline eye{Size}(::Type{SArray{Size}}) = eye(SArray{Size,Float64})
69-
@inline zeros{Size}(::Type{SArray{Size}}) = zeros(SArray{Size,Float64})
70-
@inline ones{Size}(::Type{SArray{Size}}) = ones(SArray{Size,Float64})
71-
68+
@inline one(::Type{SArray{S}}) where {S} = one(SArray{S,Float64,length(S)})
69+
@inline eye(::Type{SArray{S}}) where {S} = eye(SArray{S,Float64,length(S)})
70+
@inline one(::Type{SArray{S,T}}) where {S,T} = one(SArray{S,T,length(S)})
71+
@inline eye(::Type{SArray{S,T}}) where {S,T} = eye(SArray{S,T,length(S)})
7272

7373
####################
7474
## SArray methods ##
@@ -79,7 +79,7 @@ end
7979
@pure Size{S,T,N}(::Type{SArray{S,T,N}}) = Size(S)
8080
@pure Size{S,T,N,L}(::Type{SArray{S,T,N,L}}) = Size(S)
8181

82-
function getindex(v::SArray, i::Integer)
82+
function getindex(v::SArray, i::Int)
8383
Base.@_inline_meta
8484
v.data[i]
8585
end

src/SMatrix.jl

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,26 @@ immutable SMatrix{S1, S2, T, L} <: StaticMatrix{T}
2828
end
2929
end
3030

31-
@generated function check_smatrix_params{S1,S2,L}(::Type{Val{S1}}, ::Type{Val{S2}}, T, ::Type{Val{L}})
32-
if !(T <: DataType) # I think the way types are handled in generated fnctions might have changed in 0.5?
33-
return :(error("SMatrix: Parameter T must be a DataType. Got $T"))
34-
end
31+
function check_smatrix_params(::Type{Val{S1}}, ::Type{Val{S2}}, T, ::Type{Val{L}}) where {S1,S2,L}
32+
throw(ArgumentError("SMatrix: Parameter T must be a Type. Got $T"))
33+
end
3534

35+
@generated function check_smatrix_params(::Type{Val{S1}}, ::Type{Val{S2}}, ::Type{T}, ::Type{Val{L}}) where {S1,S2,L,T}
3636
if !isa(S1, Int) || !isa(S2, Int) || !isa(L, Int) || S1 < 0 || S2 < 0 || L < 0
37-
return :(error("SMatrix: Sizes must be positive integers. Got $S1 × $S2 ($L elements)"))
37+
throw(ArgumentError("SMatrix: Sizes must be positive integers. Got $S1 × $S2 ($L elements)"))
3838
end
3939

4040
if S1*S2 == L
4141
return nothing
4242
else
43-
str = "Size mismatch in SMatrix. S1 = $S1, S2 = $S2, but recieved $L elements"
44-
return :(error($str))
43+
throw(ArgumentError("Size mismatch in SMatrix. S1 = $S1, S2 = $S2, but recieved $L elements"))
4544
end
4645
end
4746

4847
@generated function (::Type{SMatrix{S1}}){S1,L}(x::NTuple{L,Any})
4948
S2 = div(L, S1)
5049
if S1*S2 != L
51-
error("Incorrect matrix sizes. $S1 does not divide $L elements")
50+
throw(DimensionMismatch("Incorrect matrix sizes. $S1 does not divide $L elements"))
5251
end
5352
T = promote_tuple_eltype(x)
5453

@@ -66,7 +65,7 @@ end
6665
SMatrix{S1, S2, $T, L}(x)
6766
end
6867
end
69-
@compat SMatrixNoType{S1, S2, L, T} = SMatrix{S1, S2, T, L}
68+
SMatrixNoType{S1, S2, L, T} = SMatrix{S1, S2, T, L}
7069
@generated function (::Type{SMatrixNoType{S1, S2, L}}){S1,S2,L}(x::NTuple{L,Any})
7170
T = promote_tuple_eltype(x)
7271
return quote
@@ -85,32 +84,9 @@ end
8584
@inline convert{S1,S2,T}(::Type{SMatrix{S1,S2}}, a::StaticArray{T}) = SMatrix{S1,S2,T}(Tuple(a))
8685
@inline SMatrix(a::StaticMatrix) = SMatrix{size(typeof(a),1),size(typeof(a),2)}(Tuple(a))
8786

88-
#=
89-
@inline (::Type{SMatrix{S1}}){S1}(x1) = SMatrix{S1}((x1,))
90-
@inline (::Type{SMatrix{S1}}){S1}(x1,x2) = SMatrix{S1}((x1,x2))
91-
@inline (::Type{SMatrix{S1}}){S1}(x1,x2,x3) = SMatrix{S1}((x1,x2,x3))
92-
@inline (::Type{SMatrix{S1}}){S1}(x1,x2,x3,x4) = SMatrix{S1}((x1,x2,x3,x4))
93-
@inline (::Type{SMatrix{S1}}){S1}(x...) = SMatrix{S1}(x)
94-
95-
@inline (::Type{SMatrix{S1,S2}}){S1,S2}(x1) = SMatrix{S1,S2}((x1,))
96-
@inline (::Type{SMatrix{S1,S2}}){S1,S2}(x1,x2) = SMatrix{S1,S2}((x1,x2))
97-
@inline (::Type{SMatrix{S1,S2}}){S1,S2}(x1,x2,x3) = SMatrix{S1,S2}((x1,x2,x3))
98-
@inline (::Type{SMatrix{S1,S2}}){S1,S2}(x1,x2,x3,x4) = SMatrix{S1,S2}((x1,x2,x3,x4))
99-
@inline (::Type{SMatrix{S1,S2}}){S1,S2}(x...) = SMatrix{S1,S2}(x)
100-
101-
@inline (::Type{SMatrix{S1,S2,T}}){S1,S2,T}(x1) = SMatrix{S1,S2,T}((x1,))
102-
@inline (::Type{SMatrix{S1,S2,T}}){S1,S2,T}(x1,x2) = SMatrix{S1,S2,T}((x1,x2))
103-
@inline (::Type{SMatrix{S1,S2,T}}){S1,S2,T}(x1,x2,x3) = SMatrix{S1,S2,T}((x1,x2,x3))
104-
@inline (::Type{SMatrix{S1,S2,T}}){S1,S2,T}(x1,x2,x3,x4) = SMatrix{S1,S2,T}((x1,x2,x3,x4))
105-
@inline (::Type{SMatrix{S1,S2,T}}){S1,S2,T}(x...) = SMatrix{S1,S2,T}(x)
106-
=#
107-
10887
# Some more advanced constructor-like functions
10988
@inline one{N}(::Type{SMatrix{N}}) = one(SMatrix{N,N})
11089
@inline eye{N}(::Type{SMatrix{N}}) = eye(SMatrix{N,N})
111-
@inline eye{N,M}(::Type{SMatrix{N,M}}) = eye(SMatrix{N,M,Float64})
112-
@inline zeros{N,M}(::Type{SMatrix{N,M}}) = zeros(SMatrix{N,M,Float64})
113-
@inline ones{N,M}(::Type{SMatrix{N,M}}) = ones(SMatrix{N,M,Float64})
11490

11591
#####################
11692
## SMatrix methods ##
@@ -120,7 +96,7 @@ end
12096
@pure Size{S1,S2,T}(::Type{SMatrix{S1,S2,T}}) = Size(S1, S2)
12197
@pure Size{S1,S2,T,L}(::Type{SMatrix{S1,S2,T,L}}) = Size(S1, S2)
12298

123-
function getindex(v::SMatrix, i::Integer)
99+
function getindex(v::SMatrix, i::Int)
124100
Base.@_inline_meta
125101
v.data[i]
126102
end

0 commit comments

Comments
 (0)