Skip to content

Commit f3ba15c

Browse files
felixcremerFelix Cremerrafaqz
authored
Add functionality to use arbitrary singular values in ConcatDiskArrays (#256)
* Add test case for zero fill concatdiskarray * Enable arbitrary single values in concatDiskArray * Update src/cat.jl Co-authored-by: Rafael Schouten <[email protected]> * Update src/cat.jl Co-authored-by: Rafael Schouten <[email protected]> * Apply review Co-authored-by: Rafael Schouten <[email protected]> * Wrap fill values in MissingTile for ConcatDiskArray This introduces a MissingTile type to wrap the values for ConcatDiskArray. This allows to use vectors as elements in the fillvalue. --------- Co-authored-by: Felix Cremer <[email protected]> Co-authored-by: Rafael Schouten <[email protected]>
1 parent 2c4f0da commit f3ba15c

File tree

3 files changed

+85
-19
lines changed

3 files changed

+85
-19
lines changed

src/cat.jl

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
"""
32
ConcatDiskArray <: AbstractDiskArray
43
@@ -31,16 +30,17 @@ function ConcatDiskArray(arrays::AbstractArray{Union{<:AbstractArray,Missing}})
3130
M = ndims(et)
3231
_ConcatDiskArray(arrays, T, Val(N), Val(M))
3332
end
33+
3434
function infer_eltypes(arrays)
3535
foldl(arrays, init=(-1, Union{})) do (M, T), a
36-
if ismissing(a)
37-
(M, promote_type(Missing, T))
38-
else
36+
if a isa AbstractArray
3937
M == -1 || ndims(a) == M || throw(ArgumentError("All arrays to concatenate must have equal ndims"))
40-
(ndims(a), promote_type(eltype(a), T))
38+
M = ndims(a)
39+
end
40+
(M, promote_type(eltype(a), T))
4141
end
4242
end
43-
end
43+
4444
function ConcatDiskArray(arrays::AbstractArray{<:AbstractArray})
4545
N = ndims(arrays)
4646
T = eltype(eltype(arrays))
@@ -78,6 +78,11 @@ function ConcatDiskArray(arrays1::AbstractArray, T, ::Val{D},::Val{ID}) where {D
7878
return ConcatDiskArray{T,D,typeof(arrays1),typeof(chunks),typeof(hc),ID}(arrays1, startinds, sizes, chunks, hc,Val(ID))
7979
end
8080

81+
struct MissingTile{F}
82+
fillvalue::F
83+
end
84+
Base.eltype(::Type{MissingTile{F}}) where F = F
85+
8186
function extenddims(a::Tuple{Vararg{Any,N}}, b::Tuple{Vararg{Any,M}}, fillval) where {N,M}
8287
length(a) > length(b) && error("Wrong")
8388
extenddims((a..., fillval), b, fillval)
@@ -90,7 +95,7 @@ function arraysize_and_startinds(arrays1)
9095
sizes = map(i -> zeros(Int, i), size(arrays1))
9196
for i in CartesianIndices(arrays1)
9297
ai = arrays1[i]
93-
ismissing(ai) && continue
98+
ai isa MissingTile && continue
9499
sizecur = extenddims(size(ai), size(arrays1), 1)
95100
foreach(sizecur, i.I, sizes) do si, ind, sizeall
96101
if sizeall[ind] == 0
@@ -123,10 +128,10 @@ function readblock!(a::ConcatDiskArray, aout, inds::AbstractUnitRange...)
123128
# Find affected blocks and indices in blocks
124129
_concat_diskarray_block_io(a, inds...) do outer_range, array_range, I
125130
vout = view(aout, outer_range...)
126-
if ismissing(I)
127-
vout .= missing
128-
else
131+
if I isa CartesianIndex
129132
readblock!(a.parents[I], vout, array_range...)
133+
else
134+
vout .= (I.fillvalue,)
130135
end
131136
end
132137
end
@@ -170,8 +175,8 @@ function _concat_diskarray_block_io(f, a::ConcatDiskArray, inds...)
170175
#Shorten array range to shape of actual array
171176
array_range = ntuple(j -> array_range[j], ID)
172177
outer_range = fix_outerrangeshape(outer_range, array_range)
173-
if ismissing(myar)
174-
f(outer_range, array_range, missing)
178+
if myar isa MissingTile
179+
f(outer_range, array_range, myar)
175180
else
176181
f(outer_range, array_range, cI)
177182
end
@@ -189,13 +194,13 @@ function concat_chunksize(parents)
189194
newchunks = map(s -> Vector{Union{RegularChunks,IrregularChunks}}(undef, s), size(parents))
190195
for i in CartesianIndices(parents)
191196
array = parents[i]
192-
ismissing(array) && continue
197+
array isa MissingTile && continue
193198
chunks = eachchunk(array)
194199
foreach(chunks.chunks, i.I, newchunks) do c, ind, newc
195200
if !isassigned(newc, ind)
196201
newc[ind] = c
197202
elseif c != newc[ind]
198-
throw(ArgumentError("Chunk sizes don't forma grid"))
203+
throw(ArgumentError("Chunk sizes don't form a grid"))
199204
end
200205
end
201206
end

src/subarray.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ function eachchunk_view(::Chunked, vv)
4444
end
4545
eachchunk_view(::Unchunked, a) = estimate_chunksize(a)
4646

47-
# Implementaion macro
47+
# Implementation macro
4848

4949
macro implement_subarray(t)
5050
t = esc(t)

test/runtests.jl

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -492,22 +492,52 @@ end
492492
@test slic == Float64[1, 2, 3, 4, 1, 2, 3, 4]
493493
end
494494

495+
@testset "Concat DiskArray with fill zero tiles" begin
496+
a = zeros(Int, 3, 4)
497+
b = ones(Int, 2, 4)
498+
c = fill(2, 3, 5)
499+
d = fill(0, 2, 5)
500+
aconc = DiskArrays.ConcatDiskArray(reshape([a, b, c, DiskArrays.MissingTile(0)], 2, 2))
501+
abase = [a c; b d]
502+
@test all(isequal.(aconc[:, :], abase))
503+
@test all(isequal.(aconc[3:4, 4:6], abase[3:4, 4:6]))
504+
ch = DiskArrays.eachchunk(aconc)
505+
@test ch.chunks[1] == [1:3, 4:5]
506+
@test ch.chunks[2] == [1:4, 5:9]
507+
@test eltype(aconc) == Int
508+
509+
a = ones(100, 50)
510+
b = [rem(i.I[3], 5) == 0 ? DiskArrays.MissingTile(0) : a for i in CartesianIndices((1, 1, 100))]
511+
b[1] = DiskArrays.MissingTile(0)
512+
a_conc = DiskArrays.ConcatDiskArray(b)
513+
ch = eachchunk(a_conc)
514+
@test ch.chunks[1] == [1:100]
515+
@test ch.chunks[2] == [1:50]
516+
@test ch.chunks[3] === DiskArrays.RegularChunks(1, 0, 100)
517+
518+
@test all(isequal.(a_conc[2, 2, 1:5], [0, 1.0, 1.0, 1.0, 0]))
519+
@test all(isequal.(a_conc[end, end, 95:100], [0, 1.0, 1.0, 1.0, 1.0, 0]))
520+
521+
end
522+
523+
495524
@testset "Concat DiskArray with missing tiles" begin
496525
a = zeros(Int, 3, 4)
497526
b = ones(Int, 2, 4)
498527
c = fill(2, 3, 5)
499528
d = fill(missing, 2, 5)
500-
aconc = DiskArrays.ConcatDiskArray(reshape([a, b, c, missing], 2, 2))
529+
aconc = DiskArrays.ConcatDiskArray(reshape([a, b, c, DiskArrays.MissingTile(missing)], 2, 2))
501530
abase = [a c; b d]
502531
@test all(isequal.(aconc[:, :], abase))
503532
@test all(isequal.(aconc[3:4, 4:6], abase[3:4, 4:6]))
504533
ch = DiskArrays.eachchunk(aconc)
505534
@test ch.chunks[1] == [1:3, 4:5]
506535
@test ch.chunks[2] == [1:4, 5:9]
536+
@test eltype(aconc) == Union{Int, Missing}
507537

508538
a = ones(100, 50)
509-
b = [rem(i.I[3], 5) == 0 ? missing : a for i in CartesianIndices((1, 1, 100))]
510-
b[1] = missing
539+
b = [rem(i.I[3], 5) == 0 ? DiskArrays.MissingTile(missing) : a for i in CartesianIndices((1, 1, 100))]
540+
b[1] = DiskArrays.MissingTile(missing)
511541
a_conc = DiskArrays.ConcatDiskArray(b)
512542
ch = eachchunk(a_conc)
513543
@test ch.chunks[1] == [1:100]
@@ -518,6 +548,35 @@ end
518548
@test all(isequal.(a_conc[end, end, 95:100], [missing, 1.0, 1.0, 1.0, 1.0, missing]))
519549

520550
end
551+
552+
@testset "Concat DiskArray with fill zero vector tiles" begin
553+
a = fill([1,1], 3, 4)
554+
b = fill([1,2], 2, 4)
555+
c = fill([2,1], 3, 5)
556+
d = fill([2,2], 2, 5)
557+
aconc = DiskArrays.ConcatDiskArray(reshape([a, b, c, DiskArrays.MissingTile([2,2])], 2, 2))
558+
abase = [a c; b d]
559+
@test all(isequal.(aconc[:, :], abase))
560+
@test all(isequal.(aconc[3:4, 4:6], abase[3:4, 4:6]))
561+
ch = DiskArrays.eachchunk(aconc)
562+
@test ch.chunks[1] == [1:3, 4:5]
563+
@test ch.chunks[2] == [1:4, 5:9]
564+
@test eltype(aconc) == Vector{Int}
565+
566+
a = fill([1,1], 100, 50)
567+
b = [rem(i.I[3], 5) == 0 ? DiskArrays.MissingTile([0,0]) : a for i in CartesianIndices((1, 1, 100))]
568+
b[1] = DiskArrays.MissingTile([0,0])
569+
a_conc = DiskArrays.ConcatDiskArray(b)
570+
ch = eachchunk(a_conc)
571+
@test ch.chunks[1] == [1:100]
572+
@test ch.chunks[2] == [1:50]
573+
@test ch.chunks[3] === DiskArrays.RegularChunks(1, 0, 100)
574+
575+
@test all(isequal.(a_conc[2, 2, 1:5], [[0,0], [1,1],[1,1] , [1,1], [0,0]]))
576+
@test all(isequal.(a_conc[end, end, 95:100], [[0,0], [1,1], [1,1], [1,1],[1,1], [0,0]]))
577+
578+
end
579+
521580
end
522581

523582
@testset "Broadcast with length 1 and 0 final dim" begin
@@ -929,8 +988,10 @@ struct TestArray{T,N} <: AbstractArray{T,N} end
929988
DiskArrays.@implement_array_methods TestArray
930989
DiskArrays.@implement_permutedims TestArray
931990
DiskArrays.@implement_subarray TestArray
932-
DiskArrays.@implement_diskarray TestArray
933991
@test DiskArrays.isdisk(TestArray) == true
992+
DiskArrays.@implement_diskarray TestArray2
993+
@test DiskArrays.isdisk(TestArray2) == true
994+
934995
end
935996

936997
# issue #123

0 commit comments

Comments
 (0)