Exemplo n.º 1
0
def test_x_crosstalk_n_noise():
    num_qubits = 4
    noise_mod = AQTNoiseModel()
    device, qubits = get_aqt_device(num_qubits)
    circuit = Circuit(device=device)
    circuit.append(Y(qubits[1]) ** 0.5)
    circuit.append(Z(qubits[1]) ** 0.5)
    circuit.append(X(qubits[1]) ** 0.5)
    for moment in circuit.moments:
        noisy_moment = noise_mod.noisy_moment(moment, qubits)
    assert noisy_moment == [
        (cirq.X ** 0.5).on(cirq.LineQubit(1)),
        cirq.depolarize(p=0.001).on(cirq.LineQubit(1)),
        (cirq.X ** 0.015).on(cirq.LineQubit(0)),
        (cirq.X ** 0.015).on(cirq.LineQubit(2)),
    ]
Exemplo n.º 2
0
    def test_qubitop_to_paulisum_more_terms(self):
        # Given
        qubit_operator = (QubitOperator("Z0 Z1 Z2", -1.5) +
                          QubitOperator("X0", 2.5) + QubitOperator("Y1", 3.5))
        expected_qubits = (LineQubit(0), LineQubit(5), LineQubit(8))
        expected_paulisum = (PauliSum() +
                             (PauliString(Z.on(expected_qubits[0])) *
                              PauliString(Z.on(expected_qubits[1])) *
                              PauliString(Z.on(expected_qubits[2])) * -1.5) +
                             (PauliString(X.on(expected_qubits[0]) * 2.5)) +
                             (PauliString(Y.on(expected_qubits[1]) * 3.5)))

        # When
        paulisum = qubitop_to_paulisum(qubit_operator, qubits=expected_qubits)

        # Then
        self.assertEqual(paulisum.qubits, expected_qubits)
        self.assertEqual(paulisum, expected_paulisum)
Exemplo n.º 3
0
def test_represent_operations_in_circuit_local(circuit_type: str):
    """Tests all operation representations are created."""
    qreg = LineQubit.range(2)
    circ_mitiq = Circuit([CNOT(*qreg), H(qreg[0]), Y(qreg[1]), CNOT(*qreg)])
    circ = convert_from_mitiq(circ_mitiq, circuit_type)

    reps = represent_operations_in_circuit_with_local_depolarizing_noise(
        ideal_circuit=circ, noise_level=0.1,
    )

    for op in convert_to_mitiq(circ)[0].all_operations():
        found = False
        for rep in reps:
            if _equal(rep.ideal, Circuit(op), require_qubit_equality=True):
                found = True
        assert found

    # The number of reps. should match the number of unique operations
    assert len(reps) == 3
Exemplo n.º 4
0
def qubit_op_to_gate(operation: 'QubitOperator',
                     qubit) -> 'SingleQubitPauliStringGateOperation':
    """Convert a qubit operation into a gate operations that can be digested
    by a Cirq simulator.

    Args:
        operation (QubitOperator)
        qubit (Qid) - a qubit on which the Pauli matrices will act.

    Returns:
        (gate) - a gate that can be executed on the qubit passed
    """
    if operation == 'X':
        return X.on(qubit)
    if operation == 'Y':
        return Y.on(qubit)
    if operation == 'Z':
        return Z.on(qubit)
    raise ValueError('No gate identified in qubit_op_to_gate')
Exemplo n.º 5
0
    return noisy_simulation(
        circuit,
        BASE_NOISE,
        obs,
    )


# Simple identity 1-qubit circuit for testing
q = LineQubit(1)
oneq_circ = Circuit(Z.on(q), Z.on(q))

# Simple identity 2-qubit circuit for testing
qreg = LineQubit.range(2)
twoq_circ = Circuit(
    Y.on(qreg[1]),
    CNOT.on(*qreg),
    Y.on(qreg[1]),
)


@mark.parametrize("circuit", [oneq_circ, twoq_circ])
@mark.parametrize("decomposition_dict",
                  [NOISELESS_DECO_DICT, DECO_DICT_SIMP, DECO_DICT])
