Exemplo n.º 1
0
	def _decompose(self, qubits):
		# qubits = [c1, c2, ..., cn, T]
		# Will "bootstrap" an ancilla
		yield ops.H(qubits[-1])
		yield CnxLinearBorrowedBit(*(qubits[:-2] + [qubits[-1]] + [qubits[-2]])).default_decompose()
		yield ops.Z(qubits[-1])**-0.25
		yield ops.CNOT(qubits[-2], qubits[-1])
		yield ops.Z(qubits[-1])**0.25
		yield CnxLinearBorrowedBit(*(qubits[:-2] + [qubits[-1]] + [qubits[-2]])).default_decompose()
		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])

		
		# 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)))
Exemplo n.º 2
0
def test_two_qubit_state_tomography():
    # Check that the density matrices of the four Bell states closely match
    # the ideal cases.
    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))

    act_rho_00 = two_qubit_state_tomography(simulator, q_0, q_1, circuit_00,
                                            100000).data
    act_rho_01 = two_qubit_state_tomography(simulator, q_0, q_1, circuit_01,
                                            100000).data
    act_rho_10 = two_qubit_state_tomography(simulator, q_0, q_1, circuit_10,
                                            100000).data
    act_rho_11 = two_qubit_state_tomography(simulator, q_0, q_1, circuit_11,
                                            100000).data

    tar_rho_00 = np.outer([1.0, 0, 0, 1.0], [1.0, 0, 0, 1.0]) / 2.0
    tar_rho_01 = np.outer([0, 1.0, 1.0, 0], [0, 1.0, 1.0, 0]) / 2.0
    tar_rho_10 = np.outer([1.0, 0, 0, -1.0], [1.0, 0, 0, -1.0]) / 2.0
    tar_rho_11 = np.outer([0, 1.0, -1.0, 0], [0, 1.0, -1.0, 0]) / 2.0

    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)
Exemplo n.º 3
0
def test_teleportation_diagram():
    ali = ops.NamedQubit('alice')
    car = ops.NamedQubit('carrier')
    bob = ops.NamedQubit('bob')

    circuit = Circuit.from_ops(
        ops.H(car),
        ops.CNOT(car, bob),
        ops.X(ali)**0.5,
        ops.CNOT(ali, car),
        ops.H(ali),
        [ops.measure(ali), ops.measure(car)],
        ops.CNOT(car, bob),
        ops.CZ(ali, bob))

    diagram = circuit_to_latex_using_qcircuit(
        circuit,
        qubit_order=ops.QubitOrder.explicit([ali, car, bob]))
    assert diagram.strip() == """
\\Qcircuit @R=1em @C=0.75em { \\\\ 
 \\lstick{\\text{alice}}& \\qw &\\qw & \\gate{\\text{X}^{0.5}} \\qw & \\control \\qw & \\gate{\\text{H}} \\qw & \\meter \\qw &\\qw & \\control \\qw &\\qw\\\\
 \\lstick{\\text{carrier}}& \\qw & \\gate{\\text{H}} \\qw & \\control \\qw & \\targ \\qw \\qwx &\\qw & \\meter \\qw & \\control \\qw &\\qw \\qwx &\\qw\\\\
 \\lstick{\\text{bob}}& \\qw &\\qw & \\targ \\qw \\qwx &\\qw &\\qw &\\qw & \\targ \\qw \\qwx & \\control \\qw \\qwx &\\qw \\\\ 
 \\\\ }
        """.strip()
Exemplo n.º 4
0
def test_query_overlapping_operations_inclusive():
    q = ops.QubitId()
    zero = Timestamp(picos=0)
    ps = Duration(picos=1)
    op1 = ScheduledOperation(zero, 2 * ps, ops.H(q))
    op2 = ScheduledOperation(zero + ps, 2 * ps, ops.H(q))
    schedule = Schedule(device=UnconstrainedDevice,
                        scheduled_operations=[op2, op1])

    def query(t, d=Duration(), qubits=None):
        return schedule.query(time=t,
                              duration=d,
                              qubits=qubits,
                              include_query_end_time=True,
                              include_op_end_times=True)

    assert query(zero - 0.5 * ps, ps) == [op1]
    assert query(zero - 0.5 * ps, 2 * ps) == [op1, op2]
    assert query(zero, ps) == [op1, op2]
    assert query(zero + 0.5 * ps, ps) == [op1, op2]
    assert query(zero + ps, ps) == [op1, op2]
    assert query(zero + 1.5 * ps, ps) == [op1, op2]
    assert query(zero + 2.0 * ps, ps) == [op1, op2]
    assert query(zero + 2.5 * ps, ps) == [op2]
    assert query(zero + 3.0 * ps, ps) == [op2]
    assert query(zero + 3.5 * ps, ps) == []
