예제 #1
0
def test_tomography_plot_raises_for_incorrect_number_of_axes():
    simulator = sim.Simulator()
    qubit = GridQubit(0, 0)
    circuit = circuits.Circuit(ops.X(qubit)**0.5)
    result = single_qubit_state_tomography(simulator, qubit, circuit, 1000)
    with pytest.raises(TypeError):  # ax is not a List[plt.Axes]
        ax = plt.subplot()
        result.plot(ax)
    with pytest.raises(ValueError):
        _, axes = plt.subplots(1, 3)
        result.plot(axes)
예제 #2
0
파일: moment_test.py 프로젝트: YZNIU/Cirq
def test_validation():
    a = ops.QubitId()
    b = ops.QubitId()
    c = ops.QubitId()
    d = ops.QubitId()

    _ = Moment([])
    _ = Moment([ops.X(a)])
    _ = Moment([ops.CZ(a, b)])
    _ = Moment([ops.CZ(b, d)])
    _ = Moment([ops.CZ(a, b), ops.CZ(c, d)])
    _ = Moment([ops.CZ(a, c), ops.CZ(b, d)])
    _ = Moment([ops.CZ(a, c), ops.X(b)])

    with pytest.raises(ValueError):
        _ = Moment([ops.X(a), ops.X(a)])
    with pytest.raises(ValueError):
        _ = Moment([ops.CZ(a, c), ops.X(c)])
    with pytest.raises(ValueError):
        _ = Moment([ops.CZ(a, c), ops.CZ(c, d)])
예제 #3
0
def _xx_yy_zz_interaction_via_full_czs(
    q0: 'cirq.Qid', q1: 'cirq.Qid', x: float, y: float, z: float
):
    a = x * -2 / np.pi + 0.5
    b = y * -2 / np.pi + 0.5
    c = z * -2 / np.pi + 0.5
    yield ops.X(q0) ** 0.5
    yield ops.H(q1)
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
    yield ops.X(q0) ** a
    yield ops.Y(q1) ** b
    yield ops.H.on(q0)
    yield ops.CZ(q1, q0)
    yield ops.H(q0)
    yield ops.X(q1) ** -0.5
    yield ops.Z(q1) ** c
    yield ops.H(q1)
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
예제 #4
0
def _easy_direction_partial_cz(q0: ops.QubitId, q1: ops.QubitId, t: float):
    """The actual hardware can only do CZs that phase counter-clockwise.

    This method replaces clockwise phase(t) to counter-clockwise.

    Args:
      q0: The first qubit being operated on.
      q1: The other qubit being operated on.
      t: The parameter to describe partial-CZ(CZ^t).

    Yields:
      Yields an equivalent circuit for CZ^t with counter-clock phased CZs.
    """
    if t >= 0:
        yield ops.CZ(q0, q1)**t
        return
    yield ops.Z(q0)**t
    yield ops.X(q1)
    yield ops.CZ(q0, q1)**(-t)
    yield ops.X(q1)
예제 #5
0
def test_text_diagrams():
    a = ops.NamedQubit('a')
    b = ops.NamedQubit('b')
    circuit = Circuit.from_ops(ops.SWAP(a, b), ops.X(a), ops.Y(a), ops.Z(a),
                               ops.CZ(a, b), ops.CNOT(a, b), ops.CNOT(b, a),
                               ops.H(a))
    assert circuit.to_text_diagram().strip() == """
a: ───×───X───Y───Z───@───@───X───H───
      │               │   │   │
b: ───×───────────────@───X───@───────
    """.strip()
예제 #6
0
파일: qasm_output.py 프로젝트: xcgfth/Cirq
    def default_decompose(self, qubits: Sequence[ops.QubitId]) -> ops.OP_TREE:
        q0, q1 = qubits
        a = self.x * -2 / np.pi + 0.5
        b = self.y * -2 / np.pi + 0.5
        c = self.z * -2 / np.pi + 0.5

        yield self.before0(q0)
        yield self.before1(q1)

        yield ops.X(q0)**0.5
        yield ops.CNOT(q0, q1)
        yield ops.X(q0)**a
        yield ops.Y(q1)**b
        yield ops.CNOT(q1, q0)
        yield ops.X(q1)**-0.5
        yield ops.Z(q1)**c
        yield ops.CNOT(q0, q1)

        yield self.after0(q0)
        yield self.after1(q1)
예제 #7
0
def test_clears_known_empties_even_at_zero_tolerance():
    m = circuits.DropNegligible(0.001)
    q = ops.QubitId()
    q2 = ops.QubitId()
    c = circuits.Circuit.from_ops(
        ops.Z(q)**0,
        ops.Y(q)**0.0000001,
        ops.X(q)**-0.0000001,
        ops.CZ(q, q2)**0)

    m.optimize_circuit(c)
    assert c == circuits.Circuit([circuits.Moment()] * 4)
