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