MentPy

MentPy is a library is composed of the following modules:

Operators

class mentpy.PauliOp

Class for representing Pauli operators as matrices and strings.

This module contains operators for MBQC circuits.

class mentpy.operators.ControlMent(condition: bool | MentOutcome | None = None, true_angle: int | float | tuple | str | None = None, true_plane: str | None = 'XY', false_angle: int | float | tuple | str | None = 0, false_plane: str | None = 'X')
angle(*args, **kwargs)
property condition : bool
copy()

Returns a copy of the measurement.

get_povm(angle: float | None = None, *args, **kwargs)

Returns the POVM representation of the measurement.

is_trainable()

Returns True if the measurement is trainable.

matrix(angle: float | None = None, *args, **kwargs)

Return the matrix of the controlled measurement operator.

plane(*args, **kwargs)
mentpy.operators.ControlledMent

alias of ControlMent

mentpy.operators.Measurement

alias of Ment

class mentpy.operators.Ment(angle: int | float | tuple | str | None = None, plane: str | None = 'XY')

Measurement operator.

Parameters:
angle : float

The angle of the measurement. Only used if plane is “XY”, “XZ”, “YZ”, or “XYZ”. If plane is “XYZ”, the input should be a tuple of two angles.

plane : str

The plane of the measurement. Can be “XY”, “XZ”, “YZ”, “XYZ”, “X”, “Y”, “Z”.

property angle
copy()

Returns a copy of the measurement.

get_povm(angle: float | None = None, *args, **kwargs)

Returns the POVM representation of the measurement.

is_trainable()

Returns True if the measurement is trainable.

matrix(angle: float | None = None, *args, **kwargs)

Returns the matrix representation of the measurement.

property node_id : Any
property outcome : MentOutcome
property plane
set_angle(angle)

Sets the angle of the measurement.

class mentpy.operators.MentOutcome(outcome: Callable[[...], bool], node_id=None, cond_nodes=None)

Measurement outcome class.

property cond_nodes
property node_id
class mentpy.operators.PauliOp(op: ndarray | str | List[str])

Class for representing Pauli operators as matrices and strings.

Parameters:
op : Union[np.ndarray, str, List[str]]

The Pauli operator to be represented. Can be a matrix, a string, or a list of strings.

Examples

Create a Pauli operator from a matrix

In [1]: op = mp.PauliOp(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]))

In [2]: print(op)
XI
IX
IZ
ZI

Create a Pauli operator from a string

In [3]: op = mp.PauliOp('XIZ;ZII;IIZ;IZI')

In [4]: print(op)
XIZ
ZII
IIZ
IZI

Create a Pauli operator from a list of strings

In [5]: op = mp.PauliOp(['XIZ', 'ZII', 'IIZ', 'IZI'])

In [6]: print(op)
XIZ
ZII
IIZ
IZI
Group:

operators

append(other)

Appends a Pauli operator to the end of another Pauli operator.

Examples

In [1]: op1 = mp.PauliOp('XIZ;IZI')

In [2]: op2 = mp.PauliOp('XZZ')

In [3]: op1.append(op2)

In [4]: print(op1)
XIZ
IZI
XZZ
commutator(other) PauliOp

Returns the commutator of two Pauli operators.

get_subset(indices)

Returns a subset of the Pauli operator.

Parameters:
indices : List[int]

The indices of the Pauli operators to be returned.

Examples

In [1]: op = mp.PauliOp('XIZ;ZII;IIZ;IZI')

In [2]: print(op.get_subset([0, 2]))
XZ
ZI
IZ
II
property number_of_qubits

Returns the number of qubits in the Pauli operator.

symplectic_prod(other)

Returns the symplectic product of two Pauli operators.

MBQCircuits

class mentpy.GraphState(networkx.classes.graph.Graph)

A graph state class that inherits from networkx.Graph.

class mentpy.MBQCircuit

The MBQCircuit class that deals with operations and manipulations of graph states

mentpy.draw(state: MBQCircuit | GraphState, fix_wires=None, **)

Draws mbqc circuit with flow.

mentpy.hstack(states)

Horizontally stack a list of graph states into a larger graph state. This is, the input of the new MBQC circuit is the input of the first state, and the output is the output of the last state.

mentpy.vstack(states)

Vertically stack a list of graph states into a larger graph state. This is, the input of the new MBQC circuit is the input of the first state, and the output is the output of the last state.

This module provides the functionalities to define graph states

class mentpy.mbqc.GraphState(*args, **kwargs)

A graph state class that inherits from networkx.Graph.

Examples

Create a 1D cluster state \(|G>\) of five qubits

In [1]: g = mp.GraphState()

In [2]: g.add_edges_from([(0,1), (1,2), (2,3), (3, 4)])

In [3]: print(g)
GraphState with 5 nodes and 4 edges
Group:

states

index_mapping()

Return a mapping of the nodes to their indices.

stabilizers()

Generate the stabilizers of a graph state.

