def _reverse_echo_rzx_dag(theta): """Return the following circuit .. parsed-literal:: ┌───┐┌───────────────┐ ┌────────────────┐┌───┐ q_0: ┤ H ├┤1 ├─────┤1 ├┤ H ├───── ├───┤│ Rzx(theta/2) │┌───┐│ Rzx(-theta/2) │├───┤┌───┐ q_1: ┤ H ├┤0 ├┤ X ├┤0 ├┤ X ├┤ H ├ └───┘└───────────────┘└───┘└────────────────┘└───┘└───┘ """ reverse_rzx_dag = DAGCircuit() qr = QuantumRegister(2) reverse_rzx_dag.add_qreg(qr) reverse_rzx_dag.apply_operation_back(HGate(), [qr[0]], []) reverse_rzx_dag.apply_operation_back(HGate(), [qr[1]], []) reverse_rzx_dag.apply_operation_back(RZXGate(theta / 2), [qr[1], qr[0]], []) reverse_rzx_dag.apply_operation_back(XGate(), [qr[1]], []) reverse_rzx_dag.apply_operation_back(RZXGate(-theta / 2), [qr[1], qr[0]], []) reverse_rzx_dag.apply_operation_back(XGate(), [qr[1]], []) reverse_rzx_dag.apply_operation_back(HGate(), [qr[0]], []) reverse_rzx_dag.apply_operation_back(HGate(), [qr[1]], []) return reverse_rzx_dag
def _define_decompositions(self): """ gate cu1(lambda) a,b { u1(lambda/2) a; cx a,b; u1(-lambda/2) b; cx a,b; u1(lambda/2) b; } """ decomposition = DAGCircuit() q = QuantumRegister(2, "q") decomposition.add_qreg(q) decomposition.add_basis_element("u1", 1, 0, 1) decomposition.add_basis_element("cx", 2, 0, 0) rule = [ U1Gate(self.param[0] / 2, q[0]), CnotGate(q[0], q[1]), U1Gate(-self.param[0] / 2, q[1]), CnotGate(q[0], q[1]), U1Gate(self.param[0] / 2, q[1]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def test_two_qubit_natural_direction_true_duration_fallback(self): """Verify not attempting pulse optimal decomposition when pulse_optimize==False.""" # this assumes iswawp pulse optimal decomposition doesn't exist backend = FakeVigo() conf = backend.configuration() # conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates] qr = QuantumRegister(2) coupling_map = CouplingMap([[0, 1], [1, 0], [1, 2], [1, 3], [3, 4]]) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=True, natural_direction=True, ) pm = PassManager([triv_layout_pass, unisynth_pass]) qc_out = pm.run(qc) self.assertTrue( all(([qr[0], qr[1]] == qlist for _, qlist, _ in qc_out.get_instructions("cx"))))
def test_two_qubit_pulse_optimal_true_raises(self): """Verify raises if pulse optimal==True but cx is not in the backend basis.""" backend = FakeVigo() conf = backend.configuration() # this assumes iswawp pulse optimal decomposition doesn't exist conf.basis_gates = [ gate if gate != "cx" else "iswap" for gate in conf.basis_gates ] qr = QuantumRegister(2) coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=True, natural_direction=True, ) pm = PassManager([triv_layout_pass, unisynth_pass]) with self.assertRaises(QiskitError): pm.run(qc)
def test_layout_repr(self): """Layout repr reproduces layout""" qr = QuantumRegister(5, "qr") layout = Layout( { qr[0]: 2, qr[1]: 4, qr[2]: 3, qr[3]: 0, qr[4]: 1, } ) repr_layout = eval( # pylint: disable=eval-used layout.__repr__(), { "Qubit": Qubit, "QuantumRegister": QuantumRegister, "Layout": Layout, }, ) self.assertDictEqual(layout._p2v, repr_layout._p2v) self.assertDictEqual(layout._v2p, repr_layout._v2p)
def _gate_rules_to_qiskit_circuit(self, node, params): """From a gate definition in qasm, to a QuantumCircuit format.""" rules = [] qreg = QuantumRegister(node['n_bits']) bit_args = {node['bits'][i]: q for i, q in enumerate(qreg)} exp_args = {node['args'][i]: Real(q) for i, q in enumerate(params)} for child_op in node['body'].children: qparams = [] eparams = [] for param_list in child_op.children[1:]: if param_list.type == 'id_list': qparams = [ bit_args[param.name] for param in param_list.children ] elif param_list.type == 'expression_list': for param in param_list.children: eparams.append(param.sym(nested_scope=[exp_args])) op = self._create_op(child_op.name, params=eparams) rules.append((op, qparams, [])) circ = QuantumCircuit(qreg) circ._data = rules return circ
def test_measure_to_registers_when_conditionals(self): """Verify assemble_circuits maps all measure ops on to a register slot for a circuit containing conditionals.""" qr = QuantumRegister(2) cr1 = ClassicalRegister(1) cr2 = ClassicalRegister(2) qc = QuantumCircuit(qr, cr1, cr2) qc.measure(qr[0], cr1) # Measure not required for a later conditional qc.measure(qr[1], cr2[1]) # Measure required for a later conditional qc.h(qr[1]).c_if(cr2, 3) qobj = assemble(qc) first_measure, second_measure = [ op for op in qobj.experiments[0].instructions if op.name == 'measure' ] self.assertTrue(hasattr(first_measure, 'register')) self.assertEqual(first_measure.register, first_measure.memory) self.assertTrue(hasattr(second_measure, 'register')) self.assertEqual(second_measure.register, second_measure.memory)
def test_if_else_body_builder(self, method): backend = self.backend(method=method) qreg = QuantumRegister(4) creg = ClassicalRegister(1) circ = QuantumCircuit(qreg, creg) circ.h(circ.qubits[1:4]) circ.barrier() circ.measure(0, 0) with circ.if_test((creg, 1)) as else_: pass with else_: circ.h(circ.qubits[1:4]) circ.measure_all() result = backend.run(circ, method=method).result() self.assertSuccess(result) counts = result.get_counts() self.assertEqual(len(counts), 1) self.assertIn('0000 0', counts)
def _zero_reflection( num_state_qubits: int, qubits: List[int], mcx_mode: Optional[str] = None ) -> QuantumCircuit: qr_state = QuantumRegister(num_state_qubits, "state") reflection = QuantumCircuit(qr_state, name="S_0") num_ancillas = MCXGate.get_num_ancilla_qubits(len(qubits) - 1, mcx_mode) if num_ancillas > 0: qr_ancilla = AncillaRegister(num_ancillas, "ancilla") reflection.add_register(qr_ancilla) else: qr_ancilla = [] reflection.x(qubits) if len(qubits) == 1: reflection.z(0) # MCX does not allow 0 control qubits, therefore this is separate else: reflection.h(qubits[-1]) reflection.mcx(qubits[:-1], qubits[-1], qr_ancilla[:], mode=mcx_mode) reflection.h(qubits[-1]) reflection.x(qubits) return reflection
def test_resize_value_to_register(self): """Verify assemble_circuits converts the value provided on the classical creg to its mapped location on the device register.""" qr = QuantumRegister(1) cr1 = ClassicalRegister(2) cr2 = ClassicalRegister(2) cr3 = ClassicalRegister(1) qc = QuantumCircuit(qr, cr1, cr2, cr3) qc.h(qr[0]).c_if(cr2, 2) qobj = assemble(qc) validate_qobj_against_schema(qobj) bfunc_op, h_op = qobj.experiments[0].instructions self.assertEqual(bfunc_op.name, 'bfunc') self.assertEqual(bfunc_op.mask, '0xC') self.assertEqual(bfunc_op.val, '0x8') self.assertEqual(bfunc_op.relation, '==') self.assertTrue(hasattr(h_op, 'conditional')) self.assertEqual(bfunc_op.register, h_op.conditional)
def _define_from_label(self): q = QuantumRegister(self.num_qubits, "q") initialize_circuit = QuantumCircuit(q, name="init_def") for qubit, param in enumerate(reversed(self.params)): if param == "1": initialize_circuit.append(XGate(), [q[qubit]]) elif param == "+": initialize_circuit.append(HGate(), [q[qubit]]) elif param == "-": initialize_circuit.append(XGate(), [q[qubit]]) initialize_circuit.append(HGate(), [q[qubit]]) elif param == "r": # |+i> initialize_circuit.append(HGate(), [q[qubit]]) initialize_circuit.append(SGate(), [q[qubit]]) elif param == "l": # |-i> initialize_circuit.append(HGate(), [q[qubit]]) initialize_circuit.append(SdgGate(), [q[qubit]]) if self._inverse: initialize_circuit = initialize_circuit.inverse() return initialize_circuit
def test_substituting_node_preserves_args_condition(self, inplace): """Verify args and condition are preserved by a substitution.""" dag = DAGCircuit() qr = QuantumRegister(2) cr = ClassicalRegister(1) dag.add_qreg(qr) dag.add_creg(cr) dag.apply_operation_back(HGate(), [qr[1]]) node_to_be_replaced = dag.apply_operation_back(CXGate(), [qr[1], qr[0]], condition=(cr, 1)) dag.apply_operation_back(HGate(), [qr[1]]) replacement_node = dag.substitute_node(node_to_be_replaced, CZGate(), inplace=inplace) raise_if_dagcircuit_invalid(dag) self.assertEqual(replacement_node.name, 'cz') self.assertEqual(replacement_node.qargs, [qr[1], qr[0]]) self.assertEqual(replacement_node.cargs, []) self.assertEqual(replacement_node.condition, (cr, 1)) self.assertEqual(replacement_node is node_to_be_replaced, inplace)
def test_apply_ch_to_slice(self): """test applying ch to slice""" qr = QuantumRegister(10) cr = ClassicalRegister(10) # test slice qc = QuantumCircuit(qr, cr) ctl_slice = slice(0, 2) tgt_slice = slice(2, 4) qc.ch(qr[ctl_slice], qr[tgt_slice]) for (gate, qargs, _), ictrl, itgt in zip(qc.data, range(0, 2), range(2, 4)): self.assertEqual(gate.name, 'ch') self.assertEqual(len(qargs), 2) self.assertEqual(qargs[0].index, ictrl) self.assertEqual(qargs[1].index, itgt) # test single qubit args qc = QuantumCircuit(qr, cr) qc.ch(qr[0], qr[1]) self.assertEqual(len(qc.data), 1) op, qargs, _ = qc.data[0] self.assertEqual(op.name, 'ch') self.assertEqual(qargs[0].index, 0) self.assertEqual(qargs[1].index, 1)
def _build(self): num_state_qubits = self.oracle.num_qubits - self.oracle.num_ancillas self.add_register(QuantumRegister(num_state_qubits, name='state')) num_ancillas = numpy.max([self.oracle.num_ancillas, self.zero_reflection.num_ancillas, self.state_preparation.num_ancillas]) if num_ancillas > 0: self.add_register(AncillaRegister(num_ancillas, name='ancilla')) self.compose(self.oracle, list(range(self.oracle.num_qubits)), inplace=True) if self._insert_barriers: self.barrier() self.compose(self.state_preparation.inverse(), list(range(self.state_preparation.num_qubits)), inplace=True) if self._insert_barriers: self.barrier() self.compose(self.zero_reflection, list(range(self.zero_reflection.num_qubits)), inplace=True) if self._insert_barriers: self.barrier() self.compose(self.state_preparation, list(range(self.state_preparation.num_qubits)), inplace=True)
def test_parameterized_circuits(self, basis): """Parameters should be treated as opaque gates.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) theta = Parameter('theta') qc.p(0.3, qr) qc.p(0.4, qr) qc.p(theta, qr) qc.p(0.1, qr) qc.p(0.2, qr) qc.p(theta, qr) qc.p(0.3, qr) qc.p(0.2, qr) passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(qc) self.assertTrue( Operator(qc.bind_parameters({theta: 3.14})).equiv( Operator(result.bind_parameters({theta: 3.14}))))
def test_numpy_array_of_registers(self): """Test numpy array of Registers . See https://github.com/Qiskit/qiskit-terra/issues/1898 """ qrs = [QuantumRegister(2, name="q%s" % i) for i in range(5)] qreg_array = np.array([], dtype=object, ndmin=1) qreg_array = np.append(qreg_array, qrs) expected = [ qrs[0][0], qrs[0][1], qrs[1][0], qrs[1][1], qrs[2][0], qrs[2][1], qrs[3][0], qrs[3][1], qrs[4][0], qrs[4][1], ] self.assertEqual(len(qreg_array), 10) self.assertEqual(qreg_array.tolist(), expected)
def get_ghz_po( self, n: int, delta: float, ) -> Tuple[QuantumCircuit, Dict]: """ This function creates an Parity Oscillation circuit with n qubits, where the middle superposition rotation around the x and y axes is by delta Args: n: number of qubits delta: the middle superposition rotation Returns: The Parity Oscillation circuit and the initial GHZ layout """ circ, initial_layout = self.get_ghz_layout(n) q = QuantumRegister(n, 'q') rotate = QuantumCircuit(q) rotate.barrier() rotate.u2(delta, -delta, q) rotate.barrier() rotate = transpile(rotate, backend=self.backend, initial_layout=initial_layout) meas = self.get_measurement_circ(n, 'q', 'c', True) meas = transpile(meas, backend=self.backend, initial_layout=initial_layout) new_circ = circ + rotate + meas return new_circ, initial_layout
def _build(self): if self._data is not None: return self._check_configuration() self._data = [] # get the evolved operators as circuits coeff = Parameter("c") evolved_ops = [self.evolution.convert((coeff * op).exp_i()) for op in self.operators] circuits = [evolved_op.reduce().to_circuit() for evolved_op in evolved_ops] # set the registers num_qubits = circuits[0].num_qubits try: qr = QuantumRegister(num_qubits, "q") self.add_register(qr) except CircuitError: # the register already exists, probably because of a previous composition pass # build the circuit times = ParameterVector("t", self.reps * len(self.operators)) times_it = iter(times) first = True for _ in range(self.reps): for circuit in circuits: if first: first = False else: if self._insert_barriers: self.barrier() self.compose(circuit.assign_parameters({coeff: next(times_it)}), inplace=True) if self._initial_state: self.compose(self._initial_state, front=True, inplace=True)
def swap_mapper_layer_update(self, i, first_layer, best_layout, best_d, best_circ, layer_list): """Update the QASM string for an iteration of swap_mapper. i = layer number first_layer = True if this is the first layer with multi-qubit gates best_layout = layout returned from swap algorithm best_d = depth returned from swap algorithm best_circ = swap circuit returned from swap algorithm layer_list = list of circuit objects for each layer Return DAGCircuit object to append to the output DAGCircuit. """ layout = best_layout dagcircuit_output = DAGCircuit() QR = QuantumRegister(self.coupling_map.size(), 'q') dagcircuit_output.add_qreg(QR) # Identity wire-map for composing the circuits identity_wire_map = {(QR, j): (QR, j) for j in range(self.coupling_map.size())} # If this is the first layer with multi-qubit gates, # output all layers up to this point and ignore any # swap gates. Set the initial layout. if first_layer: # Output all layers up to this point for j in range(i + 1): dagcircuit_output.compose_back(layer_list[j]["graph"], layout) # Otherwise, we output the current layer and the associated swap gates. else: # Output any swaps if best_d > 0: dagcircuit_output.compose_back(best_circ, identity_wire_map) # Output this layer dagcircuit_output.compose_back(layer_list[i]["graph"], layout) return dagcircuit_output
def _define_decompositions(self): decomposition = DAGCircuit() q = QuantumRegister(4, "q") decomposition.add_qreg(q) decomposition.add_basis_element("u1", 1, 0, 1) decomposition.add_basis_element("h", 1, 0, 0) decomposition.add_basis_element("x", 1, 0, 0) decomposition.add_basis_element("cx", 2, 0, 0) decomposition.add_basis_element("ccx", 3, 0, 0) decomposition.add_basis_element("t", 1, 0, 0) decomposition.add_basis_element("tdg", 1, 0, 0) rule = [ HGate(q[3]), ToffoliGate(q[0], q[1], q[3]), TdgGate(q[3]), CnotGate(q[2], q[3]), TGate(q[3]), ToffoliGate(q[0], q[1], q[3]), TdgGate(q[3]), CnotGate(q[2], q[3]), TGate(q[3]), HGate(q[3]), ToffoliGate(q[0], q[1], q[2]), CnotGate(q[0], q[1]), XGate(q[0]), U1Gate(-math.pi / 8, q[1]), U1Gate(-math.pi / 4, q[2]), XGate(q[0]), CnotGate(q[0], q[1]), ToffoliGate(q[0], q[1], q[2]), U1Gate(math.pi / 8, q[0]), U1Gate(math.pi / 8, q[1]), U1Gate(math.pi / 4, q[2]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def test_cx_equivalence_3cx_random(self): """Check random circuits with 3 cx gates are outside the 0, 1, and 2 qubit regions. """ qr = QuantumRegister(2, name='q') qc = QuantumCircuit(qr) rnd = 2 * np.pi * np.random.random(size=3) qc.u3(rnd[0], rnd[1], rnd[2], qr[0]) rnd = 2 * np.pi * np.random.random(size=3) qc.u3(rnd[0], rnd[1], rnd[2], qr[1]) qc.cx(qr[1], qr[0]) rnd = 2 * np.pi * np.random.random(size=3) qc.u3(rnd[0], rnd[1], rnd[2], qr[0]) rnd = 2 * np.pi * np.random.random(size=3) qc.u3(rnd[0], rnd[1], rnd[2], qr[1]) qc.cx(qr[0], qr[1]) rnd = 2 * np.pi * np.random.random(size=3) qc.u3(rnd[0], rnd[1], rnd[2], qr[0]) rnd = 2 * np.pi * np.random.random(size=3) qc.u3(rnd[0], rnd[1], rnd[2], qr[1]) qc.cx(qr[1], qr[0]) rnd = 2 * np.pi * np.random.random(size=3) qc.u3(rnd[0], rnd[1], rnd[2], qr[0]) rnd = 2 * np.pi * np.random.random(size=3) qc.u3(rnd[0], rnd[1], rnd[2], qr[1]) sim = UnitarySimulatorPy() U = execute(qc, sim).result().get_unitary() self.assertEqual(two_qubit_cnot_decompose.num_basis_gates(U), 3)
def run(self, dag): """Run the ApplyLayout pass on `dag`. Args: dag (DAGCircuit): DAG to map. Returns: DAGCircuit: A mapped DAG (with physical qubits). Raises: TranspilerError: if no layout is found in `property_set` or no full physical qubits. """ layout = self.property_set["layout"] if not layout: raise TranspilerError( "No 'layout' is found in property_set. Please run a Layout pass in advance." ) if len(layout) != (1 + max(layout.get_physical_bits())): raise TranspilerError("The 'layout' must be full (with ancilla).") for qreg in dag.qregs.values(): self.property_set["layout"].add_register(qreg) q = QuantumRegister(len(layout), "q") new_dag = DAGCircuit() new_dag.add_qreg(q) new_dag.metadata = dag.metadata new_dag.add_clbits(dag.clbits) for creg in dag.cregs.values(): new_dag.add_creg(creg) for node in dag.topological_op_nodes(): qargs = [q[layout[qarg]] for qarg in node.qargs] new_dag.apply_operation_back(node.op, qargs, node.cargs) new_dag._global_phase = dag._global_phase return new_dag
def test_blocks_in_topological_order(self): """the pass returns blocks in correct topological order ______ q0:--[u1]-------.---- q0:-------------| |-- | ______ | U2 | q1:--[u2]--(+)-(+)--- = q1:---| |--|______|-- | | U1 | q2:---------.-------- q2:---|______|------------ """ qr = QuantumRegister(3, "qr") qc = QuantumCircuit(qr) qc.u1(0.5, qr[0]) qc.u2(0.2, 0.6, qr[1]) qc.cx(qr[2], qr[1]) qc.cx(qr[0], qr[1]) dag = circuit_to_dag(qc) topo_ops = [i for i in dag.topological_op_nodes()] block_1 = [topo_ops[1], topo_ops[2]] block_2 = [topo_ops[0], topo_ops[3]] pass_ = Collect2qBlocks() pass_.run(dag) self.assertTrue(pass_.property_set['block_list'], [block_1, block_2])
def test_name_collision(self): """Name collision during ancilla allocation.""" qr_ancilla = QuantumRegister(3, 'ancilla') circuit = QuantumCircuit(qr_ancilla) circuit.h(qr_ancilla) dag = circuit_to_dag(circuit) initial_layout = Layout() initial_layout[0] = qr_ancilla[0] initial_layout[1] = qr_ancilla[1] initial_layout[2] = qr_ancilla[2] pass_ = FullAncillaAllocation(self.cmap5) pass_.property_set['layout'] = initial_layout pass_.run(dag) after_layout = pass_.property_set['layout'] qregs = set(v[0] for v in after_layout.get_virtual_bits().keys()) self.assertEqual(2, len(qregs)) self.assertIn(qr_ancilla, qregs) qregs.remove(qr_ancilla) other_reg = qregs.pop() self.assertEqual(len(other_reg), 2) self.assertRegex(other_reg.name, r'^ancilla\d+$')
def test_apply_barrier_to_slice(self): """test applying barrier to register slice""" n_qubits = 10 qr = QuantumRegister(n_qubits) cr = ClassicalRegister(n_qubits) qc = QuantumCircuit(qr, cr) qc.barrier(qr) # barrier works a little different than normal gates for expansion # test full register self.assertEqual(len(qc.data), 1) self.assertEqual(qc.data[0][0].name, 'barrier') self.assertEqual(len(qc.data[0][1]), n_qubits) for i, bit in enumerate(qc.data[0][1]): self.assertEqual(bit.index, i) # test slice n_qubits = 2 qc = QuantumCircuit(qr, cr) qc.barrier(qr[0:n_qubits]) self.log.info(qc.qasm()) self.assertEqual(len(qc.data), 1) self.assertEqual(qc.data[0][0].name, 'barrier') self.assertEqual(len(qc.data[0][1]), n_qubits) for i in range(n_qubits): self.assertEqual(qc.data[0][1][i].index, i)
def test_non_commutative_circuit_2(self): """A simple circuit where no gates commute qr0:----.------------- | qr1:---(+)------.----- | qr2:---[H]-----(+)---- """ qr = QuantumRegister(3, "qr") circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[1]) circuit.h(qr[2]) circuit.cx(qr[1], qr[2]) dag = circuit_to_dag(circuit) self.pass_.run(dag) expected = { qr[0]: [[0], [6], [1]], qr[1]: [[2], [6], [8], [3]], qr[2]: [[4], [7], [8], [5]], } self.assertCommutationSet(self.pset["commutation_set"], expected)
def test_compose_raises_if_splitting_condition_creg(self): """Verify compose raises if a condition is mapped to more than one creg. ┌───┐ q_0: q_0: ─┤ H ├─ └─┬─┘ c0: 1/ + ┌──┴──┐ = DAGCircuitError c: 2/╡ = 2 ╞ c1: 1/ └─────┘ """ qreg = QuantumRegister(1) creg1 = ClassicalRegister(1) creg2 = ClassicalRegister(1) circuit_left = QuantumCircuit(qreg, creg1, creg2) wide_creg = ClassicalRegister(2) circuit_right = QuantumCircuit(qreg, wide_creg) circuit_right.h(0).c_if(wide_creg, 2) with self.assertRaisesRegex(DAGCircuitError, 'more than one creg'): circuit_left.compose(circuit_right)
def _define(self): """Calculate a subcircuit that implements this initialization Implements a recursive initialization algorithm, including optimizations, from "Synthesis of Quantum Logic Circuits" Shende, Bullock, Markov https://arxiv.org/abs/quant-ph/0406176v5 Additionally implements some extra optimizations: remove zero rotations and double cnots. """ # call to generate the circuit that takes the desired vector to zero disentangling_circuit = self.gates_to_uncompute() # invert the circuit to create the desired vector from zero (assuming # the qubits are in the zero state) initialize_instr = disentangling_circuit.to_instruction().inverse() q = QuantumRegister(self.num_qubits, 'q') initialize_circuit = QuantumCircuit(q, name='init_def') for qubit in q: initialize_circuit.append(Reset(), [qubit]) initialize_circuit.append(initialize_instr, q[:]) self.definition = initialize_circuit.data
def test_two_qubit_synthesis_not_pulse_optimal(self): """Verify not attempting pulse optimal decomposition when pulse_optimize==False.""" backend = FakeVigo() conf = backend.configuration() qr = QuantumRegister(2) coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=False, natural_direction=True, ) pm = PassManager([triv_layout_pass, unisynth_pass]) qc_out = pm.run(qc) if isinstance(qc_out, QuantumCircuit): num_ops = qc_out.count_ops() else: num_ops = qc_out[0].count_ops() self.assertIn("sx", num_ops) self.assertGreaterEqual(num_ops["sx"], 16)
def _define(self): """ gate ch a,b { s b; h b; t b; cx a, b; tdg b; h b; sdg b; } """ from qiskit.extensions.standard.s import SGate, SdgGate from qiskit.extensions.standard.t import TGate, TdgGate from qiskit.extensions.standard.x import CnotGate definition = [] q = QuantumRegister(2, "q") rule = [(SGate(), [q[1]], []), (HGate(), [q[1]], []), (TGate(), [q[1]], []), (CnotGate(), [q[0], q[1]], []), (TdgGate(), [q[1]], []), (HGate(), [q[1]], []), (SdgGate(), [q[1]], [])] for inst in rule: definition.append(inst) self.definition = definition