def get_ZTT_mineig(Lags, Olist, UPlistlist, eigvals_only=False): modenum = len(Olist) mineigw = mp.inf modemineig = -1 if eigvals_only: for mode in range(modenum): ZTT = Z_TT(Lags, Olist[mode], UPlistlist[mode]) eigw = mp.eigh(ZTT, eigvals_only=True) if eigw[0] <= 0: return mode, eigw[0] elif eigw[0] < mineigw: mineigw = eigw[0] modemineig = mode return modemineig, mineigw else: for mode in range(modenum): ZTT = Z_TT(Lags, Olist[mode], UPlistlist[mode]) eigw, eigv = mp.eigh(ZTT) if eigw[0] <= 0: return mode, eigw[0], eigv[:, 0] elif eigw[0] < mineigw: mineigw = eigw[0] mineigv = eigv[:, 0] modemineig = mode return modemineig, mineigw, mineigv
def get_ZTT_mineig_grad(ZTT, gradZTT): eigw, eigv = mp.eigh(ZTT) eiggrad = mp.matrix(len(gradZTT), 1) for i in range(len(eiggrad)): eiggrad[i] = mp.re(mp_conjdot(eigv[:, 0], gradZTT[i] * eigv[:, 0])) return eiggrad
def FreeFermions(subsystem, C): C = mp.matrix([[C[x, y] for x in subsystem] for y in subsystem]) C_eigval = mp.eigh(C, eigvals_only=True) EH_eigval = mp.matrix( [mp.log(mp.fdiv(mp.fsub(mp.mpf(1.0), x), x)) for x in C_eigval]) S = mp.re( mp.fsum([ mp.log(mp.mpf(1.0) + mp.exp(-x)) + mp.fdiv(x, mp.exp(x) + mp.mpf(1.0)) for x in EH_eigval ])) return (S)
def check_spatialProj_Lags_validity(Lags, Olist, UPlistlist): modenum = len(Olist) mineig = np.inf for mode in range(modenum): ZTT = Z_TT(Lags, Olist[mode], UPlistlist[mode]) eigZTT = mp.eigh(ZTT, eigvals_only=True) if eigZTT[0] < 0: print('mineig', eigZTT[0]) return eigZTT[0] mineig = min(mineig, eigZTT[0]) return mineig
def FreeFermions(subsystem, C_t): #implements free fermion technique by peschel C = mp.matrix([[C_t[x, y] for x in subsystem] for y in subsystem]) C_eigval = mp.eigh(C, eigvals_only=True) EH_eigval = mp.matrix( [mp.log(mp.fdiv(mp.fsub(mp.mpf(1.0), x), x)) for x in C_eigval]) S = mp.re( mp.fsum([ mp.log(mp.mpf(1.0) + mp.exp(-x)) + mp.fdiv(x, mp.exp(x) + mp.mpf(1.0)) for x in EH_eigval ])) return (S)
def find_singular_ZTT_eigv(Lags, Olist, UPlistlist): modenum = len(Olist) mineigw = mp.inf mineigv = mp.matrix(Olist[0].rows, 1) modemineig = -1 for i in range(modenum): ZTT = Z_TT(Lags, Olist[i], UPlistlist[i]) eigw, eigv = mp.eigh(ZTT) if eigw[0] <= 0: modemineig = i mineigv = eigv[:, 0] return modemineig, mineigv elif eigw[0] < mineigw: mineigw = eigw[0] mineigv = eigv[:, 0] modemineig = i return modemineig, mineigv
def SvN(Dm, Dp, Kpart): dim = 2 * len(Kpart) gamma = mp.matrix(dim, dim) KpartH = Kpart.H for m in list(range(0, dim, 2)): for n in list(range(0, dim, 2)): row = int((m + 1) / 2) col = int((n + 1) / 2) gamma[m, n] = mp.j * Dp[row, col] gamma[m, n + 1] = mp.j * Kpart[row, col] gamma[m + 1, n] = -mp.j * KpartH[row, col] gamma[m + 1, n + 1] = mp.j * Dm[row, col] eigvalgamma = mp.eigh(gamma, eigvals_only=True) Spart = mp.fsum([ -((mp.mpf(1.0) + x) / mp.mpf(2)) * mp.log( (mp.mpf(1.0) + x) / mp.mpf(2)) for x in eigvalgamma ]) return (Spart)
def solver_mp(x, V, units, num_states=15): """Uses finite difference to discretize and solve for the eigenstates and energy eigenvalues one dimensional potentials. The domain fed to this routine defines the problem space allowing non-uniform point density to pay close attention to particular parts of the potential. Assumes infinite walls at both ends of the problem space. Input x : np.array([x_i]) The spacial grid points including the endpoints V : np.array([V(x_i)]) The potential function defined on the grid units : class Class whose attributes are the fundamental constants hbar, e, m, c, etc. Output psi : np.array([psi_0(x), ..., psi_N(x)]) where N = NumStates Eigenfunctions of Hamiltonian E : np.array([E_0, ..., E_N]) Eigenvalues of Hamiltonian Optional: num_states : int, default 15 Dictates the number of states to solve for. Must be less than the number of spatial points - 2. """ # Determine number of points in spacial grid N = len(x) dx = x[1] - x[0] #Reset num_states if the resolution of the space is less than the called for # numer of states if num_states >= N - 2: print("Resolution too poor for requested number of states." + str(N - 1) + "states returned.") num_states = N - 1 # Construct the Hamiltonian in position space H = solver_utils.make_hamiltonian(dx, V, units, boundary='hard_wall', prec=30) # Compute eigenvalues and eigenfunctions: E, psi = mp.eigh(mp.matrix(H)) # Truncate to the desired number of states E = E[:num_states] psi = psi[:, :num_states] psi = sp.insert(np.array(psi.tolist()), 0, sp.zeros(num_states), axis=0) psi = sp.insert(np.array(psi.tolist()), len(x) - 1, sp.zeros(num_states), axis=0) for i in range(num_states): psi[:, i] = psi[:, i] / sp.sqrt(sp.trapz(psi[:, i] * psi[:, i], x)) psi = np.array(psi.tolist()) psi = psi.transpose() E = np.array(E.tolist()) return psi, E
t, s, r ) #if an error occurs this will tell me where the loops have stopped #BUILD THE HAMILTONIAN for i in range(END): j = (i + 1) % L #j is nearest neighbor of i if i % 2 == 0: #intracell case H[i, j] = -t + rn(s) H[j, i] = H[i, j] elif j % 2 == 0: #intercell case H[i, j] = -1 + rn(s / 2) H[j, i] = H[i, j] # find its eigenvalues and vectors eigval, eigvec = mp.eigh(H) eigval, eigvec = mp.eig_sort(eigval, eigvec) #build correlation matrix Cij = Cij_0(eigvec, Np) #use free fermions to obtain the entanglement entropies of the SB = FreeFermions(B, Cij) / mp.log(mp.mpf(2.0)) SAB = FreeFermions(A + B, Cij) / mp.log(mp.mpf(2.0)) SBC = FreeFermions(B + C, Cij) / mp.log(mp.mpf(2.0)) SABC = FreeFermions(D, Cij) / mp.log(mp.mpf(2.0)) # In the end I calculate Sqtopo ad proposed by Wen