Examples

Calculate the stabilizers of a 1D cluster state \(|G>\) of five qubits

In [1]: g = mp.GraphState()

In [2]: g.add_edges_from([(0,1), (1,2), (2,3), (3, 4)])

In [3]: print(g.stabilizers())
XZIII
ZXZII
IZXZI
IIZXZ
IIIZX
class mentpy.mbqc.MBQCircuit(graph: GraphState, input_nodes: List[int] = [], output_nodes: List[int] = [], measurements: Dict[int, Ment] | None = None, default_measurement: Ment | None = Ment(θ, XY), flow: Callable | None = None, partial_order: callable | None = None, measurement_order: List[int] | None = None, relabel_indices: bool = True)

The MBQCircuit class that deals with operations and manipulations of graph states

Parameters:
graph : mp.GraphState

The graph state of the MBQC circuit.

input_nodes : list

The input nodes of the MBQC circuit.

output_nodes : list

The output nodes of the MBQC circuit.

measurements : dict

The measurements of the MBQC circuit. The keys are the nodes and the values are the measurements.

Examples

Create a 1D cluster state \(|G>\) of five qubits

In [1]: g = mp.GraphState()

In [2]: g.add_edges_from([(0,1), (1,2), (2,3), (3, 4)])

In [3]: state = mp.MBQCircuit(g, input_nodes=[0], output_nodes=[4])

See also

mp.GraphState

Group:

states

add_edge(u, v)

Adds an edge between nodes u and v

add_edges_from(edges, **kwargs)

Adds edges from a list of tuples

calculate_order()

Returns the order of the measurements

property classical_output_nodes : List[int]

Return the output nodes of the MBQC circuit.

property controlled_nodes : List[int]

Return the controlled nodes of the MBQC circuit.

property depth : int

Return the depth of the MBQC circuit.

property flow : Callable

Return the flow function of the MBQC circuit.

property graph : GraphState

Return the graph of the resource state.

property input_nodes : List[int]

Return the input nodes of the MBQC circuit.

property inputc : List

Returns \(I^c\), the complement of input nodes.

property measurement_order : List[int]

Return the measurement order of the MBQC circuit.

property measurements : Dict[int, Ment]

Return the measurements of the MBQC circuit.

ordered_layers(train_indices=False) List[List[int]]

Returns the layers of the MBQC circuit.

property output_nodes : List[int]

Return the output nodes of the MBQC circuit.

property outputc : List

Returns \(O^c\), the complement of output nodes.

property partial_order : Callable

Return the partial order function of the MBQC circuit.

property quantum_output_nodes : List[int]

Return the output nodes of the MBQC circuit.

property trainable_nodes : List[int]

Return the trainable nodes of the MBQC circuit.

mentpy.mbqc.draw(state: MBQCircuit | GraphState, fix_wires=None, **kwargs)

Draws mbqc circuit with flow.

TODO: Add support for graphs without flow, but with gflow TODO: Improve fix when there are control nodes

Group:

states

mentpy.mbqc.hstack(states)

Horizontally stack a list of graph states into a larger graph state. This is, the input of the new MBQC circuit is the input of the first state, and the output is the output of the last state.

Group:

states

mentpy.mbqc.merge(state1: MBQCircuit, state2: MBQCircuit, along=[]) MBQCircuit

Merge two MBQC circuits into a larger MBQC circuit. This is, the input and output of the new MBQC circuit will depend on the concat_indices.

mentpy.mbqc.vstack(states)

Vertically stack a list of graph states into a larger graph state. This is, the input of the new MBQC circuit is the input of the first state, and the output is the output of the last state.

Group:

states

Simulators

class mentpy.BaseSimulator(abc.ABC)

Base class for simulators.

class mentpy.PatternSimulator

Simulator for measuring patterns of MBQC circuits.

class mentpy.PennylaneSimulator(mentpy.BaseSimulator)

Simulator for measuring patterns of MBQC circuits.

This module contains the different simulators for the MBQCircuit class

class mentpy.simulators.BaseSimulator(mbqcircuit: MBQCircuit, input_state: ndarray | None = None)

Base class for simulators.

Note

This class should not be used directly. Instead, use one of the subclasses.

Parameters:
mbqcircuit : mp.MBQCircuit

The MBQC circuit used for the simulation.

input_state : np.ndarray

The input state of the simulator.

See also

mp.PatternSimulator, mp.PennylaneSimulator, mp.CirqSimulator

Group:

simulators

property input_state : ndarray

The input state of the simulator.

property mbqcircuit : MBQCircuit

The MBQC circuit used for the simulation.

abstract measure(angle: float, **kwargs)

Measures the state of the system.

Parameters:
angle : float

The angle of measurement.

property outcomes : dict

The outcomes of the simulation.

abstract reset(input_state=None)

Resets the simulator to the initial state.

abstract run(angles: List[float], **kwargs) Tuple[List[int], ndarray]

Measures the state of the system.

Parameters:
angles : List[float]

