Backends

In order to benefit as much as possible from the vast range of existing python functionality, this simulation library supports four separate backends. Each backend uses a distinct data type for quantum objects (kets, bras, operators, vectorized operators and superoperators) and provides an elementary set of functions that construct and operate on these objects. Backends are specified with the method keyword argument.

Warning

Although we tried to minimize deviations between backends some small differences may remain. Further, some advanced functionality is not supported for the sympy backend.

Backend Overview

Backends

Backend Name

Data Type of Quantum Objects

Benefits / Remarks

Numpy [HMW+20]

Custom data type QNdarray based on numpy.ndarray

Utilizes numpy instead of specific libraries; optimizes computational performance and portability.

Qutip [JNN20]

qutip.Qobj

Whenever possible, qutip functionality is being used. Ideal for users that are familiar with qutip, allows to smoothly extend the SimOS capabilities with qutip functionality.

Scipy Sparse [VGO+20]

Custom data type Qcsc_matrix based on scipy.sparse.csc_matrix

The main data type for all quantum objects is a scipy sparse matrix, thereby reducing storage space requirements and accelerating calculation for sparse systems.

Sympy [MSP+17]

Cutom data type QSMatrix based on sympy.matrix

Uses sympy functionality and therefore allows to obtain symbolic expressions. Note that some functionality of the library does not support this backend. In general, the sympy backend is not suited for extensive time dynamics simulations but a didactic tool allowing to obtain an intuitive understanding of a systems spin physics.

Quantum Object Data Type

The backend defines the data type of all quantum objects, i.e. kets, bras, operators , vectorized operators and superoperators. For numpy, scipy and sympy, the quantum objects are custom data types. They are based on native data types of the underlying python packages that were subclassed to enable the most important functionality of qutips qutip.Qobj. Important features of these quantum object data type classes are:

  1. The python product operator * is overloaded such that a matrix multiplication is performed instead of elementwise multiplication.

  2. An attribute Q.dims stores the structure of the quantum objects Hilbert space.

  3. In analogy to qutip, a set of additional functions directly operates on instances of the quantum object class. Note that these functions can also be accessed as f(Q, *args, **kwargs) instead of Q.f(*args, **kwargs).

Functions Operating on Quantum Object Class

Function

Command

Description

Dagger

Q.dag()

returns the adjoint of the quantum object, output is again a quantum object

Conjugate

Q.conj()

returns the conjugate of the quantum object, output is again a quantum object

Transpose

Q.trans()

returns the transpose of the quantum object, output is again a quantum object

Trace

Q.tr()

returns the trace of the quantum object, output is a scalar

Diagonal

Q.diag()

returns the diagonal of the quantum object, output is a numpy.ndarray

Unit

Q.unit()

returns the normalized quantum object, output is again a quantum object

Conjugate

Q.transform(U)

performs a basis transformation defined by the transformation matrix U, output is again a quantum object

Matrix Exponential

Q.expm()

returns the matrix exponential of the quantum object, output is again a quantum object

Partial Trace

Q.ptrace(i)

performs a partial trace, keeping only the selected ith subsystem

Eigenstates

Q.eigenstates()

returns eigenvalues and eigenvectors of the quantum object

Permutation

Q.permute(order)

permutes members of the quantum object following user specified order

To transform an object to a quantum object of any backend the tidyup(Q) function can be used. To extract the data of a quantum object as a standard numpy.ndarray() the data(Q) function can be applied.

tidyup(arg, method=None, dims=None, **kwargs)[source]

Transforms an input argument to a quantum object data type of an available backend. The data types of the individual elements of the quantum object are NOT altered by this routine.

Parameters:
  • arg – Input object.

  • method (str) – Backend to which type conversion should be performed. If omitted, the target backend is determined via the data type of the input argument.

  • dims (list) – Specifies dims attribute of the output quantum object. If dims == None but the input argument is already a quantum object with valid dims, the old dims are retained.

  • **kwargs

    See below

Keyword Arguments:
  • atol (float) – Values smaller than atol are set to 0. Only used in ‘scipy’ and ‘qutip’ backends.

Returns:

Quantum object data type.

data(arg)[source]

Returns data of a quantum object as a numpy.ndarray.

Parameters:

arg – Quantum object.

Returns:

Numpy.ndarray holding data of input quantum object.

Manipulating Quantum Objects

