Random Ensembles#

Functions that can generate random quantum objects.

Haar-random \(U_{3}\)#

qibo.quantum_info.uniform_sampling_U3(ngates, seed=None, backend=None)[source]#

Samples parameters for Haar-random qibo.gates.U3.

Parameters:
  • ngates (int) – Total number of \(U_{3}\) gates to be sampled.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Default: None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

array of shape (ngates, \(3\)).

Return type:

ArrayLike

Random Gaussian matrix#

qibo.quantum_info.random_gaussian_matrix(dims, rank=None, mean=0.0, stddev=1.0, seed=None, backend=None)[source]#

Generates a random Gaussian Matrix.

Gaussian matrices are matrices where each entry is sampled from a Gaussian probability distribution

\[p(x) = \frac{1}{\sqrt{2 \, \pi} \, \sigma} \, \exp{\left(-\frac{(x - \mu)^{2}}{2\,\sigma^{2}}\right)}\]

with mean \(\mu\) and standard deviation \(\sigma\).

Parameters:
  • dims (int) – dimension of the matrix.

  • rank (int, optional) – rank of the matrix. If None, then rank == dims. Default: None.

  • mean (float, optional) – mean of the Gaussian distribution. Defaults to 0.

  • stddev (float, optional) – standard deviation of the Gaussian distribution. Defaults to 1.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Default: None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

Random Gaussian matrix with dimensions (dims, rank).

Return type:

ArrayLike

Random Hermitian matrix#

qibo.quantum_info.random_hermitian(dims, semidefinite=False, normalize=False, seed=None, backend=None)[source]#

Generates a random Hermitian matrix \(H\), i.e. a random matrix such that \(H = H^{\dagger}.\)

Parameters:
  • dims (int) – dimension of the matrix.

  • semidefinite (bool, optional) – if True, returns a Hermitian matrix that is also positive semidefinite. Defaults to False.

  • normalize (bool, optional) – if True and semidefinite=False, returns a Hermitian matrix with eigenvalues in the interval \([-1, \, 1]\). If True and semidefinite=True, interval is \([0, \, 1]\). Defaults to False.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

Hermitian matrix \(H\) with dimensions (dims, dims).

Return type:

ArrayLike

Random IQP circuit#

qibo.quantum_info.random_iqp(nqubits, architecture='all-to-all', closed_boundary=False, seed=None, backend=None, **kwargs)[source]#

Create a random instantaneous quantum polynomial-time (IQP) circuit.

The circuit is composed of a layer of Hadamard gates on all qubits, followed by a diagonal layer, and closed by a second layer of Hadamard gates on all qubits. The diagonal layer is composed of single-qubit qibo.gates.RZ rotations on all qubits and two-qubit qibo.gates.RZZ gates. Hence, the circuit implements

\[\mathcal{U} = H^{\otimes n} \, \exp\left( -\frac{i}{2} \sum_{j} \theta_{j} \, Z_{j} -\frac{i}{2} \sum_{(j, k) \in P} \theta_{j, k} \, Z_{j} \, Z_{k} \right) \, H^{\otimes n} \, ,\]

where \(P\) is the set of pairs of qubits coupled by the chosen architecture. All angles \(\theta_{j}\) and \(\theta_{j, k}\) are sampled uniformly at random from \([0, 2\pi)\).

Parameters:
  • nqubits (int) – number of qubits.

  • architecture (str, optional) – architecture of the layer of qibo.gates.RZZ gates. For the available options, see qibo.models.encodings.entangling_layer(). Defaults to "all-to-all".

  • closed_boundary (bool, optional) – If True and architecture not in ["all-to-all", "pyramid", "v", "x"], adds a closed-boundary condition to the entangling layer. Defaults to False.

  • seed (int or ArrayLike, optional) – either a generator of random numbers or a fixed seed to initialize a generator. If None, a random seed is used. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. For details, see the documentation of qibo.models.circuit.Circuit.

Returns:

Random IQP circuit.

Return type:

qibo.models.circuit.Circuit

References

1. M. J. Bremner, R. Jozsa, and D. J. Shepherd, Classical simulation of commuting quantum computations implies collapse of the polynomial hierarchy, Proc. R. Soc. A 467, 459 (2011).

Random isometry#

qibo.quantum_info.random_isometry(dims, rank=None, seed=None, backend=None)[source]#