The parameters of the MBQC circuit (if any).

class mentpy.simulators.NumpySimulatorDM(mbqcircuit: MBQCircuit, input_state: ndarray | None = None, **kwargs)

A density matrix simulator that uses numpy to simulate the quantum circuit.

current_number_simulated_nodes() int

Returns the number of nodes that are currently simulated.

current_simulated_nodes() List[int]

Returns the nodes that are currently simulated.

find_swaps(source, target)
future_neighbors_in_wire(node: int) List[int]
measure(angle: float, mode='sample') Tuple

Measures the state of the system.

Parameters:
angle : float

The angle of measurement.

measure_ment(ment: Ment, angle, i, force0=False, mode='sample')

Measures a ment

neighbors_in_wire(node: int) List[int]

Returns the neighbors of a node in the same wire.

node_in_which_wire(node: int) int

Returns the wire in which the node is.

reorder_qubits(state, current_order, target_order)

Reorders the qubits in the given order.

reset(input_state: ndarray | None = None)

Resets the simulator to the initial state.

run(angles: List[float], mode='sample', input_state=None) Tuple[List[int], ndarray]

Measures the quantum state in the given pattern.

class mentpy.simulators.PatternSimulator(mbqcircuit: MBQCircuit, input_state: ndarray | None = None, backend='pennylane', *args, **kwargs)

Simulator for measuring patterns of MBQC circuits.

Parameters:
mbqcircuit : mp.MBQCircuit

The MBQC circuit used for the simulation.

backend : str

The simulator to use. Currently only ‘pennylane-default.qubit’ is supported.

See also

mp.PennylaneSimulator, mp.CirqSimulator

Group:

simulators

measure(angle: float, **kwargs)
reset(input_state: ndarray | None = None)
run(angles: List[float], **kwargs) Tuple[List[int], ndarray]
class mentpy.simulators.PennylaneSimulator(mbqcircuit: MBQCircuit, input_state: ndarray, *args, **kwargs)

Simulator for measuring patterns of MBQC circuits.

Parameters:
mbqcircuit : mp.MBQCircuit

The MBQC circuit used for the simulation.

input_state : np.ndarray

The input state of the simulator.

See also

mp.PatternSimulator, mp.CirqSimulator

Group:

simulators

measure(angle: float, plane: str = 'XY')

Measures the state of the system.

Parameters:
angle : float

The angle of measurement.

reset(input_state=None)

Resets the simulator to the initial state.

run(angles: List[float], **kwargs) Tuple[List[int], ndarray]

Measures the state of the system.

Parameters:
angles : List[float]

The parameters of the MBQC circuit (if any).

Optimizers

This module contains the optimizers for the MBQCircuit class

class mentpy.optimizers.AdamOptimizer(step_size=0.1, b1=0.9, b2=0.999, eps=1e-08)

Class for the Adam optimizer.

Parameters:
step_size : float, optional

The step size of the optimizer, by default 0.1

b1 : float, optional

The first moment decay rate, by default 0.9

b2 : float, optional

The second moment decay rate, by default 0.999

eps : float, optional

A small number to avoid division by zero, by default 10**-8

Examples

Create an Adam optimizer

In [1]: opt = mp.optimizers.AdamOptimizer()

In [2]: print(opt)
<mentpy.optimizers.adam.AdamOptimizer object at 0x7f64b5ecbeb0>

See also

mp.optimizers.SGDOptimizer

Group:

optimizers

optimize(f, x0, num_iters=100, callback=None, verbose=False, **kwargs)

Optimize a function f using the Adam optimizer.

optimize_and_gradient_norm(f, x0, num_iters=100, callback=None, verbose=False, **kwargs)

Optimize a function f using the Adam optimizer.

reset()

Reset the optimizer.

step(f, x, i, **kwargs)

Take a step of the optimizer.

update_step_size(x, i, factor=0.99)

Update the step size of the optimizer.

class mentpy.optimizers.RCDOptimizer(step_size=0.1, adaptive=False)

Class for the random coordinate descent optimizer.

Parameters:
step_size : float, optional

The initial step size of the optimizer, by default 0.1

adaptive : bool, optional

Whether to use an adaptive step size, by default False

Examples

Create a random coordinate descent optimizer

In [1]: opt = mp.optimizers.RCDOptimizer()

In [2]: print(opt)
<mentpy.optimizers.rcd.RCDOptimizer object at 0x7f64b5f65570>
Group:

optimizers

optimize(f, x0, num_iters=100, callback=None, verbose=False, **kwargs)

Optimize a function f using the random coordinate descent optimizer.

optimize_and_gradient_norm(f, x0, num_iters=100, callback=None, verbose=False, **kwargs)

Optimize a function f using the random coordinate descent optimizer.

reset(*args, **kwargs)
step(f, x, i, **kwargs)

Take a step using the random coordinate descent optimizer.

update_step_size(x, i, factor=0.99)

Update the step size of the optimizer.

