qnet.algebra.core.scalar_algebra module

Implementation of the scalar (quantum) algebra

Summary

Classes:

Scalar Base class for Scalars
ScalarDerivative Symbolic partial derivative of a scalar
ScalarExpression Base class for scalars with non-scalar arguments
ScalarIndexedSum Indexed sum over scalars
ScalarPlus Sum of scalars
ScalarPower A scalar raised to a power
ScalarTimes Product of scalars
ScalarValue Wrapper around a numeric or symbolic value

Functions:

KroneckerDelta Kronecker delta symbol
is_scalar Check if scalar is a Scalar or a scalar value
sqrt Square root of a Scalar or scalar value

Data:

One The neutral element with respect to scalar multiplication
Zero The neutral element with respect to scalar addition

__all__: KroneckerDelta, One, Scalar, ScalarDerivative, ScalarExpression, ScalarIndexedSum, ScalarPlus, ScalarPower, ScalarTimes, ScalarValue, Zero, sqrt

Reference

class qnet.algebra.core.scalar_algebra.Scalar(*args, **kwargs)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumExpression

Base class for Scalars

space

TrivialSpace, by definition

conjugate()[source]

Complex conjugate

real

Real part

imag

Imaginary part

class qnet.algebra.core.scalar_algebra.ScalarValue(val)[source]

Bases: qnet.algebra.core.scalar_algebra.Scalar

Wrapper around a numeric or symbolic value

The wrapped value may be of any of the following types:

>>> for t in ScalarValue._val_types:
...     print(t)
<class 'int'>
<class 'float'>
<class 'complex'>
<class 'sympy.core.basic.Basic'>
<class 'numpy.int64'>
<class 'numpy.complex128'>
<class 'numpy.float64'>

A ScalarValue behaves exactly like its wrapped value in all algebraic contexts:

>>> 5 * ScalarValue.create(2)
10

Any unknown attributes or methods will be forwarded to the wrapped value to ensure complete “duck-typing”:

>>> alpha = ScalarValue(sympy.symbols('alpha', positive=True))
>>> alpha.is_positive   # same as alpha.val.is_positive
True
>>> ScalarValue(5).is_positive
Traceback (most recent call last):
  ...
AttributeError: 'int' object has no attribute 'is_positive'
classmethod create(val)[source]

Instatiate the ScalarValue while recognizing Zero and One.

Scalar instances as val (including ScalarExpression instances) are left unchanged. This makes ScalarValue.create() a safe method for converting unknown objects to Scalar.

val

The wrapped scalar value

args

Tuple containing the wrapped scalar value as its only element

real

Real part

imag

Imaginary part

class qnet.algebra.core.scalar_algebra.ScalarExpression(*args, **kwargs)[source]

Bases: qnet.algebra.core.scalar_algebra.Scalar

Base class for scalars with non-scalar arguments

For example, a BraKet is a Scalar, but has arguments that are states.

qnet.algebra.core.scalar_algebra.Zero = Zero[source]

The neutral element with respect to scalar addition

Equivalent to the scalar value zero:

>>> Zero == 0
True
qnet.algebra.core.scalar_algebra.One = One[source]

The neutral element with respect to scalar multiplication

Equivalent to the scalar value one:

>>> One == 1
True
class qnet.algebra.core.scalar_algebra.ScalarPlus(*operands, **kwargs)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumPlus, qnet.algebra.core.scalar_algebra.Scalar

Sum of scalars

Generally, ScalarValue instances are combined directly:

>>> alpha = ScalarValue.create(sympy.symbols('alpha'))
>>> print(srepr(alpha + 1))
ScalarValue(Add(Symbol('alpha'), Integer(1)))

An unevaluated ScalarPlus remains only for ScalarExpression instaces:

>>> braket = KetSymbol('Psi', hs=0).dag() * KetSymbol('Phi', hs=0)
>>> print(srepr(braket + 1, indented=True))
ScalarPlus(
    One,
    BraKet(
        KetSymbol(
            'Psi',
            hs=LocalSpace(
                '0')),
        KetSymbol(
            'Phi',
            hs=LocalSpace(
                '0'))))
simplifications = [<function assoc>, <function convert_to_scalars>, <function orderby>, <function collect_scalar_summands>, <function match_replace_binary>]
conjugate()[source]

Complex conjugate of of the sum

class qnet.algebra.core.scalar_algebra.ScalarTimes(*operands, **kwargs)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumTimes, qnet.algebra.core.scalar_algebra.Scalar

Product of scalars

Generally, ScalarValue instances are combined directly:

