← Atlas

Basic circuits · Distribution loading

Loading a probability distribution (uniformly controlled rotations)

Puts a list of 2ⁿ probabilities into n qubits as amplitudes √p, exactly, with one uniformly controlled RY rotation per qubit.

Exact & formalUpdated

A small worked example, computed in your browser. It is not a result from this record's papers.

Loading a binomial distribution into 3 qubits

3 qubits, loading Binomial(7, ½): x = 0…7 with probability C(7, x)/128, as the amplitudes √p.

q0q1q2Step 1 of 3 · Split in halvesSplit in halvesStep 2 of 3 · Split in quartersSplit in quartersStep 3 of 3 · Split in eighthsSplit in eighths

Step 1 of 3 · Split in halves

Probability of each outcome after this step

  • 00050%
  • 10050%
  1. One RY on qubit 2 splits the probability between the lower half, x = 0…3, and the upper half, x = 4…7. Each half of this distribution holds exactly ½, so the angle is π/2.

    Probability spreads from 1 outcome to 2. All 2 are equally likely.

  2. Within each half, the next split is between its two quarters. The two halves need different angles, so qubit 2 selects the angle: a uniformly controlled rotation, two RY and two CX.

    Probability spreads from 2 outcomes to 4. This is the step that entangles the qubits: from here on no single qubit has a state of its own, only the register as a whole does.

  3. The last split, between neighbours, needs four angles, one per quarter, selected by qubits 1 and 2: four RY and four CX. After it the eight probabilities are C(7, x)/128.

    Probability spreads from 4 outcomes to 8.

Readout Measuring gives x with probability C(7, x)/128: 1, 7, 21, 35, 35, 21, 7 and 1 in 128. The check compares all eight with the input, to within 10⁻⁹.

Open in Studio
  • Steps3
  • Wires3
  • Qubits3
  • Gate count (n=3)7 RY + 6 CX
  • Rotation layers3 (RY: 1 + 2 + 4)
  • Papers4
Native
load_distribution.py
import numpy as np
from math import comb
from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector


def gray(i):
    return i ^ (i >> 1)


def uniformly_controlled_ry(qc, alphas, controls, target):
    # Möttönen et al. (quant-ph/0407010), Fig. 2 and Eq. (3):
    # 2^k RY rotations and 2^k CNOTs for k controls.
    k = len(controls)
    if k == 0:
        qc.ry(alphas[0], target)
        return
    size = 2**k
    thetas = [
        sum((-1) ** bin(j & gray(i)).count("1") * alphas[j] for j in range(size)) / size
        for i in range(size)
    ]
    for i in range(size):
        qc.ry(thetas[i], target)
        flipped = (gray(i) ^ gray((i + 1) % size)).bit_length() - 1
        qc.cx(controls[flipped], target)


def load_distribution(p):
    # Qubit 0 is the least significant bit of x. Level k splits each block of
    # 2^k consecutive values between its lower and upper half.
    p = np.asarray(p, dtype=float)
    n = int(np.log2(len(p)))
    qc = QuantumCircuit(n)
    for k in range(n, 0, -1):
        blocks = p.reshape(-1, 2**k)
        upper = blocks[:, 2 ** (k - 1):].sum(axis=1)
        total = blocks.sum(axis=1)
        alphas = [2 * np.arcsin(np.sqrt(u / t)) if t > 0 else 0.0 for u, t in zip(upper, total)]
        uniformly_controlled_ry(qc, alphas, controls=list(range(k, n)), target=k - 1)
    return qc


p = np.array([comb(7, x) for x in range(8)]) / 128
qc = load_distribution(p)
probabilities = Statevector.from_instruction(qc).probabilities()
print(np.allclose(probabilities, p, atol=1e-9))  # True
print(qc.count_ops())  # 7 ry, 6 cx

FINAL_CIRCUIT = qc

References

Exact & formal
  • Exact statevector simulation
  • Verified by construction
  • Peer-reviewed paper
Method
Leona's load_distribution block builds the circuit for Binomial(7, ½) on 3 qubits, and the exact statevector's outcome probabilities are compared with C(7, x)/128 for every x. A separate test holds the block to the target amplitudes for random probability lists on 1 to 6 qubits, and holds its gate count to 2ⁿ − 2 CNOTs and 2ⁿ − 1 RY.
Result
Pass · all eight probabilities match C(7, x)/128 to within 10⁻⁹.
Caveat
The circuit is exact but not efficient: its gate count grows with 2ⁿ. The Qiskit code on this page builds the same circuit by hand from the same angles, with the CNOTs of each rotation in a different order from Leona's block and the same count, 7 RY and 6 CX. Qiskit's own StatePreparation builds a different circuit: on this example it uses 4 CNOTs (Qiskit 2.5.2, transpiled to CX and U with no optimisation).
Transformation of quantum states using uniformly controlled rotations ↗
Kind
curated reference
Reviewed by
Leona Quantum curation pass
License
CC BY 4.0-compatible reference metadata
state preparationdistribution loadingamplitude encodinguniformly controlled rotationbinomial distribution

Atlas stars stay in the public catalog. Saving this entry to your workspace starts an unstarred private copy.