class mentpy.optimizers.SGDOptimizer(step_size=0.1, momentum=0.0, nesterov=False)

Class for the SGD optimizer.

Parameters:
step_size : float, optional

The step size of the optimizer, by default 0.1

momentum : float, optional

The momentum of the optimizer, by default 0.9

nesterov : bool, optional

Whether to use Nesterov momentum, by default False

Examples

Create an SGD optimizer

In [1]: opt = mp.optimizers.SGDOptimizer()

In [2]: print(opt)
<mentpy.optimizers.sgd.SGDOptimizer object at 0x7f64b5e04040>

See also

mp.optimizers.AdamOptimizer

Group:

optimizers

optimize(f, x0, num_iters=100, callback=None, verbose=False, **kwargs)

Optimize a function f using the SGD optimizer.

optimize_and_gradient_norm(f, x0, num_iters=100, callback=None, verbose=False, **kwargs)

Optimize a function f using the SGD optimizer.

reset(*args, **kwargs)

Reset the optimizer.

step(f, x, i, **kwargs)

Take a step of the SGD optimizer.

update_step_size(x, i, factor=0.99)

Update the step size of the optimizer.

Templates

This is the common_ansatz module. It has several common ansatzes that can be used for MBQC algorithms

class mentpy.templates.GraphState(*args, **kwargs)

A graph state class that inherits from networkx.Graph.

Examples

Create a 1D cluster state \(|G>\) of five qubits

In [3]: g = mp.GraphState()

In [4]: g.add_edges_from([(0,1), (1,2), (2,3), (3, 4)])

In [5]: print(g)
GraphState with 5 nodes and 4 edges
Group:

states

index_mapping()

Return a mapping of the nodes to their indices.

stabilizers()

Generate the stabilizers of a graph state.

Examples

Calculate the stabilizers of a 1D cluster state \(|G>\) of five qubits

In [6]: g = mp.GraphState()

In [7]: g.add_edges_from([(0,1), (1,2), (2,3), (3, 4)])

In [8]: print(g.stabilizers())
XZIII
ZXZII
IZXZI
IIZXZ
IIIZX
class mentpy.templates.MBQCircuit(graph: GraphState, input_nodes: List[int] = [], output_nodes: List[int] = [], measurements: Dict[int, Ment] | None = None, default_measurement: Ment | None = Ment(θ, XY), flow: Callable | None = None, partial_order: callable | None = None, measurement_order: List[int] | None = None, relabel_indices: bool = True)

The MBQCircuit class that deals with operations and manipulations of graph states

Parameters:
graph : mp.GraphState

The graph state of the MBQC circuit.

input_nodes : list

The input nodes of the MBQC circuit.

output_nodes : list

The output nodes of the MBQC circuit.

measurements : dict

The measurements of the MBQC circuit. The keys are the nodes and the values are the measurements.

Examples

Create a 1D cluster state \(|G>\) of five qubits

In [9]: g = mp.GraphState()

In [10]: g.add_edges_from([(0,1), (1,2), (2,3), (3, 4)])

In [11]: state = mp.MBQCircuit(g, input_nodes=[0], output_nodes=[4])

See also

mp.GraphState

Group:

states

add_edge(u, v)

Adds an edge between nodes u and v

add_edges_from(edges, **kwargs)

Adds edges from a list of tuples

calculate_order()

Returns the order of the measurements

property classical_output_nodes : List[int]

Return the output nodes of the MBQC circuit.

property controlled_nodes : List[int]

Return the controlled nodes of the MBQC circuit.

property depth : int

Return the depth of the MBQC circuit.

property flow : Callable

Return the flow function of the MBQC circuit.

property graph : GraphState

Return the graph of the resource state.

property input_nodes : List[int]

Return the input nodes of the MBQC circuit.

property inputc : List

Returns \(I^c\), the complement of input nodes.

property measurement_order : List[int]

Return the measurement order of the MBQC circuit.

property measurements : Dict[int, Ment]

Return the measurements of the MBQC circuit.

ordered_layers(train_indices=False) List[List[int]]

Returns the layers of the MBQC circuit.

property output_nodes : List[int]

Return the output nodes of the MBQC circuit.

property outputc : List

Returns \(O^c\), the complement of output nodes.

property partial_order : Callable

Return the partial order function of the MBQC circuit.

property quantum_output_nodes : List[int]

Return the output nodes of the MBQC circuit.

property trainable_nodes : List[int]

Return the trainable nodes of the MBQC circuit.

class mentpy.templates.Ment(angle: int | float | tuple | str | None = None, plane: str | None = 'XY')

Measurement operator.

Parameters:
angle : float

The angle of the measurement. Only used if plane is “XY”, “XZ”, “YZ”, or “XYZ”. If plane is “XYZ”, the input should be a tuple of two angles.

plane : str

The plane of the measurement. Can be “XY”, “XZ”, “YZ”, “XYZ”, “X”, “Y”, “Z”.

property angle
copy()

