Files

photonic_circuit_solver.stabilizer

Contains the Stabilizer class to represent stabilizer states

photonic_circuit_solver.circuit

Contains the functions needed to implement the emission circuit solving procedure

photonic_circuit_solver.supplementalfuncs

Adding test and utility functions built by Tarek Razzaz.

API Documentation

class photonic_circuit_solver.Stabilizer(n: int = None, stabs: str | list = None, edgelist: list[list] = None)[source]

This is a class that encodes the stabilizer state in terms of its stabilizers. If no input is given, it will initialize a two qubit bell state. If only the n is given, it will initialize the n qubit computational zero state

Parameters:
  • n (int, Optional (only if providing edgelist)) – Number of qubits

  • stabs (list or string, optional (initializes zero state by default)) – The stabilizers, either in a string or a list, in the format ‘XX,-YY’ or ‘[XX,-YY]’. Optional

  • edgelist (list) – A list of edges for a graph state. Optional

Variables:
  • size – The number of qubits, initial value: n

  • __stabs – The stabilizers of the state, initial value: stabs (note, this is a dunder attribute, can’t be directly called outside the class. Use the .stabilizers() method instead)

  • tab – The tableau of the state

  • signvector – The signvector of the state

  • gauss – A nxn Gaussian matrix (used for empty_column calculations)

build_and_measure()[source]

A circuit to implement the circuit and then to measure the associated stabilizers (requires qiskit).

Returns:

A qiskit circuit for measureing stabilizer

Return type:

QuantumCircuit

circuit_builder()[source]

Uses reverse operations to build the stabilizer state (requires qiskit)

Returns:

A Qiskit circuit that makes the stabilizer

Return type:

QuantumCircuit

clifford(type: str, q1: int, q2: int = None)[source]

Applies a clifford gate to the stabilizer

Parameters:
  • type (string) – The clifford gate to be operated, ‘H’, ‘X’, ‘Y’, ‘Z’, ‘CNOT’ or ‘CX’, ‘SWAP’, ‘CZ’, or ‘S’

  • q1 (int) – The qubit to operate on, or the control qubit for entangling gates

  • q2 (int) – The qubit to target, defaults to None

clone()[source]

Generates a copy of the stabilizer state

commuter() bool[source]

Tests whether the stabilizers commute with each other

Returns:

Whether or not they commute

Return type:

boolean

draw_circuit(style='text', save=None)[source]

Draws a circuit that can generate the given stabilizer state (requires qiskit, matplotlib and pylatexenc package)

Parameters:
  • style (string, optional. Defaults to 'text') – The type of output, ‘mpl’ for matplotlib, ‘text’ for ASCII drawing, ‘latex_source’ for raw latex output

  • save (string) – If you want to save the file to something (optional)

empty_column() bool[source]

Tests whether there are any empty stabilizers (free qubits)

Returns:

Whether there is an empty column or not

Return type:

boolean

flip()[source]

Flips the tableau over

gaussian()[source]

Generates an array that contains information about where stabilizers are known

graph_state(edgelist: list[list] = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 0]])[source]

Generates a graph state based on inputed edgelist

Parameters:

edgelist (Nested list) – The list of connections, defaults to [[0,1],[1,2],[2,3],[3,4],[4,0]]

linear_independence()[source]

Checks if the generators are linearly independent

measurement(stabilizers: list | str, outcomes: list = None)[source]

Implements a measurement of a Pauli string with a specified outcome (Pauli string shouldn’t have a sign on it, use the outcomes to denote sign. Ex, measuring -X is equivalent to measurement ‘X’, [1])

If the state is measured by a Pauli that is a stabilizer of the state (modulo sign) then the measurement does nothing and is ignored. Note, since the measurement stabilizer is already a member of the stabilizer group, there is only one valid measurement outcome. As of right now, the code doesn’t verify that whether what you provided matches the expected outcome.

Parameters:
  • stabilizers (str) – The set of stabilizers that were measured, in order

  • outcomes (list) – The outcomes of these measurements (defaults to 0 for all, can put 0 or 1)

