def real_hermitian_ansatz(p, n=2): U = np.eye(4) for w in p: local1 = np.kron(Ry(w), I) entangling = swap() @ CRy(np.pi - w) @ swap() @ CRy(-w) U = entangling @ local1 @ U return U
def ϵ(x): u_state, v_state, e_state = state_function( x, 'u_purity'), state_function(x, 'v_purity'), state_function( x, 'energy') v_purity = np.real(v_state.conj().T @ np.kron( np.eye(2), np.kron(swap(), np.eye(2))) @ v_state) u_purity = np.real(u_state.conj().T @ np.kron( np.eye(4), np.kron(swap(), np.eye(4))) @ u_state) energy = np.real(e_state.conj().T @ H @ e_state) return energy + u_purity + v_purity
def ϵ_op(x): uv_state, u_state, v_state, e_state = state_function( x, 'uv_purity'), state_function(x, 'u_purity'), state_function( x, 'v_purity'), state_function(x, 'energy') v_purity = np.real(v_state.conj().T @ np.kron( np.eye(2), np.kron(swap(), np.eye(2))) @ v_state) u_purity = np.real(u_state.conj().T @ np.kron( np.eye(4), np.kron(swap(), np.eye(4))) @ u_state) uv_purity = np.real(uv_state.conj().T @ np.kron( np.kron(np.eye(2), swap()), np.eye(4)) @ uv_state) energy = np.real(e_state.conj().T @ H @ e_state) k = 10 return energy, +k * u_purity, +k * v_purity, -2 * k * uv_purity
def ϵ(x): uv_state, u_state, v_state, e_state = (state(x, 'uv_purity'), state(x, 'u_purity'), state(x, 'v_purity'), state(x, 'energy')) v_purity = np.real(v_state.conj().T @ np.kron( np.eye(2), np.kron(swap(), np.eye(2))) @ v_state) u_purity = np.real(u_state.conj().T @ np.kron( np.eye(4), np.kron(swap(), np.eye(4))) @ u_state) uv_purity = np.real(uv_state.conj().T @ np.kron( np.kron(np.eye(2), swap()), np.eye(4)) @ uv_state) energy = np.real(e_state.conj().T @ H @ e_state) k = 1 return sum( [energy, +k * u_purity, +k * v_purity, -2 * k * uv_purity])
def fixindices(v, ϵ=4e-2): # don't feed the parameters straight into the # lie algebra but add a swap and perturb slightly (ϵ) # necessary to embed D=2 result into D=4 &c. # swap makes i, j have same tensor product structure # perturbation gets away from singular points N = int(np.sqrt(len(v) + 1)) U = SU(v + ϵ, N) n_qubits = int(np.log2(N)) + 1 S12 = reduce(np.kron, [np.eye(2)] * (n_qubits - 3) + [swap()]) U = U @ S12 return extractv(U)
def swapper(): return -np.kron(np.kron(np.eye(2), swap()), np.eye(8))