def __init__( self, num_qubits: Optional[int] = None, reps: int = 3, seed: Optional[int] = None, insert_barriers: bool = False, ): from qiskit.circuit.library import RYGate # pylint: disable=cyclic-import # store a random number generator self._seed = seed self._rng = np.random.default_rng(seed) # store a dict to keep track of the random gates self._gates = dict() super().__init__( num_qubits, reps=reps, entanglement_blocks="cz", entanglement="pairwise", insert_barriers=insert_barriers, ) # set the initial layer self._prepended_blocks = [RYGate(np.pi / 4)] self._prepended_entanglement = ["linear"]
def test_calibrations_basis_gates(self): """Check if the calibrations for basis gates provided are added correctly.""" circ = QuantumCircuit(2) with pulse.build() as q0_x180: pulse.play(pulse.library.Gaussian(20, 1.0, 3.0), pulse.DriveChannel(0)) with pulse.build() as q1_y90: pulse.play(pulse.library.Gaussian(20, -1.0, 3.0), pulse.DriveChannel(1)) # Add calibration circ.add_calibration(RXGate(3.14), [0], q0_x180) circ.add_calibration(RYGate(1.57), [1], q1_y90) self.assertEqual(set(circ.calibrations.keys()), {"rx", "ry"}) self.assertEqual(set(circ.calibrations["rx"].keys()), {((0, ), (3.14, ))}) self.assertEqual(set(circ.calibrations["ry"].keys()), {((1, ), (1.57, ))}) self.assertEqual( circ.calibrations["rx"][((0, ), (3.14, ))].instructions, q0_x180.instructions) self.assertEqual( circ.calibrations["ry"][((1, ), (1.57, ))].instructions, q1_y90.instructions)
def test_get_instructions_for_qargs(self): with self.assertRaises(KeyError): self.empty_target.operations_for_qargs((0, )) expected = [RZGate(self.theta), IGate(), SXGate(), XGate(), Measure()] res = self.ibm_target.operations_for_qargs((0, )) for gate in expected: self.assertIn(gate, res) expected = [ECRGate()] res = self.fake_backend_target.operations_for_qargs((1, 0)) for gate in expected: self.assertIn(gate, res) expected = [CXGate()] res = self.fake_backend_target.operations_for_qargs((0, 1)) self.assertEqual(expected, res) ideal_sim_expected = [ UGate(self.theta, self.phi, self.lam), RXGate(self.theta), RYGate(self.theta), RZGate(self.theta), CXGate(), ECRGate(), CCXGate(), Measure(), ] for gate in ideal_sim_expected: self.assertIn(gate, self.ideal_sim_target.operations_for_qargs(None))
def exp_i(self) -> OperatorBase: """ Return a ``CircuitOp`` equivalent to e^-iH for this operator H. """ # if only one qubit is significant, we can perform the evolution corrected_x = self.primitive.x[::-1] # type: ignore corrected_z = self.primitive.z[::-1] # type: ignore # pylint: disable=import-outside-toplevel,no-member sig_qubits = np.logical_or(corrected_x, corrected_z) if np.sum(sig_qubits) == 0: # e^I is just a global phase, but we can keep track of it! Should we? # For now, just return identity return PauliOp(self.primitive) if np.sum(sig_qubits) == 1: sig_qubit_index = sig_qubits.tolist().index(True) coeff = np.real(self.coeff) \ if not isinstance(self.coeff, ParameterExpression) \ else self.coeff # Y rotation if corrected_x[sig_qubit_index] and corrected_z[sig_qubit_index]: rot_op = PrimitiveOp(RYGate(coeff)) # Z rotation elif corrected_z[sig_qubit_index]: rot_op = PrimitiveOp(RZGate(coeff)) # X rotation elif corrected_x[sig_qubit_index]: rot_op = PrimitiveOp(RXGate(coeff)) from ..operator_globals import I left_pad = I.tensorpower(sig_qubit_index) right_pad = I.tensorpower(self.num_qubits - sig_qubit_index - 1) # Need to use overloaded operators here in case left_pad == I^0 return left_pad ^ rot_op ^ right_pad else: from ..evolutions.evolved_op import EvolvedOp return EvolvedOp(self)
def test_operations(self): self.assertEqual(self.empty_target.operations, []) ibm_expected = [ RZGate(self.theta), IGate(), SXGate(), XGate(), CXGate(), Measure() ] for gate in ibm_expected: self.assertIn(gate, self.ibm_target.operations) aqt_expected = [ RZGate(self.theta), RXGate(self.theta), RYGate(self.theta), RGate(self.theta, self.phi), RXXGate(self.theta), ] for gate in aqt_expected: self.assertIn(gate, self.aqt_target.operations) fake_expected = [ UGate(self.fake_backend._theta, self.fake_backend._phi, self.fake_backend._lam), CXGate(), Measure(), ECRGate(), RXGate(math.pi / 6), RXGate(self.fake_backend._theta), ] for gate in fake_expected: self.assertIn(gate, self.fake_backend_target.operations) ideal_sim_expected = [ UGate(self.theta, self.phi, self.lam), RXGate(self.theta), RYGate(self.theta), RZGate(self.theta), CXGate(), ECRGate(), CCXGate(), Measure(), ] for gate in ideal_sim_expected: self.assertIn(gate, self.ideal_sim_target.operations)
def test_multi_controlled_y_rotation_matrix_basic_mode( self, num_controls, use_basis_gates): """Test the multi controlled Y rotation using the mode 'basic'. Based on the test moved here from Aqua: https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mcr.py """ # get the number of required ancilla qubits if num_controls <= 2: num_ancillas = 0 else: num_ancillas = num_controls - 2 q_controls = QuantumRegister(num_controls) q_target = QuantumRegister(1) for ctrl_state in range(2**num_controls): bitstr = bin(ctrl_state)[2:].zfill(num_controls)[::-1] theta = 0.871236 * pi if num_ancillas > 0: q_ancillas = QuantumRegister(num_ancillas) qc = QuantumCircuit(q_controls, q_target, q_ancillas) else: qc = QuantumCircuit(q_controls, q_target) q_ancillas = None for idx, bit in enumerate(bitstr): if bit == '0': qc.x(q_controls[idx]) qc.mcry(theta, q_controls, q_target[0], q_ancillas, mode='basic', use_basis_gates=use_basis_gates) for idx, bit in enumerate(bitstr): if bit == '0': qc.x(q_controls[idx]) rot_mat = RYGate(theta).to_matrix() backend = BasicAer.get_backend('unitary_simulator') simulated = execute(qc, backend).result().get_unitary(qc) if num_ancillas > 0: simulated = simulated[:2**(num_controls + 1), :2**(num_controls + 1)] expected = _compute_control_matrix(rot_mat, num_controls, ctrl_state=ctrl_state) with self.subTest(msg='control state = {}'.format(ctrl_state)): self.assertTrue(matrix_equal(simulated, expected))
def test_multi_controlled_rotation_gate_matrices(self, num_controls, base_gate_name, use_basis_gates): """Test the multi controlled rotation gates without ancillas. Based on the test moved here from Aqua: https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mcr.py """ q_controls = QuantumRegister(num_controls) q_target = QuantumRegister(1) # iterate over all possible combinations of control qubits for ctrl_state in range(2**num_controls): bitstr = bin(ctrl_state)[2:].zfill(num_controls)[::-1] theta = 0.871236 * pi qc = QuantumCircuit(q_controls, q_target) for idx, bit in enumerate(bitstr): if bit == '0': qc.x(q_controls[idx]) # call mcrx/mcry/mcrz if base_gate_name == 'y': qc.mcry(theta, q_controls, q_target[0], None, mode='noancilla', use_basis_gates=use_basis_gates) else: # case 'x' or 'z' only support the noancilla mode and do not have this keyword getattr(qc, 'mcr' + base_gate_name)( theta, q_controls, q_target[0], use_basis_gates=use_basis_gates) for idx, bit in enumerate(bitstr): if bit == '0': qc.x(q_controls[idx]) backend = BasicAer.get_backend('unitary_simulator') simulated = execute(qc, backend).result().get_unitary(qc) if base_gate_name == 'x': rot_mat = RXGate(theta).to_matrix() elif base_gate_name == 'y': rot_mat = RYGate(theta).to_matrix() else: # case 'z' rot_mat = U1Gate(theta).to_matrix() expected = _compute_control_matrix(rot_mat, num_controls, ctrl_state=ctrl_state) with self.subTest(msg='control state = {}'.format(ctrl_state)): self.assertTrue(matrix_equal(simulated, expected))
def ry_matrix(phi: float) -> np.ndarray: """ Computes an RY rotation by the angle of ``phi``. Args: phi: rotation angle. Returns: an RY rotation matrix. """ return RYGate(phi).to_matrix()
def gate_to_qiskit(gate2): if gate2.name == 'X': return XGate() elif gate2.name == 'Ry': return RYGate(-gate2.arg) elif gate2.name == 'Rz': return RZGate(-gate2.arg) elif gate2.name == 'R1': return U1Gate(gate2.arg) else: raise RuntimeError("Can't implement: %s" % gate2)
def test_hadamard_to_rot_gates(self): """Test a transpilation from H to Rx, Ry gates""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) qc.h(0) expected = QuantumCircuit(qr, global_phase=np.pi / 2) expected.append(RYGate(theta=np.pi / 2), [0]) expected.append(RXGate(theta=np.pi), [0]) circuit = transpile(qc, basis_gates=['rx', 'ry'], optimization_level=0) self.assertEqual(circuit, expected)
class TestParameterCtrlState(QiskitTestCase): """Test gate equality with ctrl_state parameter.""" @data((RXGate(0.5), CRXGate(0.5)), (RYGate(0.5), CRYGate(0.5)), (RZGate(0.5), CRZGate(0.5)), (XGate(), CXGate()), (YGate(), CYGate()), (ZGate(), CZGate()), (U1Gate(0.5), CU1Gate(0.5)), (SwapGate(), CSwapGate()), (HGate(), CHGate()), (U3Gate(0.1, 0.2, 0.3), CU3Gate(0.1, 0.2, 0.3))) @unpack def test_ctrl_state_one(self, gate, controlled_gate): """Test controlled gates with ctrl_state See https://github.com/Qiskit/qiskit-terra/pull/4025 """ self.assertEqual(gate.control(1, ctrl_state='1'), controlled_gate)
def test_instructions(self): self.assertEqual(self.empty_target.instructions, []) ibm_expected = [ (IGate(), (0, )), (IGate(), (1, )), (IGate(), (2, )), (IGate(), (3, )), (IGate(), (4, )), (RZGate(self.theta), (0, )), (RZGate(self.theta), (1, )), (RZGate(self.theta), (2, )), (RZGate(self.theta), (3, )), (RZGate(self.theta), (4, )), (SXGate(), (0, )), (SXGate(), (1, )), (SXGate(), (2, )), (SXGate(), (3, )), (SXGate(), (4, )), (XGate(), (0, )), (XGate(), (1, )), (XGate(), (2, )), (XGate(), (3, )), (XGate(), (4, )), (CXGate(), (3, 4)), (CXGate(), (4, 3)), (CXGate(), (3, 1)), (CXGate(), (1, 3)), (CXGate(), (1, 2)), (CXGate(), (2, 1)), (CXGate(), (0, 1)), (CXGate(), (1, 0)), (Measure(), (0, )), (Measure(), (1, )), (Measure(), (2, )), (Measure(), (3, )), (Measure(), (4, )), ] self.assertEqual(ibm_expected, self.ibm_target.instructions) ideal_sim_expected = [ (UGate(self.theta, self.phi, self.lam), None), (RXGate(self.theta), None), (RYGate(self.theta), None), (RZGate(self.theta), None), (CXGate(), None), (ECRGate(), None), (CCXGate(), None), (Measure(), None), ] self.assertEqual(ideal_sim_expected, self.ideal_sim_target.instructions)
def test_instruction_schedule_map_ideal_sim_backend(self): ideal_sim_target = Target(num_qubits=3) theta = Parameter("theta") phi = Parameter("phi") lam = Parameter("lambda") for inst in [ UGate(theta, phi, lam), RXGate(theta), RYGate(theta), RZGate(theta), CXGate(), ECRGate(), CCXGate(), Measure(), ]: ideal_sim_target.add_instruction(inst, {None: None}) inst_map = ideal_sim_target.instruction_schedule_map() self.assertEqual(InstructionScheduleMap(), inst_map)
def _define(self): # The y angle matrix stands for the absolute value, while the z angles stand for phases # The difficulty lies in the "global" phases that must be later accounted for in each subspace y_angle_matrix = self._to_angle_matrix_y() z_angle_matrix, global_phases = self._to_angle_matrix_z() # As the subspace phase correction is a very expensive module, we only want to do it if the # z rotation matrix is non-zero! no_z_rotations = abs(sparse.linalg.norm(z_angle_matrix)) < 1e-6 control = QuantumRegister(self.num_controls_qb, "q^c") target = QuantumRegister(self.num_targets_qb, "q^t") qc_y = QuantumCircuit(control, target, name=self.name) qc_z = QuantumCircuit(control, target, name=self.name) for l in range(1, self.num_targets_qb + 1): qargs = list(control) + target[0:l] # If there are no z-rotations we save a lot of gates, so we want to rule that out if not no_z_rotations: angles_z: sparse.spmatrix = z_angle_matrix[range(ControlledStatePreparationGate._chi(l) - 1, ControlledStatePreparationGate._chi(l + 1) - 1), :] angles_z = angles_z.reshape(-1, 1) gate_z = UniformRotationGate(gate=lambda a: RZGate(a), alpha=angles_z.todok()) qc_z.append(gate_z, qargs) qc_z.barrier() # The uniform rotation for the y rotation will take care of the absolute value angles_y: sparse.spmatrix = y_angle_matrix[range(ControlledStatePreparationGate._chi(l) - 1, ControlledStatePreparationGate._chi(l + 1) - 1), :] angles_y = angles_y.reshape(-1, 1) gate_y = UniformRotationGate(gate=lambda a: RYGate(a), alpha=angles_y.todok()) qc_y.append(gate_y, qargs) qc_y.barrier() if not no_z_rotations: # A relative phase correction is pretty intensive: a state preparation on the control global_phase_correction = MöttönenStatePreparationGate( sparse.dok_matrix(np.exp(1.0j * global_phases.T.toarray())), neglect_absolute_value=True ) qc_z.append(global_phase_correction, qargs=control) qc_z.barrier() qc = qc_y + qc_z self._definition = qc
def add_cnry( param: float, qbits: List[int], qr: QuantumRegister, circuits: List[Union[Circuit, QuantumCircuit]], ) -> None: """Add a CnRy gate to each circuit in a list, each one being either a tket or qiskit circuit.""" assert len(qbits) >= 2 for circ in circuits: if isinstance(circ, Circuit): circ.add_gate(OpType.CnRy, param, qbits) else: # param was "raw", so needs an extra PI. new_ry_gate = RYGate(param * pi) new_gate = MCMT(gate=new_ry_gate, num_ctrl_qubits=len(qbits) - 1, num_target_qubits=1) circ.append(new_gate, [qr[nn] for nn in qbits])
def setUp(self): super().setUp() self.fake_backend = FakeBackendV2() self.fake_backend_target = self.fake_backend.target self.theta = Parameter("theta") self.phi = Parameter("phi") self.ibm_target = Target() i_props = { (0, ): InstructionProperties(duration=35.5e-9, error=0.000413), (1, ): InstructionProperties(duration=35.5e-9, error=0.000502), (2, ): InstructionProperties(duration=35.5e-9, error=0.0004003), (3, ): InstructionProperties(duration=35.5e-9, error=0.000614), (4, ): InstructionProperties(duration=35.5e-9, error=0.006149), } self.ibm_target.add_instruction(IGate(), i_props) rz_props = { (0, ): InstructionProperties(duration=0, error=0), (1, ): InstructionProperties(duration=0, error=0), (2, ): InstructionProperties(duration=0, error=0), (3, ): InstructionProperties(duration=0, error=0), (4, ): InstructionProperties(duration=0, error=0), } self.ibm_target.add_instruction(RZGate(self.theta), rz_props) sx_props = { (0, ): InstructionProperties(duration=35.5e-9, error=0.000413), (1, ): InstructionProperties(duration=35.5e-9, error=0.000502), (2, ): InstructionProperties(duration=35.5e-9, error=0.0004003), (3, ): InstructionProperties(duration=35.5e-9, error=0.000614), (4, ): InstructionProperties(duration=35.5e-9, error=0.006149), } self.ibm_target.add_instruction(SXGate(), sx_props) x_props = { (0, ): InstructionProperties(duration=35.5e-9, error=0.000413), (1, ): InstructionProperties(duration=35.5e-9, error=0.000502), (2, ): InstructionProperties(duration=35.5e-9, error=0.0004003), (3, ): InstructionProperties(duration=35.5e-9, error=0.000614), (4, ): InstructionProperties(duration=35.5e-9, error=0.006149), } self.ibm_target.add_instruction(XGate(), x_props) cx_props = { (3, 4): InstructionProperties(duration=270.22e-9, error=0.00713), (4, 3): InstructionProperties(duration=305.77e-9, error=0.00713), (3, 1): InstructionProperties(duration=462.22e-9, error=0.00929), (1, 3): InstructionProperties(duration=497.77e-9, error=0.00929), (1, 2): InstructionProperties(duration=227.55e-9, error=0.00659), (2, 1): InstructionProperties(duration=263.11e-9, error=0.00659), (0, 1): InstructionProperties(duration=519.11e-9, error=0.01201), (1, 0): InstructionProperties(duration=554.66e-9, error=0.01201), } self.ibm_target.add_instruction(CXGate(), cx_props) measure_props = { (0, ): InstructionProperties(duration=5.813e-6, error=0.0751), (1, ): InstructionProperties(duration=5.813e-6, error=0.0225), (2, ): InstructionProperties(duration=5.813e-6, error=0.0146), (3, ): InstructionProperties(duration=5.813e-6, error=0.0215), (4, ): InstructionProperties(duration=5.813e-6, error=0.0333), } self.ibm_target.add_instruction(Measure(), measure_props) self.aqt_target = Target(description="AQT Target") rx_props = { (0, ): None, (1, ): None, (2, ): None, (3, ): None, (4, ): None, } self.aqt_target.add_instruction(RXGate(self.theta), rx_props) ry_props = { (0, ): None, (1, ): None, (2, ): None, (3, ): None, (4, ): None, } self.aqt_target.add_instruction(RYGate(self.theta), ry_props) rz_props = { (0, ): None, (1, ): None, (2, ): None, (3, ): None, (4, ): None, } self.aqt_target.add_instruction(RZGate(self.theta), rz_props) r_props = { (0, ): None, (1, ): None, (2, ): None, (3, ): None, (4, ): None, } self.aqt_target.add_instruction(RGate(self.theta, self.phi), r_props) rxx_props = { (0, 1): None, (0, 2): None, (0, 3): None, (0, 4): None, (1, 0): None, (2, 0): None, (3, 0): None, (4, 0): None, (1, 2): None, (1, 3): None, (1, 4): None, (2, 1): None, (3, 1): None, (4, 1): None, (2, 3): None, (2, 4): None, (3, 2): None, (4, 2): None, (3, 4): None, (4, 3): None, } self.aqt_target.add_instruction(RXXGate(self.theta), rxx_props) measure_props = { (0, ): None, (1, ): None, (2, ): None, (3, ): None, (4, ): None, } self.aqt_target.add_instruction(Measure(), measure_props) self.empty_target = Target() self.ideal_sim_target = Target(num_qubits=3, description="Ideal Simulator") self.lam = Parameter("lam") for inst in [ UGate(self.theta, self.phi, self.lam), RXGate(self.theta), RYGate(self.theta), RZGate(self.theta), CXGate(), ECRGate(), CCXGate(), Measure(), ]: self.ideal_sim_target.add_instruction(inst, {None: None})
from qiskit.circuit.library import HGate, XGate, YGate, ZGate, CXGate, CYGate, CZGate, CHGate from qiskit.circuit.library import SwapGate, IGate, SGate, TGate, TdgGate, SdgGate, RYGate from qiskit import QuantumCircuit, Aer, execute, QuantumRegister, ClassicalRegister import numpy as np SINGLE_GATE_DICT = { 'I' : IGate(), 'H' : HGate(), 'X' : XGate(), 'Y' : YGate(), 'Z' : ZGate(), 'S' : SGate(), 'T' : TGate(), 'T_dg' : TdgGate(), 'S_dg' : SdgGate(), 'Ry' : RYGate(np.pi / 4) } CONTROLLED_GATE_DICT = { 'CX0' : CXGate(), 'CX1' : CXGate(), 'CY0' : CYGate(), 'CY1' : CYGate(), 'CZ0' : CZGate(), 'CZ1' : CYGate(), 'CH0' : CHGate(), 'CH1' : CHGate() } def _state_to_gates(state):
def append_tk_command_to_qiskit( op: "Op", args: List["UnitID"], qcirc: QuantumCircuit, qregmap: Dict[str, QuantumRegister], cregmap: Dict[str, ClassicalRegister], symb_map: Dict[Parameter, sympy.Symbol], range_preds: Dict[Bit, Tuple[List["UnitID"], int]], ) -> Instruction: optype = op.type if optype == OpType.Measure: qubit = args[0] bit = args[1] qb = qregmap[qubit.reg_name][qubit.index[0]] b = cregmap[bit.reg_name][bit.index[0]] return qcirc.measure(qb, b) if optype == OpType.Reset: qb = qregmap[args[0].reg_name][args[0].index[0]] return qcirc.reset(qb) if optype in [ OpType.CircBox, OpType.ExpBox, OpType.PauliExpBox, OpType.Custom ]: subcircuit = op.get_circuit() subqc = tk_to_qiskit(subcircuit) qargs = [] cargs = [] for a in args: if a.type == UnitType.qubit: qargs.append(qregmap[a.reg_name][a.index[0]]) else: cargs.append(cregmap[a.reg_name][a.index[0]]) if optype == OpType.Custom: instruc = subqc.to_gate() instruc.name = op.get_name() else: instruc = subqc.to_instruction() return qcirc.append(instruc, qargs, cargs) if optype == OpType.Unitary2qBox: qargs = [qregmap[q.reg_name][q.index[0]] for q in args] u = op.get_matrix() g = UnitaryGate(u, label="u2q") return qcirc.append(g, qargs=qargs) if optype == OpType.Barrier: qargs = [qregmap[q.reg_name][q.index[0]] for q in args] g = Barrier(len(args)) return qcirc.append(g, qargs=qargs) if optype == OpType.RangePredicate: if op.lower != op.upper: raise NotImplementedError range_preds[args[-1]] = (args[:-1], op.lower) # attach predicate to bit, # subsequent conditional will handle it return Instruction("", 0, 0, []) if optype == OpType.ConditionalGate: if args[0] in range_preds: assert op.value == 1 condition_bits, value = range_preds[args[0]] del range_preds[args[0]] args = condition_bits + args[1:] width = len(condition_bits) else: width = op.width value = op.value regname = args[0].reg_name if len(cregmap[regname]) != width: raise NotImplementedError( "OpenQASM conditions must be an entire register") for i, a in enumerate(args[:width]): if a.reg_name != regname: raise NotImplementedError( "OpenQASM conditions can only use a single register") if a.index != [i]: raise NotImplementedError( "OpenQASM conditions must be an entire register in order") instruction = append_tk_command_to_qiskit(op.op, args[width:], qcirc, qregmap, cregmap, symb_map, range_preds) instruction.c_if(cregmap[regname], value) return instruction # normal gates qargs = [qregmap[q.reg_name][q.index[0]] for q in args] if optype == OpType.CnX: return qcirc.mcx(qargs[:-1], qargs[-1]) # special case if optype == OpType.CnRy: # might as well do a bit more checking assert len(op.params) == 1 alpha = param_to_qiskit(op.params[0], symb_map) assert len(qargs) >= 2 if len(qargs) == 2: # presumably more efficient; single control only new_gate = CRYGate(alpha) else: new_ry_gate = RYGate(alpha) new_gate = MCMT(gate=new_ry_gate, num_ctrl_qubits=len(qargs) - 1, num_target_qubits=1) qcirc.append(new_gate, qargs) return qcirc # others are direct translations try: gatetype = _known_qiskit_gate_rev[optype] except KeyError as error: raise NotImplementedError("Cannot convert tket Op to Qiskit gate: " + op.get_name()) from error params = [param_to_qiskit(p, symb_map) for p in op.params] g = gatetype(*params) return qcirc.append(g, qargs=qargs)
def test_controlled_ry(self): """Test the creation of a controlled RY gate.""" theta = 0.5 self.assertEqual(RYGate(theta).control(), CRYGate(theta))
from math import sqrt, cos, sin, pi # The unitary matrices of Alice and Bob's possible operations. U_X = [[0, 1], [1, 0]] # identity I U_H = [[1 / sqrt(2), 1 / sqrt(2)], [1 / sqrt(2), -1 / sqrt(2)]] U_alice_0 = [[1, 0], [0, 1]] # identity I U_alice_1 = [[cos(pi / 4), sin(pi / 4)], [-sin(pi / 4), cos(pi / 4)]] U_bob_0 = [[cos(pi / 8), sin(pi / 8)], [-sin(pi / 8), cos(pi / 8)]] U_bob_1 = [[cos(3 * pi / 8), sin(3 * pi / 8)], [-sin(3 * pi / 8), cos(3 * pi / 8)]] U_alice_1 = RYGate(-67.5 * np.pi / 180).to_matrix() U_bob_0 = [[1, 0], [0, 1]] U_bob_1 = [[1, 0], [0, 1]] # Alice and Bob win when their input (a, b) # and their response (s, t) satisfy this relationship. def win(a, b, s, t): return (a and b) == (s != t) wins = 0 # generate "questions" in equal number a = [] b = []