예제 #8
0
def test_eq():
    q0 = ops.QubitId()

    eq = EqualsTester()
    eq.make_equality_pair(
        lambda: ScheduledOperation(Timestamp(), Duration(), ops.H(q0)))
    eq.make_equality_pair(
        lambda: ScheduledOperation(Timestamp(picos=5), Duration(), ops.H(q0)))
    eq.make_equality_pair(
        lambda: ScheduledOperation(Timestamp(), Duration(picos=5), ops.H(q0)))
    eq.make_equality_pair(
        lambda: ScheduledOperation(Timestamp(), Duration(), ops.X(q0)))
예제 #9
0
 def _decompose_(self) -> ops.OP_TREE:
     if len(self.pauli_string) <= 0:
         return
     qubits = self.qubits
     any_qubit = qubits[0]
     to_z_ops = ops.freeze_op_tree(self.pauli_string.to_z_basis_ops())
     xor_decomp = tuple(xor_nonlocal_decompose(qubits, any_qubit))
     yield to_z_ops
     yield xor_decomp
     if isinstance(self.half_turns, sympy.Symbol):
         if self.pauli_string.negated:
             yield ops.X(any_qubit)
         yield ops.Z(any_qubit)**self.half_turns
         if self.pauli_string.negated:
             yield ops.X(any_qubit)
     else:
         half_turns = self.half_turns * (-1 if self.pauli_string.negated
                                         else 1)
         yield ops.Z(any_qubit)**half_turns
     yield protocols.inverse(xor_decomp)
     yield protocols.inverse(to_z_ops)
예제 #10
0
 def default_decompose(self) -> ops.OP_TREE:
     if len(self.pauli_string) <= 0:
         return
     qubits = self.qubits
     any_qubit = qubits[0]
     to_z_ops = tuple(pauli_string_to_z_ops(self.pauli_string))
     xor_decomp = tuple(xor_nonlocal_decompose(qubits, any_qubit))
     yield to_z_ops
     yield xor_decomp
     if isinstance(self.half_turns, value.Symbol):
         if self.pauli_string.negated:
             yield ops.X(any_qubit)
         yield ops.RotZGate(half_turns=self.half_turns)(any_qubit)
         if self.pauli_string.negated:
             yield ops.X(any_qubit)
     else:
         half_turns = self.half_turns * (-1 if self.pauli_string.negated
                                         else 1)
         yield ops.Z(any_qubit)**half_turns
     yield ops.inverse(xor_decomp)
     yield ops.inverse(to_z_ops)
예제 #11
0
def test_from_braket_non_parameterized_single_qubit_gates():
    braket_circuit = BKCircuit()
    instructions = [
        Instruction(braket_gates.I(), target=0),
        Instruction(braket_gates.X(), target=1),
        Instruction(braket_gates.Y(), target=2),
        Instruction(braket_gates.Z(), target=3),
        Instruction(braket_gates.H(), target=0),
        Instruction(braket_gates.S(), target=1),
        Instruction(braket_gates.Si(), target=2),
        Instruction(braket_gates.T(), target=3),
        Instruction(braket_gates.Ti(), target=0),
        Instruction(braket_gates.V(), target=1),
        Instruction(braket_gates.Vi(), target=2),
    ]
    for instr in instructions:
        braket_circuit.add_instruction(instr)
    cirq_circuit = from_braket(braket_circuit)

    for i, op in enumerate(cirq_circuit.all_operations()):
        assert np.allclose(
            instructions[i].operator.to_matrix(), protocols.unitary(op)
        )

    qreg = LineQubit.range(4)
    expected_cirq_circuit = Circuit(
        ops.I(qreg[0]),
        ops.X(qreg[1]),
        ops.Y(qreg[2]),
        ops.Z(qreg[3]),
        ops.H(qreg[0]),
        ops.S(qreg[1]),
        ops.S(qreg[2]) ** -1,
        ops.T(qreg[3]),
        ops.T(qreg[0]) ** -1,
        ops.X(qreg[1]) ** 0.5,
        ops.X(qreg[2]) ** -0.5,
    )
    assert _equal(cirq_circuit, expected_cirq_circuit)
