2
$\begingroup$

It seems like I can use https://qiskit.org/documentation/stubs/qiskit.circuit.random.random_circuit.html but I would like to control the gates that are allowed.

What is an efficient way to make random circuits with a fixed set of gates?

$\endgroup$

2 Answers 2

4
$\begingroup$

I think you should report of "feature request" issue if you have a good use case for this. It should not be hard to implement and I could help with it.

If by any chance your fixed set of gates is based on the amount of qubits involved in gate, you can control that with max_operands. For example, you can exclude CCXGate and CSwapGate (3-qubit operands) with max_operand=2.

If this is not the case, the source code for random_circuit seems straightforward to modify for your need. You can remove or add the gates from *_q_ops and *_param variables on top.

def random_circuit(num_qubits, depth, max_operands=3, measure=False,
                   conditional=False, reset=False, seed=None):
    
    if max_operands < 1 or max_operands > 3:
        raise CircuitError("max_operands must be between 1 and 3")

    one_q_ops = [IGate, U1Gate, U2Gate, U3Gate, XGate, YGate, ZGate,
                 HGate, SGate, SdgGate, TGate, TdgGate, RXGate, RYGate, RZGate]
    one_param = [U1Gate, RXGate, RYGate, RZGate, RZZGate, CU1Gate, CRZGate]
    two_param = [U2Gate]
    three_param = [U3Gate, CU3Gate]
    two_q_ops = [CXGate, CYGate, CZGate, CHGate, CRZGate,
                 CU1Gate, CU3Gate, SwapGate, RZZGate]
    three_q_ops = [CCXGate, CSwapGate]

    qr = QuantumRegister(num_qubits, 'q')
    qc = QuantumCircuit(num_qubits)

    if measure or conditional:
        cr = ClassicalRegister(num_qubits, 'c')
        qc.add_register(cr)

    if reset:
        one_q_ops += [Reset]

    if seed is None:
        seed = np.random.randint(0, np.iinfo(np.int32).max)
    rng = np.random.default_rng(seed)

    # apply arbitrary random operations at every depth
    for _ in range(depth):
        # choose either 1, 2, or 3 qubits for the operation
        remaining_qubits = list(range(num_qubits))
        while remaining_qubits:
            max_possible_operands = min(len(remaining_qubits), max_operands)
            num_operands = rng.choice(range(max_possible_operands)) + 1
            rng.shuffle(remaining_qubits)
            operands = remaining_qubits[:num_operands]
            remaining_qubits = [q for q in remaining_qubits if q not in operands]
            if num_operands == 1:
                operation = rng.choice(one_q_ops)
            elif num_operands == 2:
                operation = rng.choice(two_q_ops)
            elif num_operands == 3:
                operation = rng.choice(three_q_ops)
            if operation in one_param:
                num_angles = 1
            elif operation in two_param:
                num_angles = 2
            elif operation in three_param:
                num_angles = 3
            else:
                num_angles = 0
            angles = [rng.uniform(0, 2 * np.pi) for x in range(num_angles)]
            register_operands = [qr[i] for i in operands]
            op = operation(*angles)

            # with some low probability, condition on classical bit values
            if conditional and rng.choice(range(10)) == 0:
                value = rng.integers(0, np.power(2, num_qubits))
                op.condition = (cr, value)

            qc.append(op, register_operands)

    if measure:
        qc.measure(qr, cr)

    return qc
$\endgroup$
1
  • $\begingroup$ That's neat, I can indeed modify the source code of random circuit. It's probably not useful enough for most people to make a feature request but it's nice to have for me. Thank you! $\endgroup$ Commented Sep 13, 2020 at 0:49
1
$\begingroup$

You have the random_circuit function in qiskit.circuit.random to generate a random circuit of arbitrary size and form. Have a look at the documentation. This function will generate a random circuit by randomly selecting gates from the set of standard gates in qiskit.extensions.

The signature of the function with all the params is the following:

random_circuit(num_qubits, depth, max_operands=3, measure=False, conditional=False, reset=False, seed=None, *, n_qubits=None)

Following code

from qiskit.circuit.random import random_circuit

circ = random_circuit(2, 2, measure=True)
circ.draw(output='mpl')

will produce, for instance, this circuit:

a qiskit random circuit

Just in case you need coding your own function, the whole source code of that function is here: https://qiskit.org/documentation/stable/0.19/_modules/qiskit/circuit/random/utils.html#random_circuit

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.