Skip to content

Commit

Permalink
Functional style plaquette (#203)
Browse files Browse the repository at this point in the history
## Goal of the PR

Per [this
comment](#173 (review))
from @inmzhang and [the discussion/poll that
followed](#179) it seems
like the active developers in this repository prefer a functional-style
rather than an inheritance based style. This means that instead of
```py
class Plaquette:
    pass

class EmptyPlaquette(Plaquette):
    pass

class ZInitialisationPlaquette(Plaquette):
    pass

# many more
```
with a `Plaquette` class whose sole purpose is to provide a common
interface between plaquette, everyone voted for a functional-style:
```py
class Plaquette:
    pass

def empty_plaquette(qubits: PlaquetteQubits) -> Plaquette:
    pass

def z_initialisation_plaquette(qubits: PlaquetteQubits) -> Plaquette:
    pass

# many more
```
with `Plaquette` being the only class used, and sub-classes are replaced
by functions that initialise `Plaquette` instances.

## How was it done?
This change is mostly (entirely?) cosmetic, as the sub-classes of
`Plaquette` were only initialising correctly their `Plaquette`
subclasses. This shows quite well in this PR: the changes are quite
small and can be summarised in 2 points:
- Change the subclass name by the function name. The new functions have
exactly the same parameters as their corresponding `Plaquette` subclass,
so this change can be done using a "dumb" tool (i.e., just search &
replace, no need for code-aware tools).
- Change the subclasses to functions:
  ```py
  class [CLASSNAME](Plaquette):
      def __init__(self, [PARAMETERS]):
          [CODE]
          super().__init__([SUPER_PARAMETERS])
  ```
  becomes
  ```py
  def [SNAKE_CASE(CLASSNAME)](PARAMETERS) -> Plaquette:
      CODE
      return Plaquette([SUPER_PARAMETERS])
  ```
with a slight variation for classes that were 2 or more levels under
`Plaquette` in the inheritance hierarchy (e.g.
`ZRoundedInitialisationPlaquette` -> `ZInitialisationPlaquette` ->
`Plaquette`) for which the `super().__init__` call should be replaced
with their superclass corresponding function.
  • Loading branch information
nelimee authored May 3, 2024
1 parent fea0458 commit b990e8d
Show file tree
Hide file tree
Showing 13 changed files with 379 additions and 377 deletions.
80 changes: 40 additions & 40 deletions notebooks/logical_qubit_extended_memory_experiment.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
"\n",
"This notebook aims at performing a memory experiment on an extended logical qubit (see image below).\n",
"\n",
"![A logical qubit that has been extended horizontally by 2 plaquettes](./images/extended_logical_qubit.png)"
"![A logical qubit that has been extended horizontally by 2 plaquettes](./images/extended_logical_qubit.png)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Mandatory imports"
"## Mandatory imports\n"
]
},
{
Expand Down Expand Up @@ -43,14 +43,14 @@
")\n",
"from tqec.plaquette.plaquette import Plaquette\n",
"from tqec.plaquette.library import (\n",
" ZSquareInitialisationPlaquette,\n",
" ZRoundedInitialisationPlaquette,\n",
" XXMemoryPlaquette,\n",
" XXXXMemoryPlaquette,\n",
" ZZMemoryPlaquette,\n",
" ZZZZMemoryPlaquette,\n",
" MeasurementRoundedPlaquette,\n",
" MeasurementSquarePlaquette,\n",
" z_initialisation_square_plaquette,\n",
" z_initialisation_rounded_plaquette,\n",
" xx_memory_plaquette,\n",
" xxxx_memory_plaquette,\n",
" zz_memory_plaquette,\n",
" zzzz_memory_plaquette,\n",
" measurement_rounded_plaquette,\n",
" measurement_square_plaquette,\n",
")\n",
"from tqec.templates.display import display_template"
]
Expand All @@ -65,7 +65,7 @@
"\n",
"The first pass normalises the `cirq.Circuit` produced. This pass was performing several modifications before, but is now simply removing potential empty `cirq.Moment` instances from the `cirq.Circuit` instance.\n",
"\n",
"The second pass applies the noise model(s) we want to consider in the `stim` simulation."
"The second pass applies the noise model(s) we want to consider in the `stim` simulation.\n"
]
},
{
Expand Down Expand Up @@ -102,7 +102,7 @@
"\n",
"The main goal of the `tqec` library is to construct the `cirq.Circuit` instance representing the QEC experiment we are interested in. In this notebook, we want to perform a memory experiment on an \"extended\" logical qubit.\n",
"\n",
"The different pre-defined Plaquette instances `XXPlaquetteList`, ... implement by default the memory experiment, so we can use them without worrying about the quantum circuits actually executed."
"The different pre-defined Plaquette instances `XXPlaquetteList`, ... implement by default the memory experiment, so we can use them without worrying about the quantum circuits actually executed.\n"
]
},
{
Expand Down Expand Up @@ -144,58 +144,58 @@
" # - Measurement index is 8\n",
" plaquettes: list[list[Plaquette]] = [\n",
" [\n",
" ZRoundedInitialisationPlaquette(PlaquetteOrientation.UP),\n",
" XXMemoryPlaquette(\n",
" z_initialisation_rounded_plaquette(PlaquetteOrientation.UP),\n",
" xx_memory_plaquette(\n",
" PlaquetteOrientation.UP,\n",
" [1, 2, 5, 6, 7, 8],\n",
" include_detector=False,\n",
" is_first_round=True,\n",
" ),\n",
" XXMemoryPlaquette(PlaquetteOrientation.UP, [1, 2, 5, 6, 7, 8]),\n",
" MeasurementRoundedPlaquette(\n",
" xx_memory_plaquette(PlaquetteOrientation.UP, [1, 2, 5, 6, 7, 8]),\n",
" measurement_rounded_plaquette(\n",
" PlaquetteOrientation.UP, include_detector=False\n",
" ),\n",
" ],\n",
" [\n",
" ZRoundedInitialisationPlaquette(PlaquetteOrientation.LEFT),\n",
" ZZMemoryPlaquette(\n",
" z_initialisation_rounded_plaquette(PlaquetteOrientation.LEFT),\n",
" zz_memory_plaquette(\n",
" PlaquetteOrientation.LEFT, [1, 5, 6, 8], is_first_round=True\n",
" ),\n",
" ZZMemoryPlaquette(PlaquetteOrientation.LEFT, [1, 5, 6, 8]),\n",
" MeasurementRoundedPlaquette(PlaquetteOrientation.LEFT),\n",
" zz_memory_plaquette(PlaquetteOrientation.LEFT, [1, 5, 6, 8]),\n",
" measurement_rounded_plaquette(PlaquetteOrientation.LEFT),\n",
" ],\n",
" [\n",
" ZSquareInitialisationPlaquette(),\n",
" XXXXMemoryPlaquette(\n",
" z_initialisation_square_plaquette(),\n",
" xxxx_memory_plaquette(\n",
" [1, 2, 3, 4, 5, 6, 7, 8], include_detector=False, is_first_round=True\n",
" ),\n",
" XXXXMemoryPlaquette([1, 2, 3, 4, 5, 6, 7, 8]),\n",
" MeasurementSquarePlaquette(include_detector=False),\n",
" xxxx_memory_plaquette([1, 2, 3, 4, 5, 6, 7, 8]),\n",
" measurement_square_plaquette(include_detector=False),\n",
" ],\n",
" [\n",
" ZSquareInitialisationPlaquette(),\n",
" ZZZZMemoryPlaquette([1, 3, 4, 5, 6, 8], is_first_round=True),\n",
" ZZZZMemoryPlaquette([1, 3, 4, 5, 6, 8]),\n",
" MeasurementSquarePlaquette(),\n",
" z_initialisation_square_plaquette(),\n",
" zzzz_memory_plaquette([1, 3, 4, 5, 6, 8], is_first_round=True),\n",
" zzzz_memory_plaquette([1, 3, 4, 5, 6, 8]),\n",
" measurement_square_plaquette(),\n",
" ],\n",
" [\n",
" ZRoundedInitialisationPlaquette(PlaquetteOrientation.RIGHT),\n",
" ZZMemoryPlaquette(\n",
" z_initialisation_rounded_plaquette(PlaquetteOrientation.RIGHT),\n",
" zz_memory_plaquette(\n",
" PlaquetteOrientation.RIGHT, [1, 3, 4, 8], is_first_round=True\n",
" ),\n",
" ZZMemoryPlaquette(PlaquetteOrientation.RIGHT, [1, 3, 4, 8]),\n",
" MeasurementRoundedPlaquette(PlaquetteOrientation.RIGHT),\n",
" zz_memory_plaquette(PlaquetteOrientation.RIGHT, [1, 3, 4, 8]),\n",
" measurement_rounded_plaquette(PlaquetteOrientation.RIGHT),\n",
" ],\n",
" [\n",
" ZRoundedInitialisationPlaquette(PlaquetteOrientation.DOWN),\n",
" XXMemoryPlaquette(\n",
" z_initialisation_rounded_plaquette(PlaquetteOrientation.DOWN),\n",
" xx_memory_plaquette(\n",
" PlaquetteOrientation.DOWN,\n",
" [1, 2, 3, 4, 7, 8],\n",
" include_detector=False,\n",
" is_first_round=True,\n",
" ),\n",
" XXMemoryPlaquette(PlaquetteOrientation.DOWN, [1, 2, 3, 4, 7, 8]),\n",
" MeasurementRoundedPlaquette(\n",
" xx_memory_plaquette(PlaquetteOrientation.DOWN, [1, 2, 3, 4, 7, 8]),\n",
" measurement_rounded_plaquette(\n",
" PlaquetteOrientation.DOWN, include_detector=False\n",
" ),\n",
" ],\n",
Expand Down Expand Up @@ -262,7 +262,7 @@
"\n",
"In order to perform the experiement and to compute the error threshold for such an experiment, we need to be able to vary the noise applied to our circuit. Also, we would like to only have one input that controls both the width and the height, to be able to vary only that input.\n",
"\n",
"The following function builds a template that is twice as large horizontally than vertically and applies the provided noise level to the whole circuit before translating the circuit to `Stim`."
"The following function builds a template that is twice as large horizontally than vertically and applies the provided noise level to the whole circuit before translating the circuit to `Stim`.\n"
]
},
{
Expand Down Expand Up @@ -292,7 +292,7 @@
"source": [
"## TQEC plots\n",
"\n",
"We should finally be ready to perform the `stim` simulations and plot the results of our `tqec`-generated QEC memory experiment."
"We should finally be ready to perform the `stim` simulations and plot the results of our `tqec`-generated QEC memory experiment.\n"
]
},
{
Expand Down Expand Up @@ -350,7 +350,7 @@
"source": [
"## Circuit visualisation\n",
"\n",
"Some debugging relicates that are left here if you want to visualise/compare the quantum circuits generated."
"Some debugging relicates that are left here if you want to visualise/compare the quantum circuits generated.\n"
]
},
{
Expand Down Expand Up @@ -380,7 +380,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.0"
"version": "3.12.2"
}
},
"nbformat": 4,
Expand Down
Loading

0 comments on commit b990e8d

Please sign in to comment.