Skip to main content
IBM Quantum Platform

Circuit Library

The Qiskit circuit library contains functions and higher-level building blocks for building commonly used quantum circuits.


Data types

QkPauliProductRotation

struct QkPauliProductRotation

A representation of Pauli product rotation data.

A Pauli product rotation implements a rotation of an angle about an axis defined by a Pauli product on len qubits. The Pauli here is represented in ZX format with two Boolean arrays representing the Z and X components.

bool *z

Pointer to an length-len array of Z components.

bool *x

Pointer to an length-len array of X components.

size_t len

The number of Pauli terms.

QkParam *angle

The rotation angle.

QkPauliProductMeasurement

struct QkPauliProductMeasurement

A representation of Pauli product measurement data.

A Pauli product measurement implements a projection onto the eigenspace of the defined Pauli product on len qubits. The Pauli here is represented in ZX format with two Boolean arrays representing the Z and X components and can include a minus sign, indicated by flip_outcome.

bool *z

Pointer to an length-len array of Z components.

bool *x

Pointer to an length-len array of X components.

size_t len

The number of Pauli terms.

bool flip_outcome

Whether the measurement outcome has a minus sign.


Functions

qk_circuit_library_iqp

QkCircuit *qk_circuit_library_iqp(uint32_t num_qubits, const int64_t *interactions, bool check_input)

Generate an Instantaneous Quantum Polynomial (IQP) circuit from an integer interaction matrix.

The interactions matrix is interpreted as an n × n row-major array of 64-bit integers, where n = num_qubits. The diagonal entries set T-like phase powers, and the upper triangle encodes two-qubit CPhase interactions.

Safety

If num_qubits > 0, interactions must be a valid, non-null pointer to at least num_qubits * num_qubits contiguous int64_t values in row-major order. The memory pointed to by interactions must be properly aligned, readable for the duration of this call, and not mutably aliased. Passing an invalid pointer or a buffer that is too small results in undefined behaviour.

Parameters

  • num_qubits – Number of logical qubits (n). Must match the dimension of the interactions matrix.
  • interactions – Pointer to a row-major n × n matrix of type int64_t. May be NULL only if num_qubits == 0.
  • check_input – When true, this function verifies that the matrix is symmetric and returns NULL if it is not. When false, no additional validation is performed.

Returns

A newly allocated QkCircuit* on success (caller must free with qk_circuit_free), or NULL if num_qubits > 0 and interactions is NULL, or if check_input is true and the matrix is not symmetric.

qk_circuit_library_random_iqp

QkCircuit *qk_circuit_library_random_iqp(uint32_t num_qubits, int64_t seed)

Generate a random Instantaneous Quantum Polynomial (IQP) circuit.

This constructs a random symmetric integer interaction matrix internally and uses it to build an IQP circuit, mirroring the Python qiskit.circuit.library.IQP constructor.

Parameters

  • num_qubits – Number of qubits.
  • seed – RNG seed. If negative, entropy is drawn from the OS; otherwise, the given value is used as a deterministic seed.

Returns

A newly allocated QkCircuit* (caller must free with qk_circuit_free).

qk_pauli_product_rotation_clear

void qk_pauli_product_rotation_clear(QkPauliProductRotation *inst)

Clear the internal data of Rust-allocated QkPauliProductRotation.

This frees the memory of the z and x arrays and frees the angle. This function should only be called for QkPauliProductRotation objects whose data has been populated by Rust.

Example

// let `circuit` be a QkCircuit* and `index` a size_t at the position of a QkPauliProductRotation
QkPauliProductRotation inst;

// query the QkPauliProductRotation data
assert(qk_circuit_operation_kind(circuit, index) == QkOperationKind_PauliProductRotation);
qk_circuit_inst_pauli_product_rotation(circuit, index, &inst);

// do something with `inst`, and then clear the Rust-allocated data
qk_pauli_product_rotation_clear(&inst);

In contrast, this function should not be called if C already takes care of clearing the data.

bool z[4] = {false, false, true, true};
bool x[4] = {false, true, true, false};
QkParam *angle = qk_param_from_double(1.0);
QkPauliProductRotation rotation = {z, x, 4, angle};

// since this data is allocated by C, we do not call `qk_pauli_product_rotation_clear(&rotation)`!
qk_param_free(angle);

Safety

Behavior is undefined if inst is not a valid, non-null pointer to a QkPauliProductRotation, or if the internal data of QkPauliProductRotation is incoherent.

Parameters

  • inst – A pointer to the QkPauliProductRotation to clear.

qk_pauli_product_measurement_clear

void qk_pauli_product_measurement_clear(QkPauliProductMeasurement *inst)

