qnet.algebra.core.algebraic_properties module¶
Summary¶
Functions:
accept_bras |
Accept operands that are all bras, and turn that into to bra of the operation applied to all corresponding kets |
assoc |
Associatively expand out nested arguments of the flat class. |
assoc_indexed |
Flatten nested indexed structures while pulling out possible prefactors |
basis_ket_zero_outside_hs |
For BasisKet.create(ind, hs) with an integer label ind, return a ZeroKet if ind is outside of the range of the underlying Hilbert space |
check_cdims |
Check that all operands (ops) have equal channel dimension. |
collect_scalar_summands |
Collect ValueScalar and ScalarExpression summands |
collect_summands |
Collect summands that occur multiple times into a single summand |
commutator_order |
Apply anti-commutative property of the commutator to apply a standard ordering of the commutator arguments |
convert_to_scalars |
Convert any entry in ops that is not a Scalar instance into a ScalarValue instance |
convert_to_spaces |
For all operands that are merely of type str or int, substitute LocalSpace objects with corresponding labels: For a string, just itself, for an int, a string version of that int. |
delegate_to_method |
Create a simplification rule that delegates the instantiation to the method mtd of the operand (if defined) |
derivative_via_diff |
Implementation of the QuantumDerivative.create() interface via the use of QuantumExpression._diff() . |
disjunct_hs_zero |
Return ZeroOperator if all the operators in ops have a disjunct Hilbert space, or an unchanged ops, kwargs otherwise |
empty_trivial |
A ProductSpace of zero Hilbert spaces should yield the TrivialSpace |
filter_cid |
Remove occurrences of the circuit_identity() cid(n) for any n . |
filter_neutral |
Remove occurrences of a neutral element from the argument/operand list, if that list has at least two elements. |
idem |
Remove duplicate arguments and order them via the cls’s order_key key object/function. |
implied_local_space |
Return a simplification that converts the positional argument arg_index from (str, int) to a subclass of LocalSpace , as well as any keyword argument with one of the given keys. |
indexed_sum_over_const |
Execute an indexed sum over a term that does not depend on the summation indices |
indexed_sum_over_kronecker |
Execute sums over KroneckerDelta prefactors |
match_replace |
Match and replace a full operand specification to a function that provides a replacement for the whole expression or raises a CannotSimplify exception. |
match_replace_binary |
Similar to func:match_replace, but for arbitrary length operations, such that each two pairs of subsequent operands are matched pairwise. |
orderby |
Re-order arguments via the class’s order_key key object/function. |
scalars_to_op |
Convert any scalar \(\alpha\) in ops into an operator $alpha identity$ |
Reference¶
-
qnet.algebra.core.algebraic_properties.
assoc
(cls, ops, kwargs)[source]¶ Associatively expand out nested arguments of the flat class. E.g.:
>>> class Plus(Operation): ... simplifications = [assoc, ] >>> Plus.create(1,Plus(2,3)) Plus(1, 2, 3)
-
qnet.algebra.core.algebraic_properties.
assoc_indexed
(cls, ops, kwargs)[source]¶ Flatten nested indexed structures while pulling out possible prefactors
For example, for an
IndexedSum
:\[\sum_j \left( a \sum_i \dots \right) = a \sum_{j, i} \dots\]
-
qnet.algebra.core.algebraic_properties.
idem
(cls, ops, kwargs)[source]¶ Remove duplicate arguments and order them via the cls’s order_key key object/function. E.g.:
>>> class Set(Operation): ... order_key = lambda val: val ... simplifications = [idem, ] >>> Set.create(1,2,3,1,3) Set(1, 2, 3)
-
qnet.algebra.core.algebraic_properties.
orderby
(cls, ops, kwargs)[source]¶ Re-order arguments via the class’s
order_key
key object/function. Use this for commutative operations: E.g.:>>> class Times(Operation): ... order_key = lambda val: val ... simplifications = [orderby, ] >>> Times.create(2,1) Times(1, 2)
-
qnet.algebra.core.algebraic_properties.
filter_neutral
(cls, ops, kwargs)[source]¶ Remove occurrences of a neutral element from the argument/operand list, if that list has at least two elements. To use this, one must also specify a neutral element, which can be anything that allows for an equality check with each argument. E.g.:
>>> class X(Operation): ... _neutral_element = 1 ... simplifications = [filter_neutral, ] >>> X.create(2,1,3,1) X(2, 3)
-
qnet.algebra.core.algebraic_properties.
collect_summands
(cls, ops, kwargs)[source]¶ Collect summands that occur multiple times into a single summand
Also filters out zero-summands.
Example
>>> A, B, C = (OperatorSymbol(s, hs=0) for s in ('A', 'B', 'C')) >>> collect_summands( ... OperatorPlus, (A, B, C, ZeroOperator, 2 * A, B, -C) , {}) ((3 * A^(0), 2 * B^(0)), {}) >>> collect_summands(OperatorPlus, (A, -A), {}) ZeroOperator >>> collect_summands(OperatorPlus, (B, A, -B), {}) A^(0)
-
qnet.algebra.core.algebraic_properties.
collect_scalar_summands
(cls, ops, kwargs)[source]¶ Collect
ValueScalar
andScalarExpression
summandsExample
>>> srepr(collect_scalar_summands(Scalar, (1, 2, 3), {})) 'ScalarValue(6)' >>> collect_scalar_summands(Scalar, (1, 1, -1), {}) One >>> collect_scalar_summands(Scalar, (1, -1), {}) Zero
>>> Psi = KetSymbol("Psi", hs=0) >>> Phi = KetSymbol("Phi", hs=0) >>> braket = BraKet.create(Psi, Phi)
>>> collect_scalar_summands(Scalar, (1, braket, -1), {}) <Psi|Phi>^(0) >>> collect_scalar_summands(Scalar, (1, 2 * braket, 2, 2 * braket), {}) ((3, 4 * <Psi|Phi>^(0)), {}) >>> collect_scalar_summands(Scalar, (2 * braket, -braket, -braket), {}) Zero
-
qnet.algebra.core.algebraic_properties.
match_replace
(cls, ops, kwargs)[source]¶ Match and replace a full operand specification to a function that provides a replacement for the whole expression or raises a
CannotSimplify
exception. E.g.First define an operation:
>>> class Invert(Operation): ... _rules = OrderedDict() ... simplifications = [match_replace, ]
Then some _rules:
>>> A = wc("A") >>> A_float = wc("A", head=float) >>> Invert_A = pattern(Invert, A) >>> Invert._rules.update([ ... ('r1', (pattern_head(Invert_A), lambda A: A)), ... ('r2', (pattern_head(A_float), lambda A: 1./A)), ... ])
Check rule application:
>>> print(srepr(Invert.create("hallo"))) # matches no rule Invert('hallo') >>> Invert.create(Invert("hallo")) # matches first rule 'hallo' >>> Invert.create(.2) # matches second rule 5.0
A pattern can also have the same wildcard appear twice:
>>> class X(Operation): ... _rules = { ... 'r1': (pattern_head(A, A), lambda A: A), ... } ... simplifications = [match_replace, ] >>> X.create(1,2) X(1, 2) >>> X.create(1,1) 1
-
qnet.algebra.core.algebraic_properties.
match_replace_binary
(cls, ops, kwargs)[source]¶ Similar to func:match_replace, but for arbitrary length operations, such that each two pairs of subsequent operands are matched pairwise.
>>> A = wc("A") >>> class FilterDupes(Operation): ... _binary_rules = { ... 'filter_dupes': (pattern_head(A,A), lambda A: A)} ... simplifications = [match_replace_binary, assoc] ... _neutral_element = 0 >>> FilterDupes.create(1,2,3,4) # No duplicates FilterDupes(1, 2, 3, 4) >>> FilterDupes.create(1,2,2,3,4) # Some duplicates FilterDupes(1, 2, 3, 4)
Note that this only works for subsequent duplicate entries:
>>> FilterDupes.create(1,2,3,2,4) # No *subsequent* duplicates FilterDupes(1, 2, 3, 2, 4)
Any operation that uses binary reduction must be associative and define a neutral element. The binary rules must be compatible with associativity, i.e. there is no specific order in which the rules are applied to pairs of operands.
-
qnet.algebra.core.algebraic_properties.
check_cdims
(cls, ops, kwargs)[source]¶ Check that all operands (ops) have equal channel dimension.
-
qnet.algebra.core.algebraic_properties.
filter_cid
(cls, ops, kwargs)[source]¶ Remove occurrences of the
circuit_identity()
cid(n)
for anyn
. Cf.filter_neutral()
-
qnet.algebra.core.algebraic_properties.
convert_to_spaces
(cls, ops, kwargs)[source]¶ For all operands that are merely of type str or int, substitute LocalSpace objects with corresponding labels: For a string, just itself, for an int, a string version of that int.
-
qnet.algebra.core.algebraic_properties.
empty_trivial
(cls, ops, kwargs)[source]¶ A ProductSpace of zero Hilbert spaces should yield the TrivialSpace
-
qnet.algebra.core.algebraic_properties.
implied_local_space
(*, arg_index=None, keys=None)[source]¶ Return a simplification that converts the positional argument arg_index from (str, int) to a subclass of
LocalSpace
, as well as any keyword argument with one of the given keys.The exact type of the resulting Hilbert space is determined by the default_hs_cls argument of
init_algebra()
.In many cases, we have
implied_local_space()
(increate
) in addition to a conversion in__init__
, so thatmatch_replace()
etc can rely on the relevant arguments being aHilbertSpace
instance.
-
qnet.algebra.core.algebraic_properties.
delegate_to_method
(mtd)[source]¶ Create a simplification rule that delegates the instantiation to the method mtd of the operand (if defined)
-
qnet.algebra.core.algebraic_properties.
scalars_to_op
(cls, ops, kwargs)[source]¶ Convert any scalar \(\alpha\) in ops into an operator $alpha identity$
-
qnet.algebra.core.algebraic_properties.
convert_to_scalars
(cls, ops, kwargs)[source]¶ Convert any entry in ops that is not a
Scalar
instance into aScalarValue
instance
-
qnet.algebra.core.algebraic_properties.
disjunct_hs_zero
(cls, ops, kwargs)[source]¶ Return ZeroOperator if all the operators in ops have a disjunct Hilbert space, or an unchanged ops, kwargs otherwise
-
qnet.algebra.core.algebraic_properties.
commutator_order
(cls, ops, kwargs)[source]¶ Apply anti-commutative property of the commutator to apply a standard ordering of the commutator arguments
-
qnet.algebra.core.algebraic_properties.
accept_bras
(cls, ops, kwargs)[source]¶ Accept operands that are all bras, and turn that into to bra of the operation applied to all corresponding kets
-
qnet.algebra.core.algebraic_properties.
basis_ket_zero_outside_hs
(cls, ops, kwargs)[source]¶ For
BasisKet.create(ind, hs)
with an integer label ind, return aZeroKet
if ind is outside of the range of the underlying Hilbert space
-
qnet.algebra.core.algebraic_properties.
indexed_sum_over_const
(cls, ops, kwargs)[source]¶ Execute an indexed sum over a term that does not depend on the summation indices
\[\sum_{j=1}^{N} a = N a\]>>> a = symbols('a') >>> i, j = (IdxSym(s) for s in ('i', 'j')) >>> unicode(Sum(i, 1, 2)(a)) '2 a' >>> unicode(Sum(j, 1, 2)(Sum(i, 1, 2)(a * i))) '∑_{i=1}^{2} 2 i a'
-
qnet.algebra.core.algebraic_properties.
indexed_sum_over_kronecker
(cls, ops, kwargs)[source]¶ Execute sums over KroneckerDelta prefactors
-
qnet.algebra.core.algebraic_properties.
derivative_via_diff
(cls, ops, kwargs)[source]¶ Implementation of the
QuantumDerivative.create()
interface via the use ofQuantumExpression._diff()
.Thus, by having
QuantumExpression.diff()
delegate toQuantumDerivative.create()
, instead ofQuantumExpression._diff()
directly, we get automatic caching of derivatives