---
title: Circuit Library (latest version)
description: API reference for Circuit Library in the latest version of qiskit-c
source: https://quantum.cloud.ibm.com/docs/en/api/qiskit-c/qk-circuit-library
---

# 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

```c
// 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.

```c
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

```c
// 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.

```c
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](https://arxiv.org/abs/1811.12926)

#### Example

```c
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

```c
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](https://arxiv.org/abs/quant-ph/0508139)

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

**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.
