예제 #1
0
    def __init__(self,
                 lhs: QuantumRegister,
                 rhs: QuantumRegister,
                 output_carry: QubitType,
                 input_carry: QubitType,
                 qcirc: QuantumCircuit = None):
        """Initialise the AddRCGate class.

        Implements the Ripple-Carry Adder presented in "A new quantum ripple-carry addition circuit"
        and written by Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin and David Petrie Moulton
        in 2008.

        Parameters:
            lhs          (QuantumRegister)      left-hand side.
            rhs          (QuantumRegister)      right-hand side AND result.
            output_carry (QuantumRegister, int) set to 1 if the addition overflowed.
            input_carry  (QubitType)            input_carry qubit.
            qcirc        (QuantumCircuit)       the circuit on which to add the gates.
        """

        used_qubits = [
            qubit[i] for qubit in [lhs, rhs] for i in range(len(qubit))
        ] + [output_carry, input_carry]

        super().__init__(
            self.__class__.__name__,  # name
            [],  # parameters
            used_qubits,  # qubits
            qcirc)  # circuit

        qubit_number = min(len(lhs), len(rhs))
        # qubit_number is the number of qubits we will use, so it cost nothing to check.
        lhs.check_range(qubit_number - 1)
        rhs.check_range(qubit_number - 1)

        _maj(self, input_carry, rhs[0], lhs[0], qcirc)
        for i in range(1, qubit_number):
            _maj(self, lhs[i - 1], rhs[i], lhs[i], qcirc)

        self.cx(lhs[qubit_number - 1], output_carry)
        for i in range(qubit_number - 1, 0, -1):
            _uma(self, lhs[i - 1], rhs[i], lhs[i], qcirc)
        _uma(self, input_carry, rhs[0], lhs[0], qcirc)
예제 #2
0
    def __init__(self,
                 lhs: QuantumRegister,
                 rhs: QuantumRegister,
                 output_carry: QubitType,
                 ancilla: QuantumRegister,
                 qcirc: QuantumCircuit = None):
        """Initialize the AddCQP class.

        Implements the CQP adder presented in "Quantum Plain and Carry Look-Ahead Adders"
        written by Kai-Wen Cheng and Chien-Cheng Tseng in 2002.
        The implementation is FAR from optimal, this algorithm is a naive algorithm to
        add 2 quantum registers.

        Parameters:
            lhs          (QuantumRegister)      left-hand side.
            rhs          (QuantumRegister)      right-hand side.
            output_carry (QuantumRegister, int) set to 1 if the addition overflowed.
            ancilla      (QuantumRegister)      ancilla register: should contain at least N qubits.
            qcirc        (QuantumCircuit)       the associated circuit.
        """

        used_qubits = [
            qubit[i] for qubit in [lhs, rhs, ancilla]
            for i in range(len(qubit))
        ] + [output_carry]

        super().__init__(
            self.__class__.__name__,  # name
            [],  # parameters
            used_qubits,  # qubits
            qcirc)  # circuit

        qubit_number = min([len(lhs), len(rhs), len(ancilla)])
        # qubit_number is the number of qubits we will use, so it cost nothing to check.
        lhs.check_range(qubit_number - 1)
        rhs.check_range(qubit_number - 1)
        ancilla.check_range(qubit_number - 1)

        # 1. Compute the final carry
        for i in range(qubit_number - 1):
            _carry(self, ancilla[i], lhs[i], rhs[i], ancilla[i + 1], qcirc)
        _carry(self, ancilla[qubit_number - 1], lhs[qubit_number - 1],
               rhs[qubit_number - 1], output_carry, qcirc)

        self.cx(lhs[qubit_number - 1], rhs[qubit_number - 1])

        # 2. Perform the additions with the computed carry bits and reverse
        #    the carry operation
        for i in range(qubit_number - 1, 0, -1):
            _bit_add_without_carry(self, ancilla[i], lhs[i], rhs[i], qcirc)
            _icarry(self, ancilla[i - 1], lhs[i - 1], rhs[i - 1], ancilla[i],
                    qcirc)
        _bit_add_without_carry(self, ancilla[0], lhs[0], rhs[0], qcirc)