def cnot_rxx_decompose(plus_ry=True, plus_rxx=True): """Decomposition of CNOT gate. NOTE: this differs to CNOT by a global phase. The matrix returned is given by exp(1j * pi/4) * CNOT Args: plus_ry (bool): positive initial RY rotation plus_rxx (bool): positive RXX rotation. Returns: QuantumCircuit: The decomposed circuit for CNOT gate (up to global phase). """ # Convert boolean args to +/- 1 signs if plus_ry: sgn_ry = 1 else: sgn_ry = -1 if plus_rxx: sgn_rxx = 1 else: sgn_rxx = -1 circuit = QuantumCircuit(2) circuit.append(RYGate(sgn_ry * np.pi / 2), [0]) circuit.append(RXXGate(sgn_rxx * np.pi / 2), [0, 1]) circuit.append(RXGate(-sgn_rxx * np.pi / 2), [0]) circuit.append(RXGate(-sgn_rxx * sgn_ry * np.pi / 2), [1]) circuit.append(RYGate(-sgn_ry * np.pi / 2), [0]) return circuit
def test_get_variables(self): """Test instantiating gate with variable parmeters""" from qiskit.extensions.standard.rx import RXGate theta = sympy.Symbol('θ') qr = QuantumRegister(1) qc = QuantumCircuit(qr) rxg = RXGate(theta) qc.append(rxg, [qr[0]], []) vparams = qc.variable_table self.assertIs(theta, next(iter(vparams))) self.assertIs(rxg, next(iter(next(iter(vparams[theta])))))
def test_get_parameters(self): """Test instantiating gate with variable parmeters""" from qiskit.extensions.standard.rx import RXGate theta = Parameter('θ') qr = QuantumRegister(1) qc = QuantumCircuit(qr) rxg = RXGate(theta) qc.append(rxg, [qr[0]], []) vparams = qc._parameter_table self.assertEqual(len(vparams), 1) self.assertIs(theta, next(iter(vparams))) self.assertIs(rxg, vparams[theta][0][0])
def _define(self): """Calculate a subcircuit that implements this unitary.""" from qiskit.extensions.standard.x import CXGate from qiskit.extensions.standard.rx import RXGate from qiskit.extensions.standard.rz import RZGate definition = [] q = QuantumRegister(2, 'q') theta = self.params[0] rule = [ (RXGate(np.pi / 2), [q[0]], []), (RXGate(np.pi / 2), [q[1]], []), (CXGate(), [q[0], q[1]], []), (RZGate(theta), [q[1]], []), (CXGate(), [q[0], q[1]], []), (RXGate(-np.pi / 2), [q[0]], []), (RXGate(-np.pi / 2), [q[1]], []), ] for inst in rule: definition.append(inst) self.definition = definition
def _define(self): """ gate cz a,b { h b; cx a,b; h b; } """ theta, phi, lam = self.params definition = [] q = QuantumRegister(1, "q") rule = [(RZGate(theta), [q[0]], []), (RXGate(phi), [q[0]], []), (RZGate(lam), [q[0]], [])] for inst in rule: definition.append(inst) self.definition = definition
def test_is_parameterized(self): """Test checking if a gate is parameterized (bound/unbound)""" from qiskit.extensions.standard.h import HGate from qiskit.extensions.standard.rx import RXGate theta = Parameter('θ') rxg = RXGate(theta) self.assertTrue(rxg.is_parameterized()) theta_bound = theta.bind({theta: 3.14}) rxg = RXGate(theta_bound) self.assertFalse(rxg.is_parameterized()) h_gate = HGate() self.assertFalse(h_gate.is_parameterized())
def create_dag_op(self, name, args, qubits): """Create a DAG op node. """ if name == "u0": op = U0Gate(args[0], qubits[0]) elif name == "u1": op = U1Gate(args[0], qubits[0]) elif name == "u2": op = U2Gate(args[0], args[1], qubits[0]) elif name == "u3": op = U3Gate(args[0], args[1], args[2], qubits[0]) elif name == "x": op = XGate(qubits[0]) elif name == "y": op = YGate(qubits[0]) elif name == "z": op = ZGate(qubits[0]) elif name == "t": op = TGate(qubits[0]) elif name == "tdg": op = TdgGate(qubits[0]) elif name == "s": op = SGate(qubits[0]) elif name == "sdg": op = SdgGate(qubits[0]) elif name == "swap": op = SwapGate(qubits[0], qubits[1]) elif name == "rx": op = RXGate(args[0], qubits[0]) elif name == "ry": op = RYGate(args[0], qubits[0]) elif name == "rz": op = RZGate(args[0], qubits[0]) elif name == "rzz": op = RZZGate(args[0], qubits[0], qubits[1]) elif name == "id": op = IdGate(qubits[0]) elif name == "h": op = HGate(qubits[0]) elif name == "cx": op = CnotGate(qubits[0], qubits[1]) elif name == "cy": op = CyGate(qubits[0], qubits[1]) elif name == "cz": op = CzGate(qubits[0], qubits[1]) elif name == "ch": op = CHGate(qubits[0], qubits[1]) elif name == "crz": op = CrzGate(args[0], qubits[0], qubits[1]) elif name == "cu1": op = Cu1Gate(args[0], qubits[0], qubits[1]) elif name == "cu3": op = Cu3Gate(args[0], args[1], args[2], qubits[0], qubits[1]) elif name == "ccx": op = ToffoliGate(qubits[0], qubits[1], qubits[2]) elif name == "cswap": op = FredkinGate(qubits[0], qubits[1], qubits[2]) else: raise BackendError("unknown operation for name ast node name %s" % name) self.circuit.add_basis_element(op.name, len(op.qargs), len(op.cargs), len(op.param)) self.start_gate(op) self.end_gate(op)
def _RX_adj_ctl(control: Union[AllOneControl, Qubits], angle: float, q: Qubits): _multiplexed_control(RXGate(angle).inverse(), control, q)
def _RX_adj(theta: float, q: Qubits): bp.__ALLOCATIONS__[-1].circuit.append(RXGate(theta).inverse(), [q.qiskit_qubits])
def run(self, dag): """Run the CommutativeCancellation pass on a dag Args: dag (DAGCircuit): the DAG to be optimized. Returns: DAGCircuit: the optimized DAG. Raises: TranspilerError: when the 1 qubit rotation gates are not found """ # Now the gates supported are hard-coded q_gate_list = ['cx', 'cy', 'cz', 'h', 'y'] # Gate sets to be cancelled cancellation_sets = defaultdict(lambda: []) # Traverse each qubit to generate the cancel dictionaries # Cancel dictionaries: # - For 1 qubit gates the key is (gate_type, qubit_id, commutation_set_id), # the value is the list of gates that share the same gate type, qubit, commutation set. # - For 2qbit gates the key: (gate_type, first_qbit, sec_qbit, first commutation_set_id, # sec_commutation_set_id), the value is the list gates that share the same gate type, # qubits and commutation sets. for wire in dag.wires: wire_name = "{0}[{1}]".format(str(wire.register.name), str(wire.index)) wire_commutation_set = self.property_set['commutation_set'][ wire_name] for com_set_idx, com_set in enumerate(wire_commutation_set): if com_set[0].type in ['in', 'out']: continue for node in com_set: num_qargs = len(node.qargs) if num_qargs == 1 and node.name in q_gate_list: cancellation_sets[(node.name, wire_name, com_set_idx)].append(node) if num_qargs == 1 and node.name in [ 'z', 'u1', 'rz', 't', 's' ]: cancellation_sets[('z_rotation', wire_name, com_set_idx)].append(node) if num_qargs == 1 and node.name in ['rx', 'x']: cancellation_sets[('x_rotation', wire_name, com_set_idx)].append(node) # Doen't deal with Y rotaion, because Y rotation doesn't commute with CNOT, so # it should be dealt with by optimized1qgate pass elif num_qargs == 2 and node.qargs[0] == wire: second_op_name = "{0}[{1}]".format( str(node.qargs[1].register.name), str(node.qargs[1].index)) q2_key = (node.name, wire_name, second_op_name, com_set_idx, self.property_set['commutation_set'][( node, second_op_name)]) cancellation_sets[q2_key].append(node) for cancel_set_key in cancellation_sets: set_len = len(cancellation_sets[cancel_set_key]) if ((set_len) > 1 and cancel_set_key[0] in q_gate_list): gates_to_cancel = cancellation_sets[cancel_set_key] for c_node in gates_to_cancel[:(set_len // 2) * 2]: dag.remove_op_node(c_node) elif ((set_len) > 1 and cancel_set_key[0] in ['z_rotation', 'x_rotation']): run = cancellation_sets[cancel_set_key] run_qarg = run[0].qargs[0] total_angle = 0.0 # lambda for current_node in run: if (current_node.condition is not None or len(current_node.qargs) != 1 or current_node.qargs[0] != run_qarg): raise TranspilerError("internal error") if current_node.name in ['u1', 'rz', 'rx']: current_angle = float(current_node.op.params[0]) elif current_node.name in ['z', 'x']: current_angle = np.pi elif current_node.name == 't': current_angle = np.pi / 4 elif current_node.name == 's': current_angle = np.pi / 2 # Compose gates total_angle = current_angle + total_angle # Replace the data of the first node in the run if cancel_set_key[0] == 'z_rotation': new_op = U1Gate(total_angle) elif cancel_set_key[0] == 'x_rotation': new_op = RXGate(total_angle) if np.mod(total_angle, (2 * np.pi)) > _CUTOFF_PRECISION: new_qarg = QuantumRegister(1, 'q') new_dag = DAGCircuit() new_dag.add_qreg(new_qarg) new_dag.apply_operation_back(new_op, [new_qarg[0]]) dag.substitute_node_with_dag(run[0], new_dag) # Delete the other nodes in the run for current_node in run[1:]: dag.remove_op_node(current_node) if np.mod(total_angle, (2 * np.pi)) < _CUTOFF_PRECISION: dag.remove_op_node(run[0]) return dag
composite_gate_2 = CompositeGate("composite2", [], [quantum_r[x] for x in range(4)]) composite_gate_2._attach(CnotGate(quantum_r[0], quantum_r[1])) circuit._attach(composite_gate_2) circuit.cx(quantum_r[0], quantum_r[1]) circuit.h(quantum_r[0]) composite_gate_3 = CompositeGate("composite3", [], [quantum_r[x] for x in range(4)]) composite_gate_3._attach(CnotGate(quantum_r[0], quantum_r[1])) composite_gate_3._attach(CnotGate(quantum_r[0], quantum_r[2])) circuit._attach(composite_gate_3) circuit.h(quantum_r[0]) composite_gate_4 = CompositeGate("composite4", [], [quantum_r[x] for x in range(4)]) composite_gate_4._attach(CnotGate(quantum_r[0], quantum_r[1])) composite_gate_4._attach(RXGate(0, quantum_r[0])) composite_gate_4._attach(CnotGate(quantum_r[0], quantum_r[1])) circuit._attach(composite_gate_4) print("Removed Zero Rotations: " + str(circuit.remove_zero_rotations())) print("Removed Double CNOTs: " + str(circuit.remove_double_cnots_once())) QASM_source = circuit.qasm() print(QASM_source)