def test_dag_collect_runs(self): """Test the collect_runs method with 3 different gates.""" self.dag.apply_operation_back(U1Gate(3.14), [self.qubit0]) self.dag.apply_operation_back(U1Gate(3.14), [self.qubit0]) self.dag.apply_operation_back(U1Gate(3.14), [self.qubit0]) self.dag.apply_operation_back(CnotGate(), [self.qubit2, self.qubit1]) self.dag.apply_operation_back(CnotGate(), [self.qubit1, self.qubit2]) self.dag.apply_operation_back(HGate(), [self.qubit2]) collected_runs = self.dag.collect_runs(['u1', 'cx', 'h']) self.assertEqual(len(collected_runs), 3) for run in collected_runs: if run[0].name == 'cx': self.assertEqual(len(run), 2) self.assertEqual(['cx'] * 2, [x.name for x in run]) self.assertEqual( [[self.qubit2, self.qubit1], [self.qubit1, self.qubit2]], [x.qargs for x in run]) elif run[0].name == 'h': self.assertEqual(len(run), 1) self.assertEqual(['h'], [x.name for x in run]) self.assertEqual([[self.qubit2]], [x.qargs for x in run]) elif run[0].name == 'u1': self.assertEqual(len(run), 3) self.assertEqual(['u1'] * 3, [x.name for x in run]) self.assertEqual([[self.qubit0], [self.qubit0], [self.qubit0]], [x.qargs for x in run]) else: self.fail('Unknown run encountered')
def _define(self): """ gate cu3(theta,phi,lambda) c, t { u1((lambda+phi)/2) c; u1((lambda-phi)/2) t; cx c,t; u3(-theta/2,0,-(phi+lambda)/2) t; cx c,t; u3(theta/2,phi,0) t; } """ from qiskit.extensions.standard.u1 import U1Gate from qiskit.extensions.standard.x import CnotGate definition = [] q = QuantumRegister(2, "q") rule = [ (U1Gate((self.params[2] + self.params[1]) / 2), [q[0]], []), (U1Gate((self.params[2] - self.params[1]) / 2), [q[1]], []), (CnotGate(), [q[0], q[1]], []), (U3Gate(-self.params[0] / 2, 0, -(self.params[1] + self.params[2]) / 2), [q[1]], []), (CnotGate(), [q[0], q[1]], []), (U3Gate(self.params[0] / 2, self.params[1], 0), [q[1]], []) ] for inst in rule: definition.append(inst) self.definition = definition
def _define(self): """ gate rccx a,b,c { u2(0,pi) c; u1(pi/4) c; cx b, c; u1(-pi/4) c; cx a, c; u1(pi/4) c; cx b, c; u1(-pi/4) c; u2(0,pi) c; } """ definition = [] q = QuantumRegister(3, 'q') definition = [ (U2Gate(0, pi), [q[2]], []), # H gate (U1Gate(pi / 4), [q[2]], []), # T gate (CXGate(), [q[1], q[2]], []), (U1Gate(-pi / 4), [q[2]], []), # inverse T gate (CXGate(), [q[0], q[2]], []), (U1Gate(pi / 4), [q[2]], []), (CXGate(), [q[1], q[2]], []), (U1Gate(-pi / 4), [q[2]], []), # inverse T gate (U2Gate(0, pi), [q[2]], []), # H gate ] self.definition = definition
def _define(self): """ gate rccx a,b,c { u2(0,pi) c; u1(pi/4) c; cx b, c; u1(-pi/4) c; cx a, c; u1(pi/4) c; cx b, c; u1(-pi/4) c; u2(0,pi) c; } """ definition = [] q = QuantumRegister(3, 'q') rule = [ (U2Gate(0, pi), [q[2]], []), # H gate (U1Gate(pi / 4), [q[2]], []), # T gate (CnotGate(), [q[1], q[2]], []), (U1Gate(-pi / 4), [q[2]], []), # inverse T gate (CnotGate(), [q[0], q[2]], []), (U1Gate(pi / 4), [q[2]], []), (CnotGate(), [q[1], q[2]], []), (U1Gate(-pi / 4), [q[2]], []), # inverse T gate (U2Gate(0, pi), [q[2]], []), # H gate ] for inst in rule: definition.append(inst) self.definition = definition
def _define_decompositions(self): decomposition = DAGCircuit() q = QuantumRegister(5, "q") decomposition.add_qreg(q) decomposition.add_basis_element("u1", 1, 0, 1) decomposition.add_basis_element("cx", 2, 0, 0) decomposition.add_basis_element("ccx", 3, 0, 0) decomposition.add_basis_element("c3x", 4, 0, 0) decomposition.add_basis_element("c4x", 5, 0, 0) rule = [ C4NotGate(q[0], q[1], q[2], q[3], q[4]), C3NotGate(q[0], q[1], q[2], q[3]), ToffoliGate(q[0], q[1], q[2]), CnotGate(q[0], q[1]), U1Gate(-self.param[0] / 16, q[1]), U1Gate(-self.param[0] / 8, q[2]), U1Gate(-self.param[0] / 4, q[3]), U1Gate(-self.param[0] / 2, q[4]), CnotGate(q[0], q[1]), ToffoliGate(q[0], q[1], q[2]), C3NotGate(q[0], q[1], q[2], q[3]), C4NotGate(q[0], q[1], q[2], q[3], q[4]), U1Gate(self.param[0] / 16, q[0]), U1Gate(self.param[0] / 16, q[1]), U1Gate(self.param[0] / 8, q[2]), U1Gate(self.param[0] / 4, q[3]), U1Gate(self.param[0] / 2, q[4]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def simplify_U(theta, phi, lam): """Return the gate u1, u2, or u3 implementing U with the fewest pulses. The returned gate implements U exactly, not up to a global phase. Args: theta, phi, lam: input Euler rotation angles for a general U gate Returns: Gate: one of IdGate, U1Gate, U2Gate, U3Gate. """ gate = U3Gate(theta, phi, lam) # Y rotation is 0 mod 2*pi, so the gate is a u1 if abs(gate.params[0] % (2.0 * math.pi)) < _CUTOFF_PRECISION: gate = U1Gate(gate.params[0] + gate.params[1] + gate.params[2]) # Y rotation is pi/2 or -pi/2 mod 2*pi, so the gate is a u2 if isinstance(gate, U3Gate): # theta = pi/2 + 2*k*pi if abs((gate.params[0] - math.pi / 2) % (2.0 * math.pi)) < _CUTOFF_PRECISION: gate = U2Gate(gate.params[1], gate.params[2] + (gate.params[0] - math.pi / 2)) # theta = -pi/2 + 2*k*pi if abs((gate.params[0] + math.pi / 2) % (2.0 * math.pi)) < _CUTOFF_PRECISION: gate = U2Gate( gate.params[1] + math.pi, gate.params[2] - math.pi + (gate.params[0] + math.pi / 2)) # u1 and lambda is 0 mod 4*pi so gate is nop if isinstance(gate, U1Gate) and abs(gate.params[0] % (4.0 * math.pi)) < _CUTOFF_PRECISION: gate = IdGate() return gate
def _define(self): """ gate cu3(theta,phi,lambda) c, t { u1(pi/2) t; cx c,t; u3(-theta/2,0,0) t; cx c,t; u3(theta/2,-pi/2,0) t; } """ from qiskit.extensions.standard.u1 import U1Gate from qiskit.extensions.standard.u3 import U3Gate from qiskit.extensions.standard.x import CnotGate definition = [] q = QuantumRegister(2, 'q') rule = [ (U1Gate(pi / 2), [q[1]], []), (CnotGate(), [q[0], q[1]], []), (U3Gate(-self.params[0] / 2, 0, 0), [q[1]], []), (CnotGate(), [q[0], q[1]], []), (U3Gate(self.params[0] / 2, -pi / 2, 0), [q[1]], []) ] for inst in rule: definition.append(inst) self.definition = definition
def _define(self): if PulseBackedOptimizationContext.get(): """ Cnot decomposes into: ---RX(pi)---Sdag---| CR with X side effect |---- --RX(pi/2)---------| pi/2 |---- algassert.com/quirk#circuit=%7B%22cols%22%3A%5B%5B%22X%22%2C%7B%22id%22%3A%22Rxft%22%2C%22 arg%22%3A%22pi%2F2%22%7D%5D%2C%5B%22Z%5E-%C2%BD%22%5D%2C%5B%22%E2%97%A6%22%2C%7B%22id%22%3A %22Rxft%22%2C%22arg%22%3A%22pi%2F4%22%7D%5D%2C%5B%22%E2%80%A2%22%2C%7B%22id%22%3A%22Rxft%22 %2C%22arg%22%3A%22-pi%2F4%22%7D%5D%2C%5B%5D%2C%5B%22X%22%5D%2C%5B%22%E2%97%A6%22%2C%7B%22id %22%3A%22Rxft%22%2C%22arg%22%3A%22-pi%2F4%22%7D%5D%2C%5B%5D%2C%5B%22%E2%80%A2%22%2C%7B%22id %22%3A%22Rxft%22%2C%22arg%22%3A%22pi%2F4%22%7D%5D%5D%7D """ definition = [] q = QuantumRegister(2, "q") rule = [ (U1Gate(pi / 2), [q[0]], []), (DirectRXGate(pi), [q[0]], []), (DirectRXGate(pi / 2), [q[1]], []), (CRGate(pi / 2), [q[0], q[1]], []), ] for inst in rule: definition.append(inst) self.definition = definition else: super()._define()
def _define_decompositions(self): """ gate cu3(theta,phi,lambda) c, t { u1((lambda-phi)/2) t; cx c,t; u3(-theta/2,0,-(phi+lambda)/2) t; cx c,t; u3(theta/2,phi,0) t; } """ decomposition = DAGCircuit() q = QuantumRegister(2, "q") decomposition.add_qreg(q) decomposition.add_basis_element("u1", 1, 0, 1) decomposition.add_basis_element("u3", 1, 0, 3) decomposition.add_basis_element("cx", 2, 0, 0) rule = [ U1Gate((self.param[2] - self.param[1]) / 2, q[1]), CnotGate(q[0], q[1]), U3Gate(-self.param[0] / 2, 0, -(self.param[1] + self.param[2]) / 2, q[1]), CnotGate(q[0], q[1]), U3Gate(self.param[0] / 2, self.param[1], 0, q[1]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def _define(self): definition = [] q = QuantumRegister(1, "q") rule = [(U1Gate(pi), [q[0]], [])] for inst in rule: definition.append(inst) self.definition = definition
def _define(self): """ gate crz(lambda) a,b { u1(lambda/2) b; cx a,b; u1(-lambda/2) b; cx a,b; } """ definition = [] q = QuantumRegister(2, "q") rule = [(U1Gate(self.params[0] / 2), [q[1]], []), (CnotGate(), [q[0], q[1]], []), (U1Gate(-self.params[0] / 2), [q[1]], []), (CnotGate(), [q[0], q[1]], [])] for inst in rule: definition.append(inst) self.definition = definition
def test_substituting_node_preserves_parents_children(self, inplace): """Verify parents and children are preserved by a substitution.""" qc = QuantumCircuit(3, 2) qc.cx(0, 1) qc.cx(1, 2) qc.rz(0.1, 2) qc.cx(1, 2) qc.cx(0, 1) dag = circuit_to_dag(qc) node_to_be_replaced = dag.named_nodes('rz')[0] predecessors = set(dag.predecessors(node_to_be_replaced)) successors = set(dag.successors(node_to_be_replaced)) ancestors = dag.ancestors(node_to_be_replaced) descendants = dag.descendants(node_to_be_replaced) replacement_node = dag.substitute_node(node_to_be_replaced, U1Gate(0.1), inplace=inplace) raise_if_dagcircuit_invalid(dag) self.assertEqual(set(dag.predecessors(replacement_node)), predecessors) self.assertEqual(set(dag.successors(replacement_node)), successors) self.assertEqual(dag.ancestors(replacement_node), ancestors) self.assertEqual(dag.descendants(replacement_node), descendants) self.assertEqual(replacement_node is node_to_be_replaced, inplace)
def _define(self): self.definition = [] q = QuantumRegister(self.num_qubits) self.definition.append((QFTGate(self.num_qubits), q, [])) for i in range(self.num_qubits): self.definition.append((U1Gate(float(pi * self.params[0]) / 2**i), [q[self.num_qubits - i - 1]], [])) self.definition.append((QFTGate(self.num_qubits).inverse(), q, []))
def _define_decompositions(self): decomposition = DAGCircuit() q = QuantumRegister(1, "q") decomposition.add_qreg(q) rule = [U1Gate(pi, q[0])] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def _define(self): from qiskit.extensions.standard.u1 import U1Gate definition = [] q = QuantumRegister(1, "q") rule = [(U1Gate(pi), [q[0]], [])] for inst in rule: definition.append(inst) self.definition = definition
def _define(self): """ gate crz(lambda) a,b { u1(lambda/2) b; cx a,b; u1(-lambda/2) b; cx a,b; } """ from qiskit.extensions.standard.u1 import U1Gate from qiskit.extensions.standard.x import CXGate definition = [] q = QuantumRegister(2, 'q') rule = [(U1Gate(self.params[0] / 2), [q[1]], []), (CXGate(), [q[0], q[1]], []), (U1Gate(-self.params[0] / 2), [q[1]], []), (CXGate(), [q[0], q[1]], [])] for inst in rule: definition.append(inst) self.definition = definition
def _define(self): if PulseBackedOptimizationContext.get(): """Decompose via identity similar to [McKay et al. 2017, 17] (arxiv.org/pdf/1612.00858.pdf). U3(theta, phi, lambda) = RZ(lambda - pi/2) * RX(theta) * RZ(phi + pi/2) """ definition = [] q = QuantumRegister(1, "q") theta, phi, lam = self.params[0], self.params[1], self.params[2] rule = [ (U1Gate(lam - np.pi / 2), [q[0]], []), (DirectRXGate(theta), [q[0]], []), (U1Gate(phi + np.pi / 2), [q[0]], []), ] for inst in rule: definition.append(inst) self.definition = definition else: super()._define()
def _build_composite_gate(self, x, qr): composite_gate = CompositeGate( "second_order_expansion", [], [qr[i] for i in range(self._num_qubits)]) for _ in range(self._depth): for i in range(x.shape[0]): composite_gate._attach(U2Gate(0, np.pi, qr[i])) composite_gate._attach(U1Gate(2 * x[i], qr[i])) for src, targs in self._entangler_map.items(): for targ in targs: composite_gate._attach(CnotGate(qr[src], qr[targ])) composite_gate._attach( U1Gate(2 * (np.pi - x[src]) * (np.pi - x[targ]), qr[targ])) composite_gate._attach(CnotGate(qr[src], qr[targ])) return composite_gate
def _define(self): """ gate sdg a { u1(-pi/2) a; } """ definition = [] q = QuantumRegister(1, "q") rule = [(U1Gate(-pi / 2), [q[0]], [])] for inst in rule: definition.append(inst) self.definition = definition
def _define(self): """ gate rz(phi) a { u1(phi) a; } """ definition = [] q = QuantumRegister(1, "q") rule = [(U1Gate(self.params[0]), [q[0]], [])] for inst in rule: definition.append(inst) self.definition = definition
def _define_decompositions(self): """ gate crz(lambda) a,b { u1(lambda/2) b; cx a,b; u1(-lambda/2) b; cx a,b; } """ decomposition = DAGCircuit() q = QuantumRegister(2, "q") decomposition.add_qreg(q) rule = [ U1Gate(self.params[0] / 2, q[1]), CnotGate(q[0], q[1]), U1Gate(-self.params[0] / 2, q[1]), CnotGate(q[0], q[1]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def _define_decompositions(self): decomposition = DAGCircuit() q = QuantumRegister(6, "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("c3x", 4, 0, 0) decomposition.add_basis_element("c4x", 5, 0, 0) decomposition.add_basis_element("t", 1, 0, 0) decomposition.add_basis_element("tdg", 1, 0, 0) rule = [ HGate(q[5]), C4NotGate(q[0], q[1], q[2], q[3], q[5]), TdgGate(q[5]), CnotGate(q[4], q[5]), TGate(q[5]), C4NotGate(q[0], q[1], q[2], q[3], q[5]), TdgGate(q[5]), CnotGate(q[4], q[5]), TGate(q[5]), HGate(q[5]), C4NotGate(q[0], q[1], q[2], q[3], q[4]), C3NotGate(q[0], q[1], q[2], q[3]), ToffoliGate(q[0], q[1], q[2]), CnotGate(q[0], q[1]), XGate(q[0]), U1Gate(-math.pi / 32, q[1]), U1Gate(-math.pi / 16, q[2]), U1Gate(-math.pi / 8, q[3]), U1Gate(-math.pi / 4, q[4]), XGate(q[0]), CnotGate(q[0], q[1]), ToffoliGate(q[0], q[1], q[2]), C3NotGate(q[0], q[1], q[2], q[3]), C4NotGate(q[0], q[1], q[2], q[3], q[4]), U1Gate(math.pi / 32, q[0]), U1Gate(math.pi / 32, q[1]), U1Gate(math.pi / 16, q[2]), U1Gate(math.pi / 8, q[3]), U1Gate(math.pi / 4, q[4]) ] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def _define(self): """ gate rzx(theta) a, b { h b; cx a, b; u1(theta) b; cx a, b; h b;} """ from qiskit.extensions.standard.u1 import U1Gate from qiskit.extensions.standard.h import HGate from qiskit.extensions.standard.x import CXGate q = QuantumRegister(2, 'q') self.definition = [(HGate(), [q[1]], []), (CXGate(), [q[0], q[1]], []), (U1Gate(self.params[0]), [q[1]], []), (CXGate(), [q[0], q[1]], []), (HGate(), [q[1]], [])]
def _define_decompositions(self): """ gate rz(phi) a { u1(phi) a; } """ decomposition = DAGCircuit() q = QuantumRegister(1, "q") decomposition.add_qreg(q) rule = [U1Gate(self.params[0], q[0])] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def _define(self): """ gate rz(phi) a { u1(phi) a; } """ from qiskit.extensions.standard.u1 import U1Gate definition = [] q = QuantumRegister(1, 'q') rule = [(U1Gate(self.params[0]), [q[0]], [])] for inst in rule: definition.append(inst) self.definition = definition
def _build_composite_gate(self, x, qr): composite_gate = CompositeGate( "first_order_expansion", [], [qr[i] for i in range(self._num_qubits)]) for _ in range(self._depth): for i in range(x.shape[0]): composite_gate._attach(U2Gate(0, np.pi, qr[i])) composite_gate._attach(U1Gate(2 * x[i], qr[i])) return composite_gate
def _define_decompositions(self): """ gate t a { u1(pi/4) a; } """ decomposition = DAGCircuit() q = QuantumRegister(1, "q") decomposition.add_qreg(q) decomposition.add_basis_element("u1", 1, 0, 1) rule = [U1Gate(-pi / 4, q[0])] for inst in rule: decomposition.apply_operation_back(inst) self._decompositions = [decomposition]
def _define(self): """ gate rzz(theta) a, b { cx a, b; u1(theta) b; cx a, b; } """ definition = [] q = QuantumRegister(2, "q") rule = [(CnotGate(), [q[0], q[1]], []), (U1Gate(self.params[0]), [q[1]], []), (CnotGate(), [q[0], q[1]], [])] for inst in rule: definition.append(inst) self.definition = definition
def _define(self): """ gate rcccx a,b,c,d { u2(0,pi) d; u1(pi/4) d; cx c,d; u1(-pi/4) d; u2(0,pi) d; cx a,d; u1(pi/4) d; cx b,d; u1(-pi/4) d; cx a,d; u1(pi/4) d; cx b,d; u1(-pi/4) d; u2(0,pi) d; u1(pi/4) d; cx c,d; u1(-pi/4) d; u2(0,pi) d; } """ definition = [] q = QuantumRegister(4, 'q') rule = [ (U2Gate(0, pi), [q[3]], []), # H gate (U1Gate(pi / 4), [q[3]], []), # T gate (CXGate(), [q[2], q[3]], []), (U1Gate(-pi / 4), [q[3]], []), # inverse T gate (U2Gate(0, pi), [q[3]], []), (CXGate(), [q[0], q[3]], []), (U1Gate(pi / 4), [q[3]], []), (CXGate(), [q[1], q[3]], []), (U1Gate(-pi / 4), [q[3]], []), (CXGate(), [q[0], q[3]], []), (U1Gate(pi / 4), [q[3]], []), (CXGate(), [q[1], q[3]], []), (U1Gate(-pi / 4), [q[3]], []), (U2Gate(0, pi), [q[3]], []), (U1Gate(pi / 4), [q[3]], []), (CXGate(), [q[2], q[3]], []), (U1Gate(-pi / 4), [q[3]], []), (U2Gate(0, pi), [q[3]], []), ] for inst in rule: definition.append(inst) self.definition = definition
def _define(self): definition = [] q = QuantumRegister(self.num_qubits) if self.least_significant_bit_first == False: q = q[::-1] definition.append((QFTGate(self.num_qubits, bool_swaps=False), q, [])) for i in range(self.num_qubits): definition.append((U1Gate(float(pi * self.epsilon) / 2**i), [q[self.num_qubits - i - 1]], [])) definition.append((QFTGate(self.num_qubits, bool_swaps=False).inverse(), q, [])) if self.least_significant_bit_first == False: q = q[::-1] self.definition = definition