Skip to content

Random Circuit (benchmarking & fuzz-testing)

Random circuit generation for benchmarking or fuzz-testing -- the same role Qiskit's random_circuit plays.

random_circuit

Random circuit generation for benchmarking and fuzz-testing -- the same purpose Qiskit's random_circuit serves.

random_circuit

random_circuit(
    n_qubits,
    n_gates,
    seed=None,
    gate_set=None,
    two_qubit_prob=0.4,
)

Build a random circuit for benchmarking or fuzz-testing.

Parameters

n_qubits : int Number of qubits, must be >= 1. n_gates : int Number of gate operations to generate, must be >= 0. seed : int | numpy.random.Generator, optional Seed (or an existing Generator) for reproducible circuits. gate_set : iterable of str, optional Restrict generation to this set of gate names, mixing 1- and 2-qubit gates freely (default spans both: h, x, y, z, s, sdg, t, tdg, sx, rx, ry, rz, cx, cz, cy, swap). Unrecognized names raise immediately rather than failing later inside run_circuit. two_qubit_prob : float Probability in [0, 1] of picking a 2-qubit gate at each step. Ignored (forced to single-qubit gates) once n_qubits < 2, or once gate_set excludes every 2-qubit gate name.

Returns

list[tuple]

Source code in dense_evolution/random_circuit.py
def random_circuit(n_qubits, n_gates, seed=None, gate_set=None, two_qubit_prob=0.4):
    """
    Build a random circuit for benchmarking or fuzz-testing.

    Parameters
    ----------
    n_qubits : int
        Number of qubits, must be >= 1.
    n_gates : int
        Number of gate operations to generate, must be >= 0.
    seed : int | numpy.random.Generator, optional
        Seed (or an existing Generator) for reproducible circuits.
    gate_set : iterable of str, optional
        Restrict generation to this set of gate names, mixing 1- and
        2-qubit gates freely (default spans both: h, x, y, z, s, sdg, t,
        tdg, sx, rx, ry, rz, cx, cz, cy, swap). Unrecognized names raise
        immediately rather than failing later inside run_circuit.
    two_qubit_prob : float
        Probability in [0, 1] of picking a 2-qubit gate at each step.
        Ignored (forced to single-qubit gates) once n_qubits < 2, or once
        gate_set excludes every 2-qubit gate name.

    Returns
    -------
    list[tuple]
    """
    if n_qubits < 1:
        raise ValueError(f"random_circuit needs at least 1 qubit, got {n_qubits}")
    if n_gates < 0:
        raise ValueError(f"n_gates must be >= 0, got {n_gates}")
    if not (0.0 <= two_qubit_prob <= 1.0):
        raise ValueError(f"two_qubit_prob must be in [0, 1], got {two_qubit_prob}")

    rng = seed if isinstance(seed, np.random.Generator) else np.random.default_rng(seed)

    if gate_set is not None:
        gate_set = list(gate_set)
        unknown = set(gate_set) - _ALL_KNOWN
        if unknown:
            raise ValueError(f"unknown gate name(s) in gate_set: {sorted(unknown)}")
        one_q_static = [g for g in gate_set if g in _1Q_STATIC]
        one_q_param = [g for g in gate_set if g in _1Q_PARAMETRIC]
        two_q = [g for g in gate_set if g in _2Q_STATIC]
    else:
        one_q_static = list(_1Q_STATIC)
        one_q_param = list(_1Q_PARAMETRIC)
        two_q = list(_2Q_STATIC) if n_qubits >= 2 else []

    one_q_pool = one_q_static + one_q_param
    if not one_q_pool and not two_q:
        raise ValueError("gate_set leaves no usable gates for this n_qubits")

    ops = []
    for _ in range(n_gates):
        use_two_qubit = (
            bool(two_q) and n_qubits >= 2
            and (not one_q_pool or rng.random() < two_qubit_prob)
        )
        if use_two_qubit:
            name = two_q[rng.integers(len(two_q))]
            a, b = rng.choice(n_qubits, size=2, replace=False)
            ops.append((name, int(a), int(b)))
        else:
            name = one_q_pool[rng.integers(len(one_q_pool))]
            q = int(rng.integers(n_qubits))
            if name in _1Q_PARAMETRIC:
                theta = float(rng.uniform(0, 2 * np.pi))
                ops.append((name, q, theta))
            else:
                ops.append((name, q))
    return ops