Skip to content

Commit e4dedf3

Browse files
committed
Merge branch 'master' into pull-request/fb369658
2 parents 031ce1c + d4a4d4f commit e4dedf3

File tree

9 files changed

+94
-2
lines changed

9 files changed

+94
-2
lines changed

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
julia 0.6.0-pre
1+
julia 0.6.0

src/StaticArrays.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Base: getindex, setindex!, size, similar, vec, show,
88
length, convert, promote_op, promote_rule, map, map!, reduce, reducedim, mapreducedim,
99
mapreduce, broadcast, broadcast!, conj, transpose, ctranspose,
1010
hcat, vcat, ones, zeros, eye, one, cross, vecdot, reshape, fill,
11-
fill!, det, logdet, inv, eig, eigvals, expm, logm, sqrtm, lyap, trace, diag, vecnorm, norm, dot, diagm, diag,
11+
fill!, det, logdet, inv, eig, eigvals, expm, logm, sqrtm, lyap, trace, kron, diag, vecnorm, norm, dot, diagm, diag,
1212
lu, svd, svdvals, svdfact, factorize, ishermitian, issymmetric, isposdef,
1313
sum, diff, prod, count, any, all, minimum,
1414
maximum, extrema, mean, copy, rand, randn, randexp, rand!, randn!,

src/linalg.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,21 @@ end
317317
end
318318
end
319319

320+
const _length_limit = Length(200)
321+
322+
@inline kron(a::StaticMatrix, b::StaticMatrix) = _kron(_length_limit, Size(a), Size(b), a, b)
323+
@generated function _kron(::Length{length_limit}, ::Size{SA}, ::Size{SB}, a, b) where {length_limit,SA,SB}
324+
outsize = SA .* SB
325+
if prod(outsize) > length_limit
326+
return :( SizedMatrix{$(outsize[1]),$(outsize[2])}( kron(drop_sdims(a), drop_sdims(b)) ) )
327+
end
328+
rows = [:(hcat($([:(a[$(sub2ind(SA,i,j))]*b) for j=1:SA[2]]...))) for i=1:SA[1]]
329+
return quote
330+
@_inline_meta
331+
@inbounds return vcat($(rows...))
332+
end
333+
end
334+
320335
@inline Size(::Union{RowVector{T, SA}, Type{RowVector{T, SA}}}) where {T, SA <: StaticArray} = Size(1, Size(SA)[1])
321336
@inline Size(::Union{RowVector{T, CA}, Type{RowVector{T, CA}}} where CA <: ConjVector{<:Any, SA}) where {T, SA <: StaticArray} = Size(1, Size(SA)[1])
322337
@inline Size(::Union{Symmetric{T,SA}, Type{Symmetric{T,SA}}}) where {T,SA<:StaticArray} = Size(SA)

src/util.jl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,34 @@ end
5959

6060
return nothing
6161
end
62+
63+
64+
# Trivial view used to drop static dimensions to override dispatch
65+
struct TrivialView{A,T,N} <: AbstractArray{T,N}
66+
a::A
67+
end
68+
69+
size(a::TrivialView) = size(a.a)
70+
getindex(a::TrivialView, inds...) = getindex(a.a, inds...)
71+
setindex!(a::TrivialView, inds...) = setindex!(a.a, inds...)
72+
Base.IndexStyle(::Type{<:TrivialView{A}}) where {A} = IndexStyle(A)
73+
74+
TrivialView(a::AbstractArray{T,N}) where {T,N} = TrivialView{typeof(a),T,N}(a)
75+
76+
77+
# Remove the static dimensions from an array
78+
79+
"""
80+
drop_sdims(a)
81+
82+
Return an `AbstractArray` with the same elements as `a`, but with static
83+
dimensions removed (ie, not a `StaticArray`).
84+
85+
This is useful if you want to override dispatch to call the `Base` version of
86+
operations such as `kron` instead of the implementation in `StaticArrays`.
87+
Normally you shouldn't need to do this, but it can be more efficient for
88+
certain algorithms where the number of elements of the output is a lot larger
89+
than the input.
90+
"""
91+
@inline drop_sdims(a::StaticArray) = TrivialView(a)
92+
@inline drop_sdims(a) = a