Returns a copy of the measurement.

get_povm(angle: float | None = None, *args, **kwargs)

Returns the POVM representation of the measurement.

is_trainable()

Returns True if the measurement is trainable.

matrix(angle: float | None = None, *args, **kwargs)

Returns the matrix representation of the measurement.

property node_id : Any
property outcome : MentOutcome
property plane
set_angle(angle)

Sets the angle of the measurement.

class mentpy.templates.PauliOp(op: ndarray | str | List[str])

Class for representing Pauli operators as matrices and strings.

Parameters:
op : Union[np.ndarray, str, List[str]]

The Pauli operator to be represented. Can be a matrix, a string, or a list of strings.

Examples

Create a Pauli operator from a matrix

In [12]: op = mp.PauliOp(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]))

In [13]: print(op)
XI
IX
IZ
ZI

Create a Pauli operator from a string

In [14]: op = mp.PauliOp('XIZ;ZII;IIZ;IZI')

In [15]: print(op)
XIZ
ZII
IIZ
IZI

Create a Pauli operator from a list of strings

In [16]: op = mp.PauliOp(['XIZ', 'ZII', 'IIZ', 'IZI'])

In [17]: print(op)
XIZ
ZII
IIZ
IZI
Group:

operators

append(other)

Appends a Pauli operator to the end of another Pauli operator.

Examples

In [18]: op1 = mp.PauliOp('XIZ;IZI')

In [19]: op2 = mp.PauliOp('XZZ')

In [20]: op1.append(op2)

In [21]: print(op1)
XIZ
IZI
XZZ
commutator(other) PauliOp

Returns the commutator of two Pauli operators.

get_subset(indices)

Returns a subset of the Pauli operator.

Parameters:
indices : List[int]

The indices of the Pauli operators to be returned.

Examples

In [22]: op = mp.PauliOp('XIZ;ZII;IIZ;IZI')

In [23]: print(op.get_subset([0, 2]))
XZ
ZI
IZ
II
property number_of_qubits

Returns the number of qubits in the Pauli operator.

symplectic_prod(other)

Returns the symplectic product of two Pauli operators.

mentpy.templates.from_pauli(pauli_op: PauliOp)

Returns a graph state that can implement \(U=e^{-i heta P}\)

mentpy.templates.grid_cluster(n, m, periodic=False, **kwargs) MBQCircuit

Returns a grid cluster state of n x m qubits.

Parameters:
n : int

The number of rows in the cluster state.

m : int

The number of columns in the cluster state.

periodic : bool

If True, the returned state will be a cylinder.

Return type:

The grid cluster state of n x m qubits.

Examples

Create a 2D cluster state \(|G>\) of five qubits

In [1]: g = mp.templates.grid_cluster(2, 3)

In [2]: mp.draw(g)
Out[2]: (<Figure size 800x300 with 1 Axes>, <Axes: >)
savefig/grid_cluster.png
Group:

templates

mentpy.templates.hstack(states)

Horizontally stack a list of graph states into a larger graph state. This is, the input of the new MBQC circuit is the input of the first state, and the output is the output of the last state.

Group:

states

mentpy.templates.linear_cluster(n, **kwargs) MBQCircuit

Returns a linear cluster state of n qubits.

Parameters:
n : int

The number of qubits in the cluster state.

Return type:

The linear cluster state of n qubits.

Examples

Create a 1D cluster state \(|G>\) of five qubits

In [1]: g = mp.templates.linear_cluster(5)

In [2]: mp.draw(g)
Out[2]: (<Figure size 800x300 with 1 Axes>, <Axes: >)
savefig/linear_cluster.png
Group:

templates

mentpy.templates.many_wires(n_wires: List, **kwargs) MBQCircuit

Returns a graph state with many wires.

Parameters:
n_wires : List

A list of the number of qubits in each wire.

Return type:

The graph state with many wires.

Examples

Create a graph state with three wires of 2, 3, and 4 qubits respectively

In [1]: g = mp.templates.many_wires([2, 3, 4])

In [2]: mp.draw(g)
Out[2]: (<Figure size 800x300 with 1 Axes>, <Axes: >)
savefig/many_wires.png
Group:

templates

mentpy.templates.merge(state1: MBQCircuit, state2: MBQCircuit, along=[]) MBQCircuit

Merge two MBQC circuits into a larger MBQC circuit. This is, the input and output of the new MBQC circuit will depend on the concat_indices.

mentpy.templates.muta(n_wires, n_layers, **kwargs)

This is the Multiple Triangle Ansatz (MuTA) template.

Parameters:
n_wires : int

The number of wires in the graph state.

n_layers : int

The number of layers in the graph state.

Return type:

The graph state with the MuTA template.

Examples

Create a MuTA ansatz with 3 wires and 2 layers

In [1]: g = mp.templates.muta(3, 2)

In [2]: mp.draw(g, figsize=(16,5))
Out[2]: (<Figure size 1600x500 with 1 Axes>, <Axes: >)
savefig/muta.png
Group:

