# Circuit

class perceval.components.linear_circuit.Circuit(m, name=None)

Class to represent any circuit composed of one or multiple components

Parameters
• m (int) – The number of port of the circuit

• name (Optional[str]) – Name of the circuit

property U

get the symbolic unitary matrix

__floordiv__(component)

Build a new circuit by adding component to the current circuit

>>> c = a // b   # equivalent to: Circuit(n) // self // component

Parameters

component (Union[ACircuit, Tuple[int, ACircuit]]) – the component to add, or a tuple (first_port, component)

Return type

Circuit

__ifloordiv__(component)

Shortcut for .add

>>> c //= b       # equivalent to: c.add((0:b.n),b)
>>> c //= (i, b)  # equivalent to: c.add((i:i+b.n), b)

Parameters

component (Union[ACircuit, Tuple[int, ACircuit]]) – the component to add, or a tuple (first_port, component)

Return type

Circuit

Add a component in a circuit

Parameters
• port_range (Union[int, Tuple[int], Tuple[int, int], Tuple[int, int, int]]) – the port range as a tuple of consecutive ports, or the initial port where to add the component

• component (ACircuit) – the component to add, must be a linear component or circuit

• merge (Optional[bool]) – if the component is a complex circuit,

Return type

Circuit

Returns

the circuit itself, allowing to add multiple components in a same line

Raise

AssertionError if parameters are not valid

compute_unitary(use_symbolic=False, assign=None, use_polarization=None)

Compute the unitary matrix corresponding to the circuit

Parameters
• assign (Optional[dict]) –

• use_symbolic (bool) –

• use_polarization (Optional[bool]) –

Return type

Matrix

Returns

static decomposition(U, component, phase_shifter_fn=None, shape='triangle', permutation=None, inverse_v=False, inverse_h=False, constraints=None, merge=True, precision=1e-06, max_try=10, allow_error=False)

Decompose a given unitary matrix U into a circuit with specified component type

Parameters
• U (MatrixN) – the matrix to decompose

• allow_error (bool) – allow decomposition error - when the actual solution is not locally reachable

• component (ACircuit) – a circuit, to solve any decomposition must have up to 2 independent parameters

• constraints – constraints to apply on both parameters, it is a list of individual constraints. Each constraint should have the numbers of free parameters of the system.

• inverse_v (bool) – inverse the decomposition vertically

• inverse_h (bool) – inverse the decomposition horizontally

• phase_shifter_fn (Optional[Callable[[int], ACircuit]]) – a function generating a phase_shifter circuit. If None, residual phase will be ignored

• shape (str) – triangle

• permutation (Optional[Type[ACircuit]]) – if provided, type of permutation operator to avoid unnecessary operators

• merge (bool) – don’t use sub-circuits

• precision (float) – for intermediate values - norm below precision are considered 0. If not - use global_params

• max_try (int) – number of times to try the decomposition

Returns

a circuit

property defined: bool

check if all parameters of the circuit are fully defined

Return type

bool

definition()

Gives mathematical definition of the circuit

Only defined for elementary circuits

Return type

Matrix

depths()

Return depth of the circuit for each mode

describe(map_param_kid=None)

Describe a circuit

Parameters

map_param_kid – internal parameter

Return type

str

Returns

a string describing the circuit that be re-used to define the circuit

find_subnodes(pos)

find the subnodes of a given component (Udef for pos==None)

Parameters

pos (int) – the position of the current node

Return type

List[int]

Returns

static generic_interferometer(m, fun_gen, shape='rectangle', depth=None, phase_shifter_fun_gen=None)

Generate a generic interferometer with generic elements and optional phase_shifter layer

Parameters
• m (int) – number of modes

• fun_gen (Callable[[int], ACircuit]) – generator function for the building components, index is an integer allowing to generate named parameters - for instance: fun_gen=lambda idx: phys.BS()//(0, phys.PS(pcvl.P("phi_%d"%idx)))

• shape (str) – rectangle or triangle

• depth (Optional[int]) – if None, maximal depth is $$m-1$$ for rectangular shape, $$m$$ for triangular shape. Can be used with $$2*m$$ to reproduce .

• phase_shifter_fun_gen (Optional[Callable[[int], ACircuit]]) – a function generating a phase_shifter circuit.

Return type

Circuit

Returns

a circuit

get_parameters(all_params=False)

Return the parameters of the circuit

Parameters

all_params (bool) – if False, only returns the variable parameters

Return type

List[Parameter]

Returns

the list of parameters

getitem(idx, only_parameterized=False)

Direct access to components of the circuit :type idx: Tuple[int, int] :param idx: index of the component as (row, col) :type only_parameterized: bool :param only_parameterized: if True, only count components with parameters :rtype: ACircuit :return: the component

identify(unitary_matrix, phases, precision=None, max_try=10, allow_error=False)

Identify an instance of the current circuit (should be parameterized) such as $$Q.C=U.P$$ where $$Q$$ and $$P$$ are single-mode phase shifts (resp. $$[q1, q2, ..., qn]$$, and $$[p1, p2, ...,pn]$$). This is solved through $$n^2$$ equations: $$q_i * C_{i,j}(x,y, ...) = UP_{i,j} * p_j$$

Parameters
• unitary_matrix – the matrix to identify

• phases – phase shift parameters

• max_try – the resolution is using parameter search starting on a random points, it might fail, this parameter sets the maximal number of times to try

Return type

None

is_composite()

Returns True if the component is itself composed of subcomponents

match(pattern, pos=None, pattern_pos=0, browse=False, match=None, actual_pos=None, actual_pattern_pos=None, reverse=False)

match a sub-circuit at a given position

Parameters
• match (Optional[Match]) – the partial match

• browse (bool) – true if we want to search the pattern at any location in the current circuit, if true, pos should be None

• pattern (ACircuit) – the pattern to search for

• pos (Optional[int]) – the start position in the current circuit

• pattern_pos (int) – the start position in the pattern

• actual_pos (Optional[int]) – unused, parameter only used by parent class

• actual_pattern_pos (Optional[int]) – unused, parameter only used by parent class

• reverse (bool) – true if we want to search the pattern from the end of the circuit to pos (or the 0 if browse)

Return type

Optional[Match]

Returns

ncomponents()

Return number of actual components in the circuit

property requires_polarization: bool

Does the circuit require polarization?

Return type

bool

Returns

is True if the circuit has a polarization component

transfer_from(source, force=False)

Transfer parameters of a circuit to the current one

Parameters
• source (ACircuit) – the circuit to transfer the parameters from. The shape of the circuit to transfer from should be a subset of the current circuit.

• force (bool) – force changing fixed parameter if necessary