Planar code

Simulation

class qsurface.codes.planar.sim.PerfectMeasurements(size, **kwargs)
init_surface(z=0, **kwargs)

Initializes the planar surface code on layer z.

Parameters

z (int or float, optional) – Layer of qubits, z=0 for perfect measurements.

init_parity_check(ancilla_qubit, **kwargs)

Initiates a parity check measurement.

For every ancilla qubit on (x,y), four neighboring data qubits are entangled for parity check measurements.

Parameters

ancilla_qubit (AncillaQubit) – Ancilla qubit to initialize.

init_logical_operator(**kwargs)

Initiates the logical operators [x,z] of the planar code.

add_ancilla_qubit(loc, z=0, state_type='x', **kwargs)

Initializes a AncillaQubit and saved to self.ancilla_qubits[z][loc].

Return type

AncillaQubit

add_data_qubit(loc, z=0, initial_states=None, None, **kwargs)

Initializes a DataQubit and saved to self.data_qubits[z][loc].

Parameters

initial_states (Tuple[float, float]) – Initial state for the data-qubit.

Return type

DataQubit

add_pseudo_qubit(loc, z=0, state_type='x', **kwargs)

Initializes a PseudoQubit and saved to self.pseudo_qubits[z][loc].

Return type

PseudoQubit

static entangle_pair(data_qubit, ancilla_qubit, key, edge=None, **kwargs)

Entangles one DataQubit to a AncillaQubit for parity measurement.

Parameters
init_errors(*error_modules, error_rates={}, **kwargs)

Initializes error modules.

Any error module from Error types can loaded as either a string equivalent to the module file name or as the module itself. The default error rates for all loaded error modules can be supplied as a dictionary with keywords corresponding to the default error rates of the associated error modules.

Parameters
  • error_modules (Union[str, Sim]) – The error modules to load. May be a string or an error module from Error types.

  • error_rates (dict) – The default error rates for the loaded modules. Must be a dictionary with probabilities with keywords corresponding to the default or overriding error rates of the associated error modules.

Examples

Load Pauli error and Erasure error modules via string names. Set default bitflip rate to 0.1 and erasure to 0.03.

>>> code.init_errors(
...    "pauli",
...    "erasure",
...    error_rates={"p_bitflip": 0.1, "p_erasure": 0.03}
... )

Load Pauli error module via module. Set default phaseflip rate to 0.05.

>>> import .errors.pauli as pauli
>>> code.init_errors(pauli, error_rates={"p_phaseflip": 0.05})
initialize(*args, **kwargs)

Initializes all data objects of the code.

Builds the surface with init_surface, adds the logical operators with init_logical_operator, and loads error modules with init_errors. All keyword arguments from these methods can be used for initialize.

random_errors(apply_order=None, measure=True, **kwargs)

Applies all errors loaded in self.errors attribute to layer z.

The random error is applied for each loaded error module by calling random_error. If apply_order is specified, the error modules are applied in order of the error names in the list. If no order is specified, the errors are applied in a random order. Addionally, any error rate can set by supplying the rate as a keyword argument e.g. p_bitflip = 0.1.

Parameters
  • apply_order (Optional[List[str]]) – The order in which the error modules are applied. Items in the list must equal keys in self.errors or the names of the loaded error modules.

  • measure (bool) – Measure ancilla qubits after errors have been simulated.

class qsurface.codes.planar.sim.FaultyMeasurements(size, *args, layers=None, p_bitflip_plaq=0, p_bitflip_star=0, **kwargs)
add_ancilla_qubit(loc, z=0, state_type='x', **kwargs)

Initializes a AncillaQubit and saved to self.ancilla_qubits[z][loc].

Return type

AncillaQubit

add_data_qubit(loc, z=0, initial_states=None, None, **kwargs)

Initializes a DataQubit and saved to self.data_qubits[z][loc].

Parameters

initial_states (Tuple[float, float]) – Initial state for the data-qubit.

Return type

DataQubit

add_pseudo_qubit(loc, z=0, state_type='x', **kwargs)

Initializes a PseudoQubit and saved to self.pseudo_qubits[z][loc].

Return type

PseudoQubit

add_vertical_edge(lower_ancilla, upper_ancilla, **kwargs)