templates

mentpy.templates.spturb(n_qubits: int, n_layers: int, periodic=False, **kwargs)

This is the Symmetry Protected Topological Perturbator Ansatz (SPTurb) template.

Parameters:
n_qubits : int

The number of qubits in the SPT state.

n_layers : int

The number of layers in the graph state.

periodic : bool

Whether to use periodic boundary conditions.

Return type:

The graph state with the SPTurb template.

Group:

templates

Utils

Utils module.

class mentpy.utils.FlowSpace(graph_state: MBQCircuit, allow_any_size_graphs: bool = False)

The flow space graph of a MBQCGraph.

Each node corresponds to a possible graph over len(graph_state) qubits. Each edge between nodes represent going from one graph to another via adding or removing edges.

Note

flow_space() will only work for MBQCGraph with less

than 8 qubits.

all_graphs_graph()

Returns a tuple with three graphs.

The first graph is the graph corresponding to all possible graphs. The second is the subgraph of all graphs with flow. The third is the subgraph of all graphs without flow.

generator_all_graphs()

Returns a generator that generates all possible graphs for \(n\) ordered nodes.

mentpy.utils.GF

alias of GF2

class mentpy.utils.MBQCircuit(graph: GraphState, input_nodes: List[int] = [], output_nodes: List[int] = [], measurements: Dict[int, Ment] | None = None, default_measurement: Ment | None = Ment(θ, XY), flow: Callable | None = None, partial_order: callable | None = None, measurement_order: List[int] | None = None, relabel_indices: bool = True)

The MBQCircuit class that deals with operations and manipulations of graph states

Parameters:
graph : mp.GraphState

The graph state of the MBQC circuit.

input_nodes : list

The input nodes of the MBQC circuit.

output_nodes : list

The output nodes of the MBQC circuit.

measurements : dict

The measurements of the MBQC circuit. The keys are the nodes and the values are the measurements.

Examples

Create a 1D cluster state \(|G>\) of five qubits

In [3]: g = mp.GraphState()

In [4]: g.add_edges_from([(0,1), (1,2), (2,3), (3, 4)])

In [5]: state = mp.MBQCircuit(g, input_nodes=[0], output_nodes=[4])

See also

mp.GraphState

Group:

states

add_edge(u, v)

Adds an edge between nodes u and v

add_edges_from(edges, **kwargs)

Adds edges from a list of tuples

calculate_order()

Returns the order of the measurements

property classical_output_nodes : List[int]

Return the output nodes of the MBQC circuit.

property controlled_nodes : List[int]

Return the controlled nodes of the MBQC circuit.

property depth : int

Return the depth of the MBQC circuit.

property flow : Callable

Return the flow function of the MBQC circuit.

property graph : GraphState

Return the graph of the resource state.

property input_nodes : List[int]

Return the input nodes of the MBQC circuit.

property inputc : List

Returns \(I^c\), the complement of input nodes.

property measurement_order : List[int]

Return the measurement order of the MBQC circuit.

property measurements : Dict[int, Ment]

Return the measurements of the MBQC circuit.

ordered_layers(train_indices=False) List[List[int]]

Returns the layers of the MBQC circuit.

property output_nodes : List[int]

Return the output nodes of the MBQC circuit.

property outputc : List

Returns \(O^c\), the complement of output nodes.

property partial_order : Callable

Return the partial order function of the MBQC circuit.

property quantum_output_nodes : List[int]

Return the output nodes of the MBQC circuit.

property trainable_nodes : List[int]

Return the trainable nodes of the MBQC circuit.

class mentpy.utils.PatternSimulator(mbqcircuit: MBQCircuit, input_state: ndarray | None = None, backend='pennylane', *args, **kwargs)

Simulator for measuring patterns of MBQC circuits.

Parameters:
mbqcircuit : mp.MBQCircuit

The MBQC circuit used for the simulation.

backend : str

The simulator to use. Currently only ‘pennylane-default.qubit’ is supported.

See also

mp.PennylaneSimulator, mp.CirqSimulator

Group:

simulators

measure(angle: float, **kwargs)
reset(input_state: ndarray | None = None)
run(angles: List[float], **kwargs) Tuple[List[int], ndarray]
class mentpy.utils.PauliOp(op: ndarray | str | List[str])

Class for representing Pauli operators as matrices and strings.

Parameters:
op : Union[np.ndarray, str, List[str]]

The Pauli operator to be represented. Can be a matrix, a string, or a list of strings.

Examples

Create a Pauli operator from a matrix

In [6]: op = mp.PauliOp(np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]))

In [7]: print(op)
XI
IX
IZ
ZI

Create a Pauli operator from a string

In [8]: op = mp.PauliOp('XIZ;ZII;IIZ;IZI')

In [9]: print(op)
XIZ
ZII
IIZ
IZI

Create a Pauli operator from a list of strings

