Beispiel #1
0
def test_frequency_space_gates():
    a, b, c = cirq.LineQubit.range(3)

    assert_url_to_circuit_returns('{"cols":[["QFT3"]]}',
                                  cirq.Circuit(cirq.qft(a, b, c)))
    assert_url_to_circuit_returns(
        '{"cols":[["QFT†3"]]}', cirq.Circuit(cirq.inverse(cirq.qft(a, b, c))))

    assert_url_to_circuit_returns(
        '{"cols":[["PhaseGradient3"]]}',
        cirq.Circuit(
            cirq.PhaseGradientGate(num_qubits=3, exponent=0.5)(a, b, c)),
    )
    assert_url_to_circuit_returns(
        '{"cols":[["PhaseUngradient3"]]}',
        cirq.Circuit(
            cirq.PhaseGradientGate(num_qubits=3, exponent=-0.5)(a, b, c)),
    )

    t = sympy.Symbol('t')
    assert_url_to_circuit_returns(
        '{"cols":[["grad^t2"]]}',
        cirq.Circuit(
            cirq.PhaseGradientGate(num_qubits=2, exponent=2 * t)(a, b)),
    )
    assert_url_to_circuit_returns(
        '{"cols":[["grad^t3"]]}',
        cirq.Circuit(
            cirq.PhaseGradientGate(num_qubits=3, exponent=4 * t)(a, b, c)),
    )
    assert_url_to_circuit_returns(
        '{"cols":[["grad^-t3"]]}',
        cirq.Circuit(
            cirq.PhaseGradientGate(num_qubits=3, exponent=-4 * t)(a, b, c)),
    )
Beispiel #2
0
def test_qft():
    np.testing.assert_allclose(
        cirq.unitary(cirq.qft(*cirq.LineQubit.range(2))),
        np.array(
            [
                [1, 1, 1, 1],
                [1, 1j, -1, -1j],
                [1, -1, 1, -1],
                [1, -1j, -1, 1j],
            ]
        )
        / 2,
        atol=1e-8,
    )

    np.testing.assert_allclose(
        cirq.unitary(cirq.qft(*cirq.LineQubit.range(2), without_reverse=True)),
        np.array(
            [
                [1, 1, 1, 1],
                [1, -1, 1, -1],
                [1, 1j, -1, -1j],
                [1, -1j, -1, 1j],
            ]
        )
        / 2,
        atol=1e-8,
    )

    np.testing.assert_allclose(
        cirq.unitary(cirq.qft(*cirq.LineQubit.range(4))),
        np.array([[np.exp(2j * np.pi * i * j / 16) for i in range(16)] for j in range(16)]) / 4,
        atol=1e-8,
    )

    np.testing.assert_allclose(
        cirq.unitary(cirq.qft(*cirq.LineQubit.range(2)) ** -1),
        np.array(
            [
                [1, 1, 1, 1],
                [1, -1j, -1, 1j],
                [1, -1, 1, -1],
                [1, 1j, -1, -1j],
            ]
        )
        / 2,
        atol=1e-8,
    )

    for k in range(4):
        for b in [False, True]:
            cirq.testing.assert_implements_consistent_protocols(
                cirq.QuantumFourierTransformGate(num_qubits=k, without_reverse=b)
            )
Beispiel #3
0
def test_same_partial_trace():
    qubit_order = cirq.LineQubit.range(2)
    q0, q1 = qubit_order

    angles = [0.0, 0.20160913, math.pi / 3.0, math.pi / 2.0, math.pi]

    gate_cls = [cirq.rx, cirq.ry, cirq.rz]

    for angle_0 in angles:
        for gate_0 in gate_cls:
            for angle_1 in angles:
                for gate_1 in gate_cls:
                    for use_cnot in [False, True]:
                        op0 = gate_0(angle_0)
                        op1 = gate_1(angle_1)

                        circuit = cirq.Circuit()
                        circuit.append(op0(q0))
                        if use_cnot:
                            circuit.append(cirq.qft(q0, q1))
                        circuit.append(op1(q1))
                        if use_cnot:
                            circuit.append(cirq.qft(q1, q0))

                        for initial_state in range(4):
                            expected_density_matrix = cirq.final_density_matrix(
                                circuit,
                                qubit_order=qubit_order,
                                initial_state=initial_state)
                            expected_partial_trace = cirq.partial_trace(
                                expected_density_matrix.reshape(2, 2, 2, 2),
                                keep_indices=[0])

                            mps_simulator = ccq.mps_simulator.MPSSimulator()
                            final_state = mps_simulator.simulate(
                                circuit,
                                qubit_order=qubit_order,
                                initial_state=initial_state).final_state
                            actual_density_matrix = final_state.partial_trace(
                                [q0, q1])
                            actual_partial_trace = final_state.partial_trace(
                                [q0])

                            np.testing.assert_allclose(actual_density_matrix,
                                                       expected_density_matrix,
                                                       atol=1e-4)
                            np.testing.assert_allclose(actual_partial_trace,
                                                       expected_partial_trace,
                                                       atol=1e-4)