test/SizedArray.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
@test convert(Vector, SizedArray{Tuple{4}, Int, 1}(collect(3:6))) == collect(3:6)
6969
@test Matrix(SMatrix{2,2}((1,2,3,4))) == [1 3; 2 4]
7070
@test convert(Matrix, SMatrix{2,2}((1,2,3,4))) == [1 3; 2 4]
71+
# Conversion after reshaping
72+
@test_broken Array(SizedMatrix{2,2}([1,2,3,4])) == [1 3; 2 4]
7173
end
7274

7375
@testset "promotion" begin

test/inv.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ end
7070
@test_broken norm(Matrix(sm*inv(sm) - eye(4))) < 10*norm(m*inv(m) - eye(4))
7171
end
7272

73+
@testset "Matrix inverse 5x5" begin
74+
m = randn(Float64, 5,5) + eye(5)
75+
@test inv(SMatrix{5,5}(m))::StaticMatrix inv(m)
76+
m = triu(randn(Float64, 5,5) + eye(5))
77+
@test inv(SMatrix{5,5}(m))::StaticMatrix inv(m)
78+
m = tril(randn(Float64, 5,5) + eye(5))
79+
@test inv(SMatrix{5,5}(m))::StaticMatrix inv(m)
80+
end
7381

7482
#-------------------------------------------------------------------------------
7583
# More comprehensive but qualitiative testing for inv() accuracy

test/linalg.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,19 @@ using StaticArrays, Base.Test
149149
@test vecnorm(SVector{0, Float64}(()), 1) === 0.
150150
@test trace(SMatrix{0,0,Float64}(())) === 0.
151151
end
152+
153+
@testset "kron" begin
154+
@test @inferred(kron(@SMatrix([1 2; 3 4]), @SMatrix([0 1 0; 1 0 1]))) ==
155+
SMatrix{4,6,Int}([0 1 0 0 2 0;
156+
1 0 1 2 0 2;
157+
0 3 0 0 4 0;
158+
3 0 3 4 0 4])
159+
@test @inferred(kron(@SMatrix([1 2; 3 4]), @SMatrix([2.0]))) === @SMatrix [2.0 4.0; 6.0 8.0]
160+
161+
# Output should be heap allocated into a SizedArray when it gets large
162+
# enough.
163+
M1 = collect(1:20)
164+
M2 = collect(20:-1:1).'
165+
@test @inferred(kron(SMatrix{20,1}(M1),SMatrix{1,20}(M2)))::SizedMatrix{20,20} == kron(M1,M2)
166+
end
152167
end

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ include("eigen.jl")
3131
include("expm.jl")
3232
include("sqrtm.jl")
3333
include("lyap.jl")
34+
include("lu.jl")
3435
include("chol.jl")
3536
include("deque.jl")
3637
include("io.jl")

test/util.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using StaticArrays, Base.Test
2+
3+
import StaticArrays: drop_sdims
4+
5+
@testset "util" begin
6+
@test !(drop_sdims(SVector(1,2)) isa StaticArray)
7+
@test !(drop_sdims([1,2]) isa StaticArray)
8+
@test !(drop_sdims(SizedVector{2}([1,2])) isa StaticArray)
9+
10+
@test drop_sdims(SVector(1,2)) == SVector(1,2)
11+
@test drop_sdims(@SMatrix [1 2; 3 4]) == [1 2; 3 4]
12+
# Check this works for SizedArray where it's tempting to *unwrap* rather
13+
# than add an extra wrapper. Currently unwrapping doesn't work due to
14+
# reshaping issues.
15+
@test drop_sdims(SizedMatrix{2,2}([1 2; 3 4])) == [1 2; 3 4]
16+
@test drop_sdims(SizedMatrix{2,3}([1 4;
17+
2 5;
18+
3 6])) == [1 3 5;
19+
2 4 6]
20+
end

0 commit comments

Comments
 (0)