1- struct CartesianProduct{A,B}
1+ struct CartesianPair{A,B}
2+ a:: A
3+ b:: B
4+ end
5+ arguments (a:: CartesianPair ) = (a. a, a. b)
6+ arguments (a:: CartesianPair , n:: Int ) = arguments (a)[n]
7+
8+ arg1 (a:: CartesianPair ) = a. a
9+ arg2 (a:: CartesianPair ) = a. b
10+
11+ × (a, b) = CartesianPair (a, b)
12+
13+ function Base. show (io:: IO , a:: CartesianPair )
14+ print (io, a. a, " × " , a. b)
15+ return nothing
16+ end
17+
18+ struct CartesianProduct{TA,TB,A<: AbstractVector{TA} ,B<: AbstractVector{TB} } < :
19+ AbstractVector{CartesianPair{TA,TB}}
220 a:: A
321 b:: B
422end
@@ -13,15 +31,19 @@ function Base.show(io::IO, a::CartesianProduct)
1331 return nothing
1432end
1533
16- × (a, b) = CartesianProduct (a, b)
34+ × (a:: AbstractVector , b:: AbstractVector ) = CartesianProduct (a, b)
1735Base. length (a:: CartesianProduct ) = length (a. a) * length (a. b)
18- Base. getindex (a:: CartesianProduct , i :: CartesianProduct ) = a . a[i . a] × a . b[i . b]
36+ Base. size (a:: CartesianProduct ) = ( length (a),)
1937
20- function Base. iterate (a:: CartesianProduct , state... )
21- x = iterate (Iterators. product (a. a, a. b), state... )
22- isnothing (x) && return x
23- next, new_state = x
24- return × (next... ), new_state
38+ function Base. getindex (a:: CartesianProduct , i:: CartesianProduct )
39+ return arg1 (a)[arg1 (i)] × arg2 (a)[arg2 (i)]
40+ end
41+ function Base. getindex (a:: CartesianProduct , i:: CartesianPair )
42+ return arg1 (a)[arg1 (i)] × arg2 (a)[arg2 (i)]
43+ end
44+ function Base. getindex (a:: CartesianProduct , i:: Int )
45+ I = Tuple (CartesianIndices ((length (arg1 (a)), length (arg2 (a))))[i])
46+ return a[I[1 ] × I[2 ]]
2547end
2648
2749struct CartesianProductUnitRange{T,P<: CartesianProduct ,R<: AbstractUnitRange{T} } < :
4769to_range (a:: AbstractUnitRange ) = a
4870to_range (i:: Integer ) = Base. OneTo (i)
4971cartesianrange (a, b) = cartesianrange (to_range (a) × to_range (b))
72+ function cartesianrange (p:: CartesianPair )
73+ p′ = to_range (p. a) × to_range (p. b)
74+ return cartesianrange (p′)
75+ end
5076function cartesianrange (p:: CartesianProduct )
5177 p′ = to_range (p. a) × to_range (p. b)
5278 return cartesianrange (p′, Base. OneTo (length (p′)))
5379end
80+ function cartesianrange (p:: CartesianPair , range:: AbstractUnitRange )
81+ p′ = to_range (p. a) × to_range (p. b)
82+ return cartesianrange (p′, range)
83+ end
5484function cartesianrange (p:: CartesianProduct , range:: AbstractUnitRange )
5585 p′ = to_range (p. a) × to_range (p. b)
5686 return CartesianProductUnitRange (p′, range)
0 commit comments