Ejemplo n.º 1
0
 def _normalize_state(self):
     """
         Normalizes psi_t by dividing by the trace. Internal normalization. Can be overloaded for
         tracking purposes. Is only called during the propagation
     :return:
     """
     self.psi_t /= mp.norm(self.psi_t)
Ejemplo n.º 2
0
 def fast_evolve(self, end=True):
     """
         Perform a Trotterized time evolution step by tau. Compress after each dot product. Renormalizes state after
         one full Trotter-step due to compression.
         Without setting the end flag, the evolution does not do a complete trotter step, and the resulting state is
         therefore not immediately useable. Not setting the end flag allows for leaving out some unnecessary
         double steps and can therefore be used for propagating intermediate steps
     :parameter end: Flag, which can be set to false, if the current propagation only needs to produce an
                     intermediate step, which is not used otherwise.
     :return:
     """
     self.last_state_norm = self.curr_state_norm
     if self.start and end:
         trotter_steps = self.propagator.trotter_steps
     elif self.start and not end:
         trotter_steps = self.propagator.start_trotter_steps
         self.start = False
     elif not self.start and end:
         trotter_steps = self.propagator.end_trotter_steps
         self.start = True
     else:
         trotter_steps = self.propagator.step_trotter_steps
     if not self.canonicalize_every_step:
         canonicalize_to(self.psi_t, to_cform=self.to_cform)
     for index, (trotter_ui, trotter_ui_adj) in enumerate(trotter_steps):
         self.psi_t = mp.dot(trotter_ui, self.psi_t, self.axes)
         if self.canonicalize_every_step:
             self.psi_t.compress(**self.state_compression_kwargs)
         else:
             if index < self.len_trotter_steps - 1:
                 self.psi_t.compress(**self.state_compression_kwargs_noc)
             else:
                 if self.canonicalize_last_step:
                     self.psi_t.compress(**self.state_compression_kwargs)
                 else:
                     self.psi_t.compress(
                         **self.state_compression_kwargs_noc)
         self.psi_t = mp.dot(self.psi_t, trotter_ui.adj(), self.axes)
         if self.canonicalize_every_step:
             self.psi_t.compress(**self.state_compression_kwargs)
         else:
             if index < self.len_trotter_steps - 1:
                 self.psi_t.compress(**self.state_compression_kwargs_noc)
             else:
                 if self.canonicalize_last_step:
                     self.psi_t.compress(**self.state_compression_kwargs)
                 else:
                     self.psi_t.compress(
                         **self.state_compression_kwargs_noc)
     self._normalize_state()
     self.curr_state_norm = mp.norm(self.psi_t)
     self.trotter_error += 2 * self.propagator.step_trotter_error
     self.stepno += 1
     if self.start and not end:
         self.start = False
     elif not self.start and end:
         self.start = True
Ejemplo n.º 3
0
 def _normalize_state(self):
     """
         Normalizes psi_t by dividing by the l2-norm. Is only called during the propagation.
         Tracks the trace of the density matrix during propagation
     :return:
     """
     curr_trace = mp.norm(self.psi_t)
     if self.trace_track:
         self.trace_list.append(np.abs(curr_trace)**2)
     self.psi_t /= curr_trace
Ejemplo n.º 4
0
def test_povm_ic_mpa(nr_sites, local_dim, rank, rgen):
    # Check that the tensor product of the PauliGen POVM is IC.
    paulis = povm.pauli_povm(local_dim)
    inv_map = mp_from_array_repeat(paulis.linear_inversion_map, nr_sites)
    probab_map = mp_from_array_repeat(paulis.probability_map, nr_sites)
    reconstruction_map = mp.dot(inv_map, probab_map)

    eye = factory.eye(nr_sites, local_dim**2)
    assert mp.norm(reconstruction_map - eye) < 1e-5

    # Check linear inversion for a particular example MPA.
    # Linear inversion works for arbitrary matrices, not only for states,
    # so we test it for an arbitrary MPA.
    # Normalize, otherwise the absolute error check below will not work.
    mpa = factory.random_mpa(nr_sites, local_dim**2, rank,
                             dtype=np.complex_, randstate=rgen, normalized=True)
    probabs = mp.dot(probab_map, mpa)
    recons = mp.dot(inv_map, probabs)
    assert mp.norm(recons - mpa) < 1e-6
Ejemplo n.º 5
0
def get_norm_of_hamiltonian(h_site, h_bond, compression_relerr=None):
    """
        Calculates norm of a Hamiltonian H = sum_i h_site_i + h_bond_i,i+1
    :param h_site: List of site local operators
    :param h_bond: List of bond operators
    :param compression_relerr: If not None, the result of the sum is compressed using svd compression for the
                               specified relative error
    :return: Norm of the Hamiltonian
    """
    return mp.norm(embed_hamiltonian_as_mpo(h_site, h_bond, compression_relerr=compression_relerr))
