qnet.algebra.core.abstract_quantum_algebra module

Common algebra of “quantum” objects

Quantum objects have an associated Hilbert space, and they (at least partially) summation, products, multiplication with a scalar, and adjoints.

The algebra defined in this module is the superset of the Hilbert space algebra of states (augmented by the tensor product), and the C* algebras of operators and superoperators.

Summary

Classes:

QuantumAdjoint Base class for adjoints of quantum expressions
QuantumDerivative Symbolic partial derivative
QuantumExpression Base class for expressions associated with a Hilbert space
QuantumIndexedSum Base class for indexed sums
QuantumOperation Base class for operations on quantum expression
QuantumPlus General implementation of addition of quantum expressions
QuantumSymbol Symbolic element of an algebra
QuantumTimes General implementation of product of quantum expressions
ScalarTimesQuantumExpression Product of a Scalar and a QuantumExpression
SingleQuantumOperation Base class for operations on a single quantum expression

Functions:

Sum Instantiator for an arbitrary indexed sum.
ensure_local_space Ensure that the given hs is an instance of LocalSpace.

__all__: QuantumAdjoint, QuantumDerivative, QuantumExpression, QuantumIndexedSum, QuantumOperation, QuantumPlus, QuantumSymbol, QuantumTimes, ScalarTimesQuantumExpression, SingleQuantumOperation, Sum

Reference

class qnet.algebra.core.abstract_quantum_algebra.QuantumExpression(*args, **kwargs)[source]

Bases: qnet.algebra.core.abstract_algebra.Expression

Base class for expressions associated with a Hilbert space

is_zero

Check whether the expression is equal to zero.

Specifically, this checks whether the expression is equal to the neutral element for the addition within the algebra. This does not generally imply equality with a scalar zero:

>>> ZeroOperator.is_zero
True
>>> ZeroOperator == 0
False
space

The HilbertSpace on which the operator acts non-trivially

adjoint()[source]

The Hermitian adjoint of the Expression

dag()[source]

Alias for adjoint()

expand()[source]

Expand out distributively all products of sums.

Note

This does not expand out sums of scalar coefficients. You may use simplify_scalar() for this purpose.

simplify_scalar(func=<function simplify>)[source]

Simplify all scalar symbolic (SymPy) coefficients by appyling func to them

diff(sym, n=1, expand_simplify=True)[source]

Differentiate by scalar parameter sym.

Parameters:
  • sym (Symbol) – What to differentiate by.
  • n (int) – How often to differentiate
  • expand_simplify (bool) – Whether to simplify the result.
Returns:

The n-th derivative.

series_expand(param, about, order)[source]

Expand the expression as a truncated power series in a scalar parameter.

When expanding an expr for a parameter \(x\) about the point \(x_0\) up to order \(N\), the resulting coefficients \((c_1, \dots, c_N)\) fulfill

\[\text{expr} = \sum_{n=0}^{N} c_n (x - x_0)^n + O(N+1)\]
Parameters:
  • param (Symbol) – Expansion parameter \(x\)
  • about (Scalar) – Point \(x_0\) about which to expand
  • order (int) – Maximum order \(N\) of expansion (>= 0)
Return type:

tuple

Returns:

tuple of length order + 1, where the entries are the expansion coefficients, \((c_0, \dots, c_N)\).

Note

The expansion coefficients are “type-stable”, in that they share a common base class with the original expression. In particular, this applies to “zero” coefficients:

>>> expr = KetSymbol("Psi", hs=0)
>>> t = sympy.symbols("t")
>>> assert expr.series_expand(t, 0, 1) == (expr, ZeroKet)
class qnet.algebra.core.abstract_quantum_algebra.QuantumSymbol(label, *sym_args, hs)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumExpression

Symbolic element of an algebra

