@@ -476,9 +476,10 @@ def single_site_TDVP(state: MPS, H: MPO, sim_params, numiter_lanczos: int=25):
476476 state .tensors [i - 1 ] = update_site (left_blocks [i - 1 ], right_blocks [i - 1 ], H .tensors [i - 1 ], state .tensors [i - 1 ], 0.5 * sim_params .dt , numiter_lanczos )
477477
478478
479- def two_site_TDVP (state : MPS , H : MPO , sim_params , numiter_lanczos : int = 25 ):
480- """
481- Perform symmetric two-site TDVP integration.
479+ def two_site_TDVP (
480+ state : MPS , H : MPO , sim_params : PhysicsSimParams | StrongSimParams | WeakSimParams , numiter_lanczos : int = 25
481+ ) -> None :
482+ """Perform symmetric two-site TDVP integration.
482483
483484 This function evolves the MPS by updating two neighboring sites simultaneously.
484485 The evolution includes merging the two site tensors, applying the local Hamiltonian,
@@ -499,11 +500,15 @@ def two_site_TDVP(state: MPS, H: MPO, sim_params, numiter_lanczos: int=25):
499500 "Unifying time evolution and optimization with matrix product states",
500501 Phys. Rev. B 94, 165116 (2016) (arXiv:1408.5056)
501502 """
503+ from ..data_structures .simulation_parameters import StrongSimParams , WeakSimParams
504+
502505 num_sites = H .length
503506 if num_sites != state .length :
504- raise ValueError ("State and Hamiltonian must have the same number of sites" )
507+ msg = "State and Hamiltonian must have the same number of sites"
508+ raise ValueError (msg )
505509 if num_sites < 2 :
506- raise ValueError ("Hamiltonian is too short for a two-site update (2TDVP)." )
510+ msg = "Hamiltonian is too short for a two-site update (2TDVP)."
511+ raise ValueError (msg )
507512
508513 # Compute the right operator blocks.
509514 right_blocks = initialize_right_environments (state , H )
@@ -518,8 +523,9 @@ def two_site_TDVP(state: MPS, H: MPO, sim_params, numiter_lanczos: int=25):
518523 left_identity [i , a , i ] = 1
519524 left_blocks [0 ] = left_identity
520525
526+ # Adjust simulation time step if simulation parameters require a unit time step.
521527 if isinstance (sim_params , (WeakSimParams , StrongSimParams )):
522- sim_params .dt = 1
528+ sim_params .dt = 2
523529
524530 # Left-to-right sweep for sites 0 to L-2.
525531 for i in range (num_sites - 2 ):
@@ -528,35 +534,73 @@ def two_site_TDVP(state: MPS, H: MPO, sim_params, numiter_lanczos: int=25):
528534 # Similarly, merge the corresponding MPO tensors.
529535 merged_mpo = merge_mpo_tensors (H .tensors [i ], H .tensors [i + 1 ])
530536 # Evolve the merged tensor forward by half a time step.
531- merged_tensor = update_site (left_blocks [i ], right_blocks [i + 1 ], merged_mpo , merged_tensor , 0.5 * sim_params .dt , numiter_lanczos )
537+ merged_tensor = update_site (
538+ left_blocks [i ], right_blocks [i + 1 ], merged_mpo , merged_tensor , 0.5 * sim_params .dt , numiter_lanczos
539+ )
532540 # Split the merged tensor back into two tensors.
533- state .tensors [i ], state .tensors [i + 1 ] = split_mps_tensor ( merged_tensor , 'right' , threshold = sim_params .threshold )
541+ state .tensors [i ], state .tensors [i + 1 ] = split_mps_tensor (
542+ merged_tensor , "right" , threshold = sim_params .threshold
543+ )
534544 # Update the left operator block for site i+1.
535545 left_blocks [i + 1 ] = update_left_environment (state .tensors [i ], state .tensors [i ], H .tensors [i ], left_blocks [i ])
536546 # Evolve the tensor at site i+1 backward by half a time step.
537- state .tensors [i + 1 ] = update_site (left_blocks [i + 1 ], right_blocks [i + 1 ], H .tensors [i + 1 ], state .tensors [i + 1 ], - 0.5 * sim_params .dt , numiter_lanczos )
547+ state .tensors [i + 1 ] = update_site (
548+ left_blocks [i + 1 ],
549+ right_blocks [i + 1 ],
550+ H .tensors [i + 1 ],
551+ state .tensors [i + 1 ],
552+ - 0.5 * sim_params .dt ,
553+ numiter_lanczos ,
554+ )
555+
556+ # Guarantees unit time at final site for circuits
557+ if isinstance (sim_params , (WeakSimParams , StrongSimParams )):
558+ sim_params .dt = 1
538559
539560 # Process the rightmost pair (sites L-2 and L-1)
540561 i = num_sites - 2
541562 merged_tensor = merge_mps_tensors (state .tensors [i ], state .tensors [i + 1 ])
542563 merged_mpo = merge_mpo_tensors (H .tensors [i ], H .tensors [i + 1 ])
543564 # Evolve the merged tensor forward by a full time step.
544- merged_tensor = update_site (left_blocks [i ], right_blocks [i + 1 ], merged_mpo , merged_tensor , sim_params .dt , numiter_lanczos )
565+ merged_tensor = update_site (
566+ left_blocks [i ], right_blocks [i + 1 ], merged_mpo , merged_tensor , sim_params .dt , numiter_lanczos
567+ )
568+ # Only a single sweep is needed for circuits
569+ if isinstance (sim_params , (WeakSimParams , StrongSimParams )):
570+ state .tensors [i ], state .tensors [i + 1 ] = split_mps_tensor (merged_tensor , "right" , threshold = sim_params .threshold )
571+ return
572+
545573 # Split the merged tensor using a 'left' distribution of singular values.
546- state .tensors [i ], state .tensors [i + 1 ] = split_mps_tensor (merged_tensor , 'left' , threshold = sim_params .threshold )
574+ state .tensors [i ], state .tensors [i + 1 ] = split_mps_tensor (merged_tensor , "left" , threshold = sim_params .threshold )
575+
547576 # Update the right operator block for site i.
548- right_blocks [i ] = update_right_environment (state .tensors [i + 1 ], state .tensors [i + 1 ], H .tensors [i + 1 ], right_blocks [i + 1 ])
577+ right_blocks [i ] = update_right_environment (
578+ state .tensors [i + 1 ], state .tensors [i + 1 ], H .tensors [i + 1 ], right_blocks [i + 1 ]
579+ )
580+
581+
549582
550583 # Right-to-left sweep.
551584 for i in reversed (range (num_sites - 2 )):
552585 # Evolve the tensor at site i+1 backward by half a time step.
553- state .tensors [i + 1 ] = update_site (left_blocks [i + 1 ], right_blocks [i + 1 ], H .tensors [i + 1 ], state .tensors [i + 1 ], - 0.5 * sim_params .dt , numiter_lanczos )
586+ state .tensors [i + 1 ] = update_site (
587+ left_blocks [i + 1 ],
588+ right_blocks [i + 1 ],
589+ H .tensors [i + 1 ],
590+ state .tensors [i + 1 ],
591+ - 0.5 * sim_params .dt ,
592+ numiter_lanczos ,
593+ )
554594 # Merge the tensors at sites i and i+1.
555595 merged_tensor = merge_mps_tensors (state .tensors [i ], state .tensors [i + 1 ])
556596 merged_mpo = merge_mpo_tensors (H .tensors [i ], H .tensors [i + 1 ])
557597 # Evolve the merged tensor forward by half a time step.
558- merged_tensor = update_site (left_blocks [i ], right_blocks [i + 1 ], merged_mpo , merged_tensor , 0.5 * sim_params .dt , numiter_lanczos )
598+ merged_tensor = update_site (
599+ left_blocks [i ], right_blocks [i + 1 ], merged_mpo , merged_tensor , 0.5 * sim_params .dt , numiter_lanczos
600+ )
559601 # Split the merged tensor using a 'left' distribution.
560- state .tensors [i ], state .tensors [i + 1 ] = split_mps_tensor (merged_tensor , ' left' , threshold = sim_params .threshold )
602+ state .tensors [i ], state .tensors [i + 1 ] = split_mps_tensor (merged_tensor , " left" , threshold = sim_params .threshold )
561603 # Update the right operator block.
562- right_blocks [i ] = update_right_environment (state .tensors [i + 1 ], state .tensors [i + 1 ], H .tensors [i + 1 ], right_blocks [i + 1 ])
604+ right_blocks [i ] = update_right_environment (
605+ state .tensors [i + 1 ], state .tensors [i + 1 ], H .tensors [i + 1 ], right_blocks [i + 1 ]
606+ )
0 commit comments