Exemplo n.º 5
0
def _xx_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid', x: float):
    a = x * -2 / np.pi
    yield ops.H(q1)
    yield ops.CZ(q0, q1)
    yield ops.X(q0)**a
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
Exemplo n.º 6
0
def _xx_interaction_via_full_czs(q0: ops.QubitId, q1: ops.QubitId, x: float):
    a = x * -2 / np.pi
    yield ops.H(q1)
    yield ops.CZ(q0, q1)
    yield ops.X(q0)**a
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
Exemplo n.º 7
0
def test_removes_identity_sequence():
    q = ops.QubitId()
    assert_optimizes(before=circuits.Circuit([
        circuits.Moment([ops.Z(q)]),
        circuits.Moment([ops.H(q)]),
        circuits.Moment([ops.X(q)]),
        circuits.Moment([ops.H(q)]),
    ]),
                     after=circuits.Circuit())
Exemplo n.º 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)))
Exemplo n.º 9
0
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)))
Exemplo n.º 10
0
def _xx_yy_interaction_via_full_czs(q0: 'cirq.Qid', q1: 'cirq.Qid', x: float, y: float):
    a = x * -2 / np.pi
    b = y * -2 / np.pi
    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(q1)
    yield ops.CZ(q0, q1)
    yield ops.H(q1)
    yield ops.X(q0) ** -0.5
Exemplo n.º 11
0
def test_moment_by_moment_schedule_moment_of_single_qubit_ops():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit([
        Moment(ops.H(q) for q in qubits),
    ])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    assert set(schedule.scheduled_operations) == {
        ScheduledOperation.op_at_on(ops.H(q), zero_ns, device)
        for q in qubits
    }
Exemplo n.º 12
0
def test_query_point_operation_exclusive():
    q = ops.QubitId()
    zero = Timestamp(picos=0)
    ps = Duration(picos=1)
    op = ScheduledOperation(zero, Duration(), ops.H(q))
    schedule = Schedule(device=UnconstrainedDevice, scheduled_operations=[op])

    assert schedule.query(time=zero,
                          include_query_end_time=False,
                          include_op_end_times=False) == []
    assert schedule.query(time=zero + ps,
                          include_query_end_time=False,
                          include_op_end_times=False) == []
    assert schedule.query(time=zero - ps,
                          include_query_end_time=False,
                          include_op_end_times=False) == []
    assert schedule.query(time=zero) == []
    assert schedule.query(time=zero + ps) == []
    assert schedule.query(time=zero - ps) == []

    assert schedule.query(time=zero, qubits=[]) == []
    assert schedule.query(time=zero, qubits=[q]) == []

    assert schedule.query(time=zero, duration=ps) == []
    assert schedule.query(time=zero - 0.5 * ps, duration=ps) == [op]
    assert schedule.query(time=zero - ps, duration=ps) == []
    assert schedule.query(time=zero - 2 * ps, duration=ps) == []
    assert schedule.query(time=zero - ps, duration=3 * ps) == [op]
    assert schedule.query(time=zero + ps, duration=ps) == []
Exemplo n.º 13
0
def test_moment_by_moment_schedule_empty_moment_ignored():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit(
        [Moment([ops.H(qubits[0])]),
         Moment([]),
         Moment([ops.H(qubits[0])])])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    twenty_ns = cirq.Timestamp(nanos=20)
    assert set(schedule.scheduled_operations) == {
        ScheduledOperation.op_at_on(ops.H(qubits[0]), zero_ns, device),
        ScheduledOperation.op_at_on(ops.H(qubits[0]), twenty_ns, device),
    }
