qnet.algebra.core.circuit_algebra module

Implementation of the SLH circuit algebra

For more details see Circuit Algebra.

Summary

Classes:

CPermutation Channel permuting circuit
Circuit Base class for the circuit algebra elements
CircuitSymbol Symbolic circuit element
Component Base class for circuit components
Concatenation Concatenation of circuit elements
Feedback Feedback on a single channel of a circuit
SLH Element of the SLH algebra
SeriesInverse Symbolic series product inversion operation
SeriesProduct The series product circuit operation.

Functions:

FB Wrapper for Feedback, defaulting to last channel
circuit_identity Return the circuit identity for n channels
eval_adiabatic_limit Compute the limiting SLH model for the adiabatic approximation
extract_channel Create a CPermutation that extracts channel k
getABCD Calculate the ABCD-linearization of an SLH model
map_channels Create a CPermuation based on a dict of channel mappings
move_drive_to_H Move coherent drives from the Lindblad operators to the Hamiltonian.
pad_with_identity Pad a circuit by adding a n-channel identity circuit at index k
prepare_adiabatic_limit Prepare the adiabatic elimination on an SLH object
try_adiabatic_elimination Attempt to automatically do adiabatic elimination on an SLH object

Data:

CIdentity Single pass-through channel; neutral element of SeriesProduct
CircuitZero Zero circuit, the neutral element of Concatenation

__all__: CIdentity, CPermutation, Circuit, CircuitSymbol, CircuitZero, Component, Concatenation, FB, Feedback, SLH, SeriesInverse, SeriesProduct, circuit_identity, eval_adiabatic_limit, extract_channel, getABCD, map_channels, move_drive_to_H, pad_with_identity, prepare_adiabatic_limit, try_adiabatic_elimination

Reference

class qnet.algebra.core.circuit_algebra.Circuit[source]

Bases: object

Base class for the circuit algebra elements

cdim

The channel dimension of the circuit expression, i.e. the number of external bosonic noises/inputs that the circuit couples to.

Return type:int
block_structure

If the circuit is reducible (i.e., it can be represented as a Concatenation of individual circuit expressions), this gives a tuple of cdim values of the subblocks. E.g. if A and B are irreducible and have A.cdim = 2, B.cdim = 3

>>> A = CircuitSymbol('A', cdim=2)
>>> B = CircuitSymbol('B', cdim=3)

Then the block structure of their Concatenation is:

>>> (A + B).block_structure
(2, 3)

while

>>> A.block_structure
(2,)
>>> B.block_structure
(3,)

See also

get_blocks() allows to actually retrieve the blocks:

>>> (A + B).get_blocks()
(A, B)
Return type:tuple
index_in_block(channel_index)[source]

Return the index a channel has within the subblock it belongs to

I.e., only for reducible circuits, this gives a result different from the argument itself.

Parameters:channel_index (int) – The index of the external channel
Raises:ValueError – for an invalid channel_index
Return type:int
get_blocks(block_structure=None)[source]

For a reducible circuit, get a sequence of subblocks that when concatenated again yield the original circuit. The block structure given has to be compatible with the circuits actual block structure, i.e. it can only be more coarse-grained.

Parameters:block_structure (tuple) – The block structure according to which the subblocks are generated (default = None, corresponds to the circuit’s own block structure)
Returns:A tuple of subblocks that the circuit consists of.
Raises:IncompatibleBlockStructures
series_inverse()[source]

Return the inverse object (under the series product) for a circuit

In general for any X

>>> X = CircuitSymbol('X', cdim=3)
>>> (X << X.series_inverse() == X.series_inverse() << X ==
...  circuit_identity(X.cdim))
True
Return type:Circuit
feedback(*, out_port=None, in_port=None)[source]

Return a circuit with self-feedback from the output port (zero-based) out_port to the input port in_port.

Parameters:
  • out_port (int or None) – The output port from which the feedback connection leaves (zero-based, default None corresponds to the last port).
  • in_port (int or None) – The input port into which the feedback connection goes (zero-based, default None corresponds to the last port).
show()[source]

Show the circuit expression in an IPython notebook.

render(fname='')[source]

Render the circuit expression and store the result in a file

Parameters:fname (str) – Path to an image file to store the result in.
Returns:The path to the image file
Return type:str
creduce()[source]

If the circuit is reducible, try to reduce each subcomponent once