def test_execute_with_pec_one_qubit(circuit: Circuit,
                                    decomposition_dict: DecompositionDict):
    """Tests that execute_with_pec mitigates the error of a noisy
    expectation value.
    """
    unmitigated = executor(circuit)
    mitigated = execute_with_pec(circuit,
Exemplo n.º 6
0
@pytest.mark.parametrize("gate", [X, Y, Z, CNOT])
def test_sample_sequence_types(gate: Gate):
    num_qubits = gate.num_qubits()
    qreg = LineQubit.range(num_qubits)
    for _ in range(1000):
        imp_seq, sign, norm = sample_sequence(gate.on(*qreg), DECO_DICT)
        assert all([isinstance(op, Operation) for op in imp_seq])
        assert sign in {1, -1}
        assert norm > 1


@pytest.mark.parametrize("seed", (1, 2, 3, 5))
@pytest.mark.parametrize("seed_type", (int, np.random.RandomState))
@pytest.mark.parametrize(
    "op", [X(qreg[0]), Y(qreg[0]),
           Z(qreg[0]), CNOT(*qreg)])
def test_sample_sequence_random_state(seed, seed_type, op):
    decomposition = _simple_pauli_deco_dict(0.5)

    if isinstance(seed_type, np.random.RandomState):
        seed = np.random.RandomState(seed)
    sequence, sign, norm = sample_sequence(op,
                                           decomposition,
                                           random_state=seed)

    for _ in range(20):
        if isinstance(seed_type, np.random.RandomState):
            seed = np.random.RandomState(seed)
        new_sequence, new_sign, new_norm = sample_sequence(op,
                                                           decomposition,
Exemplo n.º 7
0
@pytest.mark.parametrize(
    ("slack_length", "rule", "sequence"),
    [
        (
            5,
            xx,
            Circuit([
                X(LineQubit(0)) if i % 2 else I(LineQubit(0)) for i in range(5)
            ]),
        ),
        (
            5,
            yy,
            Circuit([
                Y(LineQubit(0)) if i % 2 else I(LineQubit(0)) for i in range(5)
            ]),
        ),
        (
            4,
            xyxy,
            Circuit([
                Y(LineQubit(0)) if i % 2 else X(LineQubit(0)) for i in range(4)
            ]),
        ),
    ],
)
def test_exact_sequences(slack_length, rule, sequence):
    sequence_to_test = rule(slack_length)
    assert _equal(sequence_to_test, sequence)
Exemplo n.º 8
0
        obs = np.array(
            [[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
        )
    else:
        raise ValueError("The input must be a circuit with 1 or 2 qubits.")

    return noisy_simulation(circuit, BASE_NOISE, obs,)


# Simple identity 1-qubit circuit for testing
q = LineQubit(1)
oneq_circ = Circuit(Z.on(q), Z.on(q))

# Simple identity 2-qubit circuit for testing
qreg = LineQubit.range(2)
twoq_circ = Circuit(Y.on(qreg[1]), CNOT.on(*qreg), Y.on(qreg[1]),)


@mark.parametrize("circuit", [oneq_circ, twoq_circ])
@mark.parametrize(
    "decomposition_dict", [NOISELESS_DECO_DICT, DECO_DICT_SIMP, DECO_DICT]
)
def test_execute_with_pec_one_qubit(
    circuit: Circuit, decomposition_dict: DecompositionDict
):
    """Tests that execute_with_pec mitigates the error of a noisy
    expectation value.
    """
    unmitigated = executor(circuit)
    mitigated = execute_with_pec(
        circuit, executor, decomposition_dict=decomposition_dict
Exemplo n.º 9
0
def _simple_pauli_deco_dict(base_noise: float,
                            simplify_paulis: bool = False
                            ) -> DecompositionDict:
    """Returns a simple hard-coded decomposition
    dictionary to be used for testing and protoptyping.

    The decomposition is compatible with one-qubit or
    two-qubit circuits involving only Pauli and CNOT gates.

    The keys of the output dictionary are Pauli and CNOT operations.

    The decomposition assumes that Pauli and CNOT operations,
    followed by local depolarizing noise, are implementable.

    Args:
        base_noise: The depolarizing noise level.
        simplify_paulis: If True, products of Paulis are simplified to a
            single Pauli. If False, Pauli sequences are not simplified.

    Returns:
        decomposition_dict: The decomposition dictionary.

    """
    # Initialize two qubits
    qreg = LineQubit.range(2)

    # Single-qubit Pauli operations
    i0 = I.on(qreg[0])
    x0 = X.on(qreg[0])
    y0 = Y.on(qreg[0])
    z0 = Z.on(qreg[0])
    i1 = I.on(qreg[1])
    x1 = X.on(qreg[1])
    y1 = Y.on(qreg[1])
    z1 = Z.on(qreg[1])
    single_paulis = [x0, y0, z0, x1, y1, z1]

    # Single-qubit decomposition coefficients
    epsilon = base_noise * 4 / 3
    c_neg = -(1 / 4) * epsilon / (1 - epsilon)
    c_pos = 1 - 3 * c_neg
    assert np.isclose(c_pos + 3 * c_neg, 1.0)

    # Single-qubit decomposition dictionary
    decomposition_dict = {}
    if simplify_paulis:
        # Hard-coded simplified gates
        decomposition_dict = {
            x0: [(c_pos, [x0]), (c_neg, [i0]), (c_neg, [z0]), (c_neg, [y0])],
            y0: [(c_pos, [y0]), (c_neg, [z0]), (c_neg, [i0]), (c_neg, [x0])],
            z0: [(c_pos, [z0]), (c_neg, [y0]), (c_neg, [x0]), (c_neg, [i0])],
            x1: [(c_pos, [x1]), (c_neg, [i1]), (c_neg, [z1]), (c_neg, [y1])],
            y1: [(c_pos, [y1]), (c_neg, [z1]), (c_neg, [i1]), (c_neg, [x1])],
            z1: [(c_pos, [z1]), (c_neg, [y1]), (c_neg, [x1]), (c_neg, [i1])],
        }
    else:
        for local_paulis in [[x0, y0, z0], [x1, y1, z1]]:
            for key in local_paulis:
                key_deco_pos = [(c_pos, [key])]
                key_deco_neg = [(c_neg, [key, op]) for op in local_paulis]
                decomposition_dict[key] = (
                    key_deco_pos + key_deco_neg  # type: ignore
                )

    # Two-qubit Paulis
    xx = [x0, x1]
    xy = [x0, y1]
    xz = [x0, z1]
    yx = [y0, x1]
    yy = [y0, y1]
    yz = [y0, z1]
    zx = [z0, x1]
    zy = [z0, y1]
    zz = [z0, z1]
    double_paulis = [xx, xy, xz, yx, yy, yz, zx, zy, zz]

    # Two-qubit decomposition coefficients (assuming local noise)
    c_pos_pos = c_pos * c_pos
    c_pos_neg = c_neg * c_pos
    c_neg_neg = c_neg * c_neg
    assert np.isclose(c_pos_pos + 6 * c_pos_neg + 9 * c_neg_neg, 1.0)

    cnot = CNOT.on(qreg[0], qreg[1])
    cnot_decomposition = [(c_pos_pos, [cnot])]
    for p in single_paulis:
        cnot_decomposition.append((c_pos_neg, [cnot] + [p]))
    for pp in double_paulis:
        cnot_decomposition.append((c_neg_neg, [cnot] + pp))  # type: ignore

    decomposition_dict[cnot] = cnot_decomposition  # type: ignore

    return decomposition_dict  # type: ignore
Exemplo n.º 10
0
class OperationGradTest(unittest.TestCase):

    @ddt.unpack
    @ddt.data(

        # d[rx(rad)] / d[rad] = d[e^{-i X rad / 2}] / d[rad]
        #                     = -i/2 X e^{-i X rads / 2}
        #                     = -i/2 X rx(rad)
        [rx(rad).on(q0), rad,
         LCO({
             (rx(rad).on(q0), X(q0)): -0.5j
         })],

        # d[XPow(e, s)] / d[e] = i pi {s + 1/2 (I - X)} XPow(e, s)
        [XPowGate(exponent=rad, global_shift=0.3).on(q0), rad,
         LCO({
             (XPowGate(exponent=rad, global_shift=0.3).on(q0),):
                 1.0j * np.pi * (0.3 + 0.5),
             (X(q0), XPowGate(exponent=rad, global_shift=0.3).on(q0)):
                 -0.5j * np.pi
         })],

        # d[e^{-i A0 A1 rad}] / d[rad] = -i A0 A1 e^{-i A0 A1 rad}
        [TwoPauliExpGate("X", "Z", rad).on(q0, q1), rad,
         LCO({
             (TwoPauliExpGate("X", "Z", rad).on(q0, q1), X(q0), Z(q1)): -1.0j
         })],

        # d[exp(i pi rad)] / d[rad] = i pi exp(i pi rad)
        [GlobalPhaseGate(rad ** 2).on(q0), rad,
         LCO({
             (GlobalPhaseGate(rad ** 2).on(q0),): 2.0j * sympy.pi * rad
         })],

        # d[e^{−i t P}] / d[t] = -i P e^{−i t P}
        [PauliWordExpGate(rad ** 2, PauliWord("ZYX")).on(q0, q1, q2), rad,
         LCO({
             (PauliWordExpGate(rad ** 2, PauliWord("ZYX")).on(q0, q1, q2),
              Z(q0), Y(q1), X(q2)): -2.0j * rad
         })],

        # d[rx(rad) ⊗ rz(rad)] / d[rad] = -i/2 { X rx(rad) ⊗ rz(rad)
        #                                      + rx(rad) ⊗ Z rz(rad) }
        [GateBlock(
            TwoRotsGenerator()
        ).on(q0, q1), rad,
         -0.5j * LCO({
             (rz(rad).on(q1), rx(rad).on(q0), X(q0)): 1,
             (rz(rad).on(q1), rx(rad).on(q0), Z(q1)): 1
         })],

        # d[CRx(rad)] / d[rad] = |1><1| ⊗ d[Rx(rad)]/d[rad]
        #                      = -i/2 |1><1| ⊗ X Rx(rad)
        #                      = -i/4 { C[X Rx(rad)] - C[-X Rx(rad)] }
        [cirq.ControlledGate(rx(rad), num_controls=1).on(q0, q1), rad,
         -1.0j / 4 * LCO({
             (ControlledGate(X).on(q0, q1), ControlledGate(rx(rad)).on(q0, q1)): 1,
             (ControlledGate(X).on(q0, q1), ControlledGate(rx(rad)).on(q0, q1),
              ControlledGate(GlobalPhaseGate(1)).on(q0, q1)): -1
         })],

        # d[CCRz(rad)] / d[rad] = |1><1| ⊗ |1><1| ⊗ d[Rz(rad)]/d[rad]
        #                       = -i/4 { CC[Z Rz(rad)] - CC[-Z Rz(rad)] }
        [ControlledGate(
            ControlledGate(
                cirq.rz(rad)
            )
        ).on(q0, q1, q2), rad,
         -1.0j / 4 * LCO({
             (ControlledGate(ControlledGate(Z)).on(q0, q1, q2),
              ControlledGate(ControlledGate(rz(rad))).on(q0, q1, q2)): 1,
             (ControlledGate(ControlledGate(Z)).on(q0, q1, q2),
              ControlledGate(ControlledGate(rz(rad))).on(q0, q1, q2),
              ControlledGate(ControlledGate(GlobalPhaseGate(1))).on(q0, q1, q2)): -1
         })],

        # d[U(rad)] = -i/2 U(rad) X.on(q0) - i/4 { U+(rad) - U-(rad) }
        [u.on(q0, q1, q2, q3, q4), rad,
         LCO({
             (X(q0), u.on(q0, q1, q2, q3, q4),): -0.5j,  # order matters!
             (u_positive.on(q0, q1, q2, q3, q4),): -0.25j,
             (u_negative.on(q0, q1, q2, q3, q4),): +0.25j
         })]

    )
    def test_grad(self, op, param, grad_lco):
        print("[Grad of {}]".format(op))
        grad = op_grad(op, param)
        if isinstance(grad, GradNotImplemented):
            print("The grad of {} is not implemented.".format(grad.operation))
            return

        for _op_series, coeff in grad.items():
            _circuit = cirq.Circuit()
            _circuit.append(_op_series)
            print("Coefficient: {}".format(coeff))
            print(_circuit, "\n")

        random_rad = typing.cast(float, np.random.rand())
        param_resolver = {"rad": random_rad}
        # param_resolver = {"rad": 0}

        test_lco_identical_with_simulator(
            cirq.resolve_parameters(grad, param_resolver),
            cirq.resolve_parameters(grad_lco, param_resolver),
            self
        )
Exemplo n.º 11
0
def test_get_imp_sequences_with_simplify():
    q = LineQubit(0)
    expected_imp_sequences = [[X.on(q)], [I.on(q)], [Z.on(q)], [Y.on(q)]]
    assert get_imp_sequences(X.on(q), DECO_DICT_SIMP) == expected_imp_sequences