def _norbs_err(self, orbs, N, real_valued=True): """norbs - 'natural orbitals': eigenstates of the 1-body RDM""" if real_valued: psi = fermifab.FermiState(orbs, N, data=np.random.rand(int(binom(orbs, N)))) else: psi = fermifab.FermiState(orbs, N, data=fermifab.crand(int(binom(orbs, N)))) # compute the one-body reduced density matrix rho = fermifab.rdm(psi, 1) # diagonalize rho and construct base change matrix operating on N-fold tensor product _, U = fermifab.eig(rho) UN = fermifab.tensor_op(U, N) # apply inverse base change matrix to psi psi = UN.H @ psi G = fermifab.rdm(psi, 1) # G should be a diagonal matrix return np.linalg.norm(np.diag(np.diag(G.data)) - G.data)
def _err_calcQ(self, psi): g1 = fermifab.rdm(psi, 1) g2 = fermifab.rdm(psi, 2) # calculate Q operator Q = fermifab.calcQ(g2, g1) # Q operator based solely on two-body RDM Q2 = fermifab.calcQ_(g2, psi.N) err = fermifab.norm(Q - Q2) # TODO: implement test for QN # generalized Q operator for p = 1 should be id - gamma^1(psi) # TODO: implement test for QN using p = 1 return err
def _tensor_op_err(self, orbs, p, N): err = 0 # random wavefunction "psi" psi = fermifab.FermiState(orbs, N, data=fermifab.crand(int(binom(orbs, N)))) # compute one-body reduced density matrix rho = fermifab.rdm(psi, 1) U, _ = np.linalg.qr(rho.data) U = fermifab.FermiOp(orbs, 1, 1, U) Up = fermifab.tensor_op(U, p) UN = fermifab.tensor_op(U, N) err += np.linalg.norm((UN.H @ UN).data - np.eye(*UN.shape)) err += np.linalg.norm((Up.H @ fermifab.rdm(UN @ psi, p) @ Up - fermifab.rdm(psi, p)).data) return err
def _err_calcT1(self, psi): g1 = fermifab.rdm(psi, 1) g2 = fermifab.rdm(psi, 2) # calculate T1 operator T = fermifab.calcT1(g2, g1) # T1 operator based solely on two-body RDM Td = fermifab.calcT1_(g2, psi.N) err = fermifab.norm(T - Td) # TODO: implement test for T1N # generalized T1 operator for p = 2 should be gamma^2(psi) + Q # TODO: implement test for T1 using p = 2 return err
def _p2N_err(self, orbs, p, N): shape_data = int(binom(orbs, p)), int(binom(orbs, p)) h = fermifab.FermiOp(orbs, p, p, fermifab.crand(*shape_data)) # random wavefunction "psi" psi = fermifab.FermiState(orbs, N, data=fermifab.crand(int(binom(orbs, N)))) return abs((psi.H @ fermifab.p2N(h, N) @ psi).data[0] - fermifab.trace(h @ fermifab.rdm(psi, p)))