Clear the internal data of Rust-allocated QkPauliProductMeasurement.

This frees the memory of the z and x arrays. This function should only be called for QkPauliProductMeasurement objects whose data has been populated by Rust.

Example

// let `circuit` be a QkCircuit* and `index` a size_t at the position
// of a QkPauliProductMeasurement
QkPauliProductMeasurement inst;

// query the QkPauliProductMeasurement data
assert(qk_circuit_operation_kind(circuit, index) == QkOperationKind_PauliProductMeasurement);
qk_circuit_inst_pauli_product_measurement(circuit, index, &inst);

// do something with `inst`, and then clear the Rust-allocated data
qk_pauli_product_measurement_clear(&inst);

In contrast, this function should not be called if C already takes care of clearing the data.

bool z[4] = {false, false, true, true};
bool x[4] = {false, true, true, false};
QkPauliProductMeasurement inst = {z, x, 4, true};

// since this data is allocated by C, we do not call `qk_pauli_product_measurement_clear(&inst)`

Safety

Behavior is undefined if inst is not a valid, non-null pointer to a QkPauliProductMeasurement, or if the internal data of QkPauliProductMeasurement is incoherent.

Parameters

  • inst – A pointer to the QkPauliProductMeasurement to clear.

qk_circuit_library_quantum_volume

QkCircuit *qk_circuit_library_quantum_volume(uint32_t num_qubits, size_t depth, int64_t seed)

Generate a Quantum Volume model circuit

The model circuits are random instances of circuits used to measure the Quantum Volume metric, as introduced in [1]. The model circuits consist of layers of Haar random elements of SU(4) applied between corresponding pairs of qubits in a random bipartition.

This function is multithreaded and will launch a thread pool with threads equal to the number of CPUs by default. You can tune the number of threads with the RAYON_NUM_THREADS environment variable. For example, setting RAYON_NUM_THREADS=4 would limit the thread pool to 4 threads.

[1] A. Cross et al. Validating quantum computers using randomized model circuits, Phys. Rev. A 100, 032328 (2019). arXiv:1811.12926

Example

QkCircuit *qc = qk_circuit_library_quantum_volume(10, 10, -1)

Parameters

  • num_qubits – The number qubits to use for the generated circuit.
  • depth – The number of layers for the generated circuit.
  • seed – An RNG seed used for generating the random SU(4) matrices used in the output circuit. If the provided number is negative the seed used will be soured from system entropy.

Returns

A pointer to the quantum volume circuit.

qk_circuit_library_suzuki_trotter

QkCircuit *qk_circuit_library_suzuki_trotter(const QkObs *op, uint32_t order, uint32_t reps, double time, bool preserve_order, bool insert_barriers)

Generate a circuit using the higher order Suzuki-Trotter product formula from an observable.

The Suzuki-Trotter formulas improve the error of the Lie-Trotter approximation. In this implementation, the operators are provided as sum terms of a Pauli operator. Higher order decompositions are based on recursions, see Ref. [1] for more details.

Example

QkObs *obs = qk_obs_zero(1);

QkBitTerm op1_bits[1] = {QkBitTerm_X};
QkObsTerm term1 = {(QkComplex64){1.0, 0.0}, 1, op1_bits, (uint32_t[1]){0}, 1};
qk_obs_add_term(obs, &term1);

QkBitTerm op2_bits[1] = {QkBitTerm_Y};
QkObsTerm term2 = {(QkComplex64){1.0, 0.0}, 1, op2_bits, (uint32_t[1]){0}, 1};
qk_obs_add_term(obs, &term2);

QkCircuit *qc = qk_circuit_library_suzuki_trotter(obs, 2, 1, 0.1, true, false);

qk_obs_free(obs);
qk_circuit_free(qc);

Safety

Behavior is undefined op is not a valid, non-null pointer to a QkObs.

References

[1]: D. Berry, G. Ahokas, R. Cleve and B. Sanders, “Efficient quantum algorithms for simulating sparse Hamiltonians” (2006). arXiv:quant-ph/0508139

[2]: N. Hatano and M. Suzuki, “Finding Exponential Product Formulas of Higher Orders” (2005). arXiv:math-ph/0506007

Parameters

  • op – The QkObs containing the sum of the Pauli terms.
  • order – The order of the product formula.
  • reps – The number of time steps.
  • time – The evolution time.
  • preserve_order – If false, allows reordering the terms of the operator to potentially yield a shallower evolution circuit. Not relevant when synthesizing an observable with a single term.
  • insert_barriers – Whether to insert barriers between the terms evolutions.

Returns

A pointer to the generated circuit.

Was this page helpful?
Report a bug, typo, or request content on GitHub.