Exemplo n.º 14
0
def test_query_point_operation_inclusive():
    q = ops.QubitId()
    zero = Timestamp(picos=0)
    ps = Duration(picos=1)
    op = ScheduledOperation(zero, Duration(), ops.H(q))
    schedule = Schedule(device=UnconstrainedDevice, scheduled_operations=[op])

    def query(t, d=Duration(), qubits=None):
        return schedule.query(time=t,
                              duration=d,
                              qubits=qubits,
                              include_query_end_time=True,
                              include_op_end_times=True)

    assert query(zero) == [op]
    assert query(zero + ps) == []
    assert query(zero - ps) == []

    assert query(zero, qubits=[]) == []
    assert query(zero, qubits=[q]) == [op]

    assert query(zero, ps) == [op]
    assert query(zero - 0.5 * ps, ps) == [op]
    assert query(zero - ps, ps) == [op]
    assert query(zero - 2 * ps, ps) == []
    assert query(zero - ps, 3 * ps) == [op]
    assert query(zero + ps, ps) == []
Exemplo n.º 15
0
def _H(
    q: int,
    args: sim.ActOnCliffordTableauArgs,
    operations: List[ops.Operation],
    qubits: List['cirq.Qid'],
):
    protocols.act_on(ops.H, args, qubits=[qubits[q]], allow_decompose=False)
    operations.append(ops.H(qubits[q]))
Exemplo n.º 16
0
 def default_decompose(self, qubits: Sequence[ops.QubitId]) -> ops.OP_TREE:
     qubit, = qubits
     if self == CliffordGate.H:
         return ops.H(qubit),
     rotations = self.decompose_rotation()
     pauli_gate_map = {Pauli.X: ops.X, Pauli.Y: ops.Y, Pauli.Z: ops.Z}
     return tuple(
         (pauli_gate_map[r](qubit)**(qt / 2) for r, qt in rotations))
Exemplo n.º 17
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=[]))
Exemplo n.º 18
0
def test_include():
    q0 = ops.QubitId()
    q1 = ops.QubitId()
    zero = Timestamp(picos=0)
    ps = Duration(picos=1)
    schedule = Schedule(device=UnconstrainedDevice)

    op0 = ScheduledOperation(zero, ps, ops.H(q0))
    schedule.include(op0)
    with pytest.raises(ValueError):
        schedule.include(ScheduledOperation(zero, ps, ops.H(q0)))
        schedule.include(ScheduledOperation(zero + 0.5 * ps, ps, ops.H(q0)))
    op1 = ScheduledOperation(zero + 2 * ps, ps, ops.H(q0))
    schedule.include(op1)
    op2 = ScheduledOperation(zero + 0.5 * ps, ps, ops.H(q1))
    schedule.include(op2)

    assert schedule.query(time=zero, duration=ps * 10) == [op0, op2, op1]
Exemplo n.º 19
0
def test_cnots_separated_by_single_gates_correct():
    q0 = ops.QubitId()
    q1 = ops.QubitId()
    assert_optimization_not_broken(
        circuits.Circuit.from_ops(
            ops.CNOT(q0, q1),
            ops.H(q1),
            ops.CNOT(q0, q1),
        ))
Exemplo n.º 20
0
    def _apply_qft(register):
        """
		applies the qft to the register according to https://arxiv.org/pdf/quant-ph/0008033.pdf
		"""
        rreg = register[::-1]
        for i, q in enumerate(rreg):
            yield ops.H(q)
            for j in range(i + 1, len(rreg)):
                yield ops.CZ(rreg[j], q)**(2 * 1 / (2**(j + 1)))
Exemplo n.º 21
0
 def simple_schedule(q, start_picos=0, duration_picos=1, num_ops=1):
     time_picos = start_picos
     scheduled_ops = []
     for _ in range(num_ops):
         op = ScheduledOperation(Timestamp(picos=time_picos),
                                 Duration(picos=duration_picos), ops.H(q))
         scheduled_ops.append(op)
         time_picos += duration_picos
     return Schedule(device=UnconstrainedDevice,
                     scheduled_operations=scheduled_ops)
