@@ -52,6 +52,9 @@ Base.kron(A::KroneckerMap, B::LinearMap) =
52
52
KroneckerMap {promote_type(eltype(A), eltype(B))} (tuple (A. maps... , B))
53
53
Base. kron (A:: KroneckerMap , B:: KroneckerMap ) =
54
54
KroneckerMap {promote_type(eltype(A), eltype(B))} (tuple (A. maps... , B. maps... ))
55
+ Base. kron (A:: ScaledMap , B:: LinearMap ) = A. λ * kron (A. lmap, B)
56
+ Base. kron (A:: LinearMap{<:RealOrComplex} , B:: ScaledMap ) = B. λ * kron (A, B. lmap)
57
+ Base. kron (A:: ScaledMap , B:: ScaledMap ) = (A. λ * B. λ) * kron (A. lmap, B. lmap)
55
58
Base. kron (A:: LinearMap , B:: LinearMap , C:: LinearMap , Ds:: LinearMap... ) =
56
59
kron (kron (A, B), C, Ds... )
57
60
Base. kron (A:: AbstractMatrix , B:: LinearMap ) = kron (LinearMap (A), B)
@@ -104,9 +107,10 @@ Base.:(==)(A::KroneckerMap, B::KroneckerMap) = (eltype(A) == eltype(B) && A.maps
104
107
# multiplication helper functions
105
108
# ################
106
109
107
- @inline function _kronmul! (y, B, X , At, T)
110
+ @inline function _kronmul! (y, B, x , At, T)
108
111
na, ma = size (At)
109
112
mb, nb = size (B)
113
+ X = reshape (x, (nb, na))
110
114
v = zeros (T, ma)
111
115
temp1 = similar (y, na)
112
116
temp2 = similar (y, nb)
@@ -119,14 +123,23 @@ Base.:(==)(A::KroneckerMap, B::KroneckerMap) = (eltype(A) == eltype(B) && A.maps
119
123
end
120
124
return y
121
125
end
122
- @inline function _kronmul! (y, B, X, At:: Union{MatrixMap, UniformScalingMap} , T)
126
+ @inline function _kronmul! (y, B, x, At:: UniformScalingMap , _)
127
+ na, ma = size (At)
128
+ mb, nb = size (B)
129
+ X = reshape (x, (nb, na))
130
+ Y = reshape (y, (mb, ma))
131
+ _unsafe_mul! (Y, B, X, At. λ, false )
132
+ return y
133
+ end
134
+ @inline function _kronmul! (y, B, x, At:: MatrixMap , _)
123
135
na, ma = size (At)
124
136
mb, nb = size (B)
137
+ X = reshape (x, (nb, na))
125
138
Y = reshape (y, (mb, ma))
126
139
if nb* ma < mb* na
127
- _unsafe_mul! (Y, B, Matrix (X * At) )
140
+ _unsafe_mul! (Y, B, X * At . lmap )
128
141
else
129
- _unsafe_mul! (Y, Matrix (B* X), _parent (At) )
142
+ _unsafe_mul! (Y, Matrix (B* X), At . lmap )
130
143
end
131
144
return y
132
145
end
@@ -140,18 +153,14 @@ const KroneckerMap2{T} = KroneckerMap{T, <:Tuple{LinearMap, LinearMap}}
140
153
function _unsafe_mul! (y:: AbstractVecOrMat , L:: KroneckerMap2 , x:: AbstractVector )
141
154
require_one_based_indexing (y)
142
155
A, B = L. maps
143
- X = LinearMap (reshape (x, (size (B, 2 ), size (A, 2 )));
144
- issymmetric = false , ishermitian = false , isposdef = false )
145
- _kronmul! (y, B, X, transpose (A), eltype (L))
156
+ _kronmul! (y, B, x, transpose (A), eltype (L))
146
157
return y
147
158
end
148
159
function _unsafe_mul! (y:: AbstractVecOrMat , L:: KroneckerMap , x:: AbstractVector )
149
160
require_one_based_indexing (y)
150
161
A = first (L. maps)
151
162
B = kron (Base. tail (L. maps)... )
152
- X = LinearMap (reshape (x, (size (B, 2 ), size (A, 2 )));
153
- issymmetric = false , ishermitian = false , isposdef = false )
154
- _kronmul! (y, B, X, transpose (A), eltype (L))
163
+ _kronmul! (y, B, x, transpose (A), eltype (L))
155
164
return y
156
165
end
157
166
# mixed-product rule, prefer the right if possible
0 commit comments