Beispiel #1
0
 def test_both_mixed(self, p1, p2):
     f = qu.fidelity(qu.eye(3) / 3, qu.eye(3) / 3)
     assert_allclose(f, 1.0)
     f = qu.fidelity(p1, p1)
     assert_allclose(f, 1.0)
     f = qu.fidelity(p1, p2)
     assert f > 0 and f < 1
Beispiel #2
0
    def get_fidelity_with(self,
                          target_state: Union[str, q.qarray] = "ghz") -> float:
        """
        :param target_state: One of "ghz", "ghz_antisymmetric", "ground", and "excited"
        :return:
        """
        assert (
            self.evo
            is not None), "evo attribute cannot be None (call solve method)"

        final_state = self.solved_states[-1]
        if target_state == "ghz":
            return q.fidelity(final_state,
                              self.ghz_state.get_state_tensor(symmetric=True))
        elif target_state == "ghz_antisymmetric":
            return q.fidelity(final_state,
                              self.ghz_state.get_state_tensor(symmetric=False))
        elif target_state == "ground":
            return q.fidelity(final_state,
                              q.kron(*states_quimb.get_ground_states(self.N)))
        elif target_state == "excited":
            return q.fidelity(final_state,
                              q.kron(*states_quimb.get_excited_states(self.N)))
        elif isinstance(target_state, q.qarray):
            return q.fidelity(final_state, target_state)
        else:
            raise ValueError(
                f"target_state has to be one of 'ghz', 'ground', or 'excited', not {target_state}."
            )
Beispiel #3
0
    def plot_ghz_states_overlaps(self,
                                 ax,
                                 with_antisymmetric_ghz: bool,
                                 plot_title: bool = True):
        labelled_states = [(self.ghz_state.get_state_tensor(),
                            r"$\psi_{\mathrm{GHZ}}^{\mathrm{s}}$")]
        if with_antisymmetric_ghz:
            labelled_states.append(
                (self.ghz_state.get_state_tensor(symmetric=False),
                 r"$\psi_{\mathrm{GHZ}}^{\mathrm{a}}$"))

        for _state, _label in labelled_states:
            ax.plot(self.solved_t_list, [
                q.fidelity(_state, _instantaneous_state)
                for _instantaneous_state in self.solved_states
            ],
                    label=_label,
                    lw=1,
                    alpha=0.8)
        ax.set_ylabel("Fidelity")
        if plot_title:
            ax.set_title("Fidelity with GHZ states")
        ax.set_ylim((-0.1, 1.1))
        ax.yaxis.set_ticks([0, 0.5, 1])
        ax.legend()
Beispiel #4
0
 def test_w_state(self, dtype):
     mps = qtn.MPS_w_state(5, dtype=dtype)
     assert mps.dtype == dtype
     psi = qu.w_state(5, dtype=dtype)
     assert mps.H @ mps == pytest.approx(1.0)
     assert mps.bond_sizes() == [2, 2, 2, 2]
     assert qu.fidelity(psi, mps.to_dense()) == pytest.approx(1.0)
Beispiel #5
0
 def test_orthog_pure(self, orthog_ks):
     k1, k2, k3 = orthog_ks
     for s1, s2, in ([k1, k2], [k2, k3], [k3, k1], [k1 @ k1.H,
                                                    k2], [k1, k2 @ k2.H],
                     [k3 @ k3.H, k2], [k3,
                                       k2 @ k2.H], [k1 @ k1.H,
                                                    k3], [k1, k3 @ k3.H],
                     [k1 @ k1.H,
                      k2 @ k2.H], [k2 @ k2.H,
                                   k3 @ k3.H], [k1 @ k1.H, k3 @ k3.H]):
         f = qu.fidelity(s1, s2)
         assert_allclose(f, 0.0, atol=1e-6)
Beispiel #6
0
if dis_flag == 1:
    H_1 = qu.ham_mbl(N,
                     W,
                     J_tab,
                     cyclic=False,
                     dh_dist='qp',
                     beta=0.721,
                     seed=seed,
                     sparse=True).real
else:
    H_1 = qu.ham_mbl(N, W, J_tab, cyclic=False, seed=seed, sparse=True).real

H_post = P.T @ H_1 @ P

compute = {'time': lambda t, p: t, 'losch': lambda t, p: qu.fidelity(psi_0, p)}
evo = qu.Evolution(psi_0, H_post, compute=compute, method='expm')

for t in evo.at_times(t_tab):
    continue

TS = evo.results['time']
LOSCH = np.array(-np.log(evo.results['losch'])) / N

if dis_flag == 1:
    directory = '../DATA/GSQPWi' + str(W_i) + '/L' + str(N) + '/D' + str(
        W) + '/'
    PATH_now = LOCAL + os.sep + directory + os.sep
    if not os.path.exists(PATH_now):
        os.makedirs(PATH_now)