Exemplo n.º 22
0
def test_query_overlapping_operations_exclusive():
    q = ops.QubitId()
    zero = Timestamp(picos=0)
    ps = Duration(picos=1)
    op1 = ScheduledOperation(zero, 2 * ps, ops.H(q))
    op2 = ScheduledOperation(zero + ps, 2 * ps, ops.H(q))
    schedule = Schedule(device=UnconstrainedDevice,
                        scheduled_operations=[op2, op1])

    assert schedule.query(time=zero - 0.5 * ps, duration=ps) == [op1]
    assert schedule.query(time=zero - 0.5 * ps, duration=2 * ps) == [op1, op2]
    assert schedule.query(time=zero, duration=ps) == [op1]
    assert schedule.query(time=zero + 0.5 * ps, duration=ps) == [op1, op2]
    assert schedule.query(time=zero + ps, duration=ps) == [op1, op2]
    assert schedule.query(time=zero + 1.5 * ps, duration=ps) == [op1, op2]
    assert schedule.query(time=zero + 2.0 * ps, duration=ps) == [op2]
    assert schedule.query(time=zero + 2.5 * ps, duration=ps) == [op2]
    assert schedule.query(time=zero + 3.0 * ps, duration=ps) == []
    assert schedule.query(time=zero + 3.5 * ps, duration=ps) == []
Exemplo n.º 23
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)
Exemplo n.º 24
0
def test_moment_by_moment_schedule_max_duration():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit([
        Moment([ops.H(qubits[0]),
                ops.CZ(qubits[1], qubits[2])]),
        Moment([ops.H(qubits[0])])
    ])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    fourty_ns = cirq.Timestamp(nanos=40)
    assert set(schedule.scheduled_operations) == {
        ScheduledOperation.op_at_on(ops.H(qubits[0]), zero_ns, device),
        ScheduledOperation.op_at_on(ops.CZ(qubits[1], qubits[2]), zero_ns,
                                    device),
        ScheduledOperation.op_at_on(ops.H(qubits[0]), fourty_ns, device),
    }
Exemplo n.º 25
0
def test_moment_by_moment_schedule_two_moments():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit([
        Moment(ops.H(q) for q in qubits),
        Moment((ops.CZ(qubits[i], qubits[i + 1]) for i in range(0, 9, 3)))
    ])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    twenty_ns = cirq.Timestamp(nanos=20)
    expected_one_qubit = set(
        ScheduledOperation.op_at_on(ops.H(q), zero_ns, device) for q in qubits)
    expected_two_qubit = set(
        ScheduledOperation.op_at_on(ops.CZ(qubits[i], qubits[i + 1]),
                                    twenty_ns, device) for i in range(0, 9, 3))
    expected = expected_one_qubit.union(expected_two_qubit)
    assert set(schedule.scheduled_operations) == expected
Exemplo n.º 26
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()
Exemplo n.º 27
0
def test_inefficient_circuit_correct():
    t = 0.1
    v = 0.11
    q0 = ops.QubitId()
    q1 = ops.QubitId()
    assert_optimization_not_broken(
        circuits.Circuit.from_ops(
            ops.H(q1),
            ops.CNOT(q0, q1),
            ops.H(q1),
            ops.CNOT(q0, q1),
            ops.CNOT(q1, q0),
            ops.H(q0),
            ops.CNOT(q0, q1),
            ops.Z(q0)**t, ops.Z(q1)**-t,
            ops.CNOT(q0, q1),
            ops.H(q0), ops.Z(q1)**v,
            ops.CNOT(q0, q1),
            ops.Z(q0)**-v, ops.Z(q1)**-v,
        ))
Exemplo n.º 28
0
def test_slice_operations():
    q0 = ops.QubitId()
    q1 = ops.QubitId()
    zero = Timestamp(picos=0)
    ps = Duration(picos=1)
    op1 = ScheduledOperation(zero, ps, ops.H(q0))
    op2 = ScheduledOperation(zero + 2 * ps, 2 * ps, ops.CZ(q0, q1))
    op3 = ScheduledOperation(zero + 10 * ps, ps, ops.H(q1))
    schedule = Schedule(device=UnconstrainedDevice,
                        scheduled_operations=[op1, op2, op3])

    assert schedule[zero] == [op1]
    assert schedule[zero + ps*0.5] == [op1]
    assert schedule[zero:zero] == []
    assert schedule[zero + ps*0.5:zero + ps*0.5] == [op1]
    assert schedule[zero:zero + ps] == [op1]
    assert schedule[zero:zero + 2 * ps] == [op1]
    assert schedule[zero:zero + 2.1 * ps] == [op1, op2]
    assert schedule[zero:zero + 20 * ps] == [op1, op2, op3]
    assert schedule[zero + 2.5 * ps:zero + 20 * ps] == [op2, op3]
    assert schedule[zero + 5 * ps:zero + 20 * ps] == [op3]
Exemplo n.º 29
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),
    ]
    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)))