예제 #12
0
def nonoptimal_toffoli_circuit(
    q0: 'cirq.Qid',
    q1: 'cirq.Qid',
    q2: 'cirq.Qid',
    device: devices.Device = devices.UNCONSTRAINED_DEVICE,
) -> circuits.Circuit:
    ret = circuits.Circuit(
        ops.Y(q2) ** 0.5,
        ops.X(q2),
        ops.CNOT(q1, q2),
        ops.Z(q2) ** -0.25,
        ops.CNOT(q1, q2),
        ops.CNOT(q2, q1),
        ops.CNOT(q1, q2),
        ops.CNOT(q0, q1),
        ops.CNOT(q1, q2),
        ops.CNOT(q2, q1),
        ops.CNOT(q1, q2),
        ops.Z(q2) ** 0.25,
        ops.CNOT(q1, q2),
        ops.Z(q2) ** -0.25,
        ops.CNOT(q1, q2),
        ops.CNOT(q2, q1),
        ops.CNOT(q1, q2),
        ops.CNOT(q0, q1),
        ops.CNOT(q1, q2),
        ops.CNOT(q2, q1),
        ops.CNOT(q1, q2),
        ops.Z(q2) ** 0.25,
        ops.Z(q1) ** 0.25,
        ops.CNOT(q0, q1),
        ops.Z(q0) ** 0.25,
        ops.Z(q1) ** -0.25,
        ops.CNOT(q0, q1),
        ops.Y(q2) ** 0.5,
        ops.X(q2),
    )
    ret._device = device
    return ret
예제 #13
0
def test_works_with_basic_gates():
    a = ops.NamedQubit('a')
    b = ops.NamedQubit('b')

    basics = [
        ops.X(a),
        ops.Y(a)**0.5,
        ops.Z(a),
        ops.CZ(a, b)**-0.25,
        ops.CNOT(a, b),
        ops.H(b),
        ops.SWAP(a, b)
    ]
    assert list(ops.inverse_of_invertible_op_tree(basics)) == [
        ops.SWAP(a, b),
        ops.H(b),
        ops.CNOT(a, b),
        ops.CZ(a, b)**0.25,
        ops.Z(a),
        ops.Y(a)**-0.5,
        ops.X(a),
    ]
예제 #14
0
파일: schedule_test.py 프로젝트: yinxx/Cirq
def test_exclude():
    q = ops.QubitId()
    zero = Timestamp(picos=0)
    ps = Duration(picos=1)
    op = ScheduledOperation(zero, ps, ops.H(q))
    schedule = Schedule(device=UnconstrainedDevice, scheduled_operations=[op])

    assert not schedule.exclude(ScheduledOperation(zero + ps, ps, ops.H(q)))
    assert not schedule.exclude(ScheduledOperation(zero, ps, ops.X(q)))
    assert schedule.query(time=zero, duration=ps * 10) == [op]
    assert schedule.exclude(ScheduledOperation(zero, ps, ops.H(q)))
    assert schedule.query(time=zero, duration=ps * 10) == []
    assert not schedule.exclude(ScheduledOperation(zero, ps, ops.H(q)))
예제 #15
0
def _cpmg_circuit(qubit: 'cirq.Qid', delay_var: sympy.Symbol,
                  max_pulses: int) -> 'cirq.Circuit':
    """Creates a CPMG circuit for a given qubit.

    The circuit will look like:

      sqrt(Y) - wait(delay_var) - X - wait(2*delay_var) - ... - wait(delay_var)

    with max_pulses number of X gates.

    The X gates are paramterizd by 'pulse_N' symbols so that pulses can be
    turned on and off.  This is done to combine circuits with different pulses
    into the same paramterized circuit.
    """
    circuit = circuits.Circuit(
        ops.Y(qubit)**0.5, ops.wait(qubit, nanos=delay_var), ops.X(qubit))
    for n in range(max_pulses):
        pulse_n_on = sympy.Symbol(f'pulse_{n}')
        circuit.append(ops.wait(qubit, nanos=2 * delay_var * pulse_n_on))
        circuit.append(ops.X(qubit)**pulse_n_on)
    circuit.append(ops.wait(qubit, nanos=delay_var))
    return circuit
    def _startdecompose(self, qubits):
        # qubits = [c1, c2, ..., cn, T]
        # Will "bootstrap" an ancilla
        CnXOneBorrow = CnXDirtyGate(num_controls=len(qubits[:-2]),
                                    num_ancilla=1)

        yield ops.H(qubits[-1])
        yield CnXOneBorrow(*(qubits[:-2] + [qubits[-1]] + [qubits[-2]]))
        yield ops.Z(qubits[-1])**-0.25
        yield ops.CNOT(qubits[-2], qubits[-1])
        yield ops.Z(qubits[-1])**0.25
        yield CnXOneBorrow(*(qubits[:-2] + [qubits[-1]] + [qubits[-2]]))
        yield ops.Z(qubits[-1])**-0.25
        yield ops.CNOT(qubits[-2], qubits[-1])
        yield ops.Z(qubits[-1])**0.25
        yield ops.H(qubits[-1])

        IncrementLinearWithBorrowedBitOp = IncrementLinearWithBorrowedBitGate(
            register_size=len(qubits) - 1)

        # Perform a +1 Gate on all of the top bits with bottom bit as borrowed
        yield IncrementLinearWithBorrowedBitOp(*qubits)

        # Perform  -rt Z gates
        for i in range(1, len(qubits) - 1):
            yield ops.Z(qubits[i])**(-1 * 1 / (2**(len(qubits) - i)))

        # Perform a -1 Gate on the top bits
        for i in range(len(qubits) - 1):
            yield ops.X(qubits[i])
        yield IncrementLinearWithBorrowedBitOp(*qubits)
        for i in range(len(qubits) - 1):
            yield ops.X(qubits[i])

        # Perform  rt Z gates
        for i in range(1, len(qubits) - 1):
            yield ops.Z(qubits[i])**(1 / (2**(len(qubits) - i)))
        yield ops.Z(qubits[0])**(1 / (2**(len(qubits) - 1)))