else:
Beispiel #7
0
subsys = range(N//2) # define subsystem

base=hf.Base_states(N,N//2)
ind_n=np.zeros((len(base), 2))
for i in range(len(base)):
    somma=0
    for j in range(N//2):
        somma+=int(base[i][j])
    ind_n[i]=[somma,i]
StateList=[]
for i in range(N//2+1):
    StateList.append(np.where(ind_n[:,0]==i)[0])

compute = {
    'time': lambda t, p: t,
    'losch': lambda t, p: np.square(np.absolute(qu.fidelity(psi_0, p))),
    'imb': lambda t,p: np.real(I.expt_value(p)),
    'entropy': lambda t, p: ent_entropy(p, basis, chain_subsys=subsys)['Sent_A'],
    'num_ent': lambda t, p: hf.Num_ent(N, p, StateList)
}
evo = qu.Evolution(psi_0, H, compute=compute, method='solve')


for pt in evo.at_times(t_tab):
    ts=evo.results['time']
Sent=N//2*(np.array(evo.results['entropy'])/np.log2(math.e))
P_N=np.array(evo.results['num_ent'])/np.log2(math.e)
Losch=np.array(-np.log(evo.results['losch']))/N
Imb=2*np.array(evo.results['imb'])

Beispiel #8
0
 def test_both_pure(self, k1, k2):
     f = qu.fidelity(k1, k1)
     assert_allclose(f, 1.0)
     f = qu.fidelity(k1, k2)
     assert f > 0 and f < 1
Beispiel #9
0
    calculate_subsystem_entropy(state_) for state_ in e_qs.solved_states
]
print(f"calculated entropies in {time.time() - start_time:.3f}s")
print("plotting.")

fig, axs = plt.subplots(3, 1, sharex='all', figsize=(10, 8))
ax0, ax1, ax2 = axs
ax0.xaxis.set_major_formatter(ticker.EngFormatter('s'))
plt.xlabel('Time')

e_qs.plot_Omega_and_Delta(ax0)

ghz_state_tensor = ghz_state.get_state_tensor(True)

ax1.plot(e_qs.t_list,
         [q.fidelity(ghz_state_tensor, _state) for _state in solved_states],
         label=r"$\psi_{\mathrm{GHZ}}^{\mathrm{s}}$",
         lw=1,
         alpha=0.8)
ax1.set_ylabel("Fidelity")
ax1.set_title("Fidelity with GHZ states")
ax1.set_ylim((-0.1, 1.1))
ax1.yaxis.set_ticks([0, 0.5, 1])
ax1.legend()

ax2.plot(
    e_qs.t_list,
    subsystem_entropy,
)
ax2.set_title("Entanglement Entropy")
ax2.set_ylabel(r"$e^{ \mathcal{S} ( \rho_A ) } \, / \, \frac{N}{2}$")
Beispiel #10
0
    def test_evo_timedep_adiabatic_with_callbacks(self, dop, linop,
                                                  num_callbacks):
        # tests time dependent Evolution via an adiabatic sweep with:
        #   a) no callbacks
        #   b) 1 callback that accesses the time-dependent Hamiltonian
        #   c) 2 callbacks where one access the Hamiltonian and one doesn't

        if num_callbacks > 0 and (dop or linop):
            # should implement this at some point
            return
        L = 6
        T = 20

        H1 = qu.ham_mbl(L, dh=1.0, seed=4, sparse=True)
        gs1 = qu.groundstate(H1)
        H2 = qu.ham_mbl(L, dh=1.0, seed=5, sparse=True)
        gs2 = qu.groundstate(H2)

        if linop:
            import scipy.sparse.linalg as spla

            H1 = spla.aslinearoperator(H1)
            H2 = spla.aslinearoperator(H2)

        # make sure two ground states are different
        assert qu.fidelity(gs1, gs2) < 0.5

        # linearly interpolate from one ham to the other
        def ham(t):
            return (1 - t / T) * H1 + (t / T) * H2

        if linop:
            assert isinstance(ham(0.3), spla.LinearOperator)

        if dop:
            p0 = qu.dop(gs1)
        else:
            p0 = gs1

        if num_callbacks == 0:
            evo = qu.Evolution(p0, ham, progbar=True)
        else:

            def gs_overlap(t, pt, H):
                evals, evecs = eigs_scipy(H(t), k=1, which='SA')
                return np.abs(qu.dot(pt.T, qu.qu(evecs[:, 0])))**2

            if num_callbacks == 1:
                compute = gs_overlap
            if num_callbacks == 2:

                def norm(t, pt):
                    return qu.dot(pt.T, pt)

                compute = {'norm': norm, 'gs_overlap': gs_overlap}
            evo = qu.Evolution(p0, ham, compute=compute, progbar=True)
        evo.update_to(T)

        # final state should now overlap much more with second hamiltonian GS
        assert qu.fidelity(evo.pt, gs1) < 0.5
        assert qu.fidelity(evo.pt, gs2) > 0.99

        if num_callbacks == 1:
            gs_overlap_results = evo.results
            # check that we stayed in the ground state the whole time
            assert ((np.array(gs_overlap_results) - 1.0) < 1e-3).all()

        if num_callbacks == 2:
            norm_results = evo.results['norm']
            gs_overlap_results = evo.results['gs_overlap']
            # check that we stayed normalized the whole time
            assert ((np.array(norm_results) - 1.0) < 1e-3).all()
            # check that we stayed in the ground state the whole time
            assert ((np.array(gs_overlap_results) - 1.0) < 1e-3).all()
Beispiel #11
0
H_ETH = P.T @ qu.ham_heis(N, J_ETH, sparse=True, cyclic=False) @ P
Psi_ETH = qu.eigvecsh(H_ETH, k=1, which='SA')

J_evo1 = (0.0, 0.0, 0.0)
H_evo1 = P.T @ qu.ham_mbl(N,
                          W,
                          J_evo1,
                          cyclic=False,
                          dh_dist='qp',
                          beta=0.721,
                          seed=seed,
                          sparse=True).real @ P

compute = {
    'time': lambda t, p: t,
    'losch': lambda t, p: qu.fidelity(Psi_ETH, p)
}
evo_ETH = qu.Evolution(Psi_ETH, H_evo1, compute=compute, method='expm')

for t in evo_ETH.at_times(t_tab):
    continue

TS = evo_ETH.results['time']
LOSCH_ETH = np.array(-np.log(evo_ETH.results['losch'])) / N

### MBL --> ETH ###
W_i = params.W_i

J_MBL = (0.0, 0.0, 0.0)

H_MBL = P.T @ qu.ham_mbl(N,