Beispiel #4
0
def run_estimate(unknown_gate, qnum, repetitions):
    """Construct the following phase estimator circuit and execute simulations.

                                     ---------
    ---H---------------------@------|         |---M--- [m4]:lowest bit
                             |      |         |
    ---H---------------@-----+------|         |---M--- [m3]
                       |     |      | QFT_inv |
    ---H---------@-----+-----+------|         |---M--- [m2]
                 |     |     |      |         |
    ---H---@-----+-----+-----+------|         |---M--- [m1]:highest bit
           |     |     |     |       ---------
    -------U-----U^2---U^4---U^8----------------------

    The measurement results M=[m1, m2,...] are translated to the estimated
    phase with the following formula:
    phi = m1*(1/2) + m2*(1/2)^2 + m3*(1/2)^3 + ...
    """

    ancilla = cirq.LineQubit(-1)
    qubits = cirq.LineQubit.range(qnum)

    oracle_raised_to_power = [
        unknown_gate.on(ancilla).controlled_by(qubits[i])**(2**i)
        for i in range(qnum)
    ]
    circuit = cirq.Circuit(
        cirq.H.on_each(*qubits),
        oracle_raised_to_power,
        cirq.qft(*qubits, without_reverse=True)**-1,
        cirq.measure(*qubits, key='phase'),
    )

    return cirq.sample(circuit, repetitions=repetitions)
Beispiel #5
0
    def test_serialize_circuit_unsupported_gate(self):
        """Ensure we error on unsupported gates."""
        q0 = cirq.GridQubit(0, 0)
        q1 = cirq.GridQubit(0, 1)
        unsupported_circuit = cirq.Circuit(cirq.qft(q0, q1))

        with self.assertRaises(ValueError):
            serializer.serialize_circuit(unsupported_circuit)
Beispiel #6
0
def test_circuit_diagram():
    cirq.testing.assert_has_diagram(
        cirq.Circuit(cirq.decompose_once(cirq.qft(*cirq.LineQubit.range(4)))),
        """
0: ───H───Grad^0.5───────#2─────────────#3─────────────×───
          │              │              │              │
1: ───────@──────────H───Grad^0.5───────#2─────────×───┼───
                         │              │          │   │
2: ──────────────────────@──────────H───Grad^0.5───×───┼───
                                        │              │
3: ─────────────────────────────────────@──────────H───×───
        """,
    )

    cirq.testing.assert_has_diagram(
        cirq.Circuit(
            cirq.decompose_once(
                cirq.qft(*cirq.LineQubit.range(4), without_reverse=True))),
        """
0: ───H───Grad^0.5───────#2─────────────#3─────────────
          │              │              │
1: ───────@──────────H───Grad^0.5───────#2─────────────
                         │              │
2: ──────────────────────@──────────H───Grad^0.5───────
                                        │
3: ─────────────────────────────────────@──────────H───
        """,
    )

    cirq.testing.assert_has_diagram(
        cirq.Circuit(cirq.qft(*cirq.LineQubit.range(4)),
                     cirq.inverse(cirq.qft(*cirq.LineQubit.range(4)))),
        """
0: ───qft───qft^-1───
      │     │
1: ───#2────#2───────
      │     │
2: ───#3────#3───────
      │     │
3: ───#4────#4───────
        """,
    )
Beispiel #7
0
def make_order_finding_circuit(x: int, n: int) -> cirq.Circuit:
    """Returns quantum circuit which computes the order of x modulo n.

    The circuit uses Quantum Phase Estimation to compute an eigenvalue of
    the unitary

        U|y⟩ = |y * x mod n⟩      0 <= y < n
        U|y⟩ = |y⟩                n <= y

    discussed in the header of this file. The circuit uses two registers:
    the target register which is acted on by U and the exponent register
    from which an eigenvalue is read out after measurement at the end. The
    circuit consists of three steps:

    1. Initialization of the target register to |0..01⟩ and the exponent
       register to a superposition state.
    2. Multiple controlled-U**2**j operations implemented efficiently using
       modular exponentiation.
    3. Inverse Quantum Fourier Transform to kick an eigenvalue to the
       exponent register.

    Args:
        x: positive integer whose order modulo n is to be found
        n: modulus relative to which the order of x is to be found

    Returns:
        Quantum circuit for finding the order of x modulo n
    """
    L = n.bit_length()
    target = cirq.LineQubit.range(L)
    exponent = cirq.LineQubit.range(L, 3 * L + 3)
    return cirq.Circuit(
        cirq.X(target[L - 1]),
        cirq.H.on_each(*exponent),
        ModularExp([2] * len(target), [2] * len(exponent), x,
                   n).on(*target + exponent),
        cirq.qft(*exponent, inverse=True),
        cirq.measure(*exponent, key='exponent'),
    )
Beispiel #8
0
 def _decompose_(self, qubits):
     qubits = list(qubits)
     yield cirq.H.on_each(*qubits[:-1])
     yield PhaseKickback(self.num_qubits(), self.U)(*qubits)
     yield cirq.qft(*qubits[:-1], without_reverse=True) ** -1
Beispiel #9
0
def test_inverse():
    a, b, c = cirq.LineQubit.range(3)
    assert cirq.qft(a, b, c, inverse=True) == cirq.qft(a, b, c)**-1
    assert cirq.qft(a, b, c, inverse=True,
                    without_reverse=True) == cirq.inverse(
                        cirq.qft(a, b, c, without_reverse=True))