Returns a Haar-random isometry \(V\), i.e. a matrix with orthonormal columns such that \(V^{\dagger} \, V = \mathbb{I}_{r}\), where \(r\) is rank.

An isometry is a distance-preserving map from a \(r\)-dimensional Hilbert space to a \(d\)-dimensional one, with \(r \leq d\), where \(d\) is dims. It is sampled from the unique probability measure that is invariant under left multiplication by \(d \times d\) unitaries. Isometries are the building blocks of Stinespring dilations of quantum channels and of Naimark dilations of POVMs. If rank == dims, then \(V\) is a Haar-random unitary matrix, as in qibo.quantum_info.random_unitary() with measure="haar".

The isometry is obtained from the (reduced) QR decomposition of a qibo.quantum_info.random_gaussian_matrix(), after fixing the phases of the diagonal of \(R\) to guarantee that the distribution is the Haar one [1].

Parameters:
  • dims (int) – dimension \(d\) of the target space, i.e. number of rows of the matrix.

  • rank (int, optional) – dimension \(r\) of the source space, i.e. number of columns of the matrix. Must satisfy rank <= dims. If None, then rank == dims. Defaults to None.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

Isometry \(V\) with dimensions (dims, rank).

Return type:

ndarray

References

  1. F. Mezzadri, How to generate random matrices from the classical compact groups, Notices of the AMS 54, 592 (2007). arXiv:math-ph/0609050.

Random unitary matrix#

qibo.quantum_info.random_unitary(dims, measure=None, seed=None, backend=None)[source]#

Returns a random Unitary operator \(U\), i.e. a random operator such that \(U^{-1} = U^{\dagger}\).

Parameters:
  • dims (int) – dimension of the matrix.

  • measure (str, optional) – probability measure in which to sample the unitary from. If None, functions returns \(\exp{(-i \, H)}\), where \(H\) is a Hermitian operator. If "haar", returns an Unitary matrix sampled from the Haar measure. Defaults to None.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

Unitary matrix \(U\) with dimensions (dims, dims).

Return type:

ArrayLike

Random quantum channel#

qibo.quantum_info.random_quantum_channel(dims, representation='liouville', measure=None, rank=None, order='row', normalize=False, precision_tol=None, validate_cp=True, nqubits=None, initial_state_env=None, seed=None, backend=None)[source]#

Creates a random superoperator from an unitary operator in one of the supported superoperator representations.

Parameters:
  • dims (int) – dimension of the \(n\)-qubit operator, i.e. \(\text{dims}=2^{n}\).

  • representation (str, optional) – If "chi", returns a random channel in the Chi representation. If "choi", returns channel in Choi representation. If "kraus", returns Kraus representation of channel. If "liouville", returns Liouville representation. If "pauli", returns Pauli-Liouville representation. If “pauli-<pauli_order>” or “chi-<pauli_order>”, (e.g. “pauli-IZXY”), returns it in the Pauli basis with the corresponding order of single-qubit Pauli elements (see qibo.quantum_info.pauli_basis()). If "stinespring", returns random channel in the Stinespring representation. Defaults to "liouville".

  • measure (str, optional) – probability measure in which to sample the unitary from. If None, functions returns \(\exp{(-i \, H)}\), where \(H\) is a Hermitian operator. If "haar", returns an Unitary matrix sampled from the Haar measure. If "bcsz", it samples an unitary from the BCSZ distribution with Kraus rank. Defaults to None.

  • rank (int, optional) – used when measure=="bcsz". Rank of the matrix. If None, then rank==dims. Defaults to None.

  • order (str, optional) – If "row", vectorization is performed row-wise. If "column", vectorization is performed column-wise. If "system", a block-vectorization is performed, which is not supported if measure="bcsz" or if representation is "liouville" or "pauli". Defaults to "row".

  • normalize (bool, optional) – used when representation="chi" or representation="pauli". If True assumes the normalized Pauli basis. If False, it assumes unnormalized Pauli basis. Defaults to False.

  • precision_tol (float, optional) – if representation="kraus", it is the precision tolerance for eigenvalues found in the spectral decomposition problem. Any eigenvalue \(\lambda <\) precision_tol is set to 0 (zero). If None, precision_tol defaults to qibo.config.PRECISION_TOL=1e-8. Defaults to None.

  • validate_cp (bool, optional) – used when representation="stinespring". If True, checks if the Choi representation of superoperator used as intermediate step is a completely positive map. If False, it assumes that it is completely positive (and Hermitian). Defaults to True.

  • nqubits (int, optional) – used when representation="stinespring". Total number of qubits in the system that is interacting with the environment. Must be equal or greater than the number of qubits that Kraus representation of the system superoperator acts on. If None, defaults to the number of qubits in the Kraus operators. Defaults to None.

  • initial_state_env (ArrayLike, optional) – used when representation="stinespring". Statevector representing the initial state of the enviroment. If None, it assumes the environment in its ground state. Defaults to None.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