Depending on whether the components at the next hierarchy-level are themselves reducible, successive circuit.creduce() operations yields an increasingly fine-grained decomposition of a circuit into its most primitive elements.

Return type:Circuit
toSLH()[source]

Return the SLH representation of a circuit. This can fail if there are un-substituted pure circuit symbols (CircuitSymbol) left in the expression

Return type:SLH
coherent_input(*input_amps)[source]

Feed coherent input amplitudes into the circuit. E.g. For a circuit with channel dimension of two, C.coherent_input(0,1) leads to an input amplitude of zero into the first and one into the second port.

Parameters:input_amps (SCALAR_TYPES) – The coherent input amplitude for each port
Returns:The circuit including the coherent inputs.
Return type:Circuit
Raises:WrongCDimError
class qnet.algebra.core.circuit_algebra.SLH(S, L, H)[source]

Bases: qnet.algebra.core.circuit_algebra.Circuit, qnet.algebra.core.abstract_algebra.Expression

Element of the SLH algebra

The SLH class encapsulate an open system model that is parametrized the a scattering matrix (S), a column vector of Lindblad operators (L), and a Hamiltonian (H).

Parameters:
  • S (Matrix) – The scattering matrix (with in general Operator-valued elements)
  • L (Matrix) – The coupling vector (with in general Operator-valued elements)
  • H (Operator) – The internal Hamiltonian operator
S

Scattering matrix

L

Coupling vector

H

Hamiltonian

args

The tuple of positional arguments for the instantiation of the Expression

Ls

Lindblad operators (entries of the L vector), as a list

cdim

The circuit dimension

space

Total Hilbert space

free_symbols

Set of all symbols occcuring in S, L, or H

series_with_slh(other)[source]

Series product with another SLH object

Parameters:other (SLH) – An upstream SLH circuit.
Returns:The combined system.
Return type:SLH
concatenate_slh(other)[source]

Concatenation with another SLH object

expand()[source]

Expand out all operator expressions within S, L and H

Return a new SLH object with these expanded expressions.

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

Simplify all scalar expressions within S, L and H

Return a new SLH object with the simplified expressions.

See also: QuantumExpression.simplify_scalar()

symbolic_liouvillian()[source]
symbolic_master_equation(rho=None)[source]

Compute the symbolic Liouvillian acting on a state rho

If no rho is given, an OperatorSymbol is created in its place. This correspnds to the RHS of the master equation in which an average is taken over the external noise degrees of freedom.

Parameters:rho (Operator) – A symbolic density matrix operator
Returns:The RHS of the master equation.
Return type:Operator
symbolic_heisenberg_eom(X=None, noises=None, expand_simplify=True)[source]

Compute the symbolic Heisenberg equations of motion of a system operator X. If no X is given, an OperatorSymbol is created in its place. If no noises are given, this correspnds to the ensemble-averaged Heisenberg equation of motion.

Parameters:
  • X (Operator) – A system operator
  • noises (Operator) – A vector of noise inputs
Returns:

The RHS of the Heisenberg equations of motion of X.

Return type:

Operator

class qnet.algebra.core.circuit_algebra.CircuitSymbol(label, *sym_args, cdim)[source]

Bases: qnet.algebra.core.circuit_algebra.Circuit, qnet.algebra.core.abstract_algebra.Expression

Symbolic circuit element

Parameters:
  • label (str) – 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.
  • cdim (int) – The circuit dimension, that is, the number of I/O lines
label
args

The tuple of positional arguments for the instantiation of the Expression

kwargs

The dictionary of keyword-only arguments for the instantiation of the Expression

sym_args

Tuple of arguments of the symbol

cdim

Dimension of circuit

class qnet.algebra.core.circuit_algebra.Component(*, label=None, **kwargs)[source]

Bases: qnet.algebra.core.circuit_algebra.CircuitSymbol

Base class for circuit components

A circuit component is a CircuitSymbol that knows its own SLH representation. Consequently, it has a fixed number of I/O channels (CDIM class attribute), and a fixed number of named arguments. Components only accept keyword arguments.

Any subclass of Component must define all of the class attributes listed below, and the _toSLH() method that return the SLH object for the component. Subclasses must also use the properties_for_args() class decorator:

@partial(properties_for_args, arg_names='ARGNAMES')
Parameters:
  • label (str) – label for the component. Defaults to IDENTIFIER
  • kwargs – values for the parameters in ARGNAMES