new_stab(size: int = None, newstabs: str | list = None)[source]

Resets the stabilizer and new tableau associated with it

Parameters:
  • size (int (optional)) – The size of the new state

  • newstabs (string or list) – The new stabilizers

num_qubits() int[source]

Returns the size of the stabilizer (the number of qubits)

Returns:

The size of the stabilizer

Return type:

int

qiskit_stabilizers()[source]

Asks Qiskit to return the stabilizers (requires qiskit)

Returns:

A qiskit stabilizer state representation

Return type:

StabilizerState (qiskit)

report()[source]

Prints the tableau and the signvector

row_add(row1: int, row2: int)[source]

Multiplies two stabilizers in the tableau together, and puts them into the second row

row_commute(stab1: str, stab2: str) bool[source]

Checks if two stabilizers commute

Parameters:
  • stab1 (string) – The first stabilizer

  • stab2 (string) – The second stabilizer

Returns:

Whether the stabilizers commute

Return type:

boolean

rref(KU: int = 0, NL: int = 0)[source]

Implements the RREF gauge procedure (details in doi.org/10.1088/1367-2630/7/1/170)

Parameters:
  • KU (int) – Starting row

  • NL (int) – Starting column

stabilizer_measurement()[source]

A circuit to measure the associated stabilizers of this state (requires qiskit)

Returns:

A qiskit circuit for measureing stabilizer

Return type:

QuantumCircuit

stabilizers() list[str][source]

Returns a list of the stabilizers of the state, as per the tableau

Returns:

A list of stabilizers

Return type:

list

swap(r1: int, r2: int)[source]

Swaps two rows in the stabilizer

Parameters:
  • r1 – The first row

  • r2 – The second row

tableau() list[source]

Converts the stabilizers to a tableau and signvector

Returns:

A list contained the tableau and the signvector

Return type:

list

class photonic_circuit_solver.Graph(edges: list[tuple])[source]

This is a class that encodes graphs, and contains a few convenient functions (most useful methods require optional packages)

Parameters:

edges (list) – A list of edges describing the graph

draw() None[source]

Method to generate an nx graph (requires NetworkX)

state(progress: bool = False)[source]

Uses SymPy to calculate the statevector associated with the graph (requires SymPy)

Parameters:

progress (bool) – A boolean option to continuously print out the progress of calculating the state (useful for large graphs), defaults to False

Returns:

A SymPy expression representing the statevector

Return type:

Expr

photonic_circuit_solver.rref(state: Stabilizer)[source]

Given a stabilizer state, implements the RREF gauge procedure (details in doi.org/10.1088/1367-2630/7/1/170)

Parameters:

state (Stabilizer) – Stabilizer state on which to implement the RREF gauge procedure

photonic_circuit_solver.heightfunction(state: Stabilizer)[source]

Given a stabilizer state, finds the height function (bipartite entanglement entropy) of the state (formula in doi.org/10.1038/s41534-022-00522-6, equation 1)

Parameters:

state (Stabilizer) – Stabilizer state from which to calculate the height function

Returns:

The outputs of the height function as a list

Return type:

list

photonic_circuit_solver.plot_height(state: Stabilizer)[source]

Given a stabilizer state, finds the height function (bipartite entanglement entropy) of the state (formula in doi.org/10.1038/s41534-022-00522-6, equation 1) and plots it (need matplotlib installed)

Parameters:

state (Stabilizer) – Stabilizer state from which to calculate the height function

photonic_circuit_solver.num_emitters(state: Stabilizer)[source]

Given a graph state with a certain fixed ordering, finds the minimal number of emitters required to emit that state

Parameters:

state (Stabilizer) – Target photonic stabilizer state

Returns:

Minimal number of photons needed to emit the input states

Return type:

int

photonic_circuit_solver.circuit_solver(state: Stabilizer)[source]

Given a stabilizer state, finds a circuit to generate it from a minimal set of emitters (details in doi.org/10.1038/s41534-022-00522-6)

Parameters:

state (Stabilizer) – Stabilizer state from which to calculate the height function

