@@ -174,7 +174,7 @@ function LinearAlgebra.diagm(codom::VectorSpace, dom::VectorSpace, v::SectorDict
174174 blockdim (dom, c), b)
175175 for (c, b) in v), codom ← dom)
176176end
177- LinearAlgebra. isdiag (t:: AbstractTensorMap ) = all (LinearAlgebra. isdiag, values ( blocks (t) ))
177+ LinearAlgebra. isdiag (t:: AbstractTensorMap ) = all (LinearAlgebra. isdiag ∘ last, blocks (t))
178178
179179# In-place methods
180180# ------------------
@@ -184,8 +184,8 @@ LinearAlgebra.isdiag(t::AbstractTensorMap) = all(LinearAlgebra.isdiag, values(bl
184184# Copy, adjoint and fill:
185185function Base. copy! (tdst:: AbstractTensorMap , tsrc:: AbstractTensorMap )
186186 space (tdst) == space (tsrc) || throw (SpaceMismatch (" $(space (tdst)) ≠ $(space (tsrc)) " ))
187- for c in blocksectors ( tdst)
188- copy! (StridedView (block (tdst, c)) , StridedView (block (tsrc, c) ))
187+ for ((c, bdst), (_, bsrc)) in zip ( blocks ( tdst), blocks (tsrc) )
188+ copy! (StridedView (bdst) , StridedView (bsrc ))
189189 end
190190 return tdst
191191end
@@ -284,20 +284,44 @@ function LinearAlgebra.mul!(tC::AbstractTensorMap,
284284 tA:: AbstractTensorMap ,
285285 tB:: AbstractTensorMap , α= true , β= false )
286286 compose (space (tA), space (tB)) == space (tC) ||
287- throw (SpaceMismatch (" $(space (tC)) ≠ $(space (tA)) * $(space (tB)) " ))
288-
289- for c in blocksectors (tC)
290- if hasblock (tA, c) # then also tB should have such a block
291- A = block (tA, c)
292- B = block (tB, c)
293- C = block (tC, c)
294- mul! (C, A, B, α, β)
295- elseif β != one (β)
296- rmul! (block (tC, c), β)
287+ throw (SpaceMismatch (lazy " $(space(tC)) ≠ $(space(tA)) * $(space(tB))" ))
288+
289+ iterC = blocks (tC)
290+ iterA = blocks (tA)
291+ iterB = blocks (tB)
292+ nextA = iterate (iterA)
293+ nextB = iterate (iterB)
294+ nextC = iterate (iterC)
295+ while ! isnothing (nextC)
296+ (cC, C), stateC = nextC
297+ if ! isnothing (nextA) && ! isnothing (nextB)
298+ (cA, A), stateA = nextA
299+ (cB, B), stateB = nextB
300+ if cA == cC && cB == cC
301+ mul! (C, A, B, α, β)
302+ nextA = iterate (iterA, stateA)
303+ nextB = iterate (iterB, stateB)
304+ nextC = iterate (iterC, stateC)
305+ elseif cA < cC
306+ nextA = iterate (iterA, stateA)
307+ elseif cB < cC
308+ nextB = iterate (iterB, stateB)
309+ else
310+ if β != one (β)
311+ rmul! (C, β)
312+ end
313+ nextC = iterate (iterC, stateC)
314+ end
315+ else
316+ if β != one (β)
317+ rmul! (C, β)
318+ end
319+ nextC = iterate (iterC, stateC)
297320 end
298321 end
299322 return tC
300323end
324+
301325# TODO : consider spawning threads for different blocks, support backends
302326
303327# TensorMap inverse
0 commit comments