def finite_dmrg_step(growing_block, system, left_block_size, number_of_states_kept): """Performs one step of the finite DMRG algorithm. Calculates the ground state of a system with a given size, then performs the DMRG transformation on the operators of *one* block, therefore increasing by one site the number of sites encoded in the Hilbert space of this block, and reset the block in the system to be the new, enlarged, truncated ones. The other block is read out from the previous sweep. Parameters ---------- growing_block : a string. The block which is growing. It must be 'left' or 'right'. system : a System object. The system you want to do the calculation on. This function assumes that you have set the Hamiltonian to something. left_block_size : an int. The number of sites in the left block in the *current* step, not including the single site. number_of_states_kept : an int. The number of states you want to keep in each block after the truncation. If the `number_of_states_kept` is smaller than the dimension of the current Hilbert space block, all states are kept. Returns ------- energy : a double. The energy at this step. entropy : a double. The Von Neumann entropy for the cut at this step. truncation_error : a double. The truncation error, i.e. the sum of the discarded eigenvalues of the reduced density matrix. Raises ------ DMRGException if `growing_side` is not 'left' or 'right'. Notes ----- This asymmetric version of the algorithm when you just grow one of the block while keeping the other one-site long, is obviously less precise than the symmetric version when you grow both sides. However as we are going to sweep next using the finite algorithm we don't care much about precision at this stage. """ model.set_hamiltonian(system) ground_state_energy, ground_state_wf = system.calculate_ground_state() if growing_block not in ('left', 'right'): raise DMRGException('Growing side must be left or right.') entropy, truncation_error = grow_block_by_one_site(growing_block, ground_state_wf, system, number_of_states_kept) system.set_block_to_old_version(left_block_size) return ground_state_energy, entropy, truncation_error
def finite_dmrg_step(growing_block, system, left_block_size, number_of_states_kept): """Performs one step of the finite DMRG algorithm. Calculates the ground state of a system with a given size, then performs the DMRG transformation on the operators of *one* block, therefore increasing by one site the number of sites encoded in the Hilbert space of this block, and reset the block in the system to be the new, enlarged, truncated ones. The other block is read out from the previous sweep. Parameters ---------- growing_block : a string. The block which is growing. It must be 'left' or 'right'. system : a System object. The system you want to do the calculation on. This function assumes that you have set the Hamiltonian to something. left_block_size : an int. The number of sites in the left block in the *current* step, not including the single site. number_of_states_kept : an int. The number of states you want to keep in each block after the truncation. If the `number_of_states_kept` is smaller than the dimension of the current Hilbert space block, all states are kept. Returns ------- energy : a double. The energy at this step. entropy : a double. The Von Neumann entropy for the cut at this step. truncation_error : a double. The truncation error, i.e. the sum of the discarded eigenvalues of the reduced density matrix. Raises ------ DMRGException if `growing_side` is not 'left' or 'right'. Notes ----- This asymmetric version of the algorithm when you just grow one of the block while keeping the other one-site long, is obviously less precise than the symmetric version when you grow both sides. However as we are going to sweep next using the finite algorithm we don't care much about precision at this stage. """ model.set_hamiltonian(system) ground_state_energy, ground_state_wf = system.calculate_ground_state() if growing_block not in ("left", "right"): raise DMRGException("Growing side must be left or right.") entropy, truncation_error = grow_block_by_one_site(growing_block, ground_state_wf, system, number_of_states_kept) system.set_block_to_old_version(left_block_size) return ground_state_energy, entropy, truncation_error
def infinite_dmrg_step(system, number_of_states_kept): """Performs one step of the (asymmetric) infinite DMRG algorithm. Calculates the ground state of a system with a given size, then performs the DMRG transformation on the operators of *one* block, therefore increasing by one site the number of sites encoded in the Hilbert space of this block, and reset the block in the system to be the new, enlarged, truncated ones. The other block is kept one-site long. Parameters ---------- system : a System object. The system you want to do the calculation on. This function assumes that you have set the Hamiltonian to something. number_of_states_kept : an int. The number of states you want to keep in each block after the truncation. If the `number_of_states_kept` is smaller than the dimension of the current Hilbert space block, all states are kept. Returns ------- energy : a double. The energy for the `current_size`. entropy : a double. The Von Neumann entropy for the cut that splits the chain into two equal halves. truncation_error : a double. The truncation error, i.e. the sum of the discarded eigenvalues of the reduced density matrix. Notes ----- This asymmetric version of the algorithm when you just grow one of the block while keeping the other one-site long, is obviously less precise than the symmetric version when you grow both sides. However as we are going to sweep next using the finite algorithm we don't care much about precision at this stage. """ model.set_hamiltonian(system) ground_state_energy, ground_state_wf = system.calculate_ground_state() entropy, truncation_error = grow_block_by_one_site('left', ground_state_wf, system, number_of_states_kept) return ground_state_energy, entropy, truncation_error
def infinite_dmrg_step(system, number_of_states_kept): """Performs one step of the (asymmetric) infinite DMRG algorithm. Calculates the ground state of a system with a given size, then performs the DMRG transformation on the operators of *one* block, therefore increasing by one site the number of sites encoded in the Hilbert space of this block, and reset the block in the system to be the new, enlarged, truncated ones. The other block is kept one-site long. Parameters ---------- system : a System object. The system you want to do the calculation on. This function assumes that you have set the Hamiltonian to something. number_of_states_kept : an int. The number of states you want to keep in each block after the truncation. If the `number_of_states_kept` is smaller than the dimension of the current Hilbert space block, all states are kept. Returns ------- energy : a double. The energy for the `current_size`. entropy : a double. The Von Neumann entropy for the cut that splits the chain into two equal halves. truncation_error : a double. The truncation error, i.e. the sum of the discarded eigenvalues of the reduced density matrix. Notes ----- This asymmetric version of the algorithm when you just grow one of the block while keeping the other one-site long, is obviously less precise than the symmetric version when you grow both sides. However as we are going to sweep next using the finite algorithm we don't care much about precision at this stage. """ model.set_hamiltonian(system) ground_state_energy, ground_state_wf = system.calculate_ground_state() entropy, truncation_error = grow_block_by_one_site("left", ground_state_wf, system, number_of_states_kept) return ground_state_energy, entropy, truncation_error