@@ -403,13 +403,12 @@ using .TestSetup
403403 end
404404 end
405405
406- if isa (UnitStyle (I), SimpleUnit) # could get these to work for GenericUnit, but somewhat hardcoded
407- if I <: ProductSector
408- N = 3
409- else
410- N = 4
411- end
412-
406+ if I <: ProductSector
407+ N = 3
408+ else
409+ N = 4
410+ end
411+ if isa (UnitStyle (I), SimpleUnit)
413412 out = random_fusion (I, N)
414413 numtrees = count (n -> true , fusiontrees ((out... , map (dual, out)... )))
415414 while ! (0 < numtrees < 100 )
@@ -419,112 +418,87 @@ using .TestSetup
419418 incoming = rand (collect (⊗ (out... )))
420419 f1 = rand (collect (fusiontrees (out, incoming, ntuple (n -> rand (Bool), N))))
421420 f2 = rand (collect (fusiontrees (out[randperm (N)], incoming, ntuple (n -> rand (Bool), N))))
422- @testset " Double fusion tree $Istr : repartitioning" begin
423- for n in 0 : (2 * N)
424- d = @constinferred TK. repartition (f1, f2, $ n)
425- @test dim (incoming) ≈
426- sum (abs2 (coef) * dim (f1. coupled) for ((f1, f2), coef) in d)
427- d2 = Dict {typeof((f1, f2)), valtype(d)} ()
428- for ((f1′, f2′), coeff) in d
429- for ((f1′′, f2′′), coeff2) in TK. repartition (f1′, f2′, N)
430- d2[(f1′′, f2′′)] = get (d2, (f1′′, f2′′), zero (coeff)) + coeff2 * coeff
431- end
432- end
433- for ((f1′, f2′), coeff2) in d2
434- if f1 == f1′ && f2 == f2′
435- @test coeff2 ≈ 1
436- else
437- @test isapprox (coeff2, 0 ; atol = 1.0e-12 , rtol = 1.0e-12 )
438- end
421+ else
422+ out = random_fusion (I, N)
423+ out2 = random_fusion (I, N)
424+ tp = ⊗ (out... )
425+ tp2 = ⊗ (out2... )
426+ while isempty (intersect (tp, tp2)) # guarantee fusion to same coloring
427+ out2 = random_fusion (I, N)
428+ tp2 = ⊗ (out2... )
429+ end
430+ @test_throws ArgumentError fusiontrees ((out... , map (dual, out)... ))
431+ incoming = rand (collect (intersect (tp, tp2)))
432+ f1 = rand (collect (fusiontrees (out, incoming, ntuple (n -> rand (Bool), N))))
433+ f2 = rand (collect (fusiontrees (out2, incoming, ntuple (n -> rand (Bool), N)))) # no permuting
434+ end
435+
436+ @testset " Double fusion tree $Istr : repartitioning" begin
437+ for n in 0 : (2 * N)
438+ d = @constinferred TK. repartition (f1, f2, $ n)
439+ @test dim (incoming) ≈
440+ sum (abs2 (coef) * dim (f1. coupled) for ((f1, f2), coef) in d)
441+ d2 = Dict {typeof((f1, f2)), valtype(d)} ()
442+ for ((f1′, f2′), coeff) in d
443+ for ((f1′′, f2′′), coeff2) in TK. repartition (f1′, f2′, N)
444+ d2[(f1′′, f2′′)] = get (d2, (f1′′, f2′′), zero (coeff)) + coeff2 * coeff
439445 end
440- if (BraidingStyle (I) isa Bosonic) && hasfusiontensor (I)
441- Af1 = convert (Array, f1)
442- Af2 = permutedims (convert (Array, f2), [N: - 1 : 1 ; N + 1 ])
443- sz1 = size (Af1)
444- sz2 = size (Af2)
445- d1 = prod (sz1[1 : (end - 1 )])
446- d2 = prod (sz2[1 : (end - 1 )])
447- dc = sz1[end ]
448- A = reshape (
449- reshape (Af1, (d1, dc)) * reshape (Af2, (d2, dc))' ,
450- (sz1[1 : (end - 1 )]. .. , sz2[1 : (end - 1 )]. .. )
451- )
452- A2 = zero (A)
453- for ((f1′, f2′), coeff) in d
454- Af1′ = convert (Array, f1′)
455- Af2′ = permutedims (convert (Array, f2′), [(2 N - n): - 1 : 1 ; 2 N - n + 1 ])
456- sz1′ = size (Af1′)
457- sz2′ = size (Af2′)
458- d1′ = prod (sz1′[1 : (end - 1 )])
459- d2′ = prod (sz2′[1 : (end - 1 )])
460- dc′ = sz1′[end ]
461- A2 += coeff *
462- reshape (
463- reshape (Af1′, (d1′, dc′)) * reshape (Af2′, (d2′, dc′))' ,
464- (sz1′[1 : (end - 1 )]. .. , sz2′[1 : (end - 1 )]. .. )
465- )
466- end
467- @test A ≈ A2
446+ end
447+ for ((f1′, f2′), coeff2) in d2
448+ if f1 == f1′ && f2 == f2′
449+ @test coeff2 ≈ 1
450+ else
451+ @test isapprox (coeff2, 0 ; atol = 1.0e-12 , rtol = 1.0e-12 )
468452 end
469453 end
470- end
471- @testset " Double fusion tree $Istr : permutation" begin
472- if BraidingStyle (I) isa SymmetricBraiding
473- for n in 0 : (2 N)
474- p = (randperm (2 * N)... ,)
475- p1, p2 = p[1 : n], p[(n + 1 ): (2 N)]
476- ip = invperm (p)
477- ip1, ip2 = ip[1 : N], ip[(N + 1 ): (2 N)]
478-
479- d = @constinferred TK. permute (f1, f2, p1, p2)
480- @test dim (incoming) ≈
481- sum (abs2 (coef) * dim (f1. coupled) for ((f1, f2), coef) in d)
482- d2 = Dict {typeof((f1, f2)), valtype(d)} ()
483- for ((f1′, f2′), coeff) in d
484- d′ = TK. permute (f1′, f2′, ip1, ip2)
485- for ((f1′′, f2′′), coeff2) in d′
486- d2[(f1′′, f2′′)] = get (d2, (f1′′, f2′′), zero (coeff)) +
487- coeff2 * coeff
488- end
489- end
490- for ((f1′, f2′), coeff2) in d2
491- if f1 == f1′ && f2 == f2′
492- @test coeff2 ≈ 1
493- else
494- @test abs (coeff2) < 1.0e-12
495- end
496- end
497-
498- if (BraidingStyle (I) isa Bosonic) && hasfusiontensor (I)
499- A = convert (Array, (f1, f2))
500- Ap = permutedims (A, (p1... , p2... ))
501- A2 = zero (Ap)
502- for ((f1′, f2′), coeff) in d
503- A2 .+ = coeff .* convert (Array, (f1′, f2′))
504- end
505- @test Ap ≈ A2
506- end
454+ if (BraidingStyle (I) isa Bosonic) && hasfusiontensor (I)
455+ Af1 = convert (Array, f1)
456+ Af2 = permutedims (convert (Array, f2), [N: - 1 : 1 ; N + 1 ])
457+ sz1 = size (Af1)
458+ sz2 = size (Af2)
459+ d1 = prod (sz1[1 : (end - 1 )])
460+ d2 = prod (sz2[1 : (end - 1 )])
461+ dc = sz1[end ]
462+ A = reshape (
463+ reshape (Af1, (d1, dc)) * reshape (Af2, (d2, dc))' ,
464+ (sz1[1 : (end - 1 )]. .. , sz2[1 : (end - 1 )]. .. )
465+ )
466+ A2 = zero (A)
467+ for ((f1′, f2′), coeff) in d
468+ Af1′ = convert (Array, f1′)
469+ Af2′ = permutedims (convert (Array, f2′), [(2 N - n): - 1 : 1 ; 2 N - n + 1 ])
470+ sz1′ = size (Af1′)
471+ sz2′ = size (Af2′)
472+ d1′ = prod (sz1′[1 : (end - 1 )])
473+ d2′ = prod (sz2′[1 : (end - 1 )])
474+ dc′ = sz1′[end ]
475+ A2 += coeff *
476+ reshape (
477+ reshape (Af1′, (d1′, dc′)) * reshape (Af2′, (d2′, dc′))' ,
478+ (sz1′[1 : (end - 1 )]. .. , sz2′[1 : (end - 1 )]. .. )
479+ )
507480 end
481+ @test A ≈ A2
508482 end
509483 end
510- @testset " Double fusion tree $Istr : transposition" begin
484+ end
485+ @testset " Double fusion tree $Istr : permutation" begin
486+ if BraidingStyle (I) isa SymmetricBraiding
511487 for n in 0 : (2 N)
512- i0 = rand (1 : (2 N))
513- p = mod1 .(i0 .+ (1 : (2 N)), 2 N)
514- ip = mod1 .(- i0 .+ (1 : (2 N)), 2 N)
515- p′ = tuple (getindex .(Ref (vcat (1 : N, (2 N): - 1 : (N + 1 ))), p)... )
516- p1, p2 = p′[1 : n], p′[(2 N): - 1 : (n + 1 )]
517- ip′ = tuple (getindex .(Ref (vcat (1 : n, (2 N): - 1 : (n + 1 ))), ip)... )
518- ip1, ip2 = ip′[1 : N], ip′[(2 N): - 1 : (N + 1 )]
519-
520- d = @constinferred transpose (f1, f2, p1, p2)
488+ p = (randperm (2 * N)... ,)
489+ p1, p2 = p[1 : n], p[(n + 1 ): (2 N)]
490+ ip = invperm (p)
491+ ip1, ip2 = ip[1 : N], ip[(N + 1 ): (2 N)]
492+
493+ d = @constinferred TK. permute (f1, f2, p1, p2)
521494 @test dim (incoming) ≈
522495 sum (abs2 (coef) * dim (f1. coupled) for ((f1, f2), coef) in d)
523496 d2 = Dict {typeof((f1, f2)), valtype(d)} ()
524497 for ((f1′, f2′), coeff) in d
525- d′ = transpose (f1′, f2′, ip1, ip2)
498+ d′ = TK . permute (f1′, f2′, ip1, ip2)
526499 for ((f1′′, f2′′), coeff2) in d′
527- d2[(f1′′, f2′′)] = get (d2, (f1′′, f2′′), zero (coeff)) + coeff2 * coeff
500+ d2[(f1′′, f2′′)] = get (d2, (f1′′, f2′′), zero (coeff)) +
501+ coeff2 * coeff
528502 end
529503 end
530504 for ((f1′, f2′), coeff2) in d2
@@ -535,69 +509,108 @@ using .TestSetup
535509 end
536510 end
537511
538- if BraidingStyle (I) isa Bosonic
539- d3 = permute (f1, f2, p1, p2)
540- for (f1′, f2′) in union (keys (d), keys (d3))
541- coeff1 = get (d, (f1′, f2′), zero (valtype (d)))
542- coeff3 = get (d3, (f1′, f2′), zero (valtype (d3)))
543- @test isapprox (coeff1, coeff3; atol = 1.0e-12 )
544- end
545- end
546-
547512 if (BraidingStyle (I) isa Bosonic) && hasfusiontensor (I)
548- Af1 = convert (Array, f1)
549- Af2 = convert (Array, f2)
550- sz1 = size (Af1)
551- sz2 = size (Af2)
552- d1 = prod (sz1[1 : (end - 1 )])
553- d2 = prod (sz2[1 : (end - 1 )])
554- dc = sz1[end ]
555- A = reshape (
556- reshape (Af1, (d1, dc)) * reshape (Af2, (d2, dc))' ,
557- (sz1[1 : (end - 1 )]. .. , sz2[1 : (end - 1 )]. .. )
558- )
513+ A = convert (Array, (f1, f2))
559514 Ap = permutedims (A, (p1... , p2... ))
560515 A2 = zero (Ap)
561516 for ((f1′, f2′), coeff) in d
562- Af1′ = convert (Array, f1′)
563- Af2′ = convert (Array, f2′)
564- sz1′ = size (Af1′)
565- sz2′ = size (Af2′)
566- d1′ = prod (sz1′[1 : (end - 1 )])
567- d2′ = prod (sz2′[1 : (end - 1 )])
568- dc′ = sz1′[end ]
569- A2 += coeff * reshape (
570- reshape (Af1′, (d1′, dc′)) *
571- reshape (Af2′, (d2′, dc′))' ,
572- (sz1′[1 : (end - 1 )]. .. , sz2′[1 : (end - 1 )]. .. )
573- )
517+ A2 .+ = coeff .* convert (Array, (f1′, f2′))
574518 end
575519 @test Ap ≈ A2
576520 end
577521 end
578522 end
579- @testset " Double fusion tree $Istr : planar trace" begin
580- d1 = transpose (f1, f1, (N + 1 , 1 : N... , ((2 N): - 1 : (N + 3 )). .. ), (N + 2 ,))
581- f1front, = TK. split (f1, N - 1 )
582- T = sectorscalartype (I)
583- d2 = Dict {typeof((f1front, f1front)), T} ()
584- for ((f1′, f2′), coeff′) in d1
585- for ((f1′′, f2′′), coeff′′) in
586- TK. planar_trace (
587- f1′, f2′, (2 : N... ,), (1 , ((2 N): - 1 : (N + 3 )). .. ), (N + 1 ,),
588- (N + 2 ,)
589- )
590- coeff = coeff′ * coeff′′
591- d2[(f1′′, f2′′)] = get (d2, (f1′′, f2′′), zero (coeff)) + coeff
523+ end
524+ @testset " Double fusion tree $Istr : transposition" begin
525+ for n in 0 : (2 N)
526+ i0 = rand (1 : (2 N))
527+ p = mod1 .(i0 .+ (1 : (2 N)), 2 N)
528+ ip = mod1 .(- i0 .+ (1 : (2 N)), 2 N)
529+ p′ = tuple (getindex .(Ref (vcat (1 : N, (2 N): - 1 : (N + 1 ))), p)... )
530+ p1, p2 = p′[1 : n], p′[(2 N): - 1 : (n + 1 )]
531+ ip′ = tuple (getindex .(Ref (vcat (1 : n, (2 N): - 1 : (n + 1 ))), ip)... )
532+ ip1, ip2 = ip′[1 : N], ip′[(2 N): - 1 : (N + 1 )]
533+
534+ d = @constinferred transpose (f1, f2, p1, p2)
535+ @test dim (incoming) ≈
536+ sum (abs2 (coef) * dim (f1. coupled) for ((f1, f2), coef) in d)
537+ d2 = Dict {typeof((f1, f2)), valtype(d)} ()
538+ for ((f1′, f2′), coeff) in d
539+ d′ = transpose (f1′, f2′, ip1, ip2)
540+ for ((f1′′, f2′′), coeff2) in d′
541+ d2[(f1′′, f2′′)] = get (d2, (f1′′, f2′′), zero (coeff)) + coeff2 * coeff
592542 end
593543 end
594- for ((f1_, f2_ ), coeff ) in d2
595- if (f1_, f2_) == (f1front, f1front)
596- @test coeff ≈ dim (f1 . coupled) / dim (f1front . coupled)
544+ for ((f1′, f2′ ), coeff2 ) in d2
545+ if f1 == f1′ && f2 == f2′
546+ @test coeff2 ≈ 1
597547 else
598- @test abs (coeff ) < 1.0e-12
548+ @test abs (coeff2 ) < 1.0e-12
599549 end
600550 end
551+
552+ if BraidingStyle (I) isa Bosonic
553+ d3 = permute (f1, f2, p1, p2)
554+ for (f1′, f2′) in union (keys (d), keys (d3))
555+ coeff1 = get (d, (f1′, f2′), zero (valtype (d)))
556+ coeff3 = get (d3, (f1′, f2′), zero (valtype (d3)))
557+ @test isapprox (coeff1, coeff3; atol = 1.0e-12 )
558+ end
559+ end
560+
561+ if (BraidingStyle (I) isa Bosonic) && hasfusiontensor (I)
562+ Af1 = convert (Array, f1)
563+ Af2 = convert (Array, f2)
564+ sz1 = size (Af1)
565+ sz2 = size (Af2)
566+ d1 = prod (sz1[1 : (end - 1 )])
567+ d2 = prod (sz2[1 : (end - 1 )])
568+ dc = sz1[end ]
569+ A = reshape (
570+ reshape (Af1, (d1, dc)) * reshape (Af2, (d2, dc))' ,
571+ (sz1[1 : (end - 1 )]. .. , sz2[1 : (end - 1 )]. .. )
572+ )
573+ Ap = permutedims (A, (p1... , p2... ))
574+ A2 = zero (Ap)
575+ for ((f1′, f2′), coeff) in d
576+ Af1′ = convert (Array, f1′)
577+ Af2′ = convert (Array, f2′)
578+ sz1′ = size (Af1′)
579+ sz2′ = size (Af2′)
580+ d1′ = prod (sz1′[1 : (end - 1 )])
581+ d2′ = prod (sz2′[1 : (end - 1 )])
582+ dc′ = sz1′[end ]
583+ A2 += coeff * reshape (
584+ reshape (Af1′, (d1′, dc′)) *
585+ reshape (Af2′, (d2′, dc′))' ,
586+ (sz1′[1 : (end - 1 )]. .. , sz2′[1 : (end - 1 )]. .. )
587+ )
588+ end
589+ @test Ap ≈ A2
590+ end
591+ end
592+ end
593+ @testset " Double fusion tree $Istr : planar trace" begin
594+ d1 = transpose (f1, f1, (N + 1 , 1 : N... , ((2 N): - 1 : (N + 3 )). .. ), (N + 2 ,))
595+ f1front, = TK. split (f1, N - 1 )
596+ T = sectorscalartype (I)
597+ d2 = Dict {typeof((f1front, f1front)), T} ()
598+ for ((f1′, f2′), coeff′) in d1
599+ for ((f1′′, f2′′), coeff′′) in
600+ TK. planar_trace (
601+ f1′, f2′, (2 : N... ,), (1 , ((2 N): - 1 : (N + 3 )). .. ), (N + 1 ,),
602+ (N + 2 ,)
603+ )
604+ coeff = coeff′ * coeff′′
605+ d2[(f1′′, f2′′)] = get (d2, (f1′′, f2′′), zero (coeff)) + coeff
606+ end
607+ end
608+ for ((f1_, f2_), coeff) in d2
609+ if (f1_, f2_) == (f1front, f1front)
610+ @test coeff ≈ dim (f1. coupled) / dim (f1front. coupled)
611+ else
612+ @test abs (coeff) < 1.0e-12
613+ end
601614 end
602615 end
603616 TK. empty_globalcaches! ()
0 commit comments