Superoperator representation of a random unitary gate.

Return type:

ArrayLike

Random statevector#

qibo.quantum_info.random_statevector(dims, dtype=None, seed=None, backend=None)[source]#

Creates a random statevector \(\ket{\psi}\).

\[\ket{\psi} = \sum_{k = 0}^{d - 1} \, \sqrt{p_{k}} \, e^{i \phi_{k}} \, \ket{k} \, ,\]

where \(d\) is dims, and \(p_{k}\) and \(\phi_{k}\) are, respectively, the probability and phase corresponding to the computational basis state \(\ket{k}\).

Note

If dtype if "float64", "float32", or an equivalent type, then \(\ket{\psi} \in \mathbb{R}^{\text{dims}}\). Otherwise, \(\ket{\psi} \in \mathbb{C}^{\text{dims}}\).

Parameters:
  • dims (int) – dimension of the matrix.

  • dtype (str or type, optional) – data type for the random statevector. Options are "complex128, "complex64", "float64", or "float32". It also accepts the equivalent data types of backend’s engines, e.g. numpy.complex128 or cupy.float64. If None, defaults to backend.dtype. Defaults to None.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

Random statevector \(\ket{\psi}\).

Return type:

ArrayLike

Random density matrix#

qibo.quantum_info.random_density_matrix(dims, rank=None, pure=False, metric='hilbert-schmidt', basis=None, normalize=False, order='row', seed=None, backend=None)[source]#

Creates a random density matrix \(\rho\). If pure=True,

\[\rho = \ketbra{\psi}{\psi} \, ,\]

where \(\ket{\psi}\) is a qibo.quantum_info.random_statevector(). If pure=False, then

\[\rho = \sum_{k} \, p_{k} \, \ketbra{\psi_{k}}{\psi_{k}} \, .\]

is a mixed state.

Parameters:
  • dims (int) – dimension of the matrix.

  • rank (int, optional) – rank of the matrix. If None, then rank == dims. Ignored when pure=True. Note that, by definition, rank must be None (or equal to dims) when metric=="hilbert-schmidt". Defaults to None.

  • pure (bool, optional) – if True, returns a pure state. Defaults to False.

  • metric (str, optional) – metric to sample the density matrix from. Options: "hilbert-schmidt", "ginibre", and "bures". For "bures", states are sampled with the algorithm of Reference [1]. Defaults to "hilbert-schmidt".

  • basis (str, optional) – if None, returns random density matrix in the computational basis. If "pauli-<pauli_order>", (e.g. "pauli-IZXY"), returns it in the Pauli basis with the corresponding order of single-qubit Pauli elements (see qibo.quantum_info.pauli_basis()). Defaults to None.

  • normalize (bool, optional) – used when basis="pauli-<pauli-order>". If True returns random density matrix in the normalized Pauli basis. If False, returns state in the unnormalized Pauli basis. Defaults to False.

  • order (str, optional) – used when basis="pauli-<pauli-order>". If "row", vectorization of Pauli basis is performed row-wise. If "column", vectorization is performed column-wise. If "system", system-wise vectorization is performed. Default is "row".

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

Random density matrix \(\rho\).

Return type:

ArrayLike

References

  1. V. A. Osipov, H.-J. Sommers, and K. Życzkowski, Random Bures mixed states and the distribution of their purity, J. Phys. A: Math. Theor. 43, 055302 (2010). arXiv:0909.5094 [quant-ph].

Random Clifford#

qibo.quantum_info.random_clifford(nqubits, return_circuit=True, seed=None, backend=None, **kwargs)[source]#