예제 #17
0
def swap_to_sqrt_iswap(a, b, turns):
    """Implement the evolution of the hopping term using two sqrt_iswap gates
     and single-qubit operations. Output unitary:
    [[1, 0,        0,     0],
     [0, g·c,    -i·g·s,  0],
     [0, -i·g·s,  g·c,    0],
     [0,   0,      0,     1]]
     where c = cos(theta) and s = sin(theta).
        Args:
            a: the first qubit
            b: the second qubit
            theta: The rotational angle that specifies the gate, where
            c = cos(π·t/2), s = sin(π·t/2), g = exp(i·π·t/2).
    """
    if not isinstance(turns, sympy.Basic) and _near_mod_n(turns, 1.0, 2):
        # Decomposition for cirq.SWAP
        yield ops.Y(a)**0.5
        yield ops.Y(b)**0.5
        yield SQRT_ISWAP(a, b)
        yield ops.Y(a)**-0.5
        yield ops.Y(b)**-0.5
        yield SQRT_ISWAP(a, b)
        yield ops.X(a)**-0.5
        yield ops.X(b)**-0.5
        yield SQRT_ISWAP(a, b)
        yield ops.X(a)**0.5
        yield ops.X(b)**0.5
        return

    yield ops.Z(a)**1.25
    yield ops.Z(b)**-0.25
    yield ops.ISWAP(a, b)**-0.5
    yield ops.Z(a)**(-turns / 2 + 1)
    yield ops.Z(b)**(turns / 2)
    yield ops.ISWAP(a, b)**-0.5
    yield ops.Z(a)**(turns / 2 - 0.25)
    yield ops.Z(b)**(turns / 2 + 0.25)
    yield ops.CZ.on(a, b)**(-turns)
예제 #18
0
파일: qasm_output.py 프로젝트: wabei/Cirq
    def _decompose_(self, qubits: Sequence[ops.Qid]) -> ops.OP_TREE:
        q0, q1 = qubits
        x, y, z = self.kak.interaction_coefficients
        a = x * -2 / np.pi + 0.5
        b = y * -2 / np.pi + 0.5
        c = z * -2 / np.pi + 0.5

        b0, b1 = self.kak.single_qubit_operations_before
        yield QasmUGate.from_matrix(b0).on(q0)
        yield QasmUGate.from_matrix(b1).on(q1)

        yield ops.X(q0)**0.5
        yield ops.CNOT(q0, q1)
        yield ops.X(q0)**a
        yield ops.Y(q1)**b
        yield ops.CNOT(q1, q0)
        yield ops.X(q1)**-0.5
        yield ops.Z(q1)**c
        yield ops.CNOT(q0, q1)

        a0, a1 = self.kak.single_qubit_operations_after
        yield QasmUGate.from_matrix(a0).on(q0)
        yield QasmUGate.from_matrix(a1).on(q1)
예제 #19
0
def nonoptimal_toffoli_circuit(
        q0: ops.Qid,
        q1: ops.Qid,
        q2: ops.Qid,
        device: devices.Device = devices.UNCONSTRAINED_DEVICE
) -> circuits.Circuit:
    return circuits.Circuit.from_ops(ops.Y(q2)**0.5,
                                     ops.X(q2),
                                     ops.CNOT(q1, q2),
                                     ops.Z(q2)**-0.25,
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q2, q1),
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q0, q1),
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q2, q1),
                                     ops.CNOT(q1, q2),
                                     ops.Z(q2)**0.25,
                                     ops.CNOT(q1, q2),
                                     ops.Z(q2)**-0.25,
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q2, q1),
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q0, q1),
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q2, q1),
                                     ops.CNOT(q1, q2),
                                     ops.Z(q2)**0.25,
                                     ops.Z(q1)**0.25,
                                     ops.CNOT(q0, q1),
                                     ops.Z(q0)**0.25,
                                     ops.Z(q1)**-0.25,
                                     ops.CNOT(q0, q1),
                                     ops.Y(q2)**0.5,
                                     ops.X(q2),
                                     device=device)