In [10]: op = mp.PauliOp(['XIZ', 'ZII', 'IIZ', 'IZI'])

In [11]: print(op)
XIZ
ZII
IIZ
IZI
Group:

operators

append(other)

Appends a Pauli operator to the end of another Pauli operator.

Examples

In [12]: op1 = mp.PauliOp('XIZ;IZI')

In [13]: op2 = mp.PauliOp('XZZ')

In [14]: op1.append(op2)

In [15]: print(op1)
XIZ
IZI
XZZ
commutator(other) PauliOp

Returns the commutator of two Pauli operators.

get_subset(indices)

Returns a subset of the Pauli operator.

Parameters:
indices : List[int]

The indices of the Pauli operators to be returned.

Examples

In [16]: op = mp.PauliOp('XIZ;ZII;IIZ;IZI')

In [17]: print(op.get_subset([0, 2]))
XZ
ZI
IZ
II
property number_of_qubits

Returns the number of qubits in the Pauli operator.

symplectic_prod(other)

Returns the symplectic product of two Pauli operators.

mentpy.utils.are_lc_equivalent(graph1, graph2, clifford_form='tensor')

Check if two EGraphs are LC equivalent, and return the Clifford operation if so. Implemented as in arXiv:quant-ph/0405023. :param graph1: the initial graph to check Clifford equivalence with. :param graph2: the graph to check Clifford equivalence against. :param clifford_form: a string describing the output form of local Clifford operation, if

it exists. If ‘tensor’ (default), produce a list of length n of 2x2 numpy arrays corresponding to

single-qubit tensor factors.

If ‘global’, return a single 2nx2n numpy array corresponding to the global operator

acting on all n qubits.

Returns:

whether the states are LC equivalent, and if they are, the local

Clifford output according to ‘clifford_form’ specification.

Return type:

(bool, numpy.array)

mentpy.utils.brownian_circuit(dim, n, dt)

Returns a random unitary matrix close to the identity matrix

mentpy.utils.calculate_complete_gens_lie_algebra(state: MBQCircuit)

Calculates the Pauli operators for the Lie algebra of a given state

mentpy.utils.calculate_gens_lie_algebra(state: MBQCircuit)

Calculates the generators of the Lie algebra of a given state

mentpy.utils.calculate_lie_algebra(state: MBQCircuit, max_iter: int = 10000)

Calculates the Lie algebra of a given state

mentpy.utils.clifford_vec_to_global(vec)

Convert a local Clifford gate on n qubits to a local Clifford gate on all n qubits. Take a vector corresponding to a local Clifford gate on n qubits, (a_1, a_2, …, a_n, b_1, b_2, …, b_n, c_1, c_2, …, c_n, d_1, d_2, …, d_n), and return a single 2n x 2n array representing a local Clifford acting on all n qubits, given as the block matrix:

[A, B] [C, D]

where each block is a n x n diagonal matrix:

A = diag(a_1, a_2, …, a_n) B = diag(b_1, b_2, …, b_n) C = diag(c_1, c_2, …, c_n) D = diag(d_1, d_2, …, d_n).

Parameters:
vec : numpy.array

a vector of size 4n specifying a local Clifford on n qubits.

Returns:

a 2n x 2n numpy array representing a local

Clifford acting on all n qubits.

Return type:

numpy.array

mentpy.utils.clifford_vec_to_tensors(vec)

Convert a local Clifford gate on n qubits to a list of n single-qubit Cliffords. Take a local Clifford operation on n qubits in the form (a_1, a_2, …, a_n, b_1, b_2, …, b_n, c_1, c_2, …, c_n, d_1, d_2, …, d_n), and return a list of single-qubit Clifford gates as a list of 2x2 arrays, where the array at index k corresponds to the Clifford acting on qubit k given as:

[a_k, b_k] [c_k, d_k].

Parameters:
vec : numpy.array

a vector of size 4n specifying a local Clifford gate on n qubits.

Returns:

n 2x2 arrays representing single-qubit local Clifford gates.

Return type:

list[numpy.array]

class mentpy.utils.combinations(iterable, r)

Return successive r-length combinations of elements in the iterable.

combinations(range(4), 3) –> (0,1,2), (0,1,3), (0,2,3), (1,2,3)

mentpy.utils.digraph_expressivity_of_flow_space(flow_space: FlowSpace, method='KL', **kwargs)

Returns digraph given the expressivity of a FlowSpace object.

Parameters:
(FlowSpace) : flow_space

(str) : method

mentpy.utils.dim_so(n)

Calculates the dimension of \(So(n)\)

mentpy.utils.dim_sp(n)

Calculates the dimension of \(Sp(n)\)

mentpy.utils.dim_su(n)

Calculates the dimension of \(Su(n)\)

mentpy.utils.draw_digraph_flow_space(digraph_expr: <module 'networkx.classes.digraph' from '/home/docs/checkouts/readthedocs.org/user_builds/mentpy/envs/latest/lib/python3.10/site-packages/networkx/classes/digraph.py'>, **kwargs)

