BlockGraph#
- class tqec.computation.BlockGraph(name='')[source]#
Bases:
object
Block graph representation of a logical computation.
A block graph consists of building blocks that fully define the boundary conditions and topological structures of a logical computation. It corresponds to the commonly used 3D spacetime diagram representation of a surface code logical computation.
The graph contains two categories of blocks:
1.
Cube
: The fundamental building blocks of the computation. A cube represents a block of quantum operations within a specific spacetime volume. These operations preserve or manipulate the quantum information encoded in the logical qubits. Cubes are represented as nodes in the graph.2.
Pipe
: Connects cubes to form the topological structure representing the logical computation. A pipe occupies no spacetime volume and only replaces the operations within the cubes it connects. Pipes are represented as edges in the graph.Methods
__init__
([name])add_cube
(position, kind[, label])Add a cube to the graph.
add_pipe
(pos1, pos2[, kind])Add a pipe to the graph.
Return the size of the bounding box of the computation structure.
clone
()Create a data-independent copy of the graph.
compose
(other, self_port, other_port)Compose the current graph with another graph.
fill_ports
(fill)Fill the ports at specified positions with cubes of the given kind.
Given a block graph with open ports, fill in the ports with the appropriate cubes that will minimize the number of simulation runs needed for the complete logical observable set.
find_correlation_surfaces
([...])Find the correlation surfaces in the block graph.
Fix the basis of those shadowed faces of the cubes in the graph.
from_dae_file
(filename[, graph_name])Construct a block graph from a COLLADA DAE file.
from_dict
(data)Construct a block graph from a dictionary representation.
from_json
([file_path, json_text])Deserialize a block graph from a JSON string or read it from a file.
get_cubes_by_label
(label)Find cubes with the specified label in the BlockGraph.
get_degree
(position)Get the degree of a node in the graph, i.e. the number of edges incident to it.
get_pipe
(pos1, pos2)Get the pipe by its endpoint positions.
has_pipe_between
(pos1, pos2)Check if there is a pipe between two positions.
Check if the graph is single connected, i.e. there is only one connected component in the graph.
pipes_at
(position)Get the pipes incident to a position.
remove_cube
(position)Remove a cube from the graph, as well as the pipes connected to it.
remove_pipe
(pos1, pos2)Remove a pipe between two positions.
rotate
(rotation_axis[, counterclockwise, ...])Rotate the graph around an axis by 0, 90, 180, or 270 degrees and create a new graph with the rotated positions.
shift_by
([dx, dy, dz])Shift the whole graph by the given offset in the x, y, z directions and creat a new graph with the shifted positions.
to_dae_file
(file_path[, pipe_length, ...])Write the block graph to a Collada DAE file.
to_dict
()Return a dictionary representation of the block graph.
to_json
([file_path, indent])Serialize the block graph to a JSON string or write it to a file.
Convert the block graph to a positioned PyZX graph.
validate
()Check the validity of the block graph to represent a logical computation.
view_as_html
([write_html_filepath, ...])View COLLADA model in html with the help of
three.js
.Attributes
cubes
The list of cubes (nodes) in the graph.
is_open
Whether the graph is an open graph, i.e. the graph has ports.
leaf_cubes
Get the leaf cubes of the graph, i.e. the cubes with degree 1.
name
Name of the graph.
num_cubes
Number of cubes (nodes) in the graph, including the ports.
num_half_y_cubes
Number of half Y cubes in the graph.
num_pipes
Number of pipes (edges) in the graph.
num_ports
Number of ports in the graph.
occupied_positions
Get the positions occupied by the cubes in the graph.
ordered_ports
Get the labels of the ports in the alphabetical order.
pipes
The list of pipes (edges) in the graph.
ports
Mapping from port labels to their positions.
spacetime_volume
Return the spacetime volume of the computation.
Detailed methods
- Parameters:
name (str)
- add_cube(position, kind, label='')[source]#
Add a cube to the graph.
- Parameters:
position (Position3D) – The position of the cube.
kind (ZXCube | Port | YHalfCube | str) – The kind of the cube. It can be a
CubeKind
instance or a string representation of the cube kind.label (str) – The label of the cube. Default is None.
- Returns:
The position of the cube added to the graph.
- Raises:
TQECException – If there is already a cube at the same position, or if the cube kind is not recognized, or if the cube is a port and there is already a port with the same label in the graph.
- Return type:
- add_pipe(pos1, pos2, kind=None)[source]#
Add a pipe to the graph.
Note
The validity of the pipe WILL NOT be checked when adding it to the graph. This allows the user to construct the invalid graph and visualize it for whatever purpose. To check the validity of the graph, use the
validate()
.- Parameters:
pos1 (Position3D) – The position of one end of the pipe.
pos2 (Position3D) – The position of the other end of the pipe.
kind (PipeKind | str | None) – The kind of the pipe connecting the cubes. If None, the kind will be automatically determined based on the cubes it connects to make the boundary conditions consistent. Default is None.
- Raises:
TQECException – If any of the positions do not have a cube in the graph, or if there is already an pipe between the given positions, or if the pipe is not compatible with the cubes it connects.
- Return type:
None
- bounding_box_size()[source]#
Return the size of the bounding box of the computation structure.
- Returns:
A tuple of three integers representing the width along the X, Y, and Z directions, respectively.
- Return type:
tuple[int, int, int]
- compose(other, self_port, other_port)[source]#
Compose the current graph with another graph.
The other graph will be shifted to match the ports in the current graph and the two graphs will be composed at the corresponding ports.
The two ports provided to this method will serve as an “anchor”, and other overlapping ports will be detected and glued automatically.
- Parameters:
other (BlockGraph) – The other graph to be composed with the current graph.
self_port (str) – The label of the port to be connected in the current graph.
other_port (str) – The label of the port to be connected in the other graph.
- Returns:
A new graph that is the composition of the current graph with the other graph.
- Raises:
TQECException – If the ports are not in the graphs, or if the two graphs cannot be composed because overlapping spacetime extents or incompatible cube kinds.
- Return type:
- fill_ports(fill)[source]#
Fill the ports at specified positions with cubes of the given kind.
- Parameters:
fill (Mapping[str, ZXCube | Port | YHalfCube] | ZXCube | Port | YHalfCube) – A mapping from the label of the ports to the cube kind to fill. If a single kind is given, all the ports will be filled with the same kind.
- Raises:
TQECException – if there is no port with the given label.
- Return type:
None
- fill_ports_for_minimal_simulation()[source]#
Given a block graph with open ports, fill in the ports with the appropriate cubes that will minimize the number of simulation runs needed for the complete logical observable set.
- Returns:
A list of
FilledGraph
instances, each containing a block graph with all ports filled and a set of correlation surfaces that can be used as logical observables for the simulation on that block graph.- Return type:
list[FilledGraph]
- find_correlation_surfaces(reduce_to_minimal_generators=True)[source]#
Find the correlation surfaces in the block graph.
- Parameters:
reduce_to_minimal_generators (bool) – Whether to reduce the correlation surfaces to the minimal generators. Other correlation surfaces can be obtained by multiplying the generators. The generators are chosen to be the smallest in terms of the correlation surface area. Default is True.
- Returns:
The list of correlation surfaces.
- Return type:
list[CorrelationSurface]
- fix_shadowed_faces()[source]#
Fix the basis of those shadowed faces of the cubes in the graph.
A pair of face can be shadowed if the cube is connected to two pipes in the same direction. Though these faces are not visible in the 3D visualization, they are still identified by the cube kind and can affect the circuit compilation.
The basis of the cube is enforced to match the pipes connected to it. If there is unmatched shadowed faces, we try to fix their basis. This will leave some freedom in constructing the model in SketchUp and make everyones’ life easier.
Additionally, for a spatial pass-through, i.e. a cube only connected to two pipes in the same direction, we will fix the cube kind to not be a spatial cube.
Note that the fixed graph is still not guaranteed to be valid as some other conditions may be violated. You still need to call
validate()
to check the validity of the graph.- Returns:
A new graph with the shadowed faces fixed.
- Return type:
- static from_dae_file(filename, graph_name='')[source]#
Construct a block graph from a COLLADA DAE file.
- Parameters:
filename (str | Path) – The input
.dae
file path.graph_name (str) – The name of the block graph. Default is an empty string.
- Returns:
The
BlockGraph
object constructed from the DAE file.- Return type:
- static from_dict(data)[source]#
Construct a block graph from a dictionary representation.
- Parameters:
data (dict[str, Any])
- Return type:
- static from_json(file_path=None, json_text=None)[source]#
Deserialize a block graph from a JSON string or read it from a file.
- Parameters:
file_path (str | Path | None) – The input json file path to read from, or
None
to indicate that the JSON string will be provided in json_text. Default is None.json_text (str | None) – The JSON string representation of the block graph, or
None
to indicate that the JSON file will be read from file_path. Default is None.
- Returns:
The
BlockGraph
object constructed from the JSON string or file.- Return type:
- get_cubes_by_label(label)[source]#
Find cubes with the specified label in the BlockGraph.
- Parameters:
label (str) – The label of the cubes.
- Returns:
The cube instances that have the specified label.
- Return type:
list[Cube]
- get_degree(position)[source]#
Get the degree of a node in the graph, i.e. the number of edges incident to it.
- Parameters:
position (Position3D)
- Return type:
int
- get_pipe(pos1, pos2)[source]#
Get the pipe by its endpoint positions. If there is no pipe between the given positions, an exception will be raised.
- Parameters:
pos1 (Position3D) – The first endpoint position.
pos2 (Position3D) – The second endpoint position.
- Returns:
The pipe between the two positions.
- Raises:
TQECException – If there is no pipe between the given positions.
- Return type:
- has_pipe_between(pos1, pos2)[source]#
Check if there is a pipe between two positions.
- Parameters:
pos1 (Position3D) – The first endpoint position.
pos2 (Position3D) – The second endpoint position.
- Returns:
True if there is an pipe between the two positions, False otherwise.
- Return type:
bool
- is_single_connected()[source]#
Check if the graph is single connected, i.e. there is only one connected component in the graph.
- Return type:
bool
- pipes_at(position)[source]#
Get the pipes incident to a position.
- Parameters:
position (Position3D)
- Return type:
list[Pipe]
- remove_cube(position)[source]#
Remove a cube from the graph, as well as the pipes connected to it.
- Parameters:
position (Position3D) – The position of the cube to be removed.
- Return type:
None
Raises: TQECException: If there is no cube at the given position.
- remove_pipe(pos1, pos2)[source]#
Remove a pipe between two positions.
- Parameters:
pos1 (Position3D) – The position of one end of the pipe.
pos2 (Position3D) – The position of the other end of the pipe.
- Raises:
TQECException – If there is no pipe between the given positions.
- Return type:
None
- rotate(rotation_axis, counterclockwise=True, num_90_degree_rotation=1)[source]#
Rotate the graph around an axis by 0, 90, 180, or 270 degrees and create a new graph with the rotated positions.
- Parameters:
rotation_axis (Direction3D) – The axis to rotate around.
counterclockwise (bool) – Whether to rotate counterclockwise. Default is True.
num_90_degree_rotation (int) – The number of 90-degree rotations. Default is 1.
- Returns:
A new graph with the rotated positions. The new graph will share no data with the original graph.
- Return type:
- shift_by(dx=0, dy=0, dz=0)[source]#
Shift the whole graph by the given offset in the x, y, z directions and creat a new graph with the shifted positions.
- Parameters:
dx (int) – The offset in the x direction.
dy (int) – The offset in the y direction.
dz (int) – The offset in the z direction.
- Returns:
A new graph with the shifted positions. The new graph will share no data with the original graph.
- Return type:
- to_dae_file(file_path, pipe_length=2.0, pop_faces_at_direction=None, show_correlation_surface=None)[source]#
Write the block graph to a Collada DAE file.
- Parameters:
file_path (str | pathlib.Path) – The output file path.
pipe_length (float) – The length of the pipes. Default is 2.0.
pop_faces_at_direction (SignedDirection3D | str | None) – Remove the faces at the given direction for all the blocks. This is useful for visualizing the internal structure of the blocks. Default is None.
show_correlation_surface (CorrelationSurface | None) – The correlation surface to show in the block graph. Default is None.
- Return type:
None
- to_dict()[source]#
Return a dictionary representation of the block graph.
- Return type:
dict[str, Any]
- to_json(file_path=None, *, indent=2)[source]#
Serialize the block graph to a JSON string or write it to a file.
- Parameters:
file_path (str | Path | None) – The output file path. If None, the JSON string will be returned.
indent (int | None) – The indentation level for pretty printing, passed to json.dumps. Default is 2.
- Returns:
The JSON string representation of the block graph if file_path is None, otherwise None.
- Return type:
str | None
- to_zx_graph()[source]#
Convert the block graph to a positioned PyZX graph.
- Returns:
A
PositionedZX
object converted from the block graph.- Return type:
- validate()[source]#
Check the validity of the block graph to represent a logical computation.
Refer to the Fig.9 in arXiv:2404.18369. Currently, we ignore the b) and e), only check the following conditions:
No fanout: ports can only have one pipe connected to them.
Time-like Y: Y Half Cubes can only have time-like pipes connected to them.
No 3D corner: a cube cannot have pipes in all three directions.
Match color at passthrough: two pipes in a “pass-through” should have the same color orientation.
Match color at turn: two pipes in a “turn” should have the matching colors on faces that are touching.
- Raises:
TQECException – If the above conditions are not satisfied.
- Return type:
None
- view_as_html(write_html_filepath=None, pipe_length=2.0, pop_faces_at_direction=None, show_correlation_surface=None)[source]#
View COLLADA model in html with the help of
three.js
.This can display a COLLADA model interactively in IPython compatible environments.
- Parameters:
write_html_filepath (str | pathlib.Path | None) – The output html file path to write the generated html content if provided. Default is None.
pipe_length (float) – The length of the pipes. Default is 2.0.
pop_faces_at_direction (SignedDirection3D | str | None) – Remove the faces at the given direction for all the blocks. This is useful for visualizing the internal structure of the blocks. Default is None.
show_correlation_surface (CorrelationSurface | None) – The correlation surface to show in the block graph. Default is None.
- Returns:
A helper class to display the 3D model, which implements the
_repr_html_
method and can be directly displayed in IPython compatible environments.- Return type:
_ColladaHTMLViewer