예제 #20
0
def nonoptimal_toffoli_circuit(
        q0: ops.Qid,
        q1: ops.Qid,
        q2: ops.Qid,
        device: devices.Device = devices.UnconstrainedDevice
) -> circuits.Circuit:
    return circuits.Circuit.from_ops(ops.Y(q2)**0.5,
                                     ops.X(q2),
                                     ops.CNOT(q1, q2),
                                     ops.Z(q2)**-0.25,
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q2, q1),
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q0, q1),
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q2, q1),
                                     ops.CNOT(q1, q2),
                                     ops.Z(q2)**0.25,
                                     ops.CNOT(q1, q2),
                                     ops.Z(q2)**-0.25,
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q2, q1),
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q0, q1),
                                     ops.CNOT(q1, q2),
                                     ops.CNOT(q2, q1),
                                     ops.CNOT(q1, q2),
                                     ops.Z(q2)**0.25,
                                     ops.Z(q1)**0.25,
                                     ops.CNOT(q0, q1),
                                     ops.Z(q0)**0.25,
                                     ops.Z(q1)**-0.25,
                                     ops.CNOT(q0, q1),
                                     ops.Y(q2)**0.5,
                                     ops.X(q2),
                                     device=device)
예제 #21
0
def single_qubit_state_tomography(
    sampler: 'cirq.Sampler',
    qubit: 'cirq.Qid',
    circuit: 'cirq.AbstractCircuit',
    repetitions: int = 1000,
) -> TomographyResult:
    """Single-qubit state tomography.

    The density matrix of the output state of a circuit is measured by first
    doing projective measurements in the z-basis, which determine the
    diagonal elements of the matrix. A X/2 or Y/2 rotation is then added before
    the z-basis measurement, which determines the imaginary and real parts of
    the off-diagonal matrix elements, respectively.

    See Vandersypen and Chuang, Rev. Mod. Phys. 76, 1037 for details.

    Args:
        sampler: The quantum engine or simulator to run the circuits.
        qubit: The qubit under test.
        circuit: The circuit to execute on the qubit before tomography.
        repetitions: The number of measurements for each basis rotation.

    Returns:
        A TomographyResult object that stores and plots the density matrix.
    """
    circuit_z = circuit + circuits.Circuit(ops.measure(qubit, key='z'))
    results = sampler.run(circuit_z, repetitions=repetitions)
    rho_11 = np.mean(results.measurements['z'])
    rho_00 = 1.0 - rho_11

    circuit_x = circuits.Circuit(circuit,
                                 ops.X(qubit)**0.5, ops.measure(qubit,
                                                                key='z'))
    results = sampler.run(circuit_x, repetitions=repetitions)
    rho_01_im = np.mean(results.measurements['z']) - 0.5

    circuit_y = circuits.Circuit(circuit,
                                 ops.Y(qubit)**-0.5, ops.measure(qubit,
                                                                 key='z'))
    results = sampler.run(circuit_y, repetitions=repetitions)
    rho_01_re = 0.5 - np.mean(results.measurements['z'])

    rho_01 = rho_01_re + 1j * rho_01_im
    rho_10 = np.conj(rho_01)

    rho = np.array([[rho_00, rho_01], [rho_10, rho_11]])

    return TomographyResult(rho)
예제 #22
0
def test_stopped_at_2qubit():
    m = MergeRotations(0.000001)
    q = ops.QubitId()
    q2 = ops.QubitId()
    c = circuits.Circuit([
        circuits.Moment([ops.Z(q)]),
        circuits.Moment([ops.H(q)]),
        circuits.Moment([ops.X(q)]),
        circuits.Moment([ops.H(q)]),
        circuits.Moment([ops.CZ(q, q2)]),
        circuits.Moment([ops.H(q)]),
    ])

    assert (m.optimization_at(c, 0, c.operation_at(
        q, 0)) == circuits.PointOptimizationSummary(clear_span=4,
                                                    clear_qubits=[q],
                                                    new_operations=[]))