Draws the expressivity digraph of flow space

mentpy.utils.expressivity_with_histogram(graph_state_circuit: MBQCircuit, n_samples: int = 10000, n_bins: int = 1000, method: str = 'KL')

Returns the expressivity calculated using the Kullback-Leiber entropy

Parameters:
graph_state_circuit : Graph state circuit for which we will calculate the expressivity

n_samples : Number of samples that we will use to estimate the expressivity

n_bins : Number of bins of the histogram

method : 'KL' for Kullback-Leibler divergence or 'RE' for relative entropy.

Returns:

expressivity (float)

Return type:

Expressivity measure for graph_state_circuit

mentpy.utils.generate_haar_random_states(n_qubits: int, n_samples: int = 1) ndarray

Makes one Haar random state over n_qubits

mentpy.utils.generate_random_dataset(unitary: ndarray, n_samples: int, test_size: float = 0.3) tuple

Return random training and test data (input, target) for a given unitary gate unitary.

mentpy.utils.generate_random_dataset_noisy(unitary: ndarray, n_samples: int, noise_level: float = 0.0, noise_type='brownian', test_size: float = 0.3) tuple

Return random training data (input, target) for a given unitary gate unitary with brownian noise parametrized by noise_level.

Parameters:
unitary : np.ndarray

unitary gate

n_samples : int

number of samples

noise_level : float

noise level

noise_type : str

type of noise. Either ‘brownian’ or ‘bitflip’

test_size : float

percentage of test data

mentpy.utils.haar_probability_density_of_fidelities(F: float, n_qubits: int)

Returns the probability density function of fidelities \(P_{Haar}(F) = (N-1)(1-F)^{N-2}\) where \(N = 2^{n}\) is the dimension of the Hilbert space.

Parameters:
(float) : F

(int) : n_qubits

Return type:

\(P_{Haar}(F) = (N-1)(1-F)^{N-2}\) where \(N = 2^{n}\)

mentpy.utils.lc_cluster_flowspace(deg_graph, sanity_check=True)

Cluster flow graph in lc_equivalent graphs.

mentpy.utils.lc_constraint_system(G, H)

Build the constraint for LC-equivalence of two adjacency matrices. Construct a binary system of equations that two adjacency matrices G and H must satisfy for equivalence through local complementations. :param G: n x n adjacency matrices. :type G: numpy.array :param H: n x n adjacency matrices. :type H: numpy.array

Returns:

an array of shape n^2 x 4n representing a system of n^2

binary linear equations with 4n unknowns.

Return type:

numpy.array

mentpy.utils.lie_algebra_completion(generators: PauliOp, max_iter: int = 1000)

Completes a given set of Pauli operators to a basis of the Lie algebra

mentpy.utils.nullspace_basis(M)

Return the nullspace basis of matrix M. Construct an array whose rows are binary basis vectors of the right nullspace of input matrix array. :param M: a binary matrix. :type M: numpy.array

Returns:

an array whose rows are basis vectors of the right

nullspace of M.

Return type:

numpy.array

mentpy.utils.randomUnitary_closetoid(dim, t, n)

Returns a random unitary matrix close to the identity matrix

mentpy.utils.reduce(function, iterable[, initial]) value

Apply a function of two arguments cumulatively to the items of a sequence or iterable, from left to right, so as to reduce the iterable to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty.

mentpy.utils.reduce_RREform_mod2(M, max_cols=None)

Put a binary matrix into row reduced echelon form modulo 2, up to a maximum number of columns given by max_cols. :param M: the matrix to reduce. :type M: numpy.array :param max_cols: the maximum number of columns of the input array to reduce. :type max_cols: int

Returns:

the reduced matrix and the the index of pivot column.

Return type:

(numpy.array, int)

mentpy.utils.remove_repeated_ops(ops: PauliOp)

Removes repeated Pauli operators from a set

mentpy.utils.sample_probability_density_of_fidelities(graph_state_circuit: MBQCircuit, n_samples=1000, backend='pennylane')

Calculates samples of the probability of fidelities of the given graph state circuit

mentpy.utils.search_nullspace(basis)
Check if the nullspace satisfies the determinant constraints.

Search through sums of pairs of basis vectors of the nullspace and see if any satisfy the determinant constraints. If no solution is found, output None. If a solution is found, return a vector specifying the local Clifford in the form:

(a_1, a_2, …, a_n, b_1, b_2, …, b_n, c_1, c_2, …, c_n, d_1, d_2, …, d_n),

where n is the number of nodes of the graph.

Parameters:
basis : numpy.array

an array whose rows are basis vectors of the nullspace

Returns:

None if no solution, or the solution array.

Return type:

NoneType or numpy.array

mentpy.utils.solve(A, b)

Solve a linear system of equations Ax = b for x.

mentpy.utils.train_test_split(inputs, targets, test_size: float = 0.3, randomize=False) tuple

Split the data into training and test sets.