Esempio n. 1
0
def _max_ent_state_circuit(num_qubits: int) -> Circuit:
    r"""Generates a circuit which prepares the maximally entangled state
    |\omega\rangle = U |0\rangle  = \sum_i |i\rangle \otimes |i\rangle .

    Args:
        num_qubits: The number of qubits on which the circuit is applied.
            It must be an even number because of the structure of a
            maximally entangled state.

    Returns:
        The circuits which prepares the state |\omega\rangle.

    Raises:
        Value error: if num_qubits is not an even positive integer.
    """

    if not isinstance(num_qubits, int) or num_qubits % 2 or num_qubits == 0:
        raise ValueError(
            "The argument 'num_qubits' must be an even and positive integer.")

    alice_reg = LineQubit.range(num_qubits // 2)
    bob_reg = LineQubit.range(num_qubits // 2, num_qubits)

    return Circuit(
        # Prepare alice_register in a uniform superposition
        H.on_each(*alice_reg),
        # Correlate alice_register with bob_register
        [CNOT.on(alice_reg[i], bob_reg[i]) for i in range(num_qubits // 2)],
    )
Esempio n. 2
0
def test_three_qubit_depolarizing_representation_error():
    q0, q1, q2 = LineQubit.range(3)
    with pytest.raises(ValueError):
        represent_operation_with_global_depolarizing_noise(
            Circuit(CCNOT(q0, q1, q2)),
            0.05,
        )
Esempio n. 3
0
def test_prepare_gaussian_state(n_qubits,
                                conserves_particle_number,
                                occupied_orbitals,
                                initial_state,
                                atol=1e-5):

    qubits = LineQubit.range(n_qubits)
    if isinstance(initial_state, list):
        initial_state = sum(1 << (n_qubits - 1 - i) for i in initial_state)

    # Initialize a random quadratic Hamiltonian
    quad_ham = random_quadratic_hamiltonian(
            n_qubits, conserves_particle_number, real=False)
    quad_ham_sparse = get_sparse_operator(quad_ham)

    # Compute the energy of the desired state
    if occupied_orbitals is None:
        energy = quad_ham.ground_energy()
    else:
        orbital_energies, _, constant = (
                quad_ham.diagonalizing_bogoliubov_transform())
        energy = sum(orbital_energies[i] for i in occupied_orbitals) + constant

    # Get the state using a circuit simulation
    circuit = cirq.Circuit.from_ops(
            prepare_gaussian_state(
                qubits, quad_ham, occupied_orbitals,
                initial_state=initial_state))
    state = circuit.apply_unitary_effect_to_state(initial_state)

    # Check that the result is an eigenstate with the correct eigenvalue
    numpy.testing.assert_allclose(
            quad_ham_sparse.dot(state), energy * state, atol=atol)
Esempio n. 4
0
def test_aqt_device_wrong_op_str():
    circuit = Circuit()
    q0, q1 = LineQubit.range(2)
    circuit.append(CNOT(q0, q1)**1.0)
    for op in circuit.all_operations():
        with pytest.raises(ValueError):
            _result = get_op_string(op)
Esempio n. 5
0
def _try_decompose_into_operations_and_qubits(
    val: Any
) -> Tuple[Optional[List['cirq.Operation']], Sequence['cirq.Qid'], Tuple[int,
                                                                         ...]]:
    """Returns the value's decomposition (if any) and the qubits it applies to.
    """
    from cirq.protocols.decompose import (decompose_once,
                                          decompose_once_with_qubits)
    from cirq import LineQubit, Gate, Operation

    if isinstance(val, Gate):
        # Gates don't specify qubits, and so must be handled specially.
        qid_shape = qid_shape_protocol.qid_shape(val)
        qubits = LineQubit.range(len(qid_shape))  # type: Sequence[cirq.Qid]
        return decompose_once_with_qubits(val, qubits, None), qubits, qid_shape

    if isinstance(val, Operation):
        qid_shape = qid_shape_protocol.qid_shape(val)
        return decompose_once(val, None), val.qubits, qid_shape

    result = decompose_once(val, None)
    if result is not None:
        qubit_set = set()
        qid_shape_dict = defaultdict(lambda: 1)  # type: Dict[cirq.Qid, int]
        for op in result:
            for level, q in zip(qid_shape_protocol.qid_shape(op), op.qubits):
                qubit_set.add(q)
                qid_shape_dict[q] = max(qid_shape_dict[q], level)
        qubits = sorted(qubit_set)
        return result, qubits, tuple(qid_shape_dict[q] for q in qubits)

    return None, (), ()
Esempio n. 6
0
def test_biased_noise_representation_with_choi(
    gate: Gate, epsilon: float, eta: float
):
    """Tests the representation by comparing exact Choi matrices."""
    qreg = LineQubit.range(gate.num_qubits())
    ideal_choi = _operation_to_choi(gate.on(*qreg))
    op_rep = represent_operation_with_local_biased_noise(
        Circuit(gate.on(*qreg)), epsilon, eta
    )
    choi_components = []

    # Define biased noise channel
    a = 1 - epsilon
    b = epsilon * (3 * eta + 1) / (3 * (eta + 1))
    c = epsilon / (3 * (eta + 1))

    mix = [
        (a, unitary(I)),
        (b, unitary(Z)),
        (c, unitary(X)),
        (c, unitary(Y)),
    ]

    for noisy_op, coeff in op_rep.basis_expansion.items():
        implementable_circ = noisy_op.circuit()
        # Apply noise after each sequence.
        # NOTE: noise is not applied after each operation.
        biased_op = ops.MixedUnitaryChannel(mix).on_each(*qreg)
        implementable_circ.append(biased_op)
        sequence_choi = _circuit_to_choi(implementable_circ)
        choi_components.append(coeff * sequence_choi)
    combination_choi = np.sum(choi_components, axis=0)
    assert np.allclose(ideal_choi, combination_choi, atol=10**-6)
Esempio n. 7
0
def test_two_qubit_representation_norm(gate: Gate, epsilon: float, eta: float):
    qreg = LineQubit.range(2)
    optimal_norm = two_qubit_biased_noise_overhead(epsilon, eta)
    norm = represent_operation_with_local_biased_noise(
        Circuit(gate(*qreg)), epsilon, eta
    ).norm
    assert np.isclose(optimal_norm, norm)
Esempio n. 8
0
def test_mitigated_execute_with_cdr(circuit_type, fit_function, kwargs,
                                    random_state):
    circuit = random_x_z_cnot_circuit(
        LineQubit.range(2),
        n_moments=5,
        random_state=random_state,
    )
    circuit = convert_from_mitiq(circuit, circuit_type)
    obs = Observable(PauliString("XZ"), PauliString("YY"))

    true_value = obs.expectation(circuit, simulate)
    noisy_value = obs.expectation(circuit, execute)

    cdr_executor = mitigate_executor(
        executor=execute,
        observable=obs,
        simulator=simulate,
        num_training_circuits=20,
        fraction_non_clifford=0.5,
        fit_function=fit_function,
        random_state=random_state,
        **kwargs,
    )
    cdr_mitigated = cdr_executor(circuit)
    assert abs(cdr_mitigated - true_value) <= abs(noisy_value - true_value)
Esempio n. 9
0
def test_from_braket_non_parameterized_two_qubit_gates():
    braket_circuit = BKCircuit()
    instructions = [
        Instruction(braket_gates.CNot(), target=[2, 3]),
        Instruction(braket_gates.Swap(), target=[3, 4]),
        Instruction(braket_gates.ISwap(), target=[2, 3]),
        Instruction(braket_gates.CZ(), target=(3, 4)),
        Instruction(braket_gates.CY(), target=(2, 3)),
    ]
    for instr in instructions:
        braket_circuit.add_instruction(instr)
    cirq_circuit = from_braket(braket_circuit)

    qreg = LineQubit.range(2, 5)
    expected_cirq_circuit = Circuit(
        ops.CNOT(*qreg[:2]),
        ops.SWAP(*qreg[1:]),
        ops.ISWAP(*qreg[:2]),
        ops.CZ(*qreg[1:]),
        ops.ControlledGate(ops.Y).on(*qreg[:2]),
    )
    assert np.allclose(
        protocols.unitary(cirq_circuit),
        protocols.unitary(expected_cirq_circuit),
    )
Esempio n. 10
0
def test_gate_type():
    qreg = LineQubit.range(3)
    allowed_op = ops.H.on(qreg[0])
    _get_base_gate(allowed_op.gate)
    with pytest.raises(GateTypeException):
        forbidden_op = CSWAP(qreg[0], qreg[1], qreg[2])
        _get_base_gate(forbidden_op)
Esempio n. 11
0
def test_simplify_circuit_exponents():
    qreg = LineQubit.range(2)
    circuit = Circuit([H.on(qreg[0]), CNOT.on(*qreg), Z.on(qreg[1])])

    # Invert circuit
    inverse_circuit = cirq.inverse(circuit)
    inverse_repr = inverse_circuit.__repr__()
    inverse_qasm = inverse_circuit._to_qasm_output().__str__()

    # Expected circuit after simplification
    expected_inv = Circuit([Z.on(qreg[1]), CNOT.on(*qreg), H.on(qreg[0])])
    expected_repr = expected_inv.__repr__()
    expected_qasm = expected_inv._to_qasm_output().__str__()

    # Check inverse_circuit is logically equivalent to expected_inverse
    # but they have a different representation
    assert inverse_circuit == expected_inv
    assert inverse_repr != expected_repr
    assert inverse_qasm != expected_qasm

    # Simplify the circuit
    _simplify_circuit_exponents(inverse_circuit)

    # Check inverse_circuit has the expected simplified representation
    simplified_repr = inverse_circuit.__repr__()
    simplified_qasm = inverse_circuit._to_qasm_output().__str__()
    assert inverse_circuit == expected_inv
    assert simplified_repr == expected_repr
    assert simplified_qasm == expected_qasm
Esempio n. 12
0
def test_simplify_circuit_exponents_controlled_gate():
    circuit = Circuit(
        ControlledGate(CNOT, num_controls=1).on(*LineQubit.range(3)))
    copy = circuit.copy()

    _simplify_circuit_exponents(circuit)
    assert _equal(circuit, copy)
Esempio n. 13
0
def test_ffft_text_diagram():
    qubits = LineQubit.range(8)

    circuit = cirq.Circuit(ffft(qubits), strategy=cirq.InsertStrategy.EARLIEST)

    assert circuit.to_text_diagram(transpose=True) == """
0   1     2   3     4   5     6   7
│   │     │   │     │   │     │   │
0↦0─1↦4───2↦1─3↦5───4↦2─5↦6───6↦3─7↦7
│   │     │   │     │   │     │   │
0↦0─1↦2───2↦1─3↦3   0↦0─1↦2───2↦1─3↦3
│   │     │   │     │   │     │   │
F₀──F₀    F₀──F₀    F₀──F₀    F₀──F₀
│   │     │   │     │   │     │   │
0↦0─1↦2───2↦1─3↦3   0↦0─1↦2───2↦1─3↦3
│   │     │   │     │   │     │   │
│   ω^0_4 │   ω^1_4 │   ω^0_4 │   ω^1_4
│   │     │   │     │   │     │   │
F₀──F₀    F₀──F₀    F₀──F₀    F₀──F₀
│   │     │   │     │   │     │   │
0↦0─1↦2───2↦1─3↦3   0↦0─1↦2───2↦1─3↦3
│   │     │   │     │   │     │   │
0↦0─1↦2───2↦4─3↦6───4↦1─5↦3───6↦5─7↦7
│   │     │   │     │   │     │   │
│   ω^0_8 │   ω^1_8 │   ω^2_8 │   ω^3_8
│   │     │   │     │   │     │   │
F₀──F₀    F₀──F₀    F₀──F₀    F₀──F₀
│   │     │   │     │   │     │   │
0↦0─1↦4───2↦1─3↦5───4↦2─5↦6───6↦3─7↦7
│   │     │   │     │   │     │   │
    """.strip()
Esempio n. 14
0
def _max_ent_state_circuit(num_qubits: int) -> Circuit:
    r"""Generates a circuits which prepares the maximally entangled state
    |\omega\rangle = U |0\rangle  = \sum_i |i\rangle \otimes |i\rangle .

    Args:
        num_qubits: The number of qubits on which the circuit is applied.
            Only 2 or 4 qubits are supported.

    Returns:
        The circuits which prepares the state |\omega\rangle.
    """

    qreg = LineQubit.range(num_qubits)
    circ = Circuit()
    if num_qubits == 2:
        circ.append(H.on(qreg[0]))
        circ.append(CNOT.on(*qreg))
    elif num_qubits == 4:
        # Prepare half of the qubits in a uniform superposition
        circ.append(H.on(qreg[0]))
        circ.append(H.on(qreg[1]))
        # Create a perfect correlation between the two halves of the qubits.
        circ.append(CNOT.on(qreg[0], qreg[2]))
        circ.append(CNOT.on(qreg[1], qreg[3]))
    else:
        raise NotImplementedError(
            "Only 2- or 4-qubit maximally entangling circuits are supported."
        )
    return circ
Esempio n. 15
0
def test_non_identity_scale_1q():
    """Tests that when scale factor = 1, the circuit is the
    same.
    """
    qreg = LineQubit.range(3)
    circ = Circuit([ops.rx(np.pi * 1.0).on_each(qreg)],
                   [ops.ry(np.pi * 1.0).on(qreg[0])])
    np.random.seed(42)
    stretch = 2
    base_noise = 0.001
    noises = np.random.normal(loc=0.0,
                              scale=np.sqrt((stretch - 1) * base_noise),
                              size=(4, ))
    np.random.seed(42)

    scaled = scale_parameters(circ,
                              scale_factor=stretch,
                              sigma=base_noise,
                              seed=42)
    result = []
    for moment in scaled:
        for op in moment.operations:
            gate = deepcopy(op.gate)
            param = gate.exponent
            result.append(param * np.pi - np.pi)
    assert np.all(np.isclose(result - noises, 0))
Esempio n. 16
0
def test_TwiddleGate_text_diagram():
    qubit = LineQubit.range(1)
    circuit = cirq.Circuit(_TwiddleGate(2, 8).on(*qubit))

    assert circuit.to_text_diagram(use_unicode_characters=False).strip() == """
0: ---w^2_8---
    """.strip()
Esempio n. 17
0
def test_pop_measurements_and_add_measurements():
    """Tests popping measurements from a circuit.."""
    # Test circuit:
    # 0: ───H───T───@───M───
    #               │   │
    # 1: ───H───M───┼───┼───
    #               │   │
    # 2: ───H───────X───M───
    qreg = LineQubit.range(3)
    circ = Circuit(
        [ops.H.on_each(qreg)],
        [ops.T.on(qreg[0])],
        [ops.measure(qreg[1])],
        [ops.CNOT.on(qreg[0], qreg[2])],
        [ops.measure(qreg[0], qreg[2])],
    )
    copy = deepcopy(circ)
    measurements = _pop_measurements(copy)
    correct = Circuit(
        [ops.H.on_each(qreg)],
        [ops.T.on(qreg[0])],
        [ops.CNOT.on(qreg[0], qreg[2])],
    )
    assert _equal(copy, correct)
    _append_measurements(copy, measurements)
    assert _equal(copy, circ)
Esempio n. 18
0
def test_two_qubit_representation_norm(gate: Gate, noise: float):
    qreg = LineQubit.range(2)
    optimal_norm = two_qubit_depolarizing_overhead(noise)
    norm = represent_operation_with_global_depolarizing_noise(
        Circuit(gate(*qreg)), noise,
    ).norm
    assert np.isclose(optimal_norm, norm)
Esempio n. 19
0
def test_represent_operations_in_circuit_with_measurements(
    circuit_type: str, rep_function,
):
    """Tests measurements in circuit are ignored (not represented)."""
    q0, q1 = LineQubit.range(2)
    circ_mitiq = Circuit(
        X(q1),
        MeasurementGate(num_qubits=1)(q0),
        X(q1),
        MeasurementGate(num_qubits=1)(q0),
    )
    circ = convert_from_mitiq(circ_mitiq, circuit_type)

    reps = rep_function(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
        if isinstance(op.gate, MeasurementGate):
            assert not found
        else:
            assert found

    # Number of unique gates excluding measurement gates
    assert len(reps) == 1
Esempio n. 20
0
def test_TwiddleGate_text_unicode_diagram():
    qubit = LineQubit.range(1)
    circuit = cirq.Circuit(_TwiddleGate(2, 8).on(*qubit))

    assert circuit.to_text_diagram().strip() == """
0: ───ω^2_8───
    """.strip()
Esempio n. 21
0
def test_simple_pauli_deco_dict_CNOT():
    """Tests that the _simple_pauli_deco_dict function returns a decomposition
    dicitonary which is consistent with a local depolarizing noise model.

    The channel acting on the state each qubit is assumed to be:
    D(rho) = = (1 - epsilon) rho + epsilon I/2
    = (1 - p) rho + p/3 (X rho X + Y rho Y^dag + Z rho Z)
    """

    # Deduce epsilon from BASE_NOISE
    epsilon = BASE_NOISE * 4.0 / 3.0
    c_neg = -(1 / 4) * epsilon / (1 - epsilon)
    c_pos = 1 - 3 * c_neg
    qreg = LineQubit.range(2)

    # Get the decomposition of a CNOT gate
    deco = DECO_DICT[CNOT.on(*qreg)]

    # The first term of 'deco' corresponds to no error occurring
    first_coefficient, first_imp_seq = deco[0]
    assert np.isclose(c_pos * c_pos, first_coefficient)
    assert first_imp_seq == [CNOT.on(*qreg)]
    # The second term corresponds to a Pauli X error on one qubit
    second_coefficient, second_imp_seq = deco[1]
    assert np.isclose(c_pos * c_neg, second_coefficient)
    assert second_imp_seq == [CNOT.on(*qreg), X.on(qreg[0])]
    # The last term corresponds to two Pauli Z errors on both qubits
    last_coefficient, last_imp_seq = deco[-1]
    assert np.isclose(c_neg * c_neg, last_coefficient)
    assert last_imp_seq == [CNOT.on(*qreg), Z.on(qreg[0]), Z.on(qreg[1])]
Esempio n. 22
0
def test_identity_scale_2q():
    """Tests that when scale factor = 1, the circuit is the
    same.
    """
    qreg = LineQubit.range(2)
    circ = Circuit([ops.CNOT.on(qreg[0], qreg[1])])
    scaled = scale_parameters(circ, scale_factor=1, sigma=0.001)
    assert _equal(circ, scaled)
Esempio n. 23
0
def test_identity_scale_1q():
    """Tests that when scale factor = 1, the circuit is the
    same.
    """
    qreg = LineQubit.range(3)
    circ = Circuit([ops.X.on_each(qreg)], [ops.Y.on(qreg[0])])
    scaled = scale_parameters(circ, scale_factor=1, sigma=0.001)
    assert _equal(circ, scaled)
Esempio n. 24
0
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
Esempio n. 25
0
def generate_rb_circuits(
    n_qubits: int,
    num_cliffords: int,
    trials: int = 1,
    return_type: Optional[str] = None,
) -> List[QPROGRAM]:
    """Returns a list of randomized benchmarking circuits, i.e. circuits that
    are equivalent to the identity.

    Args:
        n_qubits: The number of qubits. Can be either 1 or 2.
        num_cliffords: The number of Clifford group elements in the
            random circuits. This is proportional to the depth per circuit.
        trials: The number of random circuits at each num_cfd.
        return_type: String which specifies the type of the
            returned circuits. See the keys of
            ``mitiq.SUPPORTED_PROGRAM_TYPES`` for options. If ``None``, the
            returned circuits have type ``cirq.Circuit``.

    Returns:
        A list of randomized benchmarking circuits.
    """
    if n_qubits not in (1, 2):
        raise ValueError(
            "Only generates RB circuits on one or two "
            f"qubits not {n_qubits}."
        )
    qubits = LineQubit.range(n_qubits)
    cliffords = _single_qubit_cliffords()

    if n_qubits == 1:
        c1 = cliffords.c1_in_xy
        cfd_mat_1q = cast(
            np.ndarray, [_gate_seq_to_mats(gates) for gates in c1]
        )
        circuits = [
            _random_single_q_clifford(qubits[0], num_cliffords, c1, cfd_mat_1q)
            for _ in range(trials)
        ]
    else:
        cfd_matrices = _two_qubit_clifford_matrices(
            qubits[0],
            qubits[1],
            cliffords,
        )
        circuits = [
            _random_two_q_clifford(
                qubits[0],
                qubits[1],
                num_cliffords,
                cfd_matrices,
                cliffords,
            )
            for _ in range(trials)
        ]

    return_type = "cirq" if not return_type else return_type
    return [convert_from_mitiq(circuit, return_type) for circuit in circuits]
Esempio n. 26
0
def test_generate_parameter_calibration_circuit_failure():
    """Tests that parameter calibration circuit generation fails because there
    are too many qubits"""
    n_qubits = 3
    qubits = LineQubit.range(n_qubits)
    depth = 10
    # Should raise exception because too many qubits
    with pytest.raises(CircuitMismatchException):
        _generate_parameter_calibration_circuit(qubits, depth, ZPowGate)
Esempio n. 27
0
def test_F0Gate_text_unicode_diagram():
    qubits = LineQubit.range(2)
    circuit = cirq.Circuit(_F0Gate().on(*qubits))

    assert circuit.to_text_diagram().strip() == """
0: ───F₀───
      │
1: ───F₀───
    """.strip()
Esempio n. 28
0
def test_F0Gate_text_diagram():
    qubits = LineQubit.range(2)
    circuit = cirq.Circuit(_F0Gate().on(*qubits))

    assert circuit.to_text_diagram(use_unicode_characters=False).strip() == """
0: ---F0---
      |
1: ---F0---
    """.strip()
Esempio n. 29
0
def test_range():
    assert LineQubit.range(0) == []
    assert LineQubit.range(1) == [LineQubit(0)]
    assert LineQubit.range(2) == [LineQubit(0), LineQubit(1)]
    assert LineQubit.range(5) == [
        LineQubit(0),
        LineQubit(1),
        LineQubit(2),
        LineQubit(3),
        LineQubit(4),
    ]

    assert LineQubit.range(0, 0) == []
    assert LineQubit.range(0, 1) == [LineQubit(0)]
    assert LineQubit.range(1, 4) == [LineQubit(1), LineQubit(2), LineQubit(3)]

    assert LineQubit.range(3, 1, -1) == [LineQubit(3), LineQubit(2)]
    assert LineQubit.range(3, 5, -1) == []
    assert LineQubit.range(1, 5, 2) == [LineQubit(1), LineQubit(3)]
Esempio n. 30
0
def test_ffft_multi_fermionic_mode(n, initial):
    initial_state = _multi_fermionic_mode_base_state(n, *initial)
    expected_state = _fourier_transform_multi_fermionic_mode(n, *initial)
    qubits = LineQubit.range(n)

    circuit = cirq.Circuit(ffft(qubits), strategy=cirq.InsertStrategy.EARLIEST)
    state = circuit.final_wavefunction(initial_state,
                                       qubits_that_should_be_present=qubits)

    assert np.allclose(state, expected_state, rtol=0.0)
Esempio n. 31
0
def test_TwiddleGate_transform(k, n, qubit, initial, expected):
    qubits = LineQubit.range(2)
    initial_state = _single_fermionic_modes_state(initial)
    expected_state = _single_fermionic_modes_state(expected)

    circuit = cirq.Circuit(_TwiddleGate(k, n).on(qubits[qubit]))
    state = circuit.final_wavefunction(initial_state,
                                       qubits_that_should_be_present=qubits)

    assert np.allclose(state, expected_state, rtol=0.0)
Esempio n. 32
0
from cirq import LineQubit

print(LineQubit.range(6))