예제 #23
0
def test_extension():
    class DummyGate(ops.Gate):
        pass

    optimizer = MergeRotations(extensions=Extensions({
        ops.KnownMatrixGate: {
            DummyGate:
            lambda _: ops.SingleQubitMatrixGate(np.array([[0, 1], [1, 0]]))
        }
    }))

    q = ops.QubitId()
    c = circuits.Circuit([
        circuits.Moment([DummyGate().on(q)]),
    ])
    assert_optimizes(before=c,
                     after=circuits.Circuit([circuits.Moment([ops.X(q)])]),
                     optimizer=optimizer)
 def defer(op: 'cirq.Operation', _) -> 'cirq.OP_TREE':
     if op in terminal_measurements:
         return op
     gate = op.gate
     if isinstance(gate, ops.MeasurementGate):
         if gate.confusion_map:
             raise NotImplementedError(
                 "Deferring confused measurement is not implemented, but found "
                 f"measurement with key={gate.key} and non-empty confusion map."
             )
         key = value.MeasurementKey.parse_serialized(gate.key)
         targets = [_MeasurementQid(key, q) for q in op.qubits]
         measurement_qubits[key] = targets
         cxs = [ops.CX(q, target) for q, target in zip(op.qubits, targets)]
         xs = [
             ops.X(targets[i])
             for i, b in enumerate(gate.full_invert_mask()) if b
         ]
         return cxs + xs
     elif protocols.is_measurement(op):
         return [defer(op, None) for op in protocols.decompose_once(op)]
     elif op.classical_controls:
         controls = []
         for c in op.classical_controls:
             if isinstance(c, value.KeyCondition):
                 if c.key not in measurement_qubits:
                     raise ValueError(
                         f'Deferred measurement for key={c.key} not found.')
                 qubits = measurement_qubits[c.key]
                 if len(qubits) != 1:
                     # TODO: Multi-qubit conditions require
                     # https://github.com/quantumlib/Cirq/issues/4512
                     # Remember to update docstring above once this works.
                     raise ValueError(
                         'Only single qubit conditions are allowed.')
                 controls.extend(qubits)
             else:
                 raise ValueError('Only KeyConditions are allowed.')
         return op.without_classical_controls().controlled_by(
             *controls,
             control_values=[
                 tuple(range(1, q.dimension)) for q in controls
             ])
     return op
예제 #25
0
def test_two_qubit_state_tomography():
    # Check that the density matrices of the four Bell states closely match
    # the ideal cases. In addition, check that the output states of
    # single-qubit rotations (H, H), (X/2, Y/2), (Y/2, X/2) have the correct
    # density matrices.

    simulator = sim.Simulator()
    q_0 = GridQubit(0, 0)
    q_1 = GridQubit(0, 1)

    circuit_00 = circuits.Circuit.from_ops(ops.H(q_0), ops.CNOT(q_0, q_1))
    circuit_01 = circuits.Circuit.from_ops(ops.X(q_1), ops.H(q_0),
                                           ops.CNOT(q_0, q_1))
    circuit_10 = circuits.Circuit.from_ops(ops.X(q_0), ops.H(q_0),
                                           ops.CNOT(q_0, q_1))
    circuit_11 = circuits.Circuit.from_ops(ops.X(q_0), ops.X(q_1), ops.H(q_0),
                                           ops.CNOT(q_0, q_1))
    circuit_hh = circuits.Circuit.from_ops(ops.H(q_0), ops.H(q_1))
    circuit_xy = circuits.Circuit.from_ops(ops.X(q_0)**0.5, ops.Y(q_1)**0.5)
    circuit_yx = circuits.Circuit.from_ops(ops.Y(q_0)**0.5, ops.X(q_1)**0.5)

    act_rho_00 = two_qubit_state_tomography(simulator, q_0, q_1, circuit_00,
                                            1000).data
    act_rho_01 = two_qubit_state_tomography(simulator, q_0, q_1, circuit_01,
                                            1000).data
    act_rho_10 = two_qubit_state_tomography(simulator, q_0, q_1, circuit_10,
                                            1000).data
    act_rho_11 = two_qubit_state_tomography(simulator, q_0, q_1, circuit_11,
                                            1000).data
    act_rho_hh = two_qubit_state_tomography(simulator, q_0, q_1, circuit_hh,
                                            1000).data
    act_rho_xy = two_qubit_state_tomography(simulator, q_0, q_1, circuit_xy,
                                            1000).data
    act_rho_yx = two_qubit_state_tomography(simulator, q_0, q_1, circuit_yx,
                                            1000).data

    tar_rho_00 = np.outer([1.0, 0, 0, 1.0], [1.0, 0, 0, 1.0]) * 0.5
    tar_rho_01 = np.outer([0, 1.0, 1.0, 0], [0, 1.0, 1.0, 0]) * 0.5
    tar_rho_10 = np.outer([1.0, 0, 0, -1.0], [1.0, 0, 0, -1.0]) * 0.5
    tar_rho_11 = np.outer([0, 1.0, -1.0, 0], [0, 1.0, -1.0, 0]) * 0.5
    tar_rho_hh = np.outer([0.5, 0.5, 0.5, 0.5], [0.5, 0.5, 0.5, 0.5])
    tar_rho_xy = np.outer([0.5, 0.5, -0.5j, -0.5j], [0.5, 0.5, 0.5j, 0.5j])
    tar_rho_yx = np.outer([0.5, -0.5j, 0.5, -0.5j], [0.5, 0.5j, 0.5, 0.5j])

    np.testing.assert_almost_equal(act_rho_00, tar_rho_00, decimal=1)
    np.testing.assert_almost_equal(act_rho_01, tar_rho_01, decimal=1)
    np.testing.assert_almost_equal(act_rho_10, tar_rho_10, decimal=1)
    np.testing.assert_almost_equal(act_rho_11, tar_rho_11, decimal=1)
    np.testing.assert_almost_equal(act_rho_hh, tar_rho_hh, decimal=1)
    np.testing.assert_almost_equal(act_rho_xy, tar_rho_xy, decimal=1)
    np.testing.assert_almost_equal(act_rho_yx, tar_rho_yx, decimal=1)