A series of functions for construction and basic manipulation of quantum objects is provided for all backends. For functions that construct a quantum object from scratch, the backend is specified with the method keyword argument. For all other functions, the backend is automatically detected via the data type of the input argument and type conversion to a native quantum data type of the backend is performed before the actual operation is executed.

Hilbert Space Methods

bra(N: int, m: int, method='qutip')[source]

Pure state vector (bra) for the mth basis state of an N-dimensional Hilbert space.

Parameters:
  • N (int) – Number of fock states in Hilbert space.

  • m (int) – The index of the desired state, ranging from 0-(N-1)

  • method (str) – The desired backend. Can be ‘numpy’, ‘qutip’,’sparse’ or ‘sympy’.

Returns:

The pure state vector (bra)

dm2ket(dm, tol=1e-06)[source]

Constructs a state vector (ket) from a density matrix. Does only work for pure states and normalized density matrices.

Parameters:

dm – A density matrix.

Parm tol:

Tolerance used when probing whether the input density matrix is a pure state and normalized.

Returns:

State vector (ket).

expect(oper, state)[source]

Expectation value for an operator-state pair.

Parameters:
  • oper – Operator.

  • state – State.

Returns:

Expectation value.

isbra(state)[source]

Indicates if the quantum object is a bra.

Parameters:

state – Quantum object.

Return bool:

isket(state)[source]

Indicates if the quantum object is a ket.

Parameters:

state – Quantum object.

Return bool:

isoper(state)[source]

Indicates if the quantum object is an operator.

Parameters:

state – Quantum object.

Return bool:

ket(N: int, m: int, method='qutip')[source]

Pure state vector (ket) for the mth basis state of an N-dimensional Hilbert space.

Parameters:
  • N (int) – Number of fock states in Hilbert space.

  • m (int) – The index of the desired state, ranging from 0-(N-1)

  • method (str) – The desired backend. Can be ‘numpy’, ‘qutip’,’sparse’ or ‘sympy’.

Returns:

The pure state vector (ket)

ket2dm(ket)[source]

Constructs an density matrix from a state vector with an outer product.

Parameters:

ket – A fock state vector (ket or bra)

Returns:

Density matrix.

Liouville Space Methods

applySuperoperator(L, rho)[source]

Apply superoperator to a state.

Parameters:
  • L – Superoperator (Liouvillian).

  • rho – State (density matrix).

Returns:

Propagator.

issuper(state)[source]

Indicates if the quantum object is a superoperator.

Parameters:

state – Quantum object.

Return bool:

lindbladian(a, b=None)[source]

Lindbladian superoperator for a pair of collapse operators a,b, or a single collapse operator if only a is being provided.

Parameters:
  • a – Collapse operator.

  • b – Collapse operator, None per default.

Returns:

Lindbladian superoperator.

liouvillian(H, c_ops: list)[source]

Liouvillian superoperator from a hamiltonian and a list of collapse operators.

Parameters:
  • H – Hamiltonian operator.

  • c_ops (list) – List of collapse operators.

Returns:

Liouville superoperator.

spost(op)[source]

Computes superoperator by post-multiplication by op.

Parameters:

op – Operator.

Returns:

Superoperator 1 otimes op.

spre(op)[source]

Computes superoperator by pre-multiplication by op.

Parameters:

op – Operator.

Returns:

Superoperator op.T otimes 1.

Fokker-Planck Methods

dm2fp(rho, dof, try_ket=False)[source]

Copies a density matrix to a state vector in the Fokker-Planck space.

In the Fokker-Planck space, the state vector is a vector of concatenated state vectors in Hilbert space (pure quantum states) or vectorized density matrices (mixed quantum states).

Parameters:
  • rho – Density matrix or state vector

  • dof (int) – Number of degrees of freedom. This is the number of copies.

  • try_ket (bool) – If True, the function tries to convert the density matrix to a state vector in Hilbert space.

fp2dm(v, is_hilbert, dims=None, weights=None)[source]

Converts a state vector in the Fokker-Planck space to a density matrix.

In the Fokker-Planck space, the state vector is a vector of concatenated state vectors in Hilber space (pure quantum states) or vectorized density matrices (mixed quantum states).

Parameters:
  • v – State vector in the Fokker-Planck space.

  • is_hilbert (bool) – If True, the state vector is defined in the Hilbert space. If False, the state vector is defined in the Liouville space.

  • dims (list) – dims to set. If None, dims are set as the Hilbert / Liouville part.

  • weights – Weights for the density matrix. If None, the weights are set as 1.