Generates a random \(n\)-qubit Clifford operator, where \(n\) is nqubits. For the mathematical details, see Reference [1].

Parameters:
  • nqubits (int) – number of qubits.

  • return_circuit (bool, optional) – if True, returns a qibo.models.Circuit object. If False, returns an ArrayLike object. Defaults to True.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

  • kwargs (dict, optional) – Additional arguments used to initialize a Circuit object. For details, see the documentation of qibo.models.circuit.Circuit.

Returns:

Random Clifford operator.

Return type:

qibo.quantum_info.clifford.Clifford or qibo.models.Circuit

References

  1. S. Bravyi and D. Maslov, Hadamard-free circuits expose the structure of the Clifford group. arXiv:2003.09412 [quant-ph].

Random Pauli#

qibo.quantum_info.random_pauli(qubits, depth, max_qubits=None, subset=None, return_circuit=True, density_matrix=False, seed=None, backend=None)[source]#

Creates random Pauli operator(s).

Pauli operators are sampled from the single-qubit Pauli set \(\{I, \, X, \, Y, \, Z\}\).

Parameters:
  • qubits (int or list or ArrayLike) – if int and max_qubits=None, the number of qubits. If int and max_qubits != None, qubit index in which the Pauli sequence will act. If list or ArrayLike, indexes of the qubits for the Pauli sequence to act.

  • depth (int) – length of the sequence of Pauli gates.

  • max_qubits (int, optional) – total number of qubits in the circuit. If None, max_qubits = max(qubits). Defaults to None.

  • subset (list, optional) – list containing a subset of the 4 single-qubit Pauli operators. If None, defaults to the complete set. Defaults to None.

  • return_circuit (bool, optional) – if True, returns a qibo.models.Circuit object. If False, returns an ArrayLike with shape (qubits, depth, 2, 2) that contains all Pauli matrices that were sampled. Defaults to True.

  • density_matrix (bool, optional) – used when return_circuit=True. If True, the circuit would evolve density matrices. Defaults to False.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

all sampled Pauli operators.

Return type:

(ArrayLike or qibo.models.Circuit)

Random Pauli Hamiltonian#

qibo.quantum_info.random_pauli_hamiltonian(nqubits, max_eigenvalue=None, normalize=False, pauli_order='IXYZ', seed=None, backend=None)[source]#

Generates a random Hamiltonian in the Pauli basis.

Parameters:
  • nqubits (int) – number of qubits.

  • max_eigenvalue (int or float, optional) – fixes the value of the largest eigenvalue. If nqubits=1, there are only two eigenvalues, \(0\) and \(1\) if normalize=True, hence max_eigenvalue is ignored. Defaults to None.

  • normalize (bool, optional) – If True, fixes the gap of the Hamiltonian as 1.0. Moreover, if True, then max_eigenvalue must be > 1.0. Defaults to False.

  • pauli_order (str, optional) – corresponds to the order of 4 single-qubit Pauli elements in the basis. Defaults to “IXYZ”.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

Hamiltonian in the Pauli basis and its corresponding eigenvalues.

Return type:

tuple(ArrayLike, ArrayLike)

Random stochastic matrix#

qibo.quantum_info.random_stochastic_matrix(dims, bistochastic=False, diagonally_dominant=False, precision_tol=None, max_iterations=None, seed=None, backend=None)[source]#

Creates a random stochastic matrix.

Parameters:
  • dims (int) – dimension of the matrix.

  • bistochastic (bool, optional) – if True, matrix is row- and column-stochastic. If False, matrix is row-stochastic. Defaults to False.

  • diagonally_dominant (bool, optional) – if True, matrix is strictly diagonally dominant. Defaults to False.

  • precision_tol (float, optional) – tolerance level for how much each probability distribution can deviate from summing up to 1.0. If None, it defaults to qibo.config.PRECISION_TOL. Defaults to None.

  • max_iterations (int, optional) – when bistochastic=True, maximum number of iterations used to normalize all rows and columns simultaneously. If None, defaults to qibo.config.MAX_ITERATIONS. Defaults to None.

  • seed (int or numpy.random.Generator, optional) – Either a generator of random numbers or a fixed seed to initialize a generator. If None, initializes a generator with a random seed. Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – backend to be used in the execution. If None, it uses the current backend. Defaults to None.

Returns:

a random stochastic matrix.

Return type:

ArrayLike