예제 #26
0
def measure_confusion_matrix(
    sampler: 'cirq.Sampler',
    qubits: Union[Sequence['cirq.Qid'], Sequence[Sequence['cirq.Qid']]],
    repetitions: int = 1000,
) -> TensoredConfusionMatrices:
    """Prepares `TensoredConfusionMatrices` for the n qubits in the input.

    The confusion matrix (CM) for two qubits is the following matrix:

        ⎡ Pr(00|00) Pr(01|00) Pr(10|00) Pr(11|00) ⎤
        ⎢ Pr(00|01) Pr(01|01) Pr(10|01) Pr(11|01) ⎥
        ⎢ Pr(00|10) Pr(01|10) Pr(10|10) Pr(11|10) ⎥
        ⎣ Pr(00|11) Pr(01|11) Pr(10|11) Pr(11|11) ⎦

    where Pr(ij | pq) = Probability of observing “ij” given state “pq” was prepared.

    Args:
        sampler: Sampler to collect the data from.
        qubits: Qubits for which the confusion matrix should be measured.
        repetitions: Number of times to sample each circuit for a confusion matrix row.
    """
    qubits = cast(Sequence[Sequence['cirq.Qid']],
                  [qubits] if isinstance(qubits[0], ops.Qid) else qubits)
    confusion_matrices = []
    for qs in qubits:
        flip_symbols = sympy.symbols(f'flip_0:{len(qs)}')
        flip_circuit = circuits.Circuit(
            [ops.X(q)**s for q, s in zip(qs, flip_symbols)],
            ops.measure(*qs),
        )
        sweeps = study.Product(
            *[study.Points(f'flip_{i}', [0, 1]) for i in range(len(qs))])
        results = sampler.run_sweep(flip_circuit,
                                    sweeps,
                                    repetitions=repetitions)
        confusion_matrices.append(
            np.asarray([vis.get_state_histogram(r) for r in results],
                       dtype=float) / repetitions)
    return TensoredConfusionMatrices(confusion_matrices,
                                     qubits,
                                     repetitions=repetitions,
                                     timestamp=time.time())
예제 #27
0
def rabi_oscillations(
    sampler: 'cirq.Sampler',
    qubit: 'cirq.Qid',
    max_angle: float = 2 * np.pi,
    *,
    repetitions: int = 1000,
    num_points: int = 200,
) -> RabiResult:
    """Runs a Rabi oscillation experiment.

    Rotates a qubit around the x-axis of the Bloch sphere by a sequence of Rabi
    angles evenly spaced between 0 and max_angle. For each rotation, repeat
    the circuit a number of times and measure the average probability of the
    qubit being in the |1> state.

    Args:
        sampler: The quantum engine or simulator to run the circuits.
        qubit: The qubit under test.
        max_angle: The final Rabi angle in radians.
        repetitions: The number of repetitions of the circuit for each Rabi
            angle.
        num_points: The number of Rabi angles.

    Returns:
        A RabiResult object that stores and plots the result.
    """
    theta = sympy.Symbol('theta')
    circuit = circuits.Circuit(ops.X(qubit)**theta)
    circuit.append(ops.measure(qubit, key='z'))
    sweep = study.Linspace(key='theta',
                           start=0.0,
                           stop=max_angle / np.pi,
                           length=num_points)
    results = sampler.run_sweep(circuit, params=sweep, repetitions=repetitions)
    angles = np.linspace(0.0, max_angle, num_points)
    excited_state_probs = np.zeros(num_points)
    for i in range(num_points):
        excited_state_probs[i] = np.mean(results[i].measurements['z'])

    return RabiResult(angles, excited_state_probs)
예제 #28
0
def test_single_qubit_state_tomography():
    # Check that the density matrices of the output states of X/2, Y/2 and
    # H + Y gates closely match the ideal cases.
    simulator = sim.Simulator()
    qubit = GridQubit(0, 0)

    circuit_1 = circuits.Circuit(ops.X(qubit)**0.5)
    circuit_2 = circuits.Circuit(ops.Y(qubit)**0.5)
    circuit_3 = circuits.Circuit(ops.H(qubit), ops.Y(qubit))

    act_rho_1 = single_qubit_state_tomography(simulator, qubit, circuit_1,
                                              1000).data
    act_rho_2 = single_qubit_state_tomography(simulator, qubit, circuit_2,
                                              1000).data
    act_rho_3 = single_qubit_state_tomography(simulator, qubit, circuit_3,
                                              1000).data

    tar_rho_1 = np.array([[0.5, 0.5j], [-0.5j, 0.5]])
    tar_rho_2 = np.array([[0.5, 0.5], [0.5, 0.5]])
    tar_rho_3 = np.array([[0.5, -0.5], [-0.5, 0.5]])

    np.testing.assert_almost_equal(act_rho_1, tar_rho_1, decimal=1)
    np.testing.assert_almost_equal(act_rho_2, tar_rho_2, decimal=1)
    np.testing.assert_almost_equal(act_rho_3, tar_rho_3, decimal=1)
