@@ -389,3 +389,371 @@ def partially_traced_four_site_density_matrices(
389389 density_bottom_left ,
390390 density_bottom_right ,
391391 )
392+
393+
394+ def partially_traced_horizontal_two_site_density_matrices (
395+ peps_tensors : Sequence [jnp .ndarray ],
396+ peps_tensor_objs : Sequence [PEPS_Tensor ],
397+ real_physical_dimension : int ,
398+ num_coarse_grained_physical_indices : int ,
399+ open_physical_indices : Tuple [Tuple [int ], Tuple [int ]],
400+ ) -> Tuple [jnp .ndarray , jnp .ndarray ]:
401+
402+ if not all (
403+ all (isinstance (open_idx , int ) for open_idx in tup ) or len (tup ) == 0
404+ for tup in open_physical_indices
405+ ):
406+ raise TypeError (
407+ "All elements of each tuple must be integers (or the tuple may be empty)."
408+ )
409+ if not all (
410+ len (tup ) <= num_coarse_grained_physical_indices for tup in open_physical_indices
411+ ):
412+ raise ValueError (
413+ f"At least one tuple in `open_physical_indices` { open_physical_indices } has length greater"
414+ f"than the number of coarse-grained physical sites { num_coarse_grained_physical_indices } "
415+ )
416+ peps_tensors = [
417+ t .reshape (
418+ t .shape [0 ],
419+ t .shape [1 ],
420+ * ((real_physical_dimension ,) * num_coarse_grained_physical_indices ),
421+ t .shape [3 ],
422+ t .shape [4 ],
423+ )
424+ for t in peps_tensors
425+ ]
426+ t_left , t_right = peps_tensors
427+ t_obj_left , t_obj_right = peps_tensor_objs
428+ left_i , right_i = open_physical_indices
429+
430+ if any (
431+ not hasattr (
432+ Definitions ,
433+ (
434+ f"partially_traced_horizontal_two_site_density_matrices_{ pos_name } _"
435+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ pos_idx } "
436+ ),
437+ )
438+ for pos_idx , pos_name in zip (
439+ open_physical_indices , ["left" , "right" ], strict = True
440+ )
441+ ):
442+
443+ phys_contraction_i_left = list (
444+ range (11 , 11 + num_coarse_grained_physical_indices - len (left_i ))
445+ )
446+ phys_contraction_i_conj_left = list (
447+ range (11 , 11 + num_coarse_grained_physical_indices - len (left_i ))
448+ )
449+ for pos , i in enumerate (left_i ):
450+ phys_contraction_i_left .insert (i - 1 , - (pos + 1 ))
451+ phys_contraction_i_conj_left .insert (i - 1 , - len (left_i ) - (pos + 1 ))
452+ phys_contraction_i_left = tuple (phys_contraction_i_left )
453+ phys_contraction_i_conj_left = tuple (phys_contraction_i_conj_left )
454+
455+ contraction_left = {
456+ "tensors" : [["tensor" , "tensor_conj" , "C1" , "T1" , "T3" , "C4" , "T4" ]],
457+ "network" : [
458+ [
459+ (5 , 9 )
460+ + phys_contraction_i_left
461+ + (- 2 * len (left_i ) - 2 , 4 ), # tensor
462+ (7 , 10 )
463+ + phys_contraction_i_conj_left
464+ + (- 2 * len (left_i ) - 3 , 6 ), # tensor_conj
465+ (1 , 3 ), # C1
466+ (3 , 4 , 6 , - 2 * len (left_i ) - 1 ), # T1
467+ (2 , - 2 * len (left_i ) - 4 , 10 , 9 ), # T3
468+ (2 , 8 ), # C4
469+ (8 , 7 , 5 , 1 ), # T4
470+ ]
471+ ],
472+ }
473+ Definitions ._process_def (
474+ contraction_left ,
475+ (
476+ f"partially_traced_horizontal_two_site_density_matrices_left_"
477+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ left_i } "
478+ ),
479+ )
480+ setattr (
481+ Definitions ,
482+ (
483+ f"partially_traced_horizontal_two_site_density_matrices_left_"
484+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ left_i } "
485+ ),
486+ contraction_left ,
487+ )
488+
489+ phys_contraction_i_right = list (
490+ range (11 , 11 + num_coarse_grained_physical_indices - len (right_i ))
491+ )
492+ phys_contraction_i_conj_right = list (
493+ range (11 , 11 + num_coarse_grained_physical_indices - len (right_i ))
494+ )
495+ for pos , i in enumerate (right_i ):
496+ phys_contraction_i_right .insert (i - 1 , - 4 - (pos + 1 ))
497+ phys_contraction_i_conj_right .insert (i - 1 , - 4 - len (right_i ) - (pos + 1 ))
498+ phys_contraction_i_right = tuple (phys_contraction_i_right )
499+ phys_contraction_i_conj_right = tuple (phys_contraction_i_conj_right )
500+
501+ contraction_right = {
502+ "tensors" : [["tensor" , "tensor_conj" , "T1" , "C2" , "T2" , "T3" , "C3" ]],
503+ "network" : [
504+ [
505+ (- 2 , 8 ) + phys_contraction_i_right + (5 , 4 ), # tensor
506+ (- 3 , 9 ) + phys_contraction_i_conj_right + (7 , 6 ), # tensor_conj
507+ (- 1 , 4 , 6 , 3 ), # T1
508+ (3 , 1 ), # C2
509+ (5 , 7 , 10 , 1 ), # T2
510+ (- 4 , 2 , 9 , 8 ), # T3
511+ (2 , 10 ), # C3
512+ ]
513+ ],
514+ }
515+ Definitions ._process_def (
516+ contraction_right ,
517+ (
518+ f"partially_traced_horizontal_two_site_density_matrices_right_"
519+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ right_i } "
520+ ),
521+ )
522+ setattr (
523+ Definitions ,
524+ (
525+ f"partially_traced_horizontal_two_site_density_matrices_right_"
526+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ right_i } "
527+ ),
528+ contraction_right ,
529+ )
530+
531+ density_left = apply_contraction (
532+ (
533+ f"partially_traced_horizontal_two_site_density_matrices_left_"
534+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ left_i } "
535+ ),
536+ [t_left ],
537+ [t_obj_left ],
538+ [],
539+ disable_identity_check = True ,
540+ )
541+ if len (left_i ) > 0 :
542+ density_left = density_left .reshape (
543+ real_physical_dimension ** len (left_i ),
544+ real_physical_dimension ** len (left_i ),
545+ density_left .shape [- 4 ],
546+ density_left .shape [- 3 ],
547+ density_left .shape [- 2 ],
548+ density_left .shape [- 1 ],
549+ )
550+
551+ density_right = apply_contraction (
552+ (
553+ f"partially_traced_horizontal_two_site_density_matrices_right_"
554+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ right_i } "
555+ ),
556+ [t_right ],
557+ [t_obj_right ],
558+ [],
559+ disable_identity_check = True ,
560+ )
561+ if len (right_i ) > 0 :
562+ # Physical indices are at the end (ket, bra), for consistency with _two_site_workhorse
563+ density_right = density_right .reshape (
564+ density_right .shape [0 ],
565+ density_right .shape [1 ],
566+ density_right .shape [2 ],
567+ density_right .shape [3 ],
568+ real_physical_dimension ** len (right_i ),
569+ real_physical_dimension ** len (right_i ),
570+ )
571+
572+ return (
573+ density_left ,
574+ density_right ,
575+ )
576+
577+
578+ def partially_traced_vertical_two_site_density_matrices (
579+ peps_tensors : Sequence [jnp .ndarray ],
580+ peps_tensor_objs : Sequence [PEPS_Tensor ],
581+ real_physical_dimension : int ,
582+ num_coarse_grained_physical_indices : int ,
583+ open_physical_indices : Tuple [Tuple [int ], Tuple [int ]],
584+ ) -> Tuple [jnp .ndarray , jnp .ndarray ]:
585+
586+ if not all (
587+ all (isinstance (open_idx , int ) for open_idx in tup ) or len (tup ) == 0
588+ for tup in open_physical_indices
589+ ):
590+ raise TypeError (
591+ "All elements of each tuple must be integers (or the tuple may be empty)."
592+ )
593+ if not all (
594+ len (tup ) <= num_coarse_grained_physical_indices for tup in open_physical_indices
595+ ):
596+ raise ValueError (
597+ f"At least one tuple in `open_physical_indices` { open_physical_indices } has length greater"
598+ f"than the number of coarse-grained physical sites { num_coarse_grained_physical_indices } "
599+ )
600+ peps_tensors = [
601+ t .reshape (
602+ t .shape [0 ],
603+ t .shape [1 ],
604+ * ((real_physical_dimension ,) * num_coarse_grained_physical_indices ),
605+ t .shape [3 ],
606+ t .shape [4 ],
607+ )
608+ for t in peps_tensors
609+ ]
610+ t_top , t_bottom = peps_tensors
611+ t_obj_top , t_obj_bottom = peps_tensor_objs
612+ top_i , bottom_i = open_physical_indices
613+
614+ if any (
615+ not hasattr (
616+ Definitions ,
617+ (
618+ f"partially_traced_vertical_two_site_density_matrices_{ pos_name } _"
619+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ pos_idx } "
620+ ),
621+ )
622+ for pos_idx , pos_name in zip (
623+ open_physical_indices , ["top" , "bottom" ], strict = True
624+ )
625+ ):
626+
627+ phys_contraction_i_top = list (
628+ range (11 , 11 + num_coarse_grained_physical_indices - len (top_i ))
629+ )
630+ phys_contraction_i_conj_top = list (
631+ range (11 , 11 + num_coarse_grained_physical_indices - len (top_i ))
632+ )
633+ for pos , i in enumerate (top_i ):
634+ phys_contraction_i_top .insert (i - 1 , - (pos + 1 ))
635+ phys_contraction_i_conj_top .insert (i - 1 , - len (top_i ) - (pos + 1 ))
636+ phys_contraction_i_top = tuple (phys_contraction_i_top )
637+ phys_contraction_i_conj_top = tuple (phys_contraction_i_conj_top )
638+
639+ contraction_top = {
640+ "tensors" : [["tensor" , "tensor_conj" , "C1" , "T1" , "C2" , "T2" , "T4" ]],
641+ "network" : [
642+ [
643+ (8 , - 2 * len (top_i ) - 2 )
644+ + phys_contraction_i_top
645+ + (4 , 5 ), # tensor
646+ (9 , - 2 * len (top_i ) - 3 )
647+ + phys_contraction_i_conj_top
648+ + (6 , 7 ), # tensor_conj
649+ (2 , 10 ), # C1
650+ (10 , 5 , 7 , 1 ), # T1
651+ (1 , 3 ), # C2
652+ (4 , 6 , - 2 * len (top_i ) - 4 , 3 ), # T2
653+ (- 2 * len (top_i ) - 1 , 9 , 8 , 2 ), # T4
654+ ]
655+ ],
656+ }
657+ Definitions ._process_def (
658+ contraction_top ,
659+ (
660+ f"partially_traced_vertical_two_site_density_matrices_top_"
661+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ top_i } "
662+ ),
663+ )
664+ setattr (
665+ Definitions ,
666+ (
667+ f"partially_traced_vertical_two_site_density_matrices_top_"
668+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ top_i } "
669+ ),
670+ contraction_top ,
671+ )
672+
673+ phys_contraction_i_bottom = list (
674+ range (11 , 11 + num_coarse_grained_physical_indices - len (bottom_i ))
675+ )
676+ phys_contraction_i_conj_bottom = list (
677+ range (11 , 11 + num_coarse_grained_physical_indices - len (bottom_i ))
678+ )
679+ for pos , i in enumerate (bottom_i ):
680+ phys_contraction_i_bottom .insert (i - 1 , - 4 - (pos + 1 ))
681+ phys_contraction_i_conj_bottom .insert (i - 1 , - 4 - len (bottom_i ) - (pos + 1 ))
682+ phys_contraction_i_bottom = tuple (phys_contraction_i_bottom )
683+ phys_contraction_i_conj_bottom = tuple (phys_contraction_i_conj_bottom )
684+
685+ contraction_bottom = {
686+ "tensors" : [["tensor" , "tensor_conj" , "T2" , "C3" , "T3" , "C4" , "T4" ]],
687+ "network" : [
688+ [
689+ (4 , 5 ) + phys_contraction_i_bottom + (8 , - 2 ), # tensor
690+ (6 , 7 ) + phys_contraction_i_conj_bottom + (9 , - 3 ), # tensor_conj
691+ (8 , 9 , 2 , - 4 ), # T2
692+ (10 , 2 ), # C3
693+ (1 , 10 , 7 , 5 ), # T3
694+ (1 , 3 ), # C4
695+ (3 , 6 , 4 , - 1 ), # T4
696+ ]
697+ ],
698+ }
699+ Definitions ._process_def (
700+ contraction_bottom ,
701+ (
702+ f"partially_traced_vertical_two_site_density_matrices_bottom_"
703+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ bottom_i } "
704+ ),
705+ )
706+ setattr (
707+ Definitions ,
708+ (
709+ f"partially_traced_vertical_two_site_density_matrices_bottom_"
710+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ bottom_i } "
711+ ),
712+ contraction_bottom ,
713+ )
714+
715+ density_top = apply_contraction (
716+ (
717+ f"partially_traced_vertical_two_site_density_matrices_top_"
718+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ top_i } "
719+ ),
720+ [t_top ],
721+ [t_obj_top ],
722+ [],
723+ disable_identity_check = True ,
724+ )
725+ if len (top_i ) > 0 :
726+ density_top = density_top .reshape (
727+ real_physical_dimension ** len (top_i ),
728+ real_physical_dimension ** len (top_i ),
729+ density_top .shape [- 4 ],
730+ density_top .shape [- 3 ],
731+ density_top .shape [- 2 ],
732+ density_top .shape [- 1 ],
733+ )
734+
735+ density_bottom = apply_contraction (
736+ (
737+ f"partially_traced_vertical_two_site_density_matrices_bottom_"
738+ f"{ real_physical_dimension } _{ num_coarse_grained_physical_indices } _{ bottom_i } "
739+ ),
740+ [t_bottom ],
741+ [t_obj_bottom ],
742+ [],
743+ disable_identity_check = True ,
744+ )
745+ if len (bottom_i ) > 0 :
746+ # Physical indices are at the end (ket, bra), for consistency with _two_site_workhorse
747+ density_bottom = density_bottom .reshape (
748+ density_bottom .shape [0 ],
749+ density_bottom .shape [1 ],
750+ density_bottom .shape [2 ],
751+ density_bottom .shape [3 ],
752+ real_physical_dimension ** len (bottom_i ),
753+ real_physical_dimension ** len (bottom_i ),
754+ )
755+
756+ return (
757+ density_top ,
758+ density_bottom ,
759+ )
0 commit comments