From 8284afff84cfa4a642711b3b1c559d5eff0326eb Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Fri, 10 Mar 2017 16:32:35 -0600 Subject: [PATCH 1/2] Fix broadcast with RowVectors of matrices Fix #20979. Amusingly, this bug is a direct of `transpose` being recursive. --- base/linalg/rowvector.jl | 6 +++--- test/linalg/rowvector.jl | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/base/linalg/rowvector.jl b/base/linalg/rowvector.jl index ac4541ff39123..dfdb874d0ff57 100644 --- a/base/linalg/rowvector.jl +++ b/base/linalg/rowvector.jl @@ -144,12 +144,12 @@ end @inline to_vec(x::Number) = x @inline to_vecs(rowvecs...) = (map(to_vec, rowvecs)...) -# map -@inline map(f, rowvecs::RowVector...) = RowVector(map(f, to_vecs(rowvecs...)...)) +# map: Preserve the RowVector, but note that `f` expects transposed elements +@inline map(f, rowvecs::RowVector...) = RowVector(map(transpose∘f∘transpose, to_vecs(rowvecs...)...)) # broacast (other combinations default to higher-dimensional array) @inline broadcast(f, rowvecs::Union{Number,RowVector}...) = - RowVector(broadcast(f, to_vecs(rowvecs...)...)) + RowVector(broadcast(transpose∘f∘transpose, to_vecs(rowvecs...)...)) # Horizontal concatenation # diff --git a/test/linalg/rowvector.jl b/test/linalg/rowvector.jl index f188a3082c000..84ee28f29118e 100644 --- a/test/linalg/rowvector.jl +++ b/test/linalg/rowvector.jl @@ -249,3 +249,13 @@ end @test A'*x' == A'*y == B*x' == B*y == C' end end + +@testset "issue #20979" begin + f20979(z::Complex) = [z.re -z.im; z.im z.re] + v = [1+2im]' + @test (f20979.(v))[1] == f20979(v[1]) + @test f20979.(v) == f20979.(collect(v)) + + w = rand(Complex128, 3) + @test f20979.(v') == f20979.(collect(v')) == (f20979.(v))' +end From c1318e32121446255eb401deb1907dba5644eaa5 Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Sat, 11 Mar 2017 13:12:35 -0600 Subject: [PATCH 2/2] Support multi-argument map/broadcast --- base/linalg/rowvector.jl | 9 +++++---- test/linalg/rowvector.jl | 5 +++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/base/linalg/rowvector.jl b/base/linalg/rowvector.jl index dfdb874d0ff57..c1b43927c02d7 100644 --- a/base/linalg/rowvector.jl +++ b/base/linalg/rowvector.jl @@ -140,16 +140,17 @@ end @inline check_tail_indices(i1, i2, i3, is...) = i3 == 1 ? check_tail_indices(i1, i2, is...) : false # helper function for below -@inline to_vec(rowvec::RowVector) = transpose(rowvec) +@inline to_vec(rowvec::RowVector) = map(transpose, transpose(rowvec)) @inline to_vec(x::Number) = x @inline to_vecs(rowvecs...) = (map(to_vec, rowvecs)...) -# map: Preserve the RowVector, but note that `f` expects transposed elements -@inline map(f, rowvecs::RowVector...) = RowVector(map(transpose∘f∘transpose, to_vecs(rowvecs...)...)) +# map: Preserve the RowVector by un-wrapping and re-wrapping, but note that `f` +# expects to operate within the transposed domain, so to_vec transposes the elements +@inline map(f, rowvecs::RowVector...) = RowVector(map(transpose∘f, to_vecs(rowvecs...)...)) # broacast (other combinations default to higher-dimensional array) @inline broadcast(f, rowvecs::Union{Number,RowVector}...) = - RowVector(broadcast(transpose∘f∘transpose, to_vecs(rowvecs...)...)) + RowVector(broadcast(transpose∘f, to_vecs(rowvecs...)...)) # Horizontal concatenation # diff --git a/test/linalg/rowvector.jl b/test/linalg/rowvector.jl index 84ee28f29118e..92557c2561f4d 100644 --- a/test/linalg/rowvector.jl +++ b/test/linalg/rowvector.jl @@ -258,4 +258,9 @@ end w = rand(Complex128, 3) @test f20979.(v') == f20979.(collect(v')) == (f20979.(v))' + + g20979(x, y) = [x[2,1] x[1,2]; y[1,2] y[2,1]] + v = [rand(2,2), rand(2,2), rand(2,2)] + @test g20979.(v', v') == g20979.(collect(v'), collect(v')) == + map(g20979, v', v') == map(g20979, collect(v'), collect(v')) end