Skip to content

Commit b771251

Browse files
authored
Norms for CachedVector, vector views of Hcat are ApplyLayout{typeof(vcat)} (#81)
* Add norm for cache, support vector hcats * Actually its a ApplyLayout{typeof(vcat)} * Update runtests.jl * Hcat simple broadcast * Add `@inline` * ambiguity fixes * Add more tests, simplify overrides * v0.14.7
1 parent 776cf66 commit b771251

File tree

6 files changed

+79
-26
lines changed

6 files changed

+79
-26
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "LazyArrays"
22
uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02"
3-
version = "0.14.6"
3+
version = "0.14.7"
44

55

66
[deps]

src/cache.jl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,20 +199,23 @@ broadcasted(::LazyArrayStyle, op, c::Ref, A::CachedArray) =
199199
CachedArray(broadcast(op, c, paddeddata(A)), broadcast(op, c, A.array))
200200

201201

202-
function broadcasted(::LazyArrayStyle, op, A::CachedVector, B::AbstractVector)
202+
function cache_broadcast(op, A::CachedVector, B)
203203
dat = paddeddata(A)
204204
n = length(dat)
205205
m = length(B)
206206
CachedArray(broadcast(op, dat, view(B,1:n)), broadcast(op, A.array, B))
207207
end
208208

209-
function broadcasted(::LazyArrayStyle, op, A::AbstractVector, B::CachedVector)
209+
function cache_broadcast(op, A, B::CachedVector)
210210
dat = paddeddata(B)
211211
n = length(dat)
212212
m = length(A)
213213
CachedArray(broadcast(op, view(A,1:n), dat), broadcast(op, A, B.array))
214214
end
215215

216+
broadcasted(::LazyArrayStyle, op, A::CachedVector, B::AbstractVector) = cache_broadcast(op, A, B)
217+
broadcasted(::LazyArrayStyle, op, A::AbstractVector, B::CachedVector) = cache_broadcast(op, A, B)
218+
216219
function broadcasted(::LazyArrayStyle, op, A::CachedVector, B::CachedVector)
217220
n = max(A.datasize[1],B.datasize[1])
218221
resizedata!(A,n)
@@ -222,3 +225,11 @@ function broadcasted(::LazyArrayStyle, op, A::CachedVector, B::CachedVector)
222225
CachedArray(broadcast(op, Adat, Bdat), broadcast(op, A.array, B.array))
223226
end
224227

228+
###
229+
# norm
230+
###
231+
232+
norm1(a::CachedVector) = norm(paddeddata(a),1) + norm(@view(a.array[a.datasize[1]+1:end]),1)
233+
norm2(a::CachedVector) = sqrt(norm(paddeddata(a),2)^2 + norm(@view(a.array[a.datasize[1]+1:end]),2)^2)
234+
normInf(a::CachedVector) = max(norm(paddeddata(a),Inf), norm(@view(a.array[a.datasize[1]+1:end]),Inf))
235+
normp(a::CachedVector, p) = (norm(paddeddata(a),2)^p + norm(@view(a.array[a.datasize[1]+1:end]),2)^p)^inv(p)

src/lazyapplying.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ arguments(a::AbstractArray) = arguments(MemoryLayout(typeof(a)), a)
2626

2727
@inline check_applied_axes(A::Applied) = nothing
2828

29-
function instantiate(A::Applied{Style}) where Style
29+
@inline function instantiate(A::Applied{Style}) where Style
3030
check_applied_axes(A)
3131
Applied{Style}(A.f, map(instantiate, A.args))
3232
end
@@ -45,28 +45,28 @@ end
4545
@inline apply(f, args...) = materialize(applied(f, args...))
4646
@inline apply!(f, args...) = materialize!(applied(f, args...))
4747

48-
materialize(A::Applied) = copy(instantiate(A))
49-
materializeargs(A::Applied) = applied(A.f, materialize.(A.args)...)
48+
@inline materialize(A::Applied) = copy(instantiate(A))
49+
@inline materializeargs(A::Applied) = applied(A.f, materialize.(A.args)...)
5050

5151
# the following materialzes the args and calls materialize again, unless it hasn't
5252
# changed in which case it falls back to the default
53-
_default_materialize(A::App, ::App) where App = A.f(A.args...)
54-
_default_materialize(A, _) = materialize(A)
53+
@inline _default_materialize(A::App, ::App) where App = A.f(A.args...)
54+
@inline _default_materialize(A, _) = materialize(A)
5555
# copy(A::Applied{DefaultApplyStyle}) = A.f(A.args...)
56-
copy(A::Applied) = _default_materialize(materializeargs(A), A)
56+
@inline copy(A::Applied) = _default_materialize(materializeargs(A), A)
5757

5858
@inline copyto!(dest, M::Applied) = copyto!(dest, materialize(M))
5959
@inline copyto!(dest::AbstractArray, M::Applied) = copyto!(dest, materialize(M))
6060

61-
broadcastable(M::Applied) = M
61+
@inline broadcastable(M::Applied) = M
6262

6363

6464

6565
similar(M::Applied{<:AbstractArrayApplyStyle}, ::Type{T}, axes) where {T,N} = Array{T}(undef, length.(axes))
6666
similar(M::Applied{<:AbstractArrayApplyStyle}, ::Type{T}) where T = similar(M, T, axes(M))
6767
similar(M::Applied) = similar(M, eltype(M))
6868

69-
axes(A::Applied, j) = axes(A)[j]
69+
@inline axes(A::Applied, j) = axes(A)[j]
7070

7171
struct ApplyArrayBroadcastStyle{N} <: Broadcast.AbstractArrayStyle{N} end
7272
ApplyArrayBroadcastStyle{N}(::Val{N}) where N = ApplyArrayBroadcastStyle{N}()

src/lazyconcat.jl

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -289,14 +289,18 @@ BroadcastStyle(::Type{<:Hcat{<:Any}}) where N = LazyArrayStyle{2}()
289289
broadcasted(::LazyArrayStyle, op, A::Vcat) =
290290
Vcat(broadcast(x -> broadcast(op, x), A.args)...)
291291

292-
broadcasted(::LazyArrayStyle, op, A::Vcat, c::Number) =
293-
Vcat(broadcast((x,y) -> broadcast(op, x, y), A.args, c)...)
294-
broadcasted(::LazyArrayStyle, op, c::Number, A::Vcat) =
295-
Vcat(broadcast((x,y) -> broadcast(op, x, y), c, A.args)...)
296-
broadcasted(::LazyArrayStyle, op, A::Vcat, c::Ref) =
297-
Vcat(broadcast((x,y) -> broadcast(op, x, Ref(y)), A.args, c)...)
298-
broadcasted(::LazyArrayStyle, op, c::Ref, A::Vcat) =
299-
Vcat(broadcast((x,y) -> broadcast(op, Ref(x), y), c, A.args)...)
292+
for Cat in (:Vcat, :Hcat)
293+
@eval begin
294+
broadcasted(::LazyArrayStyle, op, A::$Cat, c::Number) =
295+
$Cat(broadcast((x,y) -> broadcast(op, x, y), A.args, c)...)
296+
broadcasted(::LazyArrayStyle, op, c::Number, A::$Cat) =
297+
$Cat(broadcast((x,y) -> broadcast(op, x, y), c, A.args)...)
298+
broadcasted(::LazyArrayStyle, op, A::$Cat, c::Ref) =
299+
$Cat(broadcast((x,y) -> broadcast(op, x, Ref(y)), A.args, c)...)
300+
broadcasted(::LazyArrayStyle, op, c::Ref, A::$Cat) =
301+
$Cat(broadcast((x,y) -> broadcast(op, Ref(x), y), c, A.args)...)
302+
end
303+
end
300304

301305

302306
# determine indices of components of a vcat
@@ -314,7 +318,7 @@ function broadcasted(::LazyArrayStyle, op, A::Vcat{<:Any,1}, B::AbstractVector)
314318
B_arrays = _vcat_getindex_eval(B,kr...) # evaluate B at same chunks as A
315319
ApplyVector(vcat, broadcast((a,b) -> broadcast(op,a,b), A.args, B_arrays)...)
316320
end
317-
321+
318322
function broadcasted(::LazyArrayStyle, op, A::AbstractVector, B::Vcat{<:Any,1})
319323
kr = _vcat_axes(axes.(B.args)...)
320324
A_arrays = _vcat_getindex_eval(A,kr...)
@@ -325,6 +329,14 @@ end
325329
broadcasted(::LazyArrayStyle, op, A::Vcat{<:Any,1}, B::Vcat{<:Any,1}) =
326330
Broadcasted{LazyArrayStyle}(op, (A, B))
327331

332+
# ambiguities
333+
broadcasted(::LazyArrayStyle, op, A::Vcat{<:Any,1}, B::CachedVector) = cache_broadcast(op, A, B)
334+
broadcasted(::LazyArrayStyle, op, A::CachedVector, B::Vcat{<:Any,1}) = cache_broadcast(op, A, B)
335+
336+
broadcasted(::LazyArrayStyle{1}, ::typeof(*), a::Vcat{<:Any,1}, b::Zeros{<:Any,1})=
337+
broadcast(DefaultArrayStyle{1}(), *, a, b)
338+
339+
328340

329341
function +(A::Vcat, B::Vcat)
330342
size(A) == size(B) || throw(DimensionMismatch("dimensions must match."))
@@ -477,7 +489,7 @@ function materialize!(M::MatMulVecAdd{ApplyLayout{typeof(hcat)},ApplyLayout{type
477489
####
478490

479491

480-
most(a) = reverse(tail(reverse(a)))
492+
most(a) = reverse(tail(reverse(a)))
481493
colsupport(M::Vcat, j) = first(colsupport(first(M.args),j)):(size(Vcat(most(M.args)...),1)+last(colsupport(last(M.args),j)))
482494

483495

@@ -556,6 +568,8 @@ end
556568

557569
sublayout(::ApplyLayout{typeof(vcat)}, _) = ApplyLayout{typeof(vcat)}()
558570
sublayout(::ApplyLayout{typeof(hcat)}, _) = ApplyLayout{typeof(hcat)}()
571+
# a row-slice of an Hcat is equivalent to a Vcat
572+
sublayout(::ApplyLayout{typeof(hcat)}, ::Type{<:Tuple{Number,AbstractVector}}) = ApplyLayout{typeof(vcat)}()
559573

560574
arguments(::ApplyLayout{typeof(vcat)}, V::SubArray{<:Any,2,<:Any,<:Tuple{<:Slice,<:Any}}) =
561575
view.(arguments(parent(V)), Ref(:), Ref(parentindices(V)[2]))
@@ -575,14 +589,17 @@ _view_vcat(a::Number, kr) = Fill(a,length(kr))
575589
_view_vcat(a::Number, kr, jr) = Fill(a,length(kr), length(jr))
576590
_view_vcat(a, kr...) = view(a, kr...)
577591

578-
function arguments(::ApplyLayout{typeof(vcat)}, V::SubArray{<:Any,1})
579-
A = parent(V)
592+
function _vcat_sub_arguments(::ApplyLayout{typeof(vcat)}, A, V)
580593
kr = parentindices(V)[1]
581594
sz = size.(arguments(A),1)
582595
skr = intersect.(_argsindices(sz), Ref(kr))
583596
skr2 = broadcast((a,b) -> a .- b .+ 1, skr, _vcat_firstinds(sz))
584597
_view_vcat.(arguments(A), skr2)
585598
end
599+
_vcat_sub_arguments(::ApplyLayout{typeof(hcat)}, A, V) = arguments(ApplyLayout{typeof(hcat)}(), V)
600+
601+
_vcat_sub_arguments(A, V) = _vcat_sub_arguments(MemoryLayout(typeof(A)), A, V)
602+
arguments(::ApplyLayout{typeof(vcat)}, V::SubArray{<:Any,1}) = _vcat_sub_arguments(parent(V), V)
586603

587604
function arguments(::ApplyLayout{typeof(vcat)}, V::SubArray{<:Any,2})
588605
A = parent(V)
@@ -596,7 +613,7 @@ end
596613
_view_hcat(a::Number, kr, jr) = Fill(a,length(kr),length(jr))
597614
_view_hcat(a, kr, jr) = view(a, kr, jr)
598615

599-
function arguments(::ApplyLayout{typeof(hcat)}, V::SubArray{<:Any,2})
616+
function arguments(::ApplyLayout{typeof(hcat)}, V::SubArray)
600617
A = parent(V)
601618
kr,jr = parentindices(V)
602619
sz = size.(arguments(A),2)
@@ -628,6 +645,7 @@ function sub_materialize(::ApplyLayout{typeof(hcat)}, V)
628645
end
629646
ret
630647
end
648+
631649
# temporarily allocate. In the future, we add a loop over arguments
632650
materialize!(M::MatMulMatAdd{<:AbstractColumnMajor,<:ApplyLayout{typeof(vcat)}}) =
633651
materialize!(MulAdd(M.α,M.A,Array(M.B),M.β,M.C))

test/concattests.jl

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using LazyArrays, FillArrays, LinearAlgebra, StaticArrays, Test
22
import LazyArrays: MemoryLayout, DenseColumnMajor, PaddedLayout, materialize!,
3-
MulAdd, Applied, ApplyLayout, arguments, DefaultApplyStyle
3+
MulAdd, Applied, ApplyLayout, arguments, DefaultApplyStyle, sub_materialize
44

55
@testset "concat" begin
66
@testset "Vcat" begin
@@ -303,7 +303,7 @@ import LazyArrays: MemoryLayout, DenseColumnMajor, PaddedLayout, materialize!,
303303
@test materialize!(MulAdd(1.1,A,B,2.2,[5.0 6; 7 8])) 1.1*Matrix(A)*Matrix(B)+2.2*[5.0 6; 7 8]
304304
end
305305

306-
@testset "broadcast Vcat" begin
306+
@testset "broadcast" begin
307307
x = Vcat(1:2, [1,1,1,1,1], 3)
308308
y = 1:8
309309
f = (x,y) -> cos(x*y)
@@ -328,6 +328,13 @@ import LazyArrays: MemoryLayout, DenseColumnMajor, PaddedLayout, materialize!,
328328
@test Vcat(1, Ones(5)) + Vcat(2, Fill(2.0,5)) Vcat(3, Fill(3.0,5))
329329
@test Vcat(SVector(1,2,3), Ones(5)) + Vcat(SVector(4,5,6), Fill(2.0,5))
330330
Vcat(SVector(5,7,9), Fill(3.0,5))
331+
332+
H = Hcat(1, zeros(1,10))
333+
@test H/2 isa Hcat
334+
@test 2\H isa Hcat
335+
@test H./Ref(2) isa Hcat
336+
@test Ref(2).\H isa Hcat
337+
@test H/2 == H./Ref(2) == 2\H == Ref(2) .\ H == [1/2 zeros(1,10)]
331338
end
332339

333340
@testset "maximum/minimum Vcat" begin
@@ -400,5 +407,10 @@ import LazyArrays: MemoryLayout, DenseColumnMajor, PaddedLayout, materialize!,
400407
@test MemoryLayout(typeof(V)) isa ApplyLayout{typeof(hcat)}
401408
VERSION v"1.1" && @inferred(arguments(V))
402409
@test arguments(V)[1] == reshape(3:5,3,1)
410+
411+
v = view(A,2,1:5)
412+
@test MemoryLayout(typeof(v)) isa ApplyLayout{typeof(vcat)}
413+
@test arguments(v) == ([2], zeros(4))
414+
@test A[2,1:5] == copy(v) == sub_materialize(v)
403415
end
404416
end

test/runtests.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,18 @@ end
244244
@test isempty(v[4:0])
245245
v = CachedArray([1,2,3],Fill{Int}(1,1000))
246246
@test v[3:100] == [3; ones(97)]
247+
@test norm(v) == norm(Array(v)) == norm(v,2)
248+
@test norm(v,1) == norm(Array(v),1)
249+
@test norm(v,Inf) == norm(Array(v),Inf)
250+
@test norm(v,3) == norm(Array(v),3)
251+
end
252+
253+
@testset "ambiguity broadcast" begin
254+
c = cache(1:100)
255+
v = Vcat([1,2,3],0:96)
256+
z = Zeros(100)
257+
@test v .+ c == c .+ v == Array(c) + Array(v)
258+
@test z .+ c == c .+ z == Array(c)
247259
end
248260
end
249261

0 commit comments

Comments
 (0)