>>> alpha = ScalarValue.create(sympy.symbols('alpha'))
>>> print(srepr(alpha * 2))
ScalarValue(Mul(Integer(2), Symbol('alpha')))

An unevaluated ScalarTimes remains only for ScalarExpression instaces:

>>> braket = KetSymbol('Psi', hs=0).dag() * KetSymbol('Phi', hs=0)
>>> print(srepr(braket * 2, indented=True))
ScalarTimes(
    ScalarValue(
        2),
    BraKet(
        KetSymbol(
            'Psi',
            hs=LocalSpace(
                '0')),
        KetSymbol(
            'Phi',
            hs=LocalSpace(
                '0'))))
simplifications = [<function assoc>, <function orderby>, <function filter_neutral>, <function match_replace_binary>]
classmethod create(*operands, **kwargs)[source]

Instantiate the product while applying simplification rules

conjugate()[source]

Complex conjugate of of the product

class qnet.algebra.core.scalar_algebra.ScalarIndexedSum(term, *ranges)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumIndexedSum, qnet.algebra.core.scalar_algebra.Scalar

Indexed sum over scalars

simplifications = [<function assoc_indexed>, <function indexed_sum_over_kronecker>, <function indexed_sum_over_const>, <function match_replace>]
classmethod create(term, *ranges)[source]

Instantiate the indexed sum while applying simplification rules

conjugate()[source]

Complex conjugate of of the indexed sum

real

Real part

imag

Imaginary part

class qnet.algebra.core.scalar_algebra.ScalarPower(b, e)[source]

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumOperation, qnet.algebra.core.scalar_algebra.Scalar

A scalar raised to a power

Generally, ScalarValue instances are exponentiated directly:

>>> alpha = ScalarValue.create(sympy.symbols('alpha'))
>>> print(srepr(alpha**2))
ScalarValue(Pow(Symbol('alpha'), Integer(2)))

An unevaluated ScalarPower remains only for ScalarExpression instaces, see e.g. sqrt().

simplifications = [<function convert_to_scalars>, <function match_replace>]
base

The base of the exponential

exp

The exponent

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

Bases: qnet.algebra.core.abstract_quantum_algebra.QuantumDerivative, qnet.algebra.core.scalar_algebra.Scalar

Symbolic partial derivative of a scalar

See QuantumDerivative.

qnet.algebra.core.scalar_algebra.KroneckerDelta(i, j, simplify=True)[source]

Kronecker delta symbol

Return One (i equals j)), Zero (i and j are non-symbolic an unequal), or a ScalarValue wrapping SymPy’s KroneckerDelta.

>>> i, j = IdxSym('i'), IdxSym('j')
>>> KroneckerDelta(i, i)
One
>>> KroneckerDelta(1, 2)
Zero
>>> KroneckerDelta(i, j)
KroneckerDelta(i, j)

By default, the Kronecker delta is returned in a simplified form, e.g:

>>> KroneckerDelta((i+1)/2, (j+1)/2)
KroneckerDelta(i, j)

This may be suppressed by setting simplify to False:

>>> KroneckerDelta((i+1)/2, (j+1)/2, simplify=False)
KroneckerDelta(i/2 + 1/2, j/2 + 1/2)
Raises:
  • TypeError – if i or j is not an integer or sympy expression. There
  • is no automatic sympification of i and j.
qnet.algebra.core.scalar_algebra.sqrt(scalar)[source]

Square root of a Scalar or scalar value

This always returns a Scalar, and uses a symbolic square root if possible (i.e., for non-floats):

>>> sqrt(2)
sqrt(2)

>>> sqrt(2.0)
1.414213...

For a ScalarExpression argument, it returns a ScalarPower instance:

>>> braket = KetSymbol('Psi', hs=0).dag() * KetSymbol('Phi', hs=0)
>>> nrm = sqrt(braket * braket.dag())
>>> print(srepr(nrm, indented=True))
ScalarPower(
    ScalarTimes(
        BraKet(
            KetSymbol(
                'Phi',
                hs=LocalSpace(
                    '0')),
            KetSymbol(
                'Psi',
                hs=LocalSpace(
                    '0'))),
        BraKet(
            KetSymbol(
                'Psi',
                hs=LocalSpace(
                    '0')),
            KetSymbol(
                'Phi',
                hs=LocalSpace(
                    '0')))),
    ScalarValue(
        Rational(1, 2)))
qnet.algebra.core.scalar_algebra.is_scalar(scalar)[source]

Check if scalar is a Scalar or a scalar value

Specifically, whether scalar is an instance of Scalar or an instance of a numeric or symbolic type that could be wrapped in ScalarValue.

For internal use only.