Class Attributes:
 
  • CDIM – the circuit dimension (number of I/O channels)
  • PORTSIN – list of names for the input ports of the component
  • PORTSOUT – list of names for the output ports of the component
  • ARGNAMES – the name of the keyword-arguments for the components (excluding 'label')
  • DEFAULTS – mapping of keyword-argument names to default values
  • IDENTIFIER – the default label

Note

The port names defined in PORTSIN and PORTSOUT may be used when defining connection via connect().

See also

qnet.algebra.library.circuit_components for example Component subclasses.

CDIM = 0
PORTSIN = ()
PORTSOUT = ()
ARGNAMES = ()
DEFAULTS = {}
IDENTIFIER = ''
args

Empty tuple (no arguments)

See also

sym_args is a tuple of the keyword argument values.

kwargs

An OrderedDict with the value for the label argument, as well as any name in ARGNAMES

minimal_kwargs

An OrderedDict with the keyword arguments necessary to instantiate the component.

class qnet.algebra.core.circuit_algebra.CPermutation(permutation)[source]

Bases: qnet.algebra.core.circuit_algebra.Circuit, qnet.algebra.core.abstract_algebra.Expression

Channel permuting circuit

This circuit expression is only a rearrangement of input and output fields. A channel permutation is given as a tuple of image points. A permutation \(\sigma \in \Sigma_n\) of \(n\) elements is often represented in the following form

\[\begin{split}\begin{pmatrix} 1 & 2 & \dots & n \\ \sigma(1) & \sigma(2) & \dots & \sigma(n) \end{pmatrix},\end{split}\]

but obviously it is fully sufficient to specify the tuple of images \((\sigma(1), \sigma(2), \dots, \sigma(n))\). We thus parametrize our permutation circuits only in terms of the image tuple. Moreover, we will be working with zero-based indices!

A channel permutation circuit for a given permutation (represented as a python tuple of image indices) scatters the \(j\)-th input field to the \(\sigma(j)\)-th output field.

