Skip to content

Commit c7c4f96

Browse files
authored
sub–views of Vcat and Hcat (#72)
* sub–views of Vcat and Hcat * allow memorylayout for arguments * more subconcat * Update concattests.jl
1 parent 9599f64 commit c7c4f96

File tree

4 files changed

+113
-5
lines changed

4 files changed

+113
-5
lines changed

src/lazyapplying.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ end
1717
@inline Applied{Style}(A::Applied) where Style = Applied{Style}(A.f, A.args)
1818

1919
arguments(a) = a.args
20+
arguments(_, a) = a.args
21+
arguments(a::AbstractArray) = arguments(MemoryLayout(typeof(a)), a)
2022

2123
@inline check_applied_axes(A::Applied) = nothing
2224

src/lazyconcat.jl

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,3 +550,83 @@ for Cat in (:Vcat, :Hcat)
550550
end
551551
@eval normp(a::$Cat, p) = norm(norm.(a.args, p), p)
552552
end
553+
554+
555+
###
556+
# subarrays
557+
###
558+
559+
subarraylayout(::ApplyLayout{typeof(vcat)}, _) =
560+
ApplyLayout{typeof(vcat)}()
561+
subarraylayout(::ApplyLayout{typeof(hcat)}, _) =
562+
ApplyLayout{typeof(hcat)}()
563+
564+
arguments(::ApplyLayout{typeof(vcat)}, V::SubArray{<:Any,2,<:Any,<:Tuple{<:Slice,<:Any}}) =
565+
view.(arguments(parent(V)), Ref(:), Ref(parentindices(V)[2]))
566+
arguments(::ApplyLayout{typeof(hcat)}, V::SubArray{<:Any,2,<:Any,<:Tuple{<:Any,<:Slice}}) =
567+
view.(arguments(parent(V)), Ref(parentindices(V)[1]), Ref(:))
568+
569+
570+
_vcat_lastinds(sz) = _vcat_cumsum(sz...)
571+
_vcat_firstinds(sz) = (1, (1 .+ most(_vcat_lastinds(sz)))...)
572+
573+
_argsindices(sz) = broadcast(:, _vcat_firstinds(sz), _vcat_lastinds(sz))
574+
575+
_view_vcat(a::Number, kr) = Fill(a,length(kr))
576+
_view_vcat(a::Number, kr, jr) = Fill(a,length(kr), length(jr))
577+
_view_vcat(a, kr...) = view(a, kr...)
578+
579+
function arguments(::ApplyLayout{typeof(vcat)}, V::SubArray{<:Any,1})
580+
A = parent(V)
581+
kr = parentindices(V)[1]
582+
sz = size.(arguments(A),1)
583+
skr = intersect.(_argsindices(sz), Ref(kr))
584+
skr2 = broadcast((a,b) -> a .- b .+ 1, skr, _vcat_firstinds(sz))
585+
_view_vcat.(arguments(A), skr2)
586+
end
587+
588+
function arguments(::ApplyLayout{typeof(vcat)}, V::SubArray{<:Any,2})
589+
A = parent(V)
590+
kr,jr = parentindices(V)
591+
sz = size.(arguments(A),1)
592+
skr = intersect.(_argsindices(sz), Ref(kr))
593+
skr2 = broadcast((a,b) -> a .- b .+ 1, skr, _vcat_firstinds(sz))
594+
_view_vcat.(arguments(A), skr2, Ref(jr))
595+
end
596+
597+
_view_hcat(a::Number, kr, jr) = Fill(a,length(kr),length(jr))
598+
_view_hcat(a, kr, jr) = view(a, kr, jr)
599+
600+
function arguments(::ApplyLayout{typeof(hcat)}, V::SubArray{<:Any,2})
601+
A = parent(V)
602+
kr,jr = parentindices(V)
603+
sz = size.(arguments(A),2)
604+
sjr = intersect.(_argsindices(sz), Ref(jr))
605+
sjr2 = broadcast((a,b) -> a .- b .+ 1, sjr, _vcat_firstinds(sz))
606+
_view_hcat.(arguments(A), Ref(kr), sjr2)
607+
end
608+
609+
function sub_materialize(::ApplyLayout{typeof(vcat)}, V)
610+
ret = similar(V)
611+
n = 0
612+
_,jr = parentindices(V)
613+
for a in arguments(V)
614+
m = size(a,1)
615+
view(ret,n+1:n+m,:) .= a
616+
n += m
617+
end
618+
ret
619+
end
620+
621+
function sub_materialize(::ApplyLayout{typeof(hcat)}, V)
622+
ret = similar(V)
623+
n = 0
624+
kr,_ = parentindices(V)
625+
for a in arguments(V)
626+
m = size(a,2)
627+
view(ret,:,n+1:n+m) .= a
628+
n += m
629+
end
630+
ret
631+
end
632+

src/linalg/add.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ for MulAdd_ in [MatMulMatAdd, MatMulVecAdd]
6363
B = copy(B)
6464
end
6565
_fill_lmul!(β, C)
66-
for A in arguments(A)
67-
C .= applied(+,applied(*,α, A,B), C)
66+
for a in arguments(A)
67+
C .= applied(+,applied(*,α, a,B), C)
6868
end
6969
C
7070
end
@@ -86,11 +86,11 @@ end
8686
###
8787
# views
8888
####
89-
_view(a, b::Tuple) = view(a, b...)
89+
_view_tuple(a, b::Tuple) = view(a, b...)
9090
for op in (:+, :-)
9191
@eval begin
9292
subarraylayout(a::ApplyLayout{typeof($op)}, _) = a
9393
arguments(a::SubArray{<:Any,N,<:ApplyArray{<:Any,N,typeof($op)}}) where N =
94-
_view.(arguments(parent(a)), Ref(parentindices(a)))
94+
_view_tuple.(arguments(parent(a)), Ref(parentindices(a)))
9595
end
9696
end

test/concattests.jl

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using LazyArrays, FillArrays, LinearAlgebra, StaticArrays, Test
2-
import LazyArrays: MemoryLayout, DenseColumnMajor, PaddedLayout, materialize!, MulAdd, Applied, ApplyLayout
2+
import LazyArrays: MemoryLayout, DenseColumnMajor, PaddedLayout, materialize!, MulAdd, Applied, ApplyLayout, arguments
33

44
@testset "concat" begin
55
@testset "Vcat" begin
@@ -354,4 +354,30 @@ import LazyArrays: MemoryLayout, DenseColumnMajor, PaddedLayout, materialize!, M
354354
@test norm(a,p) norm(Array(a),p)
355355
end
356356
end
357+
358+
@testset "SubVcat" begin
359+
A = Vcat(1,[2,3], Fill(5,10))
360+
V = view(A,3:5)
361+
@test MemoryLayout(typeof(V)) isa ApplyLayout{typeof(vcat)}
362+
VERSION v"1.1" && @inferred(arguments(V))
363+
@test arguments(V)[1] Fill(1,0)
364+
@test A[parentindices(V)...] == copy(V) == Array(A)[parentindices(V)...]
365+
366+
A = Vcat((1:100)', Zeros(1,100),Fill(1,2,100))
367+
V = view(A,:,3:5)
368+
@test MemoryLayout(typeof(V)) isa ApplyLayout{typeof(vcat)}
369+
@test A[parentindices(V)...] == copy(V) == Array(A)[parentindices(V)...]
370+
V = view(A,2:3,3:5)
371+
@test MemoryLayout(typeof(V)) isa ApplyLayout{typeof(vcat)}
372+
@test A[parentindices(V)...] == copy(V) == Array(A)[parentindices(V)...]
373+
374+
A = Hcat(1:10, Zeros(10,10))
375+
V = view(A,3:5,:)
376+
@test MemoryLayout(typeof(V)) isa ApplyLayout{typeof(hcat)}
377+
@test A[parentindices(V)...] == copy(V) == Array(A)[parentindices(V)...]
378+
V = view(A,3:5,1:4)
379+
@test MemoryLayout(typeof(V)) isa ApplyLayout{typeof(hcat)}
380+
VERSION v"1.1" && @inferred(arguments(V))
381+
@test arguments(V)[1] == reshape(3:5,3,1)
382+
end
357383
end

0 commit comments

Comments
 (0)