Parameters:
  • label (str or SymbolicLabelBase) – Label for the symbol
  • sym_args (Scalar) – optional scalar arguments. With zero sym_args, the resulting symbol is a constant. With one or more sym_args, it becomes a function.
  • hs (HilbertSpace, str, int, tuple) – the Hilbert space associated with the symbol. If a str or an int, an implicit (sub-)instance of LocalSpace with a corresponding label will be created, or, for a tuple of str or int, a ProducSpace. The type of the implicit Hilbert space is set by :func:.init_algebra`.
label

Label of the symbol

args

Tuple of positional arguments, consisting of the label and possible sym_args

kwargs

Dict of keyword arguments, containing only hs

sym_args

Tuple of scalar arguments of the symbol

space

The HilbertSpace on which the operator acts non-trivially

free_symbols

Set of free SymPy symbols contained within the expression.

class qnet.algebra.core.abstract_quantum_algebra.QuantumOperation(*operands, **kwargs)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumExpression, qnet.algebra.core.abstract_algebra.Operation

Base class for operations on quantum expression

These are operations on quantum expressions within the same fundamental set.

space

Hilbert space of the operation result

class qnet.algebra.core.abstract_quantum_algebra.SingleQuantumOperation(op, **kwargs)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumOperation

Base class for operations on a single quantum expression

operand

The operator that the operation acts on

class qnet.algebra.core.abstract_quantum_algebra.QuantumAdjoint(op, **kwargs)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.SingleQuantumOperation

Base class for adjoints of quantum expressions

class qnet.algebra.core.abstract_quantum_algebra.QuantumPlus(*operands, **kwargs)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumOperation

General implementation of addition of quantum expressions

order_key

alias of qnet.utils.ordering.FullCommutativeHSOrder

class qnet.algebra.core.abstract_quantum_algebra.QuantumTimes(*operands, **kwargs)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumOperation

General implementation of product of quantum expressions

order_key

alias of qnet.utils.ordering.DisjunctCommutativeHSOrder

factor_for_space(spc)[source]

Return a tuple of two products, where the first product contains the given Hilbert space, and the second product is disjunct from it.

class qnet.algebra.core.abstract_quantum_algebra.ScalarTimesQuantumExpression(coeff, term)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumExpression, qnet.algebra.core.abstract_algebra.Operation

Product of a Scalar and a QuantumExpression

classmethod create(coeff, term)[source]

Instantiate while applying automatic simplifications

Instead of directly instantiating cls, it is recommended to use create(), which applies simplifications to the args and keyword arguments according to the simplifications class attribute, and returns an appropriate object (which may or may not be an instance of the original cls).

Two simplifications of particular importance are match_replace() and match_replace_binary() which apply rule-based simplifications.

The temporary_rules() context manager may be used to allow temporary modification of the automatic simplifications that create() uses, in particular the rules for match_replace() and match_replace_binary(). Inside the managed context, the simplifications class attribute may be modified and rules can be managed with add_rule() and del_rules().

coeff
term
free_symbols

Set of free SymPy symbols contained within the expression.

space

The HilbertSpace on which the operator acts non-trivially

class qnet.algebra.core.abstract_quantum_algebra.QuantumDerivative(op, *, derivs, vals=None)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.SingleQuantumOperation

Symbolic partial derivative

\[\frac{\partial^n}{\partial x_1^{n_1} \dots \partial x_N^{n_N}} A(x_1, \dots, x_N); \qquad \text{with} \quad n = \sum_i n_i\]

Alternatively, if vals is given, a symbolic representation of the derivative (partially) evaluated at a specific point.

\[\left.\frac{\partial^n}{\partial x_1^{n_1} \dots \partial x_N^{n_N}} A(x_1, \dots, x_N) \right\vert_{x_1=v_1, \dots}\]
Parameters:
  • op (QuantumExpression) – the expression \(A(x_1, \dots, x_N)\) that is being derived
  • derivs (dict) – a map of symbols \(x_i\) to the order \(n_i\) of the derivate with respect to that symbol
  • vals (dict or None) – If not None, a map of symbols \(x_i\) to values \(v_i\) for the point at which the derivative should be evaluated.

Note

QuantumDerivative is intended to be instantiated only inside the _diff() method of a QuantumExpression, for expressions that depend on scalar arguments in an unspecified way. Generally, if a derivative can be calculated explicitly, the explicit form is preferred over the abstract QuantumDerivative.

simplifications = [<function derivative_via_diff>]
classmethod create(op, *, derivs, vals=None)[source]

Instantiate the derivative by repeatedly calling the _diff() method of op and evaluating the result at the given vals.

kwargs

Keyword arguments for the instantiation of the derivative

minimal_kwargs

Minimal keyword arguments for the instantiation of the derivative (excluding defaults)

evaluate_at(vals)[source]

Evaluate the derivative at a specific point

derivs

Mapping of symbols to the order of the derivative with respect to that symbol. Keys are ordered alphanumerically.

syms

Set of symbols with respect to which the derivative is taken

vals

Mapping of symbols to values for which the derivative is to be evaluated. Keys are ordered alphanumerically.

free_symbols

Set of free SymPy symbols contained within the expression.

bound_symbols

Set of Sympy symbols that are eliminated by evaluation.

n

The total order of the derivative.

This is the sum of the order values in derivs

class qnet.algebra.core.abstract_quantum_algebra.QuantumIndexedSum(term, *ranges)[source]

Bases: qnet.algebra.core.indexed_operations.IndexedSum, qnet.algebra.core.abstract_quantum_algebra.SingleQuantumOperation

Base class for indexed sums

space

The Hilbert space of the sum’s term

qnet.algebra.core.abstract_quantum_algebra.Sum(idx, *args, **kwargs)[source]

Instantiator for an arbitrary indexed sum.

This returns a function that instantiates the appropriate QuantumIndexedSum subclass for a given term expression. It is the preferred way to “manually” create indexed sum expressions, closely resembling the normal mathematical notation for sums.

Parameters:
  • idx (IdxSym) – The index symbol over which the sum runs
  • args – arguments that describe the values over which idx runs,
  • kwargs – keyword-arguments, used in addition to args
Returns:

an instantiator function that takes a arbitrary term that should generally contain the idx symbol, and returns an indexed sum over that term with the index range specified by the original args and kwargs.

Return type:

callable

There is considerable flexibility to specify concise args for a variety of index ranges.

Assume the following setup:

>>> i = IdxSym('i'); j = IdxSym('j')
>>> ket_i = BasisKet(FockIndex(i), hs=0)
>>> ket_j = BasisKet(FockIndex(j), hs=0)
>>> hs0 = LocalSpace('0')

Giving i as the only argument will sum over the indices of the basis states of the Hilbert space of term:

>>> s = Sum(i)(ket_i)
>>> unicode(s)
'∑_{i ∈ ℌ₀} |i⟩⁽⁰⁾'

You may also specify a Hilbert space manually:

>>> Sum(i, hs0)(ket_i) == Sum(i, hs=hs0)(ket_i) == s
True

Note that using Sum() is vastly more readable than the equivalent “manual” instantiation:

>>> s == KetIndexedSum.create(ket_i, IndexOverFockSpace(i, hs=hs0))
True

By nesting calls to Sum, you can instantiate sums running over multiple indices:

>>> unicode( Sum(i)(Sum(j)(ket_i * ket_j.dag())) )
'∑_{i,j ∈ ℌ₀} |i⟩⟨j|⁽⁰⁾'

Giving two integers in addition to the index i in args, the index will run between the two values:

>>> unicode( Sum(i, 1, 10)(ket_i) )
'∑_{i=1}^{10} |i⟩⁽⁰⁾'
>>> Sum(i, 1, 10)(ket_i) == Sum(i, 1, to=10)(ket_i)
True

You may also include an optional step width, either as a third integer or using the step keyword argument.

>>> #unicode( Sum(i, 1, 10, step=2)(ket_i) ) # TODO

Lastly, by passing a tuple or list of values, the index will run over all the elements in that tuple or list:

>>> unicode( Sum(i, (1, 2, 3))(ket_i))
'∑_{i ∈ {1,2,3}} |i⟩⁽⁰⁾'
qnet.algebra.core.abstract_quantum_algebra.ensure_local_space(hs, cls=<class 'qnet.algebra.core.hilbert_space_algebra.LocalSpace'>)[source]

Ensure that the given hs is an instance of LocalSpace.

If hs an instance of str or int, it will be converted to a cls (if possible). If it already is an instace of cls, hs will be returned unchanged.

Parameters:
  • hs (HilbertSpace or str or int) – The Hilbert space (or label) to convert/check
  • cls (type) – The class to which an int/str label for a Hilbert space should be converted. Must be a subclass of LocalSpace.
Raises:

TypeError – If hs is not a LocalSpace, str, or int.

Returns:

original or converted hs

Return type:

LocalSpace

Examples

>>> srepr(ensure_local_space(0))
"LocalSpace('0')"
>>> srepr(ensure_local_space('tls'))
"LocalSpace('tls')"
>>> srepr(ensure_local_space(0, cls=LocalSpace))
"LocalSpace('0')"
>>> srepr(ensure_local_space(LocalSpace(0)))
"LocalSpace('0')"
>>> srepr(ensure_local_space(LocalSpace(0)))
"LocalSpace('0')"
>>> srepr(ensure_local_space(LocalSpace(0) * LocalSpace(1)))
Traceback (most recent call last):
   ...
TypeError: hs must be an instance of LocalSpace