def mcu3(self, theta, phi, lam, control_qubits, target_qubit): """ Apply Multiple-Controlled U3 gate Args: theta: angle theta phi: angle phi lam: angle lambda control_qubits: The list of control qubits target_qubit: The target qubit """ if isinstance(target_qubit, QuantumRegister) and len(target_qubit) == 1: target_qubit = target_qubit[0] temp = [] self._check_qargs(control_qubits) temp += control_qubits self._check_qargs([target_qubit]) temp.append(target_qubit) self._check_dups(temp) n_c = len(control_qubits) if n_c == 1: # cu3 apply_cu3(self, theta, phi, lam, control_qubits[0], target_qubit) else: _apply_mcu3(self, theta, phi, lam, control_qubits, target_qubit)
def mcu3(self, theta, phi, lam, control_qubits, target_qubit): """ Apply Multiple-Controlled U3 gate Args: theta: angle theta phi: angle phi lam: angle lambda control_qubits: The list of control qubits target_qubit: The target qubit """ if isinstance(target_qubit, QuantumRegister) and len(target_qubit) == 1: target_qubit = target_qubit[0] temp = [] for qubit in control_qubits: try: self._check_qubit(qubit) except AttributeError as e: # TODO Temporary, _check_qubit may not exist logger.debug(str(e)) temp.append(qubit) try: self._check_qubit(target_qubit) except AttributeError as e: # TODO Temporary, _check_qubit may not exist logger.debug(str(e)) temp.append(target_qubit) self._check_dups(temp) n_c = len(control_qubits) if n_c == 1: # cu3 apply_cu3(self, theta, phi, lam, control_qubits[0], target_qubit) else: _apply_mcu3(self, theta, phi, lam, control_qubits, target_qubit)
def __init__(self, theta, phi, lam, ctls, tgt, circ=None): """Create new MCU3 gate.""" self._ctl_bits = ctls self._tgt_bits = tgt self._theta = theta self._phi = phi self._lambda = lam qubits = [v for v in ctls] + [tgt] n_c = len(ctls) super(MCU3Gate, self).__init__("mcu3", (theta, phi, lam, n_c), qubits, circ) if n_c == 1: # cx apply_cu3(circ, theta, phi, lam, ctls[0], tgt) else: self.apply_mcu3(theta, phi, lam, ctls, tgt, circ)
def _apply_mcu3(circuit, theta, phi, lam, ctls, tgt): """Apply multi-controlled u3 gate from ctls to tgt with angles theta, phi, lam.""" n = len(ctls) gray_code = list(GrayCode(n).generate_gray()) last_pattern = None theta_angle = theta * (1 / (2**(n - 1))) phi_angle = phi * (1 / (2**(n - 1))) lam_angle = lam * (1 / (2**(n - 1))) for pattern in gray_code: if not '1' in pattern: continue if last_pattern is None: last_pattern = pattern #find left most set bit lm_pos = list(pattern).index('1') #find changed bit comp = [i != j for i, j in zip(pattern, last_pattern)] if True in comp: pos = comp.index(True) else: pos = None if pos is not None: if pos != lm_pos: circuit.cx(ctls[pos], ctls[lm_pos]) else: indices = [i for i, x in enumerate(pattern) if x == '1'] for idx in indices[1:]: circuit.cx(ctls[idx], ctls[lm_pos]) #check parity if pattern.count('1') % 2 == 0: #inverse apply_cu3(circuit, -theta_angle, phi_angle, lam_angle, ctls[lm_pos], tgt) else: apply_cu3(circuit, theta_angle, phi_angle, lam_angle, ctls[lm_pos], tgt) last_pattern = pattern