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}}
2
20
a:: A
3
21
b:: B
4
22
end
@@ -13,15 +31,19 @@ function Base.show(io::IO, a::CartesianProduct)
13
31
return nothing
14
32
end
15
33
16
- × (a, b) = CartesianProduct (a, b)
34
+ × (a:: AbstractVector , b:: AbstractVector ) = CartesianProduct (a, b)
17
35
Base. 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),)
19
37
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 ]]
25
47
end
26
48
27
49
struct CartesianProductUnitRange{T,P<: CartesianProduct ,R<: AbstractUnitRange{T} } < :
44
66
function CartesianProductUnitRange (a, b)
45
67
return CartesianProductUnitRange (a × b)
46
68
end
47
- to_range (a:: AbstractUnitRange ) = a
48
- to_range (i:: Integer ) = Base. OneTo (i)
49
- cartesianrange (a, b) = cartesianrange (to_range (a) × to_range (b))
69
+ to_product_indices (a:: AbstractUnitRange ) = a
70
+ to_product_indices (i:: Integer ) = Base. OneTo (i)
71
+ cartesianrange (a, b) = cartesianrange (to_product_indices (a) × to_product_indices (b))
72
+ function cartesianrange (p:: CartesianPair )
73
+ p′ = to_product_indices (arg1 (p)) × to_product_indices (arg2 (p))
74
+ return cartesianrange (p′)
75
+ end
50
76
function cartesianrange (p:: CartesianProduct )
51
- p′ = to_range (p . a) × to_range (p . b )
77
+ p′ = to_product_indices ( arg1 (p)) × to_product_indices ( arg2 (p) )
52
78
return cartesianrange (p′, Base. OneTo (length (p′)))
53
79
end
80
+ function cartesianrange (p:: CartesianPair , range:: AbstractUnitRange )
81
+ p′ = to_product_indices (arg1 (p)) × to_product_indices (arg2 (p))
82
+ return cartesianrange (p′, range)
83
+ end
54
84
function cartesianrange (p:: CartesianProduct , range:: AbstractUnitRange )
55
- p′ = to_range (p . a) × to_range (p . b )
85
+ p′ = to_product_indices ( arg1 (p)) × to_product_indices ( arg2 (p) )
56
86
return CartesianProductUnitRange (p′, range)
57
87
end
58
88
59
89
function Base. axes (r:: CartesianProductUnitRange )
60
- return (CartesianProductUnitRange (r. product, only (axes (r. range))),)
90
+ return (CartesianProductUnitRange (cartesianproduct (r), only (axes (unproduct (r)))),)
91
+ end
92
+
93
+ function Base. checkindex (:: Type{Bool} , inds:: CartesianProductUnitRange , i:: CartesianPair )
94
+ return checkindex (Bool, arg1 (inds), arg1 (i)) && checkindex (Bool, arg2 (inds), arg2 (i))
61
95
end
62
96
63
97
using Base. Broadcast: DefaultArrayStyle
@@ -66,12 +100,12 @@ for f in (:+, :-)
66
100
function Broadcast. broadcasted (
67
101
:: DefaultArrayStyle{1} , :: typeof ($ f), r:: CartesianProductUnitRange , x:: Integer
68
102
)
69
- return CartesianProductUnitRange (r . product , $ f .(r . range , x))
103
+ return CartesianProductUnitRange (cartesianproduct (r) , $ f .(unproduct (r) , x))
70
104
end
71
105
function Broadcast. broadcasted (
72
106
:: DefaultArrayStyle{1} , :: typeof ($ f), x:: Integer , r:: CartesianProductUnitRange
73
107
)
74
- return CartesianProductUnitRange (r . product , $ f .(x, r . range ))
108
+ return CartesianProductUnitRange (cartesianproduct (r) , $ f .(x, unproduct (r) ))
75
109
end
76
110
end
77
111
end
0 commit comments