2
2
const QuasiArrayMulArray{styleA, styleB, p, q, T, V} =
3
3
Mul2{styleA, styleB, <: AbstractQuasiArray{T,p} , <: AbstractArray{V,q} }
4
4
5
+ const ArrayMulQuasiArray{styleA, styleB, p, q, T, V} =
6
+ Mul2{styleA, styleB, <: AbstractArray{T,p} , <: AbstractQuasiArray{V,q} }
7
+
5
8
const QuasiArrayMulQuasiArray{styleA, styleB, p, q, T, V} =
6
9
Mul2{styleA, styleB, <: AbstractQuasiArray{T,p} , <: AbstractQuasiArray{V,q} }
7
10
# ###
@@ -13,7 +16,7 @@ const QuasiMatMulVec{styleA, styleB, T, V} = QuasiArrayMulArray{styleA, styleB,
13
16
function getindex (M:: QuasiMatMulVec , k:: Real )
14
17
A,B = M. factors
15
18
ret = zero (eltype (M))
16
- @inbounds for j = 1 : size (A,2 )
19
+ @inbounds for j in axes (A,2 )
17
20
ret += A[k,j] * B[j]
18
21
end
19
22
ret
22
25
function getindex (M:: QuasiMatMulVec , k:: AbstractArray )
23
26
A,B = M. factors
24
27
ret = zeros (eltype (M),length (k))
25
- @inbounds for j = 1 : size (A,2 )
28
+ @inbounds for j in axes (A,2 )
26
29
ret .+ = view (A,k,j) .* B[j]
27
30
end
28
31
ret
@@ -41,3 +44,114 @@ inv(A::AbstractQuasiArray) = materialize(Inv(A))
41
44
42
45
* (A:: AbstractQuasiArray , B:: Mul ) = materialize (Mul (A, B. factors... ))
43
46
* (A:: Mul , B:: AbstractQuasiArray ) = materialize (Mul (A. factors... , B))
47
+
48
+
49
+ # ###
50
+ # MulQuasiArray
51
+ # ####
52
+
53
+ struct MulQuasiArray{T, N, MUL<: Mul } <: AbstractQuasiArray{T,N}
54
+ mul:: MUL
55
+ end
56
+
57
+ const MulQuasiVector{T, MUL<: Mul } = MulQuasiArray{T, 1 , MUL}
58
+ const MulQuasiMatrix{T, MUL<: Mul } = MulQuasiArray{T, 2 , MUL}
59
+
60
+ const Vec = MulQuasiVector
61
+
62
+
63
+ MulQuasiArray {T,N} (M:: MUL ) where {T,N,MUL<: Mul } = MulQuasiArray {T,N,MUL} (M)
64
+ MulQuasiArray {T} (M:: Mul ) where {T} = MulQuasiArray {T,ndims(M)} (M)
65
+ MulQuasiArray (M:: Mul ) = MulQuasiArray {eltype(M)} (M)
66
+ MulQuasiVector (M:: Mul ) = MulQuasiVector {eltype(M)} (M)
67
+ MulQuasiMatrix (M:: Mul ) = MulQuasiMatrix {eltype(M)} (M)
68
+
69
+ MulQuasiArray (factors... ) = MulQuasiArray (Mul (factors... ))
70
+ MulQuasiArray {T} (factors... ) where T = MulQuasiArray {T} (Mul (factors... ))
71
+ MulQuasiArray {T,N} (factors... ) where {T,N} = MulQuasiArray {T,N} (Mul (factors... ))
72
+ MulQuasiVector (factors... ) = MulQuasiVector (Mul (factors... ))
73
+ MulQuasiMatrix (factors... ) = MulQuasiMatrix (Mul (factors... ))
74
+
75
+ _MulArray (factors... ) = MulQuasiArray (factors... )
76
+ _MulArray (factors:: AbstractArray... ) = MulArray (factors... )
77
+
78
+ axes (A:: MulQuasiArray ) = axes (A. mul)
79
+ size (A:: MulQuasiArray ) = map (length, axes (A))
80
+
81
+ IndexStyle (:: MulQuasiArray{<:Any,1} ) = IndexLinear ()
82
+
83
+ == (A:: MulQuasiArray , B:: MulQuasiArray ) = A. mul == B. mul
84
+
85
+ @propagate_inbounds getindex (A:: MulQuasiArray , kj:: Real... ) = A. mul[kj... ]
86
+
87
+ * (A:: MulQuasiArray , B:: MulQuasiArray ) = A. mul * B. mul
88
+ * (A:: MulQuasiArray , B:: Mul ) = A. mul * B
89
+ * (A:: Mul , B:: MulQuasiArray ) = A * B. mul
90
+ * (A:: MulQuasiArray , B:: AbstractQuasiArray ) = A. mul * B
91
+ * (A:: AbstractQuasiArray , B:: MulQuasiArray ) = A * B. mul
92
+ * (A:: MulQuasiArray , B:: AbstractArray ) = A. mul * B
93
+ * (A:: AbstractArray , B:: MulQuasiArray ) = A * B. mul
94
+
95
+ adjoint (A:: MulQuasiArray ) = MulQuasiArray (reverse (adjoint .(A. mul. factors))... )
96
+ transpose (A:: MulQuasiArray ) = MulQuasiArray (reverse (transpose .(A. mul. factors))... )
97
+
98
+
99
+ MemoryLayout (M:: MulQuasiArray ) = MulLayout (MemoryLayout .(M. mul. factors))
100
+
101
+
102
+
103
+ # ###
104
+ # Matrix * Array
105
+ # ###
106
+
107
+ _flatten (A:: MulQuasiArray , B... ) = _flatten (A. mul. factors... , B... )
108
+ flatten (A:: MulQuasiArray ) = MulQuasiArray (Mul (_flatten (A. mul. factors... )))
109
+
110
+
111
+ # the default is always Array
112
+
113
+ _materialize (M:: QuasiArrayMulArray , _) = MulQuasiArray (M)
114
+ _materialize (M:: ArrayMulQuasiArray , _) = MulQuasiArray (M)
115
+ _materialize (M:: QuasiArrayMulQuasiArray , _) = MulQuasiArray (M)
116
+
117
+
118
+
119
+ # if multiplying two MulQuasiArrays simplifies the arguments, we materialize,
120
+ # otherwise we leave it as a lazy object
121
+ _mulquasi_join (As, M:: MulQuasiArray , Cs) = MulQuasiArray (As... , M. mul. factors... , Cs... )
122
+ _mulquasi_join (As, B, Cs) = * (As... , B, Cs... )
123
+
124
+
125
+ function _materialize (M:: Mul2{<:Any,<:Any,<:MulQuasiArray,<:MulQuasiArray} , _)
126
+ As, Bs = M. factors
127
+ _mul_join (reverse (tail (reverse (As))), last (As) * first (Bs), tail (Bs))
128
+ end
129
+
130
+
131
+ function _materialize (M:: Mul2{<:Any,<:Any,<:MulQuasiArray,<:AbstractQuasiArray} , _)
132
+ As, B = M. factors
133
+ ⋆ (As. mul. factors... , B)
134
+ end
135
+
136
+ function _materialize (M:: Mul2{<:Any,<:Any,<:AbstractQuasiArray,<:MulQuasiArray} , _)
137
+ A, Bs = M. factors
138
+ * (A, Bs. mul. factors... )
139
+ end
140
+
141
+ # A MulQuasiArray can't be materialized further left-to-right, so we do right-to-left
142
+ function _materialize (M:: Mul2{<:Any,<:Any,<:MulQuasiArray,<:AbstractArray} , _)
143
+ As, B = M. factors
144
+ ⋆ (As. mul. factors... , B)
145
+ end
146
+
147
+ function _lmaterialize (A:: MulQuasiArray , B, C... )
148
+ As = A. mul. factors
149
+ flatten (_MulArray (reverse (tail (reverse (As)))... , _lmaterialize (last (As), B, C... )))
150
+ end
151
+
152
+
153
+
154
+ function _rmaterialize (Z:: MulQuasiArray , Y, W... )
155
+ Zs = Z. mul. factors
156
+ flatten (_MulArray (_rmaterialize (first (Zs), Y, W... ), tail (Zs)... ))
157
+ end
0 commit comments