I recently built a dynamic full adder gate with Qiskit. The gate essentially copies the classical computing method for a full adder by emulating the classical gates e.g. AND == Toffoli (Quantum AND gate).
I ran a 5-bit adder with ibm_kyoto
(127 qubits Eagle processor), with 10000 shots, expecting the highest result to be the correct one, but it was far from it, with many different combinations of bits being presented as the answer by the algorithm. Please can you help me understand why my algorithm is so bad at finding the addition of two binary numbers, or is Quantum just not suited for this due to NISQ or some fundamental flaw? My code is below:
from qiskit import QuantumCircuit
# a_input and b_input should be binary strings
a_input = "001" # User input for A
b_input = "101" # User input for B
n = len(a_input) # Number of bits of numbers added
# Define the full adder function using the provided circuit template
def full_adder(qc, a_input, b_input):
# Initialize the qubits based on user inputs in little-endian order
a_input = a_input[::-1]
b_input = b_input[::-1]
for i in range(n):
# Initialize qubits for "A" inputs (little-endian order)
if a_input[i] == '1':
qc.x(3 * i + 1) # Map a_input[i] to qubit at position 3*i
# Initialize qubits for "B" inputs (little-endian order)
if b_input[i] == '1':
qc.x(3 * i + 2) # Map b_input[i] to qubit at position 3*i + 2
# Add the barriers as in the provided template
qc.barrier()
# Apply Toffoli (ccx) and CNOT (cx) gates for the full adder function
qc.ccx(1, 2, 3)
qc.cx(1, 2)
qc.ccx(0, 2, 3)
qc.cx(2, 0)
qc.cx(1, 2)
qc.barrier()
# Repeat for n blocks of qubits as specified by the input `n`
for offset in range(3, 3 * (n), 3):
# Apply Toffoli (ccx) and CNOT (cx) gates for each block
qc.ccx(1 + offset, 2 + offset, 3 + offset)
qc.cx(1 + offset, 2 + offset)
qc.ccx(0 + offset, 2 + offset, 3 + offset)
qc.cx(2 + offset, 0 + offset)
qc.cx(1 + offset, 2 + offset)
qc.barrier()
# Measure the specified qubits and store results in classical bits
qc.measure([3 * i for i in range(n + 1)], [i for i in range(n + 1)])
# Return the circuit
return qc
# Example usage of the full adder function with user inputs
qc = QuantumCircuit(n*n +1 ,n + 1)
qc = full_adder(qc, a_input, b_input)
qc.draw(plot_barriers=True, initial_state=True, scale=1, output='mpl')
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator
from qiskit import transpile
service = QiskitRuntimeService(channel="ibm_quantum", token="*******")
realBackend = service.least_busy(simulator=False, operational=True)
transpiled_qc = transpile(qc, backend=realBackend)
counts = realBackend.run(transpiled_qc, shots=10000).result().get_counts()
print(counts)
import matplotlib.pyplot as plt
def plot_histogram(counts):
# Create a new figure with a wider size
plt.figure(figsize=(15, 6)) # Adjust the width and height as needed
# Plot the histogram
plt.bar(counts.keys(), counts.values())
# Set labels and title
plt.xlabel('Categories')
plt.ylabel('Counts')
plt.title('Histogram')
# Rotate the x-axis labels by 45 degrees
plt.xticks(rotation=45, ha='right')
# Show the plot
plt.show()
plot_histogram(counts)