quantum_adder#
Functionality#
Here is a collection of quantum adder programs.
draper_adder.py#
Callee: DraperAdder
This program implements addition for two \(n\)-bit qubit arrays \(\ket{x}\) and \(\ket{y}\), i.e., Draper Adder. Given two \(n\)-qubit computational basis states \(\ket{x}_{n}\) and \(\ket{y}_{n}\), the program performs the following mapping:
The input states are defined as \(\ket{x}_{n} = \ket{q_{n-1} \cdots q_{1} q_{0}}\) and \(\ket{y}_{n} = \ket{q_{2n-1} \cdots q_{n+1} q_n}\), where \(x\) and \(y\) are the decimal values of the binary strings \(q_{n-1} \cdots q_0\) and \(q_{2n-1} \cdots q_n\), respectively.
Test expectations:
The results are stored in the most significant \(n\) qubits (the register encoding \(\ket{y}_n\)), which can be obtained by measurement.
Doc reference: [5]
weighted_adder.py#
Callee: WeightedAdder
Give \(n\) qubit basis states \(\ket{y}_{n}\) and non-negative integer weights \(\lambda_{0},\cdots,\lambda_{n-1}\). Then, let the vector \(\mathbf{w}\equiv[\lambda_0,\cdots,\lambda_{n-1}]^{\top}\in\mathbb{N}^{n\times 1}\) and \(\mathbf{y}\equiv[q_{0},\cdots,q_{n-1}]^{\top}\in\{0,1\}^{n\times 1}\), where \(\ket{y}\) defined by the binary string: \(\ket{y}\equiv\ket{q_{n-1},\cdots,q_{0}}\). This circuit performs the operation to compute the weighted sum of qubit registers:
where \(s\) is the number of sum qubits required. This can be computed as
or \(s=1\) if the sum of the weights is 0 (then the expression in the logarithm is invalid).
For qubits in a circuit diagram, the first weight applies to the upper-most qubit. For an example where the state of 4 qubits is added into a sum register, the circuit can be schematically drawn as
┌────────┐
state_0: ┤0 ├ | state_0 * weights[0]
│ │ |
state_1: ┤1 ├ | + state_1 * weights[1]
│ │ |
state_2: ┤2 ├ | + state_2 * weights[2]
│ │ |
state_3: ┤3 ├ | + state_3 * weights[3]
│ │
sum_0: ┤4 ├ |
│ Adder │ |
sum_1: ┤5 ├ | = sum_0 * 2^0 + sum_1 * 2^1 + sum_2 * 2^2
│ │ |
sum_2: ┤6 ├ |
│ │
carry_0: ┤7 ├
│ │
carry_1: ┤8 ├
│ │
control_0: ┤9 ├
└────────┘
Therefore, the total number of qubits used in the circuit is \(n + s + c + k\). \(c\) is the number of carry qubits used internally by the adder implementation, which is set as \(s-1\) to store the carry information for corresponding qubits except the most significant qubit. Operations on these carry qubits will be uncomputed finally. \(k\) is the number of control qubits which are used as the ancillae for MCX gate instead of the general meaning of controlled qubits and gates in quantum computing.
Test expectations:
The carry-free result is stored in the \(s\)-qubit register, making the probability of the corresponding basis state 1, while the input register remains unchanged. The result can be obtained by measurement.
Doc reference: [35]
full_adder.py#
Callee: FullAdder
Compute the sum of two \(n\)-sized qubit registers, including carry-in and -out qubits, thereby \(2n+2\) qubits in total. In detail, we present the index of the four registers:
Index |
\(0\) |
\(1 \sim n\) |
\(n+1 \sim 2n\) |
\(2n+1\) |
|---|---|---|---|---|
Register |
cin |
a |
b |
cout |
For two registers \(\ket{a}_{n}\) and \(\ket{b}_{n}\) with \(n\) qubits each, an adder performs the following operation: (Compared to [36], we intend to present a more accurate mathematical representation here to include all the registers.)
where
The carry-out qubit \(\ket{c_{\text{out}}}_1\) holds the value of the most significant bit of the sum \(a + b + c_{\text{in}}\).
Doc reference: [36]
API#
qolumbina.programs.quantum_adder.draper_adder#
- class DraperAdder(input_qubits, name=None)[source]#
Bases:
QuantumCircuitQFT-based quantum adder (Draper Adder), where addition is modulo 2^n.
- Parameters:
input_qubits (int) – The number of qubits in each of the two addends, i.e., \(n\) for both addends \(\ket{x}_n\) and \(\ket{y}_n\).
name (str | None) – Optional name of the circuit.
- ApplyIQFT(qc, qs)[source]#
Apply inverse QFT on the qubits in qs without the final swap layer. Remember that QFT is the one included in our repository.
- Parameters:
qc (QuantumCircuit)
qs (list[int])
- Return type:
None
- ApplyQFT(qc, qs)[source]#
Apply QFT on the qubits in qs without the final swap layer. Remember that QFT is the one included in our repository.
- Parameters:
qc (QuantumCircuit)
qs (list[int])
- Return type:
None
qolumbina.programs.quantum_adder.full_adder#
Compute the sum of two equally sized qubit registers.
- class FullAdder(num_state_qubits, label=None)[source]#
Bases:
QuantumCircuitCompute the sum of two \(n\)-sized qubit registers, including carry-in and -out bits.
- Parameters:
num_state_qubits (int) – The number of qubits \(n\) in each of the registers.
name – The name of the circuit.
label (str | None)
- property num_state_qubits: int#
The number of state qubits, i.e. the number of bits in each input register.
- Returns:
The number of state qubits.
qolumbina.programs.quantum_adder.weighted_adder#
Compute the weighted sum of qubit states.
- class WeightedAdder(num_state_qubits, weights=None, name='adder')[source]#
Bases:
QuantumCircuitA circuit to compute the weighted sum of qubit registers.
- Parameters:
num_state_qubits (int) – The number of state qubits.
weights (Optional[List[int]]) – list of non-negative integer weights \(\lambda_{0},\cdots,\lambda_{n-1}\). If None, all weights are set to 1.
name (str) – The name of the circuit.
- Raises:
ValueError – If weights is not None and contains non-integer values.
- property num_carry_qubits: int#
The number of carry qubits required to compute the sum.
Note that this is not necessarily equal to the number of ancilla qubits, these can be queried using
num_ancilla_qubits.- Returns:
The number of carry qubits required to compute the sum.
- property num_control_qubits: int#
The number of additional control qubits required.
Note that the total number of ancilla qubits can be obtained by calling the method
num_ancilla_qubits.- Returns:
The number of additional control qubits required (0 or 1).
- property num_state_qubits: int#
The number of qubits to be summed.
- Returns:
The number of state qubits.
- property num_sum_qubits: int#
The number of sum qubits in the circuit.
- Returns:
The number of qubits needed to represent the weighted sum of the qubits.
- property weights: List[int]#
The weights for the qubit states.
- Returns:
The weight for the qubit states.