Additional Matrix Methods

block_diagonal(L_list)[source]

Constructs a block-diagonal matrix from a list of operators.

Parameters:

L_list (list) – A list of operators.

Returns:

A block diagonal matrix, each block is an entry of L_list.

ddrop(operator, idx: int | list)[source]

Drops dimension(s) from an operator (i.e. a quantum object).

Parameters:
  • operator – A quantum object.

  • idx – The dimension that will be dropped.

Returns:

The operator without the dropped dimensions.

diags(v, k: int = 0, method='qutip', dims=None)[source]

Constructs an operator from a diagonal or extracts a diagonal.

Parameters:
  • v – A sequence of elements to be placed along the selected diagonal or a quantum object from which diagonal is extracted.

  • k (int) – The selected diagonal

  • dims (list) – Structure of the Hilbert space, if None or omitted dims are set as [N].

  • method (str) – The desired backend. Can be ‘numpy’, ‘qutip’,’sparse’ or ‘sympy’.

Returns:

Resulting matrix.

directsum(*args)[source]

Direct sum of a series of operators. Empty, square operators may also be specified as integers.

Parameters:

*args

A series of operators, provided as a single list or multiple arguments.

Returns:

Direct product of the operators.

dpermute(operator, order: list)[source]

Permutes dimensions of an operator.

Parameters:
  • operator – A quantum object.

  • order – A list specifying the new ordering of dimensions.

Returns:

The operator with permuted dimensions.

identity(N: int, dims=None, method='qutip')[source]

Identiy Matrix of an N-dimensional Hilbert space.

Parameters:
  • N (int) – Number of Fock states in Hilbert space.

  • dims (list) – Structure of the Hilbert space, if None or omitted dims are set as [N].

  • method (str) – The desired backend. Can be ‘numpy’, ‘qutip’,’sparse’ or ‘sympy’.

Returns:

The identity matrix.

jmat(j, op_spec: str, method='qutip')[source]

Spin operator for a spin j.

Parameters:
  • j – A non-negative integer or half-integer specifying the spin

  • op_spec (str) – A string specifying the desired operator, can be ‘x’, ‘y’, ‘z’,’+’,’-’

Returns:

The spin operator.

tensor(operators: list)[source]

Tensor product of a series of operators.

Parameters:

operators – A list of operators

Returns:

Tensor product of the operators.

References

[VGO+20]

Pauli Virtanen, Ralf Gommers, Travis E. Oliphant, Matt Haberland, Tyler Reddy, David Cournapeau, Evgeni Burovski, Pearu Peterson, Warren Weckesser, Jonathan Bright, Stéfan J. van der Walt, Matthew Brett, Joshua Wilson, K. Jarrod Millman, Nikolay Mayorov, Andrew R. J. Nelson, Eric Jones, Robert Kern, Eric Larson, CJ Carey, İlhan Polat, Yu Feng, Eric W. Moore, Jake VanderPlas, Denis Laxalde, Josef Perktold, Robert Cimrman, Ian Henriksen, E.A. Quintero, Charles R Harris, Anne M. Archibald, Antônio H. Ribeiro, Fabian Pedregosa, Paul van Mulbregt, and SciPy 1.0 Contributors. SciPy 1.0: Fundamental Algorithms for Scientific Computing in Python. Nature Methods, 17(3), 261-272 (2020).

[HMW+20]

Harris, C.R., Millman, K.J., van der Walt, S.J. et al. Array programming with NumPy. Nature 585, 357–362 (2020).

[JNN20]

Johansson, J.R., Nation, P.D. and Nori, F. QuTiP : An open-source Python framework for the dynamics of open quantum systems. Comp. Phys. Comm. 183, 1760-1772 (2012).

[MSP+17]

Meurer A, Smith CP, Paprocki M, Čertík O, Kirpichev SB, Rocklin M, Kumar A, Ivanov S, Moore JK, Singh S, Rathnayake T, Vig S, Granger BE, Muller RP, Bonazzi F, Gupta H, Vats S, Johansson F, Pedregosa F, Curry MJ, Terrel AR, Roučka Š, Saboo A, Fernando I, Kulal S, Cimrman R, Scopatz A. SymPy: symbolic computing in Python. Peer J Computer Science, 3(103) (2017).