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, global_phase=-sgn_ry * sgn_rxx * np.pi / 4) 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 _get_rule(self, node): q = QuantumRegister(node.op.num_qubits, "q") if node.name == "u1": rule = [(RZGate(node.op.params[0]), [q[0]], [])] elif node.name == "u2": rule = [ (RZGate(node.op.params[1]), [q[0]], []), (SYGate(), [q[0]], []), (RZGate(node.op.params[0]), [q[0]], []), ] elif node.name == "u3": rule = [ (RZGate(node.op.params[2]), [q[0]], []), (RYGate(node.op.params[0]), [q[0]], []), (RZGate(node.op.params[1]), [q[0]], []), ] elif node.name == "cx": # // controlled-NOT as per Maslov (2017); this implementation takes s = v = +1 # gate cx a,b # { # ry(pi/2) a; # ms(pi/2, 0) a,b; # rx(-pi/2) a; # rx(-pi/2) b; # ry(-pi/2) a; # } rule = [ (SYGate(), [q[0]], []), (MSGate(pi / 2, 0), [q[0], q[1]], []), (RXGate(-pi / 2), [q[0]], []), (RXGate(-pi / 2), [q[1]], []), (RYGate(-pi / 2), [q[0]], []), ] elif node.name == "rx": if node.op.params[0] == pi: rule = [(XGate(), [q[0]], [])] elif node.op.params[0] == pi / 2: rule = [(SXGate(), [q[0]], [])] else: rule = [(RGate(0, node.op.params[0]), [q[0]], [])] elif node.name == "h": rule = [ (ZGate(), [q[0]], []), (SYGate(), [q[0]], []), ] elif node.name == "ry": if node.op.params[0] == pi: rule = [(YGate(), [q[0]], [])] elif node.op.params[0] == pi / 2: rule = [(SYGate(), [q[0]], [])] else: rule = [(RGate(pi / 2, node.op.params[0]), [q[0]], [])] else: rule = node.op.definition return rule
def _define(self): """ gate xx_minus_yy(theta, beta) a, b { rz(-beta) b; rz(-pi/2) a; sx a; rz(pi/2) a; s b; cx a, b; ry(theta/2) a; ry(-theta/2) b; cx a, b; sdg b; rz(-pi/2) a; sxdg a; rz(pi/2) a; rz(beta) b; } """ theta, beta = self.params register = QuantumRegister(2, "q") circuit = QuantumCircuit(register, name=self.name) a, b = register rules = [ (RZGate(-beta), [b], []), (RZGate(-pi / 2), [a], []), (SXGate(), [a], []), (RZGate(pi / 2), [a], []), (SGate(), [b], []), (CXGate(), [a, b], []), (RYGate(theta / 2), [a], []), (RYGate(-theta / 2), [b], []), (CXGate(), [a, b], []), (SdgGate(), [b], []), (RZGate(-pi / 2), [a], []), (SXdgGate(), [a], []), (RZGate(pi / 2), [a], []), (RZGate(beta), [b], []), ] for instr, qargs, cargs in rules: circuit._append(instr, qargs, cargs) self.definition = circuit
def _define(self): """ gate sy a { ry(pi/2) a; } """ definition = [] q = QuantumRegister(1, "q") rule = [ (RYGate(pi / 2), [q[0]], []), ] for inst in rule: definition.append(inst) self.definition = definition
def _zyz_rule(self): """Get the circuit rule for the ZYZ decomposition.""" q = QuantumRegister(self.num_qubits) rule = [] diag = [1., 1.] alpha, beta, gamma, _ = self._zyz_dec() if abs(alpha) > _EPS: rule += [(RZGate(alpha), [q[0]], [])] if abs(beta) > _EPS: rule += [(RYGate(beta), [q[0]], [])] if abs(gamma) > _EPS: if self.up_to_diagonal: diag = [np.exp(-1j * gamma / 2.), np.exp(1j * gamma / 2.)] else: rule += [(RZGate(gamma), [q[0]], [])] return rule, diag