def test_unitary_channel_errors(): """Check errors raised by ``gates.UnitaryChannel``.""" a1 = np.array([[0, 1], [1, 0]]) a2 = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]) probs = [0.4, 0.3] matrices = [((0, ), a1), ((2, 3), a2)] # Invalid probability length with pytest.raises(ValueError): gate = gates.UnitaryChannel([0.1, 0.3, 0.2], matrices) # Probability > 1 with pytest.raises(ValueError): gate = gates.UnitaryChannel([1.1, 0.2], matrices) # Probability sum = 0 with pytest.raises(ValueError): gate = gates.UnitaryChannel([0.0, 0.0], matrices)
def test_unitary_channel(backend): a1 = np.array([[0, 1], [1, 0]]) a2 = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]) probs = [0.4, 0.3] matrices = [((0, ), a1), ((2, 3), a2)] initial_state = random_density_matrix(4) gate = gates.UnitaryChannel(probs, matrices) gate.density_matrix = True final_state = gate(K.cast(np.copy(initial_state))) eye = np.eye(2) ma1 = np.kron(np.kron(a1, eye), np.kron(eye, eye)) ma2 = np.kron(np.kron(eye, eye), a2) target_state = (0.3 * initial_state + 0.4 * ma1.dot(initial_state.dot(ma1)) + 0.3 * ma2.dot(initial_state.dot(ma2))) K.assert_allclose(final_state, target_state)
def test_unitary_channel_probability_tolerance(backend, precision): """Create ``UnitaryChannel`` with probability sum within tolerance (see #562).""" import qibo original_precision = qibo.get_precision() qibo.set_precision(precision) nqubits = 2 param = 0.006 num_terms = 2**(2 * nqubits) max_param = num_terms / (num_terms - 1) prob_identity = 1 - param / max_param prob_pauli = param / num_terms probs = [prob_identity] + [prob_pauli] * (num_terms - 1) if precision == "double": probs = np.array(probs, dtype="float64") else: probs = np.array(probs, dtype="float32") matrices = len(probs) * [((0, 1), np.random.random((4, 4)))] gate = gates.UnitaryChannel(probs, matrices) qibo.set_precision(original_precision)
def test_unitary_channel(backend, density_matrix): """Test creating `gates.UnitaryChannel` from matrices and errors.""" original_backend = qibo.get_backend() qibo.set_backend(backend) a1 = np.array([[0, 1], [1, 0]]) a2 = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]) probs = [0.4, 0.3] matrices = [((0, ), a1), ((2, 3), a2)] if density_matrix: initial_state = utils.random_density_matrix(4) else: initial_state = utils.random_numpy_state(4) c = models.Circuit(4, density_matrix=density_matrix) c.add(gates.UnitaryChannel(probs, matrices, seed=123)) final_state = c(initial_state, nshots=20).numpy() eye = np.eye(2, dtype=final_state.dtype) ma1 = np.kron(np.kron(a1, eye), np.kron(eye, eye)) ma2 = np.kron(np.kron(eye, eye), a2) if density_matrix: # use density matrices target_state = (0.3 * initial_state + 0.4 * ma1.dot(initial_state.dot(ma1)) + 0.3 * ma2.dot(initial_state.dot(ma2))) else: # sample unitary channel target_state = [] np.random.seed(123) for _ in range(20): temp_state = np.copy(initial_state) if np.random.random() < 0.4: temp_state = ma1.dot(temp_state) if np.random.random() < 0.3: temp_state = ma2.dot(temp_state) target_state.append(np.copy(temp_state)) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)