def _decompose_(self, qubits): qubits = list(qubits) assert len(qubits) == 2 * self.register_size A = qubits[:self.register_size] B = qubits[self.register_size:] for i in range(1, self.register_size): yield ops.CNOT(A[i], B[i]) for i in reversed(range(1, self.register_size - 1)): yield ops.CNOT(A[i], A[i + 1]) for i in range(self.register_size - 1): yield ops.CCX(A[i], B[i], A[i + 1]) for i in reversed(range(1, self.register_size)): yield ops.CNOT(A[i], B[i]) yield ops.CCX(A[i - 1], B[i - 1], A[i]) for i in range(1, self.register_size - 1): yield ops.CNOT(A[i], A[i + 1]) for i in range(self.register_size): yield ops.CNOT(A[i], B[i])
def _decompose_half(self, qubits): if len(qubits) % 2 != 0: # Expecting list of qubits of type [A, B, x1, C, x2, D, x3, ..., Z, T] where xi are borrowed bits for i in range(len(qubits) - 1, 0, -2): yield ops.CCX(qubits[i-2], qubits[i-1], qubits[i]) for i in range(4, len(qubits) - 2, 2): yield ops.CCX(qubits[i-2], qubits[i-1], qubits[i]) for i in range(len(qubits) - 1, 0, -2): yield ops.CCX(qubits[i-2], qubits[i-1], qubits[i]) for i in range(4, len(qubits) - 2, 2): yield ops.CCX(qubits[i-2], qubits[i-1], qubits[i]) else: # Expecting list of qubits of type [A, x1, B, x2, ..., x_n-2, Z, T] for i in range(len(qubits) - 1, 1, -2): yield ops.CCX(qubits[i-2], qubits[i-1], qubits[i]) # Handle the top CNOT separately yield ops.CNOT(qubits[0], qubits[1]) for i in range(3, len(qubits) - 2, 2): yield ops.CCX(qubits[i-2], qubits[i-1], qubits[i]) for i in range(len(qubits) - 1, 1, -2): yield ops.CCX(qubits[i-2], qubits[i-1], qubits[i]) # Handle the top CNOT separately yield ops.CNOT(qubits[0], qubits[1]) for i in range(3, len(qubits) - 2, 2): yield ops.CCX(qubits[i-2], qubits[i-1], qubits[i])
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)))
def test_depolarizer_different_gate(): q1 = ops.QubitId() q2 = ops.QubitId() cnot = Job(circuits.Circuit([ circuits.Moment([ops.CNOT(q1, q2)]), ])) allerrors = DepolarizerChannel( probability=1.0, depolarizing_gates=[xmon_gates.ExpZGate(), xmon_gates.ExpWGate()]) p0 = Symbol(DepolarizerChannel._parameter_name + '0') p1 = Symbol(DepolarizerChannel._parameter_name + '1') p2 = Symbol(DepolarizerChannel._parameter_name + '2') p3 = Symbol(DepolarizerChannel._parameter_name + '3') error_sweep = (Points(p0.name, [1.0]) + Points(p1.name, [1.0]) + Points(p2.name, [1.0]) + Points(p3.name, [1.0])) cnot_then_z = Job( circuits.Circuit([ circuits.Moment([ops.CNOT(q1, q2)]), circuits.Moment([ xmon_gates.ExpZGate(half_turns=p0).on(q1), xmon_gates.ExpZGate(half_turns=p1).on(q2) ]), circuits.Moment([ xmon_gates.ExpWGate(half_turns=p2).on(q1), xmon_gates.ExpWGate(half_turns=p3).on(q2) ]) ]), cnot.sweep * error_sweep) assert allerrors.transform_job(cnot) == cnot_then_z
def _split_incrementer_borrowed_bit(self, current, qubits): """ Args: current: list of qubits currently being broken down; if len(current) < len(qubits)/2 move to n-borrowed-bit else recurse qubits: a list keeping track of each of the qubits for reference """ # We err on the side of the bottom being shorter than the top -> will require calling this function 2 fewer times top_half = current[:(len(current) - 1) // 2 + 1] bottom_half = current[(len(current) - 1) // 2 + 1:] # len(bottom) <= len(qubits)/2 correctly_arranged_qubits_with_borrowed_bits = self._prepare_bb_bits( [bottom_half[-1]] + bottom_half[:-1], qubits) yield self._linear_increment_n_bb( correctly_arranged_qubits_with_borrowed_bits) yield ops.X(bottom_half[-1]) # CX Block for i in range(len(bottom_half) - 1): yield ops.CNOT(bottom_half[-1], bottom_half[i]) # Perform a CnX Gate CnXOneDirty = CnXDirtyGate(num_controls=len(top_half), num_ancilla=1) cnx_q_list = top_half + [bottom_half[-1]] + [bottom_half[0]] yield CnXOneDirty(*cnx_q_list) # CX Block for i in range(len(bottom_half) - 1): yield ops.CNOT(bottom_half[-1], bottom_half[i]) # len(bottom) <= len(top) for i in range(len(bottom_half) - 1): yield ops.X(bottom_half[i]) yield self._linear_increment_n_bb( correctly_arranged_qubits_with_borrowed_bits) for i in range(len(bottom_half)): yield ops.X(bottom_half[i]) # CX Block for i in range(len(bottom_half) - 1): yield ops.CNOT(bottom_half[-1], bottom_half[i]) # Perform a CnX Gate yield CnXOneDirty(*cnx_q_list) # CX Block for i in range(len(bottom_half) - 1): yield ops.CNOT(bottom_half[-1], bottom_half[i]) if 2 * len(top_half) <= len(qubits): correctly_arranged_qubits_with_borrowed_bits = self._prepare_bb_bits( top_half, qubits) yield self._linear_increment_n_bb( correctly_arranged_qubits_with_borrowed_bits) else: # Divide one more time # print(top_half + self._find_borrowable(top_half, current)) yield self._split_incrementer_borrowed_bit( top_half + self._find_borrowable(top_half, current), qubits)
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)
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()
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), ))
def test_clears_paired_cnot(): q0 = ops.QubitId() q1 = ops.QubitId() assert_optimizes( before=circuits.Circuit([ circuits.Moment([ops.CNOT(q0, q1)]), circuits.Moment([ops.CNOT(q0, q1)]), ]), after=circuits.Circuit())
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()
def test_drop(): q1 = ops.QubitId() q2 = ops.QubitId() assert_optimizes(before=circuits.Circuit([ circuits.Moment(), circuits.Moment(), circuits.Moment([ops.CNOT(q1, q2)]), circuits.Moment(), ]), after=circuits.Circuit([ circuits.Moment([ops.CNOT(q1, q2)]), ]))
def _maj(reg): """ applies the MAJ operator to a three bit register ------X--@---- ---X--|--@---- ---@--@--X---- """ yield ops.CNOT(reg[2], reg[1]) yield ops.CNOT(reg[2], reg[0]) yield ops.CCX(reg[0], reg[1], reg[2])
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)
def _linear_increment_n_bb(self, qubits): # Expecting qubits = [x1, A, x2, B, x3, C, ..., Z] i.e. alternating bb with ob = output bit for i in range(1, len(qubits) - 2, 2): yield ops.CNOT(qubits[0], qubits[i]) yield ops.X(qubits[i + 1]) yield ops.X(qubits[-1]) for i in range(2, len(qubits) - 1, 2): yield ops.CNOT(qubits[i - 2], qubits[i - 1]) yield ops.CCX(qubits[i], qubits[i - 1], qubits[i - 2]) yield ops.CCX(qubits[i - 2], qubits[i - 1], qubits[i]) yield ops.CNOT(qubits[-2], qubits[-1]) for i in reversed(range(2, len(qubits) - 1, 2)): yield ops.CCX(qubits[i - 2], qubits[i - 1], qubits[i]) yield ops.CCX(qubits[i], qubits[i - 1], qubits[i - 2]) yield ops.CNOT(qubits[i], qubits[i - 1]) for i in range(2, len(qubits) - 1, 2): yield ops.X(qubits[i]) for i in range(2, len(qubits) - 1, 2): yield ops.CNOT(qubits[i - 2], qubits[i - 1]) yield ops.CCX(qubits[i], qubits[i - 1], qubits[i - 2]) yield ops.CCX(qubits[i - 2], qubits[i - 1], qubits[i]) yield ops.CNOT(qubits[-2], qubits[-1]) for i in reversed(range(2, len(qubits) - 1, 2)): yield ops.CCX(qubits[i - 2], qubits[i - 1], qubits[i]) yield ops.CCX(qubits[i], qubits[i - 1], qubits[i - 2]) yield ops.CNOT(qubits[i], qubits[i - 1]) for i in range(1, len(qubits) - 2, 2): yield ops.CNOT(qubits[0], qubits[i])
def _uma_parallel(reg): """ applies the UMA operator which maximizes parallism ------@---@----X----- --X---X---@--X-|--X-- ----------X----@--@-- """ yield ops.X(reg[1]) yield ops.CNOT(reg[0], reg[1]) yield ops.CCX(reg[0], reg[1], reg[2]) yield ops.X(reg[1]) yield ops.CNOT(reg[2], reg[0]) yield ops.CNOT(reg[2], reg[1])
def test_interchangeable_qubit_eq(): a = ops.NamedQubit('a') b = ops.NamedQubit('b') c = ops.NamedQubit('c') eq = EqualsTester() eq.add_equality_group(ops.SWAP(a, b), ops.SWAP(b, a)) eq.add_equality_group(ops.SWAP(a, c)) eq.add_equality_group(ops.CZ(a, b), ops.CZ(b, a)) eq.add_equality_group(ops.CZ(a, c)) eq.add_equality_group(ops.CNOT(a, b)) eq.add_equality_group(ops.CNOT(b, a)) eq.add_equality_group(ops.CNOT(a, c))
def _decompose_(self, qubits): qubits = list(qubits) controls = qubits[:self.reg_size] target = qubits[self.reg_size] ancilla = qubits[self.reg_size + 1:] if len(controls) == 2: yield ops.CCX(controls[0], controls[1], target) elif len(controls) == 1: yield ops.CNOT(controls[0], target) else: # Build the list depth = int(np.ceil(np.log2(len(controls))) - 1) new_bits = controls curr_ancil = 0 store_gates = [] for layer in range(depth): bits = new_bits new_bits = [] for i in range(len(bits) // 2): g = ops.CCX(bits[2 * i], bits[2 * i + 1], ancilla[curr_ancil]) yield g store_gates.append(g) new_bits.append(ancilla[curr_ancil]) curr_ancil = curr_ancil + 1 if len(bits) % 2 == 1: new_bits.append(bits[-1]) yield ops.CCX(new_bits[0], new_bits[1], target) # Get the ancilla back yield from cirq.inverse(store_gates)
def _decompose_(self, qubits): """ applies the Cuccaro adder decomposition according to https://arxiv.org/pdf/quant-ph/0410184.pdf Args: qubits: |qubits| = 2 * self.register_size + 2 """ qubits = list(qubits) assert len( qubits ) == 2 * self._register_size + 2, f'must provide the correct number of inputs' A = qubits[1:self._register_size + 1] B = qubits[self._register_size + 1:-1] cin = qubits[0] cout = qubits[-1] yield self._maj([cin, B[0], A[0]]) for i in range(1, len(B)): yield self._maj([A[i - 1], B[i], A[i]]) yield ops.CNOT(A[-1], cout) for i in reversed(range(1, len(B))): yield self._uma_parallel([A[i - 1], B[i], A[i]]) yield self._uma_parallel([cin, B[0], A[0]])
def _ccnot_congruent(c0: 'cirq.Qid', c1: 'cirq.Qid', target: 'cirq.Qid') -> List['cirq.Operation']: """Implements 3-qubit gate 'congruent' to CCNOT. Returns sequence of operations which is equivalent to applying CCNOT(c0, c1, target) and multiplying phase of |101> sate by -1. See lemma 6.2 in [1].""" return [ ops.ry(-np.pi / 4).on(target), ops.CNOT(c1, target), ops.ry(-np.pi / 4).on(target), ops.CNOT(c0, target), ops.ry(np.pi / 4).on(target), ops.CNOT(c1, target), ops.ry(np.pi / 4).on(target), ]
def test_moment_by_moment_schedule_validate_operation_fails(): device = _TestDevice() qubits = device.qubits circuit = Circuit() circuit.append(ops.CNOT(qubits[0], qubits[1])) with pytest.raises(ValueError, match="CNOT"): _ = moment_by_moment_schedule(device, circuit)
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), )
def _decompose_(self, qubits): qubits = list(qubits) controls = qubits[:self.reg_size - 1] target = qubits[self.reg_size - 1] bbits = qubits[self.reg_size:] if len(controls) == 2: yield ops.CCX(controls[0], controls[1], target) elif len(controls) == 1: yield ops.CNOT(controls[0], target) else: # Build the list bits = [] bits.append(controls[0]) for i in range(1, len(controls) - 1): bits.append(controls[i]) bits.append(bbits[i - 1]) bits.append(controls[-1]) bits.append(target) for i in range(len(bits) - 1, 0, -2): yield ops.CCX(bits[i - 2], bits[i - 1], bits[i]) for i in range(4, len(bits) - 2, 2): yield ops.CCX(bits[i - 2], bits[i - 1], bits[i]) for i in range(len(bits) - 1, 0, -2): yield ops.CCX(bits[i - 2], bits[i - 1], bits[i]) for i in range(4, len(bits) - 2, 2): yield ops.CCX(bits[i - 2], bits[i - 1], bits[i])
def test_depolarizer_no_errors(): q1 = ops.QubitId() q2 = ops.QubitId() cnot = Job(circuits.Circuit([ circuits.Moment([ops.CNOT(q1, q2)]), ])) noerrors = DepolarizerChannel(probability=0.0) assert noerrors.transform_job(cnot) == cnot
def _CNOT( q1: int, q2: int, args: sim.ActOnCliffordTableauArgs, operations: List[ops.Operation], qubits: List['cirq.Qid'], ): protocols.act_on(ops.CNOT, args, qubits=[qubits[q1], qubits[q2]], allow_decompose=False) operations.append(ops.CNOT(qubits[q1], qubits[q2]))
def backward(groups): for g in groups[1:-1]: if len(g) == 3: yield ops.CCX(*g) elif len(g) == 2: yield ops.CNOT(*g) else: half_borrowed_gate = CnUHalfBorrowedGate(register_size=len(g)) yield half_borrowed_gate(*g, *find_dirty(groups, g))
def _decompose_(self, qubits): qubits = list(qubits) if len(qubits) == 2: yield ops.CNOT(*qubits) elif len(qubits) == 1: yield ops.X(*qubits) elif len(qubits) == 3: yield ops.CCX(*qubits) else: yield self._startdecompose(qubits)
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)
def test_depolarizer_multiple_realizations(): q1 = ops.QubitId() q2 = ops.QubitId() cnot = Job(circuits.Circuit([ circuits.Moment([ops.CNOT(q1, q2)]), ])) allerrors3 = DepolarizerChannel(probability=1.0, realizations=3) p0 = Symbol(DepolarizerChannel._parameter_name + '0') p1 = Symbol(DepolarizerChannel._parameter_name + '1') error_sweep = (Points(p0.name, [1.0, 1.0, 1.0]) + Points(p1.name, [1.0, 1.0, 1.0])) cnot_then_z3 = Job( circuits.Circuit([ circuits.Moment([ops.CNOT(q1, q2)]), circuits.Moment([ xmon_gates.ExpZGate(half_turns=p0).on(q1), xmon_gates.ExpZGate(half_turns=p1).on(q2) ]) ]), cnot.sweep * error_sweep) assert allerrors3.transform_job(cnot) == cnot_then_z3
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)))