Returns:

Procedure to generate the state, of the form [‘Action’, q1, q2 (if applicable)]. ‘Action’ can be ‘X’, ‘Z’, ‘H’, ‘S’, ‘CNOT’, ‘Measure’, or ‘Emission’. For ‘CNOT’, q1 is the control and q2 is the target. For emission and measure, q1 is the emitter and q2 is the photon.

Return type:

list

photonic_circuit_solver.qiskit_circuit_solver(state: Stabilizer, simple: bool = False)[source]

Given a stabilizer state, creates a qiskit circuit to generate it from a minimal set of emitters.

Parameters:
  • state (Stabilizer) – Stabilizer state from which to calculate the height function

  • simple (bool (optional, defaults to False)) – Uses one register for both photons and emitters instead of seperate registers. Defaults to false

Returns:

Qiskit circuit corresponding to the protocol

Return type:

QuantumCircuit

photonic_circuit_solver.qiskit_circuit_solver_alternate(state: Stabilizer, simple: bool = False)[source]

Given a stabilizer state, creates a qiskit circuit to generate it from a minimal set of emitters. Uses circuit_solver to generate the protocol instead of doing it simultaneously.

Parameters:
  • state (Stabilizer) – Stabilizer state from which to calculate the height function

  • simple (bool (optional, defaults to False)) – Uses one register for both photons and emitters instead of separate ones

Returns:

Qiskit circuit corresponding to the protocol

Return type:

QuantumCircuit

photonic_circuit_solver.num_cnots(state: Stabilizer)[source]

Given a graph state with a certain fixed ordering, finds the number of emitters-emitter CNOT gates required to emit that state using this implementation of the solving algorithm

Parameters:

state (Stabilizer) – Target photonic stabilizer state

Returns:

Number of emitter-emitter CNOT gates needed to emit the input state using this version of the algorithm

Return type:

int

photonic_circuit_solver.emitter_cnot(state: Stabilizer)[source]

Given a stabilizer state, finds the number of emitters and the number of emitter-emitter CNOT gates needed to implement the circuit

Parameters:

state (Stabilizer) – Stabilizer state from which to calculate the height function

Returns:

A list of the form [emitters,cnots]

Return type:

list

photonic_circuit_solver.apply(state, operation=None, dp=False)[source]

Simplifies an expression describing a SymPy statevector

Parameters:
  • state (Expr) – The SymPy statevector to be simplified

  • operation (Expr) – An operation (usually a quantum gate) to apply to the state, defaults to None

  • dp (bool) – A boolean determining if the statevector should be dephased, defaults to False

Returns:

The simplified version of the SymPy statevector

Return type:

Expr

photonic_circuit_solver.tensor(state1, state2)[source]

Computes the tensor product of two SymPy statevectors (not fully tested) (requires SymPy)

Parameters:
  • state1 (Expr) – The first SymPy statevector in the tensor product

  • state2 (Expr) – The second SymPy statevector in the tensor product

Returns:

The SymPy statevector representing the tensor product of state1 and state2

Return type:

Expr

photonic_circuit_solver.dephase(state)[source]

Removes the global phase from a SymPy statevector by dividing by the phase of the first component (Requires SymPy)

Parameters:

state (Expr) – The SymPy statevector to be dephased

Returns:

state without the global phase

Return type:

Expr

photonic_circuit_solver.Rz(target: int, theta: float)[source]

Apply an RZ gate via SymPy (requires SymPy)

Parameters:
  • theta (float) – Rotation angle

  • target (int) – Qubit to apply the RZ gate to

photonic_circuit_solver.Rx(target: int, theta: float)[source]

Apply an RZ gate via SymPy (requires SymPy)

Parameters:
  • theta (float) – Rotation angle

  • target (int) – Qubit to apply the RZ gate to

photonic_circuit_solver.Ry(target: int, theta: float)[source]

Apply an RZ gate via SymPy (requires SymPy)

Parameters:
  • theta (float) – Rotation angle

  • target (int) – Qubit to apply the RZ gate to