Ejemplo n.º 6
0
def get_norm_of_hi(dims, hi_list, compression_relerr=None):
    """
        Calculates norm of a Hamiltonian H = sum_i hi,i+1
    :param dims: Dimensions of the sites of the chain (axis 0 legs of mpnum shape) as tuple or list
    :param hi_list: List/Tuple for all coupling terms in the Hamiltonian
    :param compression_relerr: If not None, the result of the sum is compressed using svd compression for the
                               specified relative error
    :return: Norm of the Hamiltonian
    """
    return mp.norm(embed_hi_as_mpo(dims, hi_list, compression_relerr=compression_relerr))
Ejemplo n.º 7
0
def _get_stepsize_mpa(A, g):
    """Computes stepsize :math:`\mu = \frac{\Vert g \Vert^2}{\Vert A g \Vert^2}`
    for TIHT in the representation using MPArrays.

    For more details on the arguments see :func:`TihtStepsize.__call__`.

    """
    numerator = mp.norm(g)**2
    denominator = sum(mpsp.inner_prod_mps(a, g)**2 for a in A)
    return float(numerator / denominator)
Ejemplo n.º 8
0
    def __init__(self,
                 psi_0,
                 propagator,
                 state_compression_kwargs=None,
                 t0=0,
                 psi_0_compression_kwargs=None):
        """
            Constructor for the StarTMPO class. Time evolution for quantum states represented by mpo for a
            star geometry. Does required setup steps for evolve to work.
            Uses a pre-constructed MPPropagator object

        :param psi_0: Initial state as MPArray. More precisely as an MPArray with two physical legs on each site,
                      which have the same dimension (axis 0 = axis 1). Will be normalized before propagation
        :param propagator: Pre-constructed compatible StarMPPropagator object. (Compatibility means, that the
                           chain shape with which it was constructed matches the shape of psi_0 and that
                           it was constructed without ancilla sites, but with pre-calculated adjoints)
        :param state_compression_kwargs: Optional compression kwargs for the state (see real time evolution
                                         factory function for details)
        :param t0: Initial time of the propagation
        :param psi_0_compression_kwargs: Optional compression kwargs for the initial state (see real time evolution
                                         factory function for details)
        """
        super().__init__(psi_0,
                         propagator,
                         state_compression_kwargs=state_compression_kwargs,
                         t0=t0)
        self.mpa_type = 'mpo'
        self.system_index = propagator.system_index

        # Check if propagator is valid for the selected state mpa_type
        assert not self.propagator.ancilla_sites
        assert self.propagator.build_adj
        self.axes = (-1, 0)

        self.to_cform = propagator.to_cform

        if psi_0_compression_kwargs is None:
            canonicalize_to(self.psi_t, to_cform=self.to_cform)
        else:
            compress_mpa(self.psi_t,
                         to_cform=self.to_cform,
                         **psi_0_compression_kwargs)

        # trace normalize current initial psi_t (=psi_0)
        self.normalize_state()

        # If we deal with an mpo state we want to track the L2-norm of the state.
        # It should be approximately conserved by the trotterized evolution assuming no significant compression losses.
        self.init_state_norm = mp.norm(psi_0)
        self.last_state_norm = self.init_state_norm
        self.curr_state_norm = self.init_state_norm

        # Contains accumulated trotter errors for each timestep
        self.trotter_error = 0
Ejemplo n.º 9
0
def get_maximally_mixed_pmps(dims, normalized=False):
    """
        Generates a maximally mixed state as pmps embedded on a chain with physical dimensions specified by dims
        The ancilla dimension are the same as the physical dimension on each site.
    :param dims: iterable of site local physical leg dimensions of the chain in which to embed
    :param normalized: Set True to return a normalized state
    :return: maximally mixed state as PMPS
    """
    mm_pmps = mp.eye(len(dims), dims)
    if not normalized:
        return mm_pmps
    else:
        return mm_pmps / mp.norm(mm_pmps)
Ejemplo n.º 10
0
def normalize(state, method):
    """
    Normalize a state.

    Args:
        state (mpnum.MPArray): The state to be normalized
        method (str): Whether it is a MPS, MPO or PMPS state

    Returns:
        mpnum.MPArray: The normalized state
    """
    if method == 'pmps' or method == 'mps':
        state = state / mp.norm(state)
    if method == 'mpo':
        state = state / mp.trace(state)
    return state
Ejemplo n.º 11
0
def normalize(state, method):
    """
    Normalize a state (hopefully in place)

    .. todo::
       Check if state is mutable and this operation in place. Then clear docstring

    Args:
        state (mpnum.MPArray): The state to be normalized
        method (str): Whether it is a MPS, MPO or PMPS state

    Returns:
        mpnum.MPArray: The normalized state
    """
    if method == 'pmps' or method == 'mps':
        state = state / mp.norm(state)
    if method == 'mpo':
        state = state / mp.trace(state)
    return state
