Operators and State functions are the building blocks of Quantum Algorithms.
A library for Quantum Algorithms & Applications is more than a collection of algorithms wrapped in Python functions. It needs to provide tools to make writing algorithms simple and easy. This is the layer of modules between the circuits and algorithms, providing the language and computational primitives for QA&A research.
We call this layer the Operator Flow. It works by unifying computation with theory through the common language of functions and operators, in a way which preserves physical intuition and programming freedom. In the Operator Flow, we construct functions over binary variables, manipulate those functions with operators, and evaluate properties of these functions with measurements.
The Operator Flow is meant to serve as a lingua franca between the theory and implementation of Quantum Algorithms & Applications. Meaning, the ultimate goal is that when theorists speak their theory in the Operator Flow, they are speaking valid implementation, and when the engineers speak their implementation in the Operator Flow, they are speaking valid physical formalism. To be successful, it must be fast and physically formal enough for theorists to find it easier and more natural than hacking Matlab or NumPy, and the engineers must find it straightforward enough that they can learn it as a typical software library, and learn the physics naturally and effortlessly as they learn the code. There can never be a point where we say “below this level this is all hacked out, don’t come down here, stay in the interface layer above.” It all must be clear and learnable.
Before getting into the details of the code, it’s important to note that three mathematical concepts unpin the Operator Flow. We derive most of the inspiration for the code structure from John Watrous’s formalism (but do not follow it exactly), so it may be worthwhile to review Chapters I and II, which are free online, if you feel the concepts are not clicking.
1. An n-qubit State function is a complex function over n binary variables, which we will often refer to as n-qubit binary strings. For example, the traditional quantum “zero state” is a 1-qubit state function, with a definition of f(0) = 1 and f(1) = 0.
2. An n-qubit Operator is a linear function taking n-qubit state functions to n-qubit state functions. For example, the Pauli X Operator is defined by f(Zero) = One and f(One) = Zero. Equivalently, an Operator can be defined as a complex function over two n-qubit binary strings, and it is sometimes convenient to picture things this way. By this definition, our Pauli X can be defined by its typical matrix elements, f(0, 0) = 0, f(1, 0) = 1, f(0, 1) = 1, f(1, 1) = 0.
3. An n-qubit Measurement is a functional taking n-qubit State functions to complex values. For example, a Pauli Z Measurement can be defined by f(Zero) = 0 and f(One) = 1.
While every effort has been made to make programming the Operator Flow similar to mathematical
notation, in some places our hands are tied by the design of Python. In particular, when using
mathematical operators such as
^ (tensor product), beware that these follow
Python operator precedence rules. For example,
I^X + X^I will actually be interpreted as
I ^ (X+X) ^ I == 2 * I^X^I. In these cases,
you should use extra parentheses, like
(I ^ X) + (X ^ I), or use the relevant method calls.
Below, you’ll find a base class for all Operators, some convenience immutable global variables which simplify Operator construction, and two groups of submodules: Operators and Converters.
Operator Base Class¶
The OperatorBase serves as the base class for all Operators, State functions and measurements, and enforces the presence and consistency of methods to manipulate these objects conveniently.
A base class for all Operators: PrimitiveOps, StateFns, ListOps, etc.
operator_globals is a set of immutable Operator instances that are convenient building
blocks to reach for while working with the Operator flow.
- One qubit Pauli operators:
- Clifford+T, and some other common non-parameterized gates:
- One qubit states:
The Operators submodules include the PrimitiveOp, ListOp, and StateFn class groups which represent the primary Operator modules.
Primitive Operators (qiskit.opflow.primitive_ops)
List Operators (qiskit.opflow.list_ops)
State Functions (qiskit.opflow.state_fns)
The Converter submodules include objects which manipulate Operators, usually recursing over an
Operator structure and changing certain Operators’ representation. For example, the
PauliExpectation traverses an Operator structure, and replaces all of the
OperatorStateFn measurements containing non-diagonal Pauli terms into
diagonalizing circuits following by
OperatorStateFn measurement containing
only diagonal Paulis.
Operator Evolutions (qiskit.opflow.evolutions)
Compute commutator of op_a and op_b.
Compute anti-commutator of op_a and op_b.
Compute symmetric double commutator of op_a, op_b and op_c.