Quantum Objects¶
The primary user-facing type is Qobj
, which all users will have
interacted with as it represents any quantum object in QuTiP.
Qobj
consists of two major components: the underlying data
representation of the object, and information about what object is being
represented. In fact, Qobj
itself is only really responsible for
managing this “auxiliary” information, ensuring that all mathematical operations
on the data make sense, and neatly wrapping the data-layer functions to be more
convenient for the user. All the numeric heavy lifting is handled by the data
layer.
Data Store¶
The data is actually stored in the data
attribute of a
Qobj
. This is always a “data-layer type”, which will be covered
in more detail in the coming sections. The different available types store the
data in different manners, such as full two-dimensional dense matrices (like
NumPy arrays) or compressed sparse matrix formats, as different formats have
different advantages. Qobj
in general does not care what form its
data is stored in, as all numerical operations are handed off to the data-layer
dispatchers, which will ensure the correct specialised methods are called.
Typically these data layer types do not expose buffers to Python-space
programmes directly, though individual types may have an as_array()
,
as_scipy()
, or similar method. This is for speed and memory-safety. Once
Python can access the underlying data buffers directly, all references to them
must be managed by the garbage collector to ensure that nothing goes stale, even
if only partial slices onto the data are taken. To access a copy of the data,
Qobj
exposes the full()
method, which will
always return a two-dimensional numpy.ndarray
. If your object is too
large to reasonably have a dense-matrix representation, you will need to use the
specific methods on the data-layer type that is used.
The amount of information guaranteed to be stored by data-layer types is very
small—sufficient to know whether a linear algebra operation can take place.
This is currently just the shape of the data being represented; there is no
information on Hilbert space (tensor product) dimensions, what type of object
the data represents, or anything else. This is all managed by
Qobj
.
Auxiliary Information¶
Qobj
contains several pieces of auxiliary information about the
object being represented. The major parts are:
qutip.Qobj.dims
The tensor-product structure that this quantum object lives in. This is a list of two elements—the “left” dimensions and the “right” dimensions. For example, an operator on a Hilbert space formed of two qubits has
dims
of[[2, 2], [2, 2]]
. A state (a “ket”) in the same space has dimensions of[[2, 2], [1, 1]]
. The data structure storing these two objects would not keep this information; theshape
attributes would respectively be simply(4, 4)
and(4, 1)
.qutip.Qobj.type
The type of object represented by this
Qobj
. This is typically derived fromdims
. This is a string, containing a human-readable description of what type the object is, such as"oper"
,"ket"
or"bra"
.qutip.Qobj.superrep
If this object is a super-operator, then this attribute is a string describing the particular representation used, such as the default
"super"
or something more specific like"choi"
.
Methods¶
As Qobj
is the primary Python user-facing type, it provides all
the Python niceties and “magic” methods, such as __add__()
,
__mul__()
and so forth. Qobj
will check that
the operation makes sense, returning NotImplemented
on failure, but a
successful output will typically require passing off to the data layer. The
data layer types themselves generally do not have these magic methods, as they
are not designed to be manipulated by user code in Python.
In addition to the operator-overloading methods, Qobj
also
provides many quantum-specific mathematical operations, such as
dag()
, norm()
, proj()
and
eigenstates()
. Typically these are pass-throughs to the data
layer, as Qobj
accesses its own data using the abstract interface
defined there.
Qobj
adds in its own __repr__()
methods for nice
output in REPLs, and includes IPython and Jupyter integration. When running in
a rich environment, the _repr_latex_()
method will be called
to better format the output.