qalgebra.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 qalgebra.core.scalar_algebra.Scalar(*args, **kwargs)[source]

Bases: qalgebra.core.abstract_quantum_algebra.QuantumExpression

Base class for Scalars

property space

TrivialSpace, by definition

conjugate()[source]

Complex conjugate

property real

Real part

property imag

Imaginary part

class qalgebra.core.scalar_algebra.ScalarValue(val)[source]

Bases: qalgebra.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.

property val

The wrapped scalar value

property args

Tuple containing the wrapped scalar value as its only element

property real

Real part

property imag

Imaginary part

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

Bases: qalgebra.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.

qalgebra.core.scalar_algebra.Zero = Zero[source]

The neutral element with respect to scalar addition

Equivalent to the scalar value zero:

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

The neutral element with respect to scalar multiplication

Equivalent to the scalar value one:

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

Bases: qalgebra.core.abstract_quantum_algebra.QuantumPlus, qalgebra.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 qalgebra.core.scalar_algebra.ScalarTimes(*operands, **kwargs)[source]

Bases: qalgebra.core.abstract_quantum_algebra.QuantumTimes, qalgebra.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 qalgebra.core.scalar_algebra.ScalarIndexedSum(term, *, ranges)[source]

Bases: qalgebra.core.abstract_quantum_algebra.QuantumIndexedSum, qalgebra.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.

This internally converts term to a Scalar and ranges to a tuple before applying any rules.

conjugate()[source]

Complex conjugate of of the indexed sum.

property real

Real part.

property imag

Imaginary part.

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

Bases: qalgebra.core.abstract_quantum_algebra.QuantumOperation, qalgebra.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>]
property base

The base of the exponential

property exp

The exponent

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

Bases: qalgebra.core.abstract_quantum_algebra.QuantumDerivative, qalgebra.core.scalar_algebra.Scalar

Symbolic partial derivative of a scalar

See QuantumDerivative.

qalgebra.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)))
qalgebra.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.

qalgebra.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.