simplifications = []
classmethod create(permutation)[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().

args

The tuple of positional arguments for the instantiation of the Expression

block_perms

If the circuit is reducible into permutations within subranges of the full range of channels, this yields a tuple with the internal permutations for each such block.

Type:tuple
permutation

The permutation image tuple.

cdim

The channel dimension of the circuit expression, i.e. the number of external bosonic noises/inputs that the circuit couples to.

series_with_permutation(other)[source]

Compute the series product with another channel permutation circuit

Parameters:other (CPermutation) –
Returns:
The composite permutation circuit (could also be the
identity circuit for n channels)
Return type:Circuit
qnet.algebra.core.circuit_algebra.CIdentity = CIdentity[source]

Single pass-through channel; neutral element of SeriesProduct

qnet.algebra.core.circuit_algebra.CircuitZero = CircuitZero[source]

Zero circuit, the neutral element of Concatenation

No ports, no internal dynamics.

class qnet.algebra.core.circuit_algebra.SeriesProduct(*operands, **kwargs)[source]

Bases: qnet.algebra.core.circuit_algebra.Circuit, qnet.algebra.core.abstract_algebra.Operation

The series product circuit operation. It can be applied to any sequence of circuit objects that have equal channel dimension.

simplifications = [<function assoc>, <function filter_cid>, <function check_cdims>, <function match_replace_binary>]
neutral_element = CIdentity

Single pass-through channel; neutral element of SeriesProduct

cdim

The channel dimension of the circuit expression, i.e. the number of external bosonic noises/inputs that the circuit couples to.

class qnet.algebra.core.circuit_algebra.Concatenation(*operands)[source]

Bases: qnet.algebra.core.circuit_algebra.Circuit, qnet.algebra.core.abstract_algebra.Operation

Concatenation of circuit elements

simplifications = [<function assoc>, <function filter_neutral>, <function match_replace_binary>]
neutral_element = CircuitZero

Zero circuit, the neutral element of Concatenation

No ports, no internal dynamics.

cdim

Circuit dimension (sum of dimensions of the operands)

class qnet.algebra.core.circuit_algebra.Feedback(circuit, *, out_port, in_port)[source]

Bases: qnet.algebra.core.circuit_algebra.Circuit, qnet.algebra.core.abstract_algebra.Operation

Feedback on a single channel of a circuit

The circuit feedback operation applied to a circuit of channel dimension > 1 and from an output port index to an input port index.

Parameters:
  • circuit (Circuit) – The circuit that undergoes self-feedback
  • out_port (int) – The output port index.
  • in_port (int) – The input port index.
delegate_to_method = (<class 'qnet.algebra.core.circuit_algebra.Concatenation'>, <class 'qnet.algebra.core.circuit_algebra.SLH'>, <class 'qnet.algebra.core.circuit_algebra.CPermutation'>)
simplifications = [<function match_replace>]
kwargs

The dictionary of keyword-only arguments for the instantiation of the Expression

operand

The Circuit that undergoes feedback

out_in_pair

Tuple of zero-based feedback port indices (out_port, in_port)

cdim

Circuit dimension (one less than the circuit on which the feedback acts

classmethod create(circuit, *, out_port, in_port)[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().

Return type:Feedback
class qnet.algebra.core.circuit_algebra.SeriesInverse(*operands, **kwargs)[source]

Bases: qnet.algebra.core.circuit_algebra.Circuit, qnet.algebra.core.abstract_algebra.Operation

Symbolic series product inversion operation

SeriesInverse(circuit)

One generally has

>>> C = CircuitSymbol('C', cdim=3)
>>> SeriesInverse(C) << C == circuit_identity(C.cdim)
True

and

>>> C << SeriesInverse(C) == circuit_identity(C.cdim)
True
simplifications = []
delegate_to_method = (<class 'qnet.algebra.core.circuit_algebra.SeriesProduct'>, <class 'qnet.algebra.core.circuit_algebra.Concatenation'>, <class 'qnet.algebra.core.circuit_algebra.Feedback'>, <class 'qnet.algebra.core.circuit_algebra.SLH'>, <class 'qnet.algebra.core.circuit_algebra.CPermutation'>, <class 'qnet.algebra.core.circuit_algebra.CIdentity'>)
operand

The un-inverted circuit

classmethod create(circuit)[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().

cdim

The channel dimension of the circuit expression, i.e. the number of external bosonic noises/inputs that the circuit couples to.

qnet.algebra.core.circuit_algebra.circuit_identity(n)[source]

Return the circuit identity for n channels

Parameters:n (int) – The channel dimension
Returns:n-channel identity circuit
Return type:Circuit
qnet.algebra.core.circuit_algebra.FB(circuit, *, out_port=None, in_port=None)[source]

Wrapper for Feedback, defaulting to last channel

Parameters:
  • circuit (Circuit) – The circuit that undergoes self-feedback
  • out_port (int) – The output port index, default = None –> last port
  • in_port (int) – The input port index, default = None –> last port
Returns:

The circuit with applied feedback operation.

Return type:

Circuit

qnet.algebra.core.circuit_algebra.extract_channel(k, cdim)[source]

Create a CPermutation that extracts channel k

Return a permutation circuit that maps the k-th (zero-based) input to the last output, while preserving the relative order of all other channels.

Parameters:
  • k (int) – Extracted channel index
  • cdim (int) – The circuit dimension (number of channels)
Returns:

Permutation circuit

Return type:

Circuit

qnet.algebra.core.circuit_algebra.map_channels(mapping, cdim)[source]

Create a CPermuation based on a dict of channel mappings

For a given mapping in form of a dictionary, generate the channel permutating circuit that achieves the specified mapping while leaving the relative order of all non-specified channels intact.

Parameters:
  • mapping (dict) – Input-output mapping of indices (zero-based) {in1:out1, in2:out2,...}
  • cdim (int) – The circuit dimension (number of channels)
Returns:

Circuit mapping the channels as specified

Return type:

CPermutation

qnet.algebra.core.circuit_algebra.pad_with_identity(circuit, k, n)[source]

Pad a circuit by adding a n-channel identity circuit at index k

That is, a circuit of channel dimension \(N\) is extended to one of channel dimension \(N+n\), where the channels \(k\), \(k+1\), …$k+n-1$, just pass through the system unaffected. E.g. let A, B be two single channel systems:

>>> A = CircuitSymbol('A', cdim=1)
>>> B = CircuitSymbol('B', cdim=1)
>>> print(ascii(pad_with_identity(A+B, 1, 2)))
A + cid(2) + B

This method can also be applied to irreducible systems, but in that case the result can not be decomposed as nicely.

Parameters:
  • circuit (Circuit) – circuit to pad
  • k (int) – The index at which to insert the circuit
  • n (int) – The number of channels to pass through
Returns:

An extended circuit that passes through the channels

\(k\), \(k+1\), …, \(k+n-1\)

Return type:

Circuit

qnet.algebra.core.circuit_algebra.getABCD(slh, a0=None, doubled_up=True)[source]

Calculate the ABCD-linearization of an SLH model

Return the A, B, C, D and (a, c) matrices that linearize an SLH model about a coherent displacement amplitude a0.

The equations of motion and the input-output relation are then:

dX = (A X + a) dt + B dA_in dA_out = (C X + c) dt + D dA_in

where, if doubled_up == False

dX = [a_1, …, a_m] dA_in = [dA_1, …, dA_n]

or if doubled_up == True

dX = [a_1, …, a_m, a_1^*, … a_m^*] dA_in = [dA_1, …, dA_n, dA_1^*, …, dA_n^*]
Parameters:
  • slh – SLH object
  • a0 – dictionary of coherent amplitudes {a1: a1_0, a2: a2_0, ...} with annihilation mode operators as keys and (numeric or symbolic) amplitude as values.
  • doubled_up – boolean, necessary for phase-sensitive / active systems
Returns:

A tuple (A, B, C, D, a, c])

with

  • A: coupling of modes to each other
  • B: coupling of external input fields to modes
  • C: coupling of internal modes to output
  • D: coupling of external input fields to output fields
  • a: constant coherent input vector for mode e.o.m.
  • c: constant coherent input vector of scattered amplitudes
    contributing to the output

qnet.algebra.core.circuit_algebra.move_drive_to_H(slh, which=None, expand_simplify=True)[source]

Move coherent drives from the Lindblad operators to the Hamiltonian.

For the given SLH model, move inhomogeneities in the Lindblad operators (resulting from the presence of a coherent drive, see CoherentDriveCC) to the Hamiltonian.

This exploits the invariance of the Lindblad master equation under the transformation (cf. Breuer and Pettrucione, Ch 3.2.1)

\begin{align} \Op{L}_i &\longrightarrow \Op{L}_i' = \Op{L}_i - \alpha_i \\ \Op{H} &\longrightarrow \Op{H}' = \Op{H} + \frac{1}{2i} \sum_j (\alpha_j \Op{L}_j^{\dagger} - \alpha_j^* \Op{L}_j) \end{align}

In the context of SLH, this transformation is achieved by feeding slh into

\[\SLH(\identity, -\mat{\alpha}, 0)\]

where \(\mat{\alpha}\) has the elements \(\alpha_i\).

Parameters:
  • slh (SLH) – SLH model to transform. If slh does not contain any inhomogeneities, it is invariant under the transformation.
  • which (sequence or None) – Sequence of circuit dimensions to apply the transform to. If None, all dimensions are transformed.
  • expand_simplify (bool) – if True, expand and simplify the new SLH object before returning. This has no effect if slh does not contain any inhomogeneities.
Returns:

new_slh – Transformed SLH model.

Return type:

SLH

qnet.algebra.core.circuit_algebra.prepare_adiabatic_limit(slh, k=None)[source]

Prepare the adiabatic elimination on an SLH object

Args:
slh: The SLH object to take the limit for k: The scaling parameter $k
ightarrow infty$. The default is a
positive symbol ‘k’
Returns:
tuple: The objects Y, A, B, F, G, N necessary to compute the limiting system.
qnet.algebra.core.circuit_algebra.eval_adiabatic_limit(YABFGN, Ytilde, P0)[source]

Compute the limiting SLH model for the adiabatic approximation

Parameters:
  • YABFGN – The tuple (Y, A, B, F, G, N) as returned by prepare_adiabatic_limit.
  • Ytilde – The pseudo-inverse of Y, satisfying Y * Ytilde = P0.
  • P0 – The projector onto the null-space of Y.
Returns:

Limiting SLH model

Return type:

SLH

qnet.algebra.core.circuit_algebra.try_adiabatic_elimination(slh, k=None, fock_trunc=6, sub_P0=True)[source]

Attempt to automatically do adiabatic elimination on an SLH object

This will project the Y operator onto a truncated basis with dimension specified by fock_trunc. sub_P0 controls whether an attempt is made to replace the kernel projector P0 by an IdentityOperator.