def __init__( self, num_variable_qubits: int, flags: Optional[List[int]] = None, mcx_mode: str = "noancilla", ) -> None: """Create a new logical AND circuit. Args: num_variable_qubits: The qubits of which the OR is computed. The result will be written into an additional result qubit. flags: A list of +1/0/-1 marking negations or omissions of qubits. mcx_mode: The mode to be used to implement the multi-controlled X gate. """ self.num_variable_qubits = num_variable_qubits self.flags = flags # add registers qr_variable = QuantumRegister(num_variable_qubits, name="variable") qr_result = QuantumRegister(1, name="result") circuit = QuantumCircuit(qr_variable, qr_result, name="and") # determine the control qubits: all that have a nonzero flag flags = flags or [1] * num_variable_qubits control_qubits = [ q for q, flag in zip(qr_variable, flags) if flag != 0 ] # determine the qubits that need to be flipped (if a flag is < 0) flip_qubits = [q for q, flag in zip(qr_variable, flags) if flag < 0] # determine the number of ancillas num_ancillas = MCXGate.get_num_ancilla_qubits(len(control_qubits), mode=mcx_mode) if num_ancillas > 0: qr_ancilla = AncillaRegister(num_ancillas, "ancilla") circuit.add_register(qr_ancilla) else: qr_ancilla = [] if len(flip_qubits) > 0: circuit.x(flip_qubits) circuit.mcx(control_qubits, qr_result[:], qr_ancilla[:], mode=mcx_mode) if len(flip_qubits) > 0: circuit.x(flip_qubits) super().__init__(*circuit.qregs, name="and") self.compose(circuit.to_gate(), qubits=self.qubits, inplace=True)
def __init__(self, num_variable_qubits: int, flags: Optional[List[int]] = None, mcx_mode: str = 'noancilla') -> None: """Create a new logical OR circuit. Args: num_variable_qubits: The qubits of which the OR is computed. The result will be written into an additional result qubit. flags: A list of +1/0/-1 marking negations or omisiions of qubits. mcx_mode: The mode to be used to implement the multi-controlled X gate. """ # store num_variables_qubits and flags self.num_variable_qubits = num_variable_qubits self.flags = flags # add registers qr_variable = QuantumRegister(num_variable_qubits, name='variable') qr_result = QuantumRegister(1, name='result') super().__init__(qr_variable, qr_result, name='or') # determine the control qubits: all that have a nonzero flag flags = flags or [1] * num_variable_qubits control_qubits = [ q for q, flag in zip(qr_variable, flags) if flag != 0 ] # determine the qubits that need to be flipped (if a flag is > 0) flip_qubits = [q for q, flag in zip(qr_variable, flags) if flag > 0] # determine the number of ancillas self.num_ancilla_qubits = MCXGate.get_num_ancilla_qubits( len(control_qubits), mode=mcx_mode) if self.num_ancilla_qubits > 0: qr_ancilla = QuantumRegister(self.num_ancilla_qubits, 'ancilla') self.add_register(qr_ancilla) else: qr_ancilla = [] self.x(qr_result) if len(flip_qubits) > 0: self.x(flip_qubits) self.mcx(control_qubits, qr_result[:], qr_ancilla[:], mode=mcx_mode) if len(flip_qubits) > 0: self.x(flip_qubits)
def _define(self): definition = [] qr = QuantumRegister(self.num_ctrl_qubits + 1) ctrl_qr = qr[:self.num_ctrl_qubits] target_qubit = qr[self.num_ctrl_qubits] if self.qubit_values: for qubit_index, qubit_value in enumerate(self.qubit_values): if not qubit_value: definition.append((XGate(), [ctrl_qr[qubit_index]], [])) definition.append((MCXGate(self.num_ctrl_qubits), list(ctrl_qr) + [target_qubit], [])) if self.qubit_values: for qubit_index, qubit_value in enumerate(self.qubit_values): if not qubit_value: definition.append((XGate(), [ctrl_qr[qubit_index]], [])) self.definition = definition