Adds a PseudoEdge to connect two instances of an ancilla-qubit in time.

A surface code with faulty measurements must be decoded in 3D. Instances of the same ancilla qubits in time must be connected with an edge. Here, lower_ancilla is an older instance of layer ‘z’, and upper_ancilla is a newer instance of layer ‘z+1’.

Parameters
  • lower_ancilla (AncillaQubit) – Older instance of ancilla-qubit.

  • upper_ancilla (AncillaQubit) – Newer instance of ancilla-qubit.

static entangle_pair(data_qubit, ancilla_qubit, key, edge=None, **kwargs)

Entangles one DataQubit to a AncillaQubit for parity measurement.

Parameters
init_errors(*error_modules, error_rates={}, **kwargs)

Initializes error modules.

Any error module from Error types can loaded as either a string equivalent to the module file name or as the module itself. The default error rates for all loaded error modules can be supplied as a dictionary with keywords corresponding to the default error rates of the associated error modules.

Parameters
  • error_modules (Union[str, Sim]) – The error modules to load. May be a string or an error module from Error types.

  • error_rates (dict) – The default error rates for the loaded modules. Must be a dictionary with probabilities with keywords corresponding to the default or overriding error rates of the associated error modules.

Examples

Load Pauli error and Erasure error modules via string names. Set default bitflip rate to 0.1 and erasure to 0.03.

>>> code.init_errors(
...    "pauli",
...    "erasure",
...    error_rates={"p_bitflip": 0.1, "p_erasure": 0.03}
... )

Load Pauli error module via module. Set default phaseflip rate to 0.05.

>>> import .errors.pauli as pauli
>>> code.init_errors(pauli, error_rates={"p_phaseflip": 0.05})
init_logical_operator(**kwargs)

Initiates the logical operators [x,z] of the planar code.

init_parity_check(ancilla_qubit, **kwargs)

Initiates a parity check measurement.

For every ancilla qubit on (x,y), four neighboring data qubits are entangled for parity check measurements.

Parameters

ancilla_qubit (AncillaQubit) – Ancilla qubit to initialize.

init_surface(**kwargs)

Initiates the surface code.

The 3D lattice is initialized by first building the ground layer. After that each consecutive layer is built and pseudo-edges are added to connect the ancilla qubits of each layer.

initialize(*args, **kwargs)

Initializes all data objects of the code.

Builds the surface with init_surface, adds the logical operators with init_logical_operator, and loads error modules with init_errors. All keyword arguments from these methods can be used for initialize.

random_errors(p_bitflip_plaq=None, p_bitflip_star=None, **kwargs)

Performs a round of parity measurements on layer z with faulty measurements.

Parameters
  • p_bitflip_plaq (int or float, optional) – Probability of a bitflip during a parity check measurement on plaquette operators (XXXX).

  • p_bitflip_star (int or float, optional) – Probability of a bitflip during a parity check measurement on star operators (ZZZZ).

random_errors_layer(**kwargs)

Applies a layer of random errors loaded in self.errors.

Parameters

kwargs – Keyword arguments are passed on to random_errors.

random_measure_layer(**kwargs)

Measures a layer of ancillas.

If the measured state of the current ancilla is not equal to the measured state of the previous instance, the current ancilla is a syndrome.

Parameters

kwargs – Keyword arguments are passed on to get_state.

simulate(**kwargs)

Simulate an iteration or errors and measurement.

On all but the final layer, the default or overriding error rates (via keyworded arguments) are applied. On the final layer, perfect measurements are applied by setting p_bitflip_plaq=0 and p_bitflip_star=0.

Plotting

class qsurface.codes.planar.plot.PerfectMeasurements(*args, **kwargs)
class Figure(code, *args, **kwargs)
static change_properties(artist, prop_dict)

Changes the plot properties and draw the plot object or artist.

close()

Closes the figure.

draw_figure(new_iter_name=None, output=True, carriage_return=False, **kwargs)

Draws the canvas and blocks code execution.

Draws the queued plot changes onto the canvas and calls for focus() which blocks the code execution and catches user input for history navigation.

If a new iteration is called by supplying a new_iter_name, we additionally check for future property changes in the self.future_dict, and add these changes to the queue. Finally, all queued property changes for the next iteration are applied by change_properties.

