rectangular_symmetric(V, tol=1e-11)[source]

Decomposition of a unitary into an array of symmetric beamsplitters.

This decomposition starts with the output from rectangular_phase_end() and further decomposes each of the T unitaries into Mach-Zehnder interferometers consisting of two phase-shifters and two symmetric (50:50) beamsplitters.

The two beamsplitters in this decomposition of T are modeled by BSgate with arguments \((\pi/4, \pi/2)\), and the two phase-shifters (see Rgate) act on the input mode with the lower index of the two. The phase imposed by the first phaseshifter (before the first beamsplitter) is named external_phase, while we call the phase shift between the beamsplitters internal_phase.

The algorithm applied in this function makes use of the following identity:

Rgate(alpha) | 1
Rgate(beta) | 2
Rgate(phi) | 1
BSgate(theta, 0) | 1, 2


Rgate(phi+alpha-beta) | 1
BSgate(pi/4, pi/2) | 1, 2
Rgate(2*theta+pi) | 1, 2
BSgate(pi/4, pi/2) | 1, 2
Rgate(beta-theta+pi) | 1
Rgate(beta-theta) | 2

The phase-shifts by alpha and beta are thus pushed consecutively through all the T unitaries of the interferometer and these unitaries are converted into pairs of symmetric beamsplitters with two phase shifts. The phase shifts at the end of the interferometer are added to the ones from the diagonal unitary at the end of the interferometer obtained from rectangular_phase_end().

  • V (array) – unitary matrix of size n_size

  • tol (int) – the number of decimal places to use when determining whether the matrix is unitary


returns a tuple of the form (tlist,np.diag(localV), None)


  • tlist: list containing [n, m, internal_phase, external_phase, n_size] of the T unitaries needed

  • localV: Diagonal unitary matrix to be applied at the end of circuit

  • None: the value None, in order to make the return signature identical to rectangular()

Return type