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)
Example #2
0
    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)
Example #3
0
    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