Parameters
  • new_iter_name (Optional[str]) – Name of the new iteration. If no name is supplied, no new iteration is called.

  • output (bool) – Prints information to the console.

  • carriage_return (bool) – Applies carriage return to remove last line printed.

focus()

Enables the blocking object, catches input for history navigation.

The BlockingKeyInput object is called which blocks the execution of the code. During this block, the user input is received by the blocking object and return to the current method. From here, we can manipulate the plot or move through the plot history and call focus() again when all changes in the history have been drawn and blit.

key

function

h

show help

i

show all iterations

d

redraw current iteration

enter or right

go to next iteration, enter iteration number

backspace or left

go to previous iteration

n

go to newest iteration

0-9

input iteration number

When the method is active, the focus is on the figure. This will be indicated by a green circle in the bottom right of the figure. When the focus is lost, the code execution is continued and the icon is red. The change is icon color is performed by _set_figure_state(), which also hides the interactive elements when the focus is lost.

property history_at_newest
init_legend(legend_items=[], **kwargs)

Initializes the legend of the main axis of the figure. Also takes keyword arguments for legend.

The legend of the main axis self.main_ax consists of a series of Line2D objects. The qubit, vertex and stars are always in the legend for a surface code plot. Any error from Error types loaded in the code at code.errors in de outer class will add an extra element to the legend for differentiation if an error occurs. The Line2D attributes are stored at error.Plot.legend_params of the error module (see errors._template.Plot).

Parameters

legend_items (list of Line2D, optional) – Additional elements to the legend.

init_plot(**kwargs)

Plots all elements of the surface code onto the figure. Also takes keyword arguments for init_legend.

An additional matplotlib.widgets.RadioButtons object is added to the figure which allows for the user to choose one of the loaded errors and apply the error directly to a qubit via _pick_handler. This object is added via the init_plot method to make sure that the errors are already loaded in self.code.errors. The method for each loaded error is saved to self.error_methods. See errors._template.Plot for more information.

load_interactive_backend()

Configures the plotting backend.

If the Tkinter backend is enabled or can be enabled, the function returns True. For other backends False is returned.

Return type

bool

new_artist(artist, axis=None)

Adds a new artist to the axis.

Newly added artists must be hidden in the previous iteration. To make sure the history is properly logged, the visibility of the artist is set to False, and a new property of shown visibility is added to the queue of the next iteration.

Parameters
  • artist (Artist) – New plot artist to add to the axis.

  • axis (Optional[Axes]) – Axis to add the figure to.

Return type

None

new_properties(artist, properties, saved_properties={}, **kwargs)

Parses a dictionary of property changes of a matplotlib artist.

New properties are supplied via properties. If any of the new properties is different from its current value, this is seen as a property change. The old property value is stored in self.history_dict[self.history_iteration], and the new property value is stored at self.history_dict[self.history_iteration+1]. These new properties are queued for the next interation. The queue is emptied by applying all changes when draw_figure is called. If the same property changes 2+ times within the same iteration, the previous property change is removed with next_prop.pop(key, None).

The saved_properties parameter is used when temporary property changes have been applied by temporary_changes, in which the original properties are saved to self.temporary_saved as the saved properties. Before a new iteration is drawn, the temporary changes, which can be overwritten, are compared with the saved changes and the differences in properties are saved to [self.history_dict[self.history_iter-1]] and self.history_dict[self.history_iteration].

Some color values from different matplotlib objects are nested, some are list or tuple, and others may be a numpy.ndarray. The nested methods get_nested() and get_nested_property() make sure that the return type is always a list.

Parameters
  • artist (Artist) – Plot object whose properties are changed.

  • properties (dict) – Plot properties to change.

  • saved_properties (dict) – Override current properties and parse previous and current history.

temporary_properties(artist, properties, **kwargs)

Applies temporary property changes to a matplotlib artist.

Only available on the newest iteration, as we cannot change what is already in the past. All values in properties are immediately applied to artist. Since temporary changes can be overwritten within the same iteration, the first time a temporary property change is requested, the previous value is saved to self.temporary_saved. When the iteration changes, the property differences of the previous and current iteration are recomputed and saved to self.history_dict in _draw_from_history().

Parameters
  • artist (Artist) – Plot object whose properties are changed.

  • properties (dict) – Plot properties to change.

