def test_accurate_load_multi(self): from_numpy = self.from_numpy to_numpy = self.to_numpy wf13_1 = get_random_wf(np, nqb=1, nwf=2) wf13_2 = get_random_wf(np, nqb=1, nwf=2) wf13 = kron_each(wf13_1, wf13_2) state00 = np.zeros(shape=(2, 2), dtype=complex) state00[0, :] = 1.0 loaded_into_13th_tot4qb = reduce( kron_each, [state00.copy(), wf13_1, state00.copy(), wf13_2] ) wf13 = from_numpy(wf13) loaded = load_states_into(wf13, total_qb=4, pos=[1, 3]) loaded = to_numpy(loaded) assert np.allclose(loaded, loaded_into_13th_tot4qb)
def test_trivial_case_ndim(self): from_np = self.from_numpy to_np = self.to_numpy wf = get_random_wf(np, nqb=1) rho = np.outer(wf, wf.conj()) o1 = partial_trace_wf(from_np(wf), retain_qubits=[0]) assert np.allclose(rho, to_np(o1)) wf2 = get_random_wf(np, nqb=2) rho2 = np.outer(wf2, wf2.conj()) assert np.allclose( rho2, to_np(partial_trace_wf(from_np(wf2), retain_qubits=[1, 0])) ) # lastly, test if all qubits are killed assert np.allclose(1, to_np(partial_trace_wf(from_np(wf2), retain_qubits=[])))
def test_keep_zero(self): from_np = self.from_numpy to_np = self.to_numpy wf = get_random_wf(np, 2) o = partial_trace_wf_keep_first(from_np(wf), 0) o = to_np(o) assert o.shape == (1, 1) assert np.allclose(o, [[1]])
def test_trivial(self): from_np = self.from_numpy to_np = self.to_numpy wf = get_random_wf(np, 1) o = partial_trace_wf_keep_first(from_np(wf), 1) s = np.outer(wf, wf.conj()) # s = np.sum(wf.dot(wf.conj())) assert np.allclose(to_np(o), s)
def test_3qb(self): from_np = self.from_numpy to_np = self.to_numpy wf = from_np(get_random_wf(np, 3)) rho = make_density_matrix(wf) o1 = partial_trace_wf_keep_first(wf, 1) s1 = partial_trace(rho, retain_qubits=[0]) assert np.allclose(to_np(o1), to_np(s1)) o1 = partial_trace_wf_keep_first(wf, 2) s1 = partial_trace(rho, retain_qubits=[0, 1]) assert np.allclose(to_np(o1), to_np(s1))
def test_nd_retain_qbs_order_does_not_matter(self): from_np = self.from_numpy to_np = self.to_numpy nqb = 4 qbs_tokeep = np.array([1, 2, 3]) qbs_tokeep_shuffled = qbs_tokeep.copy() while np.array_equal(qbs_tokeep_shuffled, qbs_tokeep): np.random.shuffle(qbs_tokeep_shuffled) wf = get_random_wf(np, nqb=nqb) wf = from_np(wf) assert np.allclose( to_np(partial_trace_wf(wf, retain_qubits=qbs_tokeep)), to_np(partial_trace_wf(wf, retain_qubits=qbs_tokeep_shuffled)), )
def _prep_load_state_data(): state = get_random_wf(np, nqb=2, nwf=2) state0 = np.array([[1, 1], [0, 0]]) state00 = np.array([[1, 1], [0, 0], [0, 0], [0, 0]]) kron = np.kron loaded_into_01th = np.empty(shape=(2 ** 4, 2), dtype=complex) for wfidx in range(2): loaded_into_01th[:, wfidx] = kron(state[:, wfidx], state00[:, wfidx]) loaded_into_12th = np.empty(shape=(2 ** 4, 2), dtype=complex) for wfidx in range(2): loaded_into_12th[:, wfidx] = kron( kron(state0[:, wfidx], state[:, wfidx]), state0[:, wfidx] ) loaded_into_23th = np.empty(shape=(2 ** 4, 2), dtype=complex) for wfidx in range(2): loaded_into_23th[:, wfidx] = kron(state00[:, wfidx], state[:, wfidx]) return state, loaded_into_01th, loaded_into_12th, loaded_into_23th
def test_cupy_thread_dim_limit(self): # It is import to test when the thread dim is larger then 32 for cuda # code. This happens when there are more than 6 qubits to keep. # Note: 2 ** 5 = 32, 2 ** 6 = 64. # See the implementation for cuda for details. import numpy to_np = self.to_numpy wf = self.from_numpy(get_random_wf(numpy, 7)) rho = make_density_matrix(wf) # Before boundary o1 = partial_trace_wf_keep_first(wf, 5) s1 = partial_trace(rho, retain_qubits=list(range(5))) assert numpy.allclose(to_np(o1), to_np(s1)) # After boundary o1 = partial_trace_wf_keep_first(wf, 6) s1 = partial_trace(rho, retain_qubits=list(range(6))) assert numpy.allclose(to_np(o1), to_np(s1))
def test_same_as_partial_trace(self): from_np = self.from_numpy to_np = self.to_numpy nqb = 4 wf = get_random_wf(np, nqb=nqb) wf_tmp = from_np(wf) rho = np.outer(wf, wf.conj()) def get_shouldbe(arho, retain): arho = from_np(arho) arho = partial_trace(arho, retain_qubits=retain) return to_np(arho) qbs_tokeep = [1, 2] assert np.allclose( to_np(partial_trace_wf(wf_tmp, retain_qubits=qbs_tokeep)), get_shouldbe(rho, qbs_tokeep), ) qbs_tokeep = [0, 3] assert np.allclose( to_np(partial_trace_wf(wf_tmp, retain_qubits=qbs_tokeep)), get_shouldbe(rho, qbs_tokeep), ) for qbs_tokeep in [0, 1, 2, 3]: qbs_tokeep = [qbs_tokeep] assert np.allclose( to_np(partial_trace_wf(wf_tmp, retain_qubits=qbs_tokeep)), get_shouldbe(rho, qbs_tokeep), ) for qbs_tokeep in [(0, 1), (0, 1, 2), (0, 1, 2, 3)]: assert np.allclose( to_np(partial_trace_wf(wf_tmp, retain_qubits=qbs_tokeep)), get_shouldbe(rho, qbs_tokeep), )
def f_rand(): return get_random_wf(np, nqb=size[0], nwf=size[1])