예제 #29
0
 def _decompose_(self, qubits: Sequence['cirq.Qid']) -> 'cirq.OP_TREE':
     q = qubits[0]
     yield ops.Z(q)**-self._axis_phase_exponent
     yield ops.X(q)**self._x_exponent
     yield ops.Z(q)**(self._axis_phase_exponent + self._z_exponent)
예제 #30
0
def _two_qubit_clifford(q_0: devices.GridQubit, q_1: devices.GridQubit,
                        idx: int,
                        cliffords: Cliffords) -> Iterator[ops.OP_TREE]:
    """Generates a two-qubit Clifford gate.

    An integer (idx) from 0 to 11519 is used to generate a two-qubit Clifford
    gate which is constructed with single-qubit X and Y rotations and CZ gates.
    The decomposition of the Cliffords follow those described in the appendix
    of Barends et al., Nature 508, 500.

    The integer idx is first decomposed into idx_0 (which ranges from 0 to
    23), idx_1 (ranging from 0 to 23) and idx_2 (ranging from 0 to 19). idx_0
    and idx_1 determine the two single-qubit rotations which happen at the
    beginning of all two-qubit Clifford gates. idx_2 determines the
    subsequent gates in the following:

    a) If idx_2 = 0, do nothing so the Clifford is just two single-qubit
    Cliffords (total of 24*24 = 576 possibilities).

    b) If idx_2 = 1, perform a CZ, followed by -Y/2 on q_0 and Y/2 on q_1,
    followed by another CZ, followed by Y/2 on q_0 and -Y/2 on q_1, followed
    by one more CZ and finally a Y/2 on q_1. The Clifford is then a member of
    the SWAP-like class (total of 24*24 = 576 possibilities).

    c) If 2 <= idx_2 <= 10, perform a CZ followed by a member of the S_1
    group on q_0 and a member of the S_1^(Y/2) group on q_1. The Clifford is
    a member of the CNOT-like class (a total of 3*3*24*24 = 5184 possibilities).

    d) If 11 <= idx_2 <= 19, perform a CZ, followed by Y/2 on q_0 and -X/2 on
    q_1, followed by another CZ, and finally a member of the S_1^(Y/2) group on
    q_0 and a member of the S_1^(X/2) group on q_1. The Clifford is a member
    of the iSWAP-like class (a total of 3*3*24*24 = 5184 possibilities).

    Through the above process, all 11520 members of the two-qubit Clifford
    group may be generated.

    Args:
        q_0: The first qubit under test.
        q_1: The second qubit under test.
        idx: An integer from 0 to 11519.
        cliffords: A NamedTuple that contains single-qubit Cliffords from the
            C1, S1, S_1^(X/2) and S_1^(Y/2) groups.
    """
    c1 = cliffords.c1_in_xy
    s1 = cliffords.s1
    s1_x = cliffords.s1_x
    s1_y = cliffords.s1_y

    idx_0 = int(idx / 480)
    idx_1 = int((idx % 480) / 20)
    idx_2 = idx - idx_0 * 480 - idx_1 * 20
    yield _single_qubit_gates(c1[idx_0], q_0)
    yield _single_qubit_gates(c1[idx_1], q_1)
    if idx_2 == 1:
        yield ops.CZ(q_0, q_1)
        yield ops.Y(q_0)**-0.5
        yield ops.Y(q_1)**0.5
        yield ops.CZ(q_0, q_1)
        yield ops.Y(q_0)**0.5
        yield ops.Y(q_1)**-0.5
        yield ops.CZ(q_0, q_1)
        yield ops.Y(q_1)**0.5
    elif 2 <= idx_2 <= 10:
        yield ops.CZ(q_0, q_1)
        idx_3 = int((idx_2 - 2) / 3)
        idx_4 = (idx_2 - 2) % 3
        yield _single_qubit_gates(s1[idx_3], q_0)
        yield _single_qubit_gates(s1_y[idx_4], q_1)
    elif idx_2 >= 11:
        yield ops.CZ(q_0, q_1)
        yield ops.Y(q_0)**0.5
        yield ops.X(q_1)**-0.5
        yield ops.CZ(q_0, q_1)
        idx_3 = int((idx_2 - 11) / 3)
        idx_4 = (idx_2 - 11) % 3
        yield _single_qubit_gates(s1_y[idx_3], q_0)
        yield _single_qubit_gates(s1_x[idx_4], q_1)