Ejemplo n.º 12
0
 def evolve(self):
     """
         Perform a Trotterized time evolution step by tau. Compress after each dot product or after each sweep
         through the chain. Renormalizes state after one full timestep due to compression.
     :return:
     """
     self.last_state_norm = self.curr_state_norm
     last_start_at = self.system_index
     if not self.canonicalize_every_step:
         canonicalize_to(self.psi_t, to_cform=self.to_cform)
     for (start_at, trotter_mpo,
          trotter_mpo_adj) in self.propagator.trotter_steps:
         self.psi_t = mp.partialdot(trotter_mpo,
                                    self.psi_t,
                                    start_at=start_at,
                                    axes=self.axes)
         if not self.full_compression:
             if len(trotter_mpo) > 1:
                 self.lc.compress(self.psi_t, start_at)
         self.psi_t = mp.partialdot(self.psi_t,
                                    trotter_mpo_adj,
                                    start_at=start_at,
                                    axes=self.axes)
         if self.full_compression:
             if start_at == self.propagator.L - 2 or start_at == 0:
                 # Compress after a full sweep
                 if start_at != last_start_at:
                     self.psi_t.compress(**self.state_compression_kwargs)
         else:
             if len(trotter_mpo) > 1:
                 self.lc.compress(self.psi_t, start_at)
     if self.final_compression:
         self.psi_t.compress(**self.state_compression_kwargs)
     else:
         if not self.canonicalize_every_step:
             canonicalize_to(self.psi_t, to_cform=self.to_cform)
     self._normalize_state()
     self.curr_state_norm = mp.norm(self.psi_t)
     self.trotter_error += self.propagator.step_trotter_error
     self.stepno += 1
Ejemplo n.º 13
0
 def evolve(self):
     """
         Perform a Trotterized time evolution step by tau. Compress after each dot product. Renormalizes state after
         one full timestep due to compression.
     :return:
     """
     self.last_state_norm = self.curr_state_norm
     # Can use the symmetry of the Suzuki-Trotter decomposition here to do it in one loop and
     # the fact, that for hermitian hi we have U = e^(-i*tau*hi), U^dag = U*
     for index, (trotter_ui, trotter_ui_adj) in enumerate(
             self.propagator.trotter_steps):
         self.psi_t = mp.dot(trotter_ui, self.psi_t, self.axes)
         if self.canonicalize_every_step:
             self.psi_t.compress(**self.state_compression_kwargs)
         else:
             if index < self.len_trotter_steps - 1:
                 self.psi_t.compress(**self.state_compression_kwargs_noc)
             else:
                 if self.canonicalize_last_step:
                     self.psi_t.compress(**self.state_compression_kwargs)
                 else:
                     self.psi_t.compress(
                         **self.state_compression_kwargs_noc)
         self.psi_t = mp.dot(self.psi_t, trotter_ui_adj, self.axes)
         if self.canonicalize_every_step:
             self.psi_t.compress(**self.state_compression_kwargs)
         else:
             if index < self.len_trotter_steps - 1:
                 self.psi_t.compress(**self.state_compression_kwargs_noc)
             else:
                 if self.canonicalize_last_step:
                     self.psi_t.compress(**self.state_compression_kwargs)
                 else:
                     self.psi_t.compress(
                         **self.state_compression_kwargs_noc)
     self._normalize_state()
     self.curr_state_norm = mp.norm(self.psi_t)
     self.trotter_error += 2 * self.propagator.step_trotter_error
     self.stepno += 1
Ejemplo n.º 14
0
    def reset(self,
              psi_0=None,
              state_compression_kwargs=None,
              psi_0_compression_kwargs=None):
        """
            Resets selected properties of the TMPO object

            If psi_0 is not None, we set the new initial state to psi_0, otherwise we keep the current state.
            If psi_0 is to be changed, reset overlap and trotter error tracking.
            Checks if shape of passed psi_0 is compatible with the shape of the current propagator object

        :param psi_0: Optional new initial state, need not be normalized. Is normalized before propagation
        :param state_compression_kwargs: Optional. If not None, chamge the current parameters for
                                         state compression. If set None old compression parameters are kept,
                                         if empty, default compression is used. (see real time evolution
                                         factory function for details)
        :param psi_0_compression_kwargs: Optional compression kwargs for the initial state (see real time evolution
                                         factory function for details)
        :return:
        """
        if psi_0 is not None:
            if psi_0_compression_kwargs is not None:
                compress_mpa(psi_0,
                             to_cform=self.to_cform,
                             **psi_0_compression_kwargs)
            else:
                canonicalize_to(psi_0, to_cform=self.to_cform)
            # Normalize current initial psi_t (=psi_0)
            self.normalize_state()
            self.init_state_norm = mp.norm(psi_0)
            self.last_state_norm = self.init_state_norm
            self.curr_state_norm = self.init_state_norm
            self.trotter_error = 0
            self.stepno = 0
        super().reset(psi_0=psi_0,
                      state_compression_kwargs=state_compression_kwargs)
Ejemplo n.º 15
0
 def normalize_state(self):
     """
         Normalizes psi_t by dividing by its l2 norm.
     :return:
     """
     self.psi_t /= mp.norm(self.psi_t)