add_ancilla_qubit(loc, z=0, state_type='x', **kwargs)

Initializes a AncillaQubit and saved to self.ancilla_qubits[z][loc].

Return type

AncillaQubit

add_data_qubit(loc, z=0, initial_states=None, None, **kwargs)

Initializes a DataQubit and saved to self.data_qubits[z][loc].

Parameters

initial_states (Tuple[float, float]) – Initial state for the data-qubit.

Return type

DataQubit

add_pseudo_qubit(loc, z=0, state_type='x', **kwargs)

Initializes a PseudoQubit and saved to self.pseudo_qubits[z][loc].

Return type

PseudoQubit

static entangle_pair(data_qubit, ancilla_qubit, key, edge=None, **kwargs)

Entangles one DataQubit to a AncillaQubit for parity measurement.

Parameters
init_errors(*error_modules, error_rates={}, **kwargs)

Initializes error modules.

Any error module from Error types can loaded as either a string equivalent to the module file name or as the module itself. The default error rates for all loaded error modules can be supplied as a dictionary with keywords corresponding to the default error rates of the associated error modules.

Parameters
  • error_modules (Union[str, Sim]) – The error modules to load. May be a string or an error module from Error types.

  • error_rates (dict) – The default error rates for the loaded modules. Must be a dictionary with probabilities with keywords corresponding to the default or overriding error rates of the associated error modules.

Examples

Load Pauli error and Erasure error modules via string names. Set default bitflip rate to 0.1 and erasure to 0.03.

>>> code.init_errors(
...    "pauli",
...    "erasure",
...    error_rates={"p_bitflip": 0.1, "p_erasure": 0.03}
... )

Load Pauli error module via module. Set default phaseflip rate to 0.05.

>>> import .errors.pauli as pauli
>>> code.init_errors(pauli, error_rates={"p_phaseflip": 0.05})
init_logical_operator(**kwargs)

Initiates the logical operators [x,z] of the planar code.

init_parity_check(ancilla_qubit, **kwargs)

Initiates a parity check measurement.

For every ancilla qubit on (x,y), four neighboring data qubits are entangled for parity check measurements.

Parameters

ancilla_qubit (AncillaQubit) – Ancilla qubit to initialize.

init_surface(z=0, **kwargs)

Initializes the planar surface code on layer z.

Parameters

z (int or float, optional) – Layer of qubits, z=0 for perfect measurements.

initialize(*args, **kwargs)

Initializes the code with a figure. Also takes keyword arguments for init_plot.

Since each error object delivers extra plot properties to the figure, which are dependent on the self.params values in the figure itself, we must initialize in the following sequence.

  • First load figure to load self.params instance of the PlotParams dataclass.

  • Initialize lattice, error initialization must have figure properties

  • Draw figure with plot elements from errors

plot_ancilla(iter_name=None, **kwargs)

Update plots of all ancilla-qubits. A plot iteration is added if a iter_name is supplied. See draw_figure.

plot_data(iter_name=None, **kwargs)

Update plots of all data-qubits. A plot iteration is added if a iter_name is supplied. See draw_figure.

random_errors(*args, **kwargs)

Applies all errors loaded in self.errors attribute to layer z.

The random error is applied for each loaded error module by calling random_error. If apply_order is specified, the error modules are applied in order of the error names in the list. If no order is specified, the errors are applied in a random order. Addionally, any error rate can set by supplying the rate as a keyword argument e.g. p_bitflip = 0.1.

Parameters
  • apply_order – The order in which the error modules are applied. Items in the list must equal keys in self.errors or the names of the loaded error modules.

  • measure – Measure ancilla qubits after errors have been simulated.

show_corrected(**kwargs)

Redraws the qubits and ancillas to show their states after decoding.

class qsurface.codes.planar.plot.FaultyMeasurements(*args, figure3d=True, **kwargs)

Plotting code class for faulty measurements.

Inherits from codes.planar.sim.FaultyMeasurements and codes.planar.plot.PerfectMeasurements. See documentation for these classes for more.

Dependent on the figure3d argument, either a 3D figure object is created that inherits from Template3D and codes.planar.plot.PerfectMeasurements.Figure, or the 2D codes.planar.plot.PerfectMeasurements.Figure is used.

Parameters