# Trying to understand a quantum adder

I've implemented a quantum adder and, when I build the results table, I'm having some trouble to understand what's going on. First, I'm using the adder quantum circuit proposed in this paper, which circuit is shown below:

This is my version, implemented in IBMQE, as shown below:

After building the following truth table, I've got the following results:

One can verify that there are several wrong outputs from this circuit. My question is: What's wrong in this circuit? If there is nothing wrong, am I interpreting the outputs in a wrong way? How to interpret them correctly?

• Did you run the circuit in a simulator or real device? Commented Jun 10, 2023 at 3:46
• I ran the circuit in a simulator... Commented Jun 11, 2023 at 4:39

The figure you included in your question references the paper Addition on a Quantum Computer by Draper. Qiskit has implemented this circuit natively, which you can construct as follows.

from qiskit.circuit.library import DraperQFTAdder


a_0: ─────────■──────■───────────────────────
│      │
a_1: ─────────┼──────┼────────■──────────────
┌──────┐ │P(π)  │        │     ┌───────┐
b_0: ┤0     ├─■──────┼────────┼─────┤0      ├
│  QFT │        │P(π/2)  │P(π) │  IQFT │
b_1: ┤1     ├────────■────────■─────┤1      ├
└──────┘                       └───────┘


So, looking at your question, it seems like you misplaced the control qubit of a controlled-P qubit, as your second qubit is never acted on by any gate, but be careful to take into account Qiskit's endian convention when thinking about this.

Running this naively for all inputs, I got:

import itertools
from qiskit import QuantumCircuit, Aer, transpile
from qiskit.quantum_info import Statevector

backend = Aer.get_backend('qasm_simulator')

for l in list(itertools.product([0, 1], repeat=4)):
qc = QuantumCircuit(4)

for i, bit in enumerate(l):
if bit == 1:
qc.x(i)
qc.measure_all()
qc = qc.reverse_bits()

job = backend.run(transpile(qc, backend), shots=1024)
print(f"Input: {l}. Result: {job.result().get_counts()}")

Input: (0, 0, 0, 0). Result: {'0000': 1024}
Input: (0, 0, 0, 1). Result: {'0001': 1024}
Input: (0, 0, 1, 0). Result: {'0010': 1024}
Input: (0, 0, 1, 1). Result: {'0011': 1024}
Input: (0, 1, 0, 0). Result: {'0101': 1024}
Input: (0, 1, 0, 1). Result: {'0100': 1024}
Input: (0, 1, 1, 0). Result: {'0111': 1024}
Input: (0, 1, 1, 1). Result: {'0110': 1024}
Input: (1, 0, 0, 0). Result: {'1010': 1024}
Input: (1, 0, 0, 1). Result: {'1011': 1024}
Input: (1, 0, 1, 0). Result: {'1001': 1024}
Input: (1, 0, 1, 1). Result: {'1000': 1024}
Input: (1, 1, 0, 0). Result: {'1111': 1024}
Input: (1, 1, 0, 1). Result: {'1110': 1024}
Input: (1, 1, 1, 0). Result: {'1100': 1024}
Input: (1, 1, 1, 1). Result: {'1101': 1024}


This, I think, is what you expected in your table if you take into account the endian notation for each register individually (so, e.g., the input (0, 1, 0, 1) is doing $$(2 + 2) \mod 4 = 0$$). But you can check the documentation for the adder in more detail to confirm.

The correct way to interpret the number is using a compiler that follows the qubit mapping.

You can see how it is done in Classiq, for example, by running examples from the arithmetic library

To your case, you can run:

from classiq import *

@qfunc
def main(a: Output[QNum[2, False,0]], b: Output[QNum[2,False,0]], res: Output[QNum]) -> None:
allocate(2, a)
allocate(2, b)

res |= a+b

qmod = create_model(main)
qprog = synthesize(qmod)
show(qprog)

job = execute(qprog)
result = job.result()[0].value
print(result.parsed_counts)

job.open_in_ide()


For more complex case, where the register represents a fraaction or signed number, you can use this qfunc instead:

@qfunc
def main(a: Output[QNum[3, True,2]], b: Output[QNum[4,False,1]], res: Output[QNum]) -> None:
allocate(3, a)
allocate(4, b)

res |= a+b


Will give you interpreted results:

     {'a': -0.25, 'b': 4.0, 'res': 3.75}: 23,
{'a': 0.75, 'b': 0.0, 'res': 0.75}: 22,
...

{'a': -0.75, 'b': 6.5, 'res': 5.75}: 13,
{'a': 0.0, 'b': 1.5, 'res': 1.5}: 12,
...
{'a': -0.25, 'b': 3.0, 'res': 2.75}: 11,
{'a': -0.75, 'b': 7.5, 'res': 6.75}: 10,
...
{'a': -1.0, 'b': 5.5, 'res': 4.5}: 5]


And in the IDE, you can hover on the bars and see that for every result, res=a+b