1+ throw_dimserror (dims:: Integer , N) = throw (ArgumentError (" dims = $dims does not satisfy 1 <= dims <= $N " ))
2+ throw_dimserror (dims, N) = throw (ArgumentError (" dims = $dims does not satisfy 1 <= dims <= $N for all elements" ))
3+
4+ throw_axesmismatcherror (dim, axexp, axrcv) = throw (
5+ DimensionMismatch (" axes mismatch in dimension $dim , expected $axexp but received $axrcv " ))
6+
7+ function _checkdims (A, dim, ax_exp)
8+ for a in A
9+ axadim = axes (a, dim)
10+ if axadim != ax_exp
11+ throw_axesmismatcherror (dim, ax_exp, axadim)
12+ end
13+ end
14+ end
15+
16+ function checkdims (A, dims)
17+ for (dim, ax_exp) in enumerate (axes (first (A)))
18+ if dim ∉ dims
19+ _checkdims (A, dim, ax_exp)
20+ end
21+ end
22+ end
23+
24+ function checkdims (A, d:: Integer )
25+ for (dim, ax_exp) in enumerate (axes (first (A)))
26+ dim == d && continue
27+ _checkdims (A, dim, ax_exp)
28+ end
29+ end
30+
31+ """
32+ ParallelUtilities.sumcat_aligned(A::AbstractArray{T,N}...; dims) where {T,N}
33+
34+ Concatenate the arrays along the dimensions `dims` according to their axes,
35+ with overlapping sections being summed over. Returns an `OffsetArray` with the minimal
36+ axes span encompassing all the arrays.
37+
38+ `dims` may be an `Integer` or a collection of `Integer`s, but all elements of `dims` must be from the range `1:N`.
39+
40+ # Examples
41+ ```jldoctest
42+ julia> ParallelUtilities.sumcat_aligned(ones(1:2), ones(4:5), dims=1)
43+ 5-element OffsetArray(::Array{Float64,1}, 1:5) with eltype Float64 with indices 1:5:
44+ 1.0
45+ 1.0
46+ 0.0
47+ 1.0
48+ 1.0
49+
50+ julia> ParallelUtilities.sumcat_aligned(ones(1:2, 1:2), ones(2:3, 2:3), dims=(1,2))
51+ 3×3 OffsetArray(::Array{Float64,2}, 1:3, 1:3) with eltype Float64 with indices 1:3×1:3:
52+ 1.0 1.0 0.0
53+ 1.0 2.0 1.0
54+ 0.0 1.0 1.0
55+
56+ julia> ParallelUtilities.sumcat_aligned(ones(1:2, 1:2), ones(3:4, 3:4), dims=(1,2))
57+ 4×4 OffsetArray(::Array{Float64,2}, 1:4, 1:4) with eltype Float64 with indices 1:4×1:4:
58+ 1.0 1.0 0.0 0.0
59+ 1.0 1.0 0.0 0.0
60+ 0.0 0.0 1.0 1.0
61+ 0.0 0.0 1.0 1.0
62+ ```
63+
64+ See also: [`sumhcat_aligned`](@ref), [`sumvcat_aligned`](@ref)
65+ """
66+ function sumcat_aligned (A:: AbstractArray{T,N} ...; dims) where {T,N}
67+
68+ all (x -> 1 <= x <= N, dims) || throw_dimserror (dims, N)
69+
70+ checkdims (A, dims)
71+
72+ ax = Vector {UnitRange{Int}} (undef, N)
73+ ax .= axes (first (A))
74+
75+ for d in dims
76+ axmin = minimum (minimum .(axes .(A, d)))
77+ axmax = maximum (maximum .(axes .(A, d)))
78+ ax[d] = axmin: axmax
79+ end
80+
81+ arr = OffsetArray {T,N} (undef, ax... )
82+ fill! (arr, zero (T))
83+
84+ for a in A
85+ arr[axes (a)... ] .+ = a
86+ end
87+ arr
88+ end
89+
90+ sumcat_aligned (A1:: AbstractArray ; dims) = (all (x -> 1 <= x <= ndims (A1), dims) || throw_dimserror (dims); A1)
91+
92+ """
93+ ParallelUtilities.sumvcat_aligned(A::AbstractArray{T,N}...) where {T,N}
94+
95+ Concatenate the arrays along the first dimension according to their axes,
96+ with overlapping sections being summed over. Returns an `OffsetArray` with the minimal
97+ axes span encompassing all the arrays.
98+
99+ The input arrays must be at least one-dimensional.
100+
101+ # Examples
102+ ```jldoctest
103+ julia> ParallelUtilities.sumvcat_aligned(ones(1:2), ones(4:5))
104+ 5-element OffsetArray(::Array{Float64,1}, 1:5) with eltype Float64 with indices 1:5:
105+ 1.0
106+ 1.0
107+ 0.0
108+ 1.0
109+ 1.0
110+
111+ julia> ParallelUtilities.sumvcat_aligned(ones(1:2, 1:2), ones(2:3, 1:2))
112+ 3×2 OffsetArray(::Array{Float64,2}, 1:3, 1:2) with eltype Float64 with indices 1:3×1:2:
113+ 1.0 1.0
114+ 2.0 2.0
115+ 1.0 1.0
116+ ```
117+
118+ See also: [`sumcat_aligned`](@ref), [`sumhcat_aligned`](@ref)
119+ """
120+ function sumvcat_aligned (A:: AbstractArray{T,N} ...) where {T,N}
121+
122+ N >= 1 || throw (ArgumentError (" all the arrays need to have at least 1 dimension" ))
123+ checkdims (A, 1 )
124+
125+ axmin = minimum (minimum .(axes .(A, 1 )))
126+ axmax = maximum (maximum .(axes .(A, 1 )))
127+
128+ axcat = axmin: axmax
129+
130+ trailing_axes = Base. tail (axes (first (A)))
131+
132+ arr = OffsetArray {T,N} (undef, axcat, trailing_axes... )
133+ fill! (arr, zero (T))
134+
135+ for axt in CartesianIndices (trailing_axes)
136+ for a in A, ind1 in axes (a,1 )
137+ arr[ind1, axt] += a[ind1, axt]
138+ end
139+ end
140+
141+ arr
142+ end
143+
144+ function sumvcat_aligned (A:: AbstractArray )
145+ ndims (A) >= 1 || throw (ArgumentError (" the array needs to have at least 1 dimension" ))
146+ A
147+ end
148+
149+ """
150+ ParallelUtilities.sumhcat_aligned(A::AbstractArray{T,N}...) where {T,N}
151+
152+ Concatenate the arrays along the second dimension according to their axes,
153+ with overlapping sections being summed over. Returns an `OffsetArray` with the minimal
154+ axes span encompassing all the arrays.
155+
156+ The input arrays must be at least two-dimensional.
157+
158+ # Examples
159+ ```jldoctest
160+ julia> ParallelUtilities.sumhcat_aligned(ones(2, 1:2), ones(2, 4:5))
161+ 2×5 OffsetArray(::Array{Float64,2}, 1:2, 1:5) with eltype Float64 with indices 1:2×1:5:
162+ 1.0 1.0 0.0 1.0 1.0
163+ 1.0 1.0 0.0 1.0 1.0
164+
165+ julia> ParallelUtilities.sumhcat_aligned(ones(1:2, 1:2), ones(1:2, 2:3))
166+ 2×3 OffsetArray(::Array{Float64,2}, 1:2, 1:3) with eltype Float64 with indices 1:2×1:3:
167+ 1.0 2.0 1.0
168+ 1.0 2.0 1.0
169+ ```
170+
171+ See also: [`sumcat_aligned`](@ref), [`sumvcat_aligned`](@ref)
172+ """
173+ function sumhcat_aligned (A:: AbstractArray{T,N} ...) where {T,N}
174+
175+ N >= 2 || throw (ArgumentError (" all the arrays need to have at least 2 dimensions" ))
176+ checkdims (A, 2 )
177+
178+ axmin = minimum (minimum .(axes .(A, 2 )))
179+ axmax = maximum (maximum .(axes .(A, 2 )))
180+
181+ axcat = axmin: axmax
182+
183+ trailing_axes = Base. tail (Base. tail (axes (first (A))))
184+
185+ arr = OffsetArray {T,N} (undef, axes (first (A),1 ), axcat, trailing_axes... )
186+ fill! (arr, zero (T))
187+
188+ for axt in CartesianIndices (trailing_axes)
189+ for a in A, ind2 in axes (a,2 ), ind1 in axes (a,1 )
190+ arr[ind1, ind2, axt] += a[ind1, ind2, axt]
191+ end
192+ end
193+
194+ arr
195+ end
196+
197+ function sumhcat_aligned (A:: AbstractArray )
198+ ndims (A) >= 2 || throw (ArgumentError (" the array needs to have at least 2 dimensions" ))
199+ A
200+ end
0 commit comments