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)
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)