Skip to content

Commit

Permalink
bump version; add example
Browse files Browse the repository at this point in the history
  • Loading branch information
shinich1 committed Jan 3, 2024
1 parent 42ca706 commit cc33ca9
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 12 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]


## [0.2.10] - 2024-01-03

### Added

- Added `rustworkx` as a backend for the graph state simulator
- Only `networkx` backend was available for pattern optimization.
By setting the `use_rustworkx` option to True while using `Pattern.perform_pauli_measurements()`,
graphix will run pattern optimization using `rustworkx` (#98)
- Added `.ccx()` method to `graphix.Circuit`.
- Added `.ccx` and `.swap` methods to `graphix.Circuit`.

### Fixed

Expand Down
80 changes: 80 additions & 0 deletions examples/pattern_fragments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""
Optimized pattern fragments
===========================
Graphix offers several pattern fragments for quantum gates, pre-optimized by reducing the Pauli measurements,
with fewer resource requirement than the standard pattern.
"""

#%%
# First, for Toffoli gate, here is the pattern based on the decomposition of CCX gate with CNOT and single-qubit rotations,
# turned into a measurement pattern:
from graphix import Circuit
import numpy as np

circuit = Circuit(3)
circuit.ccx(0, 1, 2)
pattern = circuit.transpile()
pattern.draw_graph()

#%%
# Using :code:`opt=True` option for :code:`transpile` method, we switch to patterns with non-XY plane measurements allowed,
# which has gflow (not flow). For CCX gate, the number of ancilla qubits required is nearly halved:
pattern = circuit.transpile(opt=True)
pattern.draw_graph(node_distance=(1,0.4))
# sphinx_gallery_thumbnail_number = 2

#%%
# Now let us add z-rotation gates, requiring two ancillas in the original pattern fragment,
# which becomes one for patterns with :code:`opt=True`.
circuit = Circuit(3)
circuit.ccx(0, 1, 2)
for i in range(3):
circuit.rz(i, np.pi/4)
pattern = circuit.transpile(opt=True)
pattern.draw_graph(node_distance=(1,0.5))

#%%
# Swap gate is just a swap of node indices during compilation, requiring no ancillas.
circuit = Circuit(3)
circuit.ccx(0, 1, 2)
circuit.swap(1,2)
circuit.swap(2,0)
for i in range(3):
circuit.rz(i, np.pi/4)
pattern = circuit.transpile(opt=True)
pattern.draw_graph(node_distance=(1,0.4))


# %%
# using :code:`opt=True` and with either CCX, Rzz or Rz gates, the graph will have gflow.
circuit = Circuit(4)
circuit.cnot(1, 2)
circuit.cnot(0, 3)
circuit.ccx(2, 1, 0)
circuit.rx(0, np.pi/3)
circuit.cnot(0, 3)
circuit.rzz(0, 3, np.pi/3)
circuit.rx(2, np.pi/3)
circuit.ccx(3, 1, 2)
circuit.rx(0, np.pi/3)
circuit.rx(3, np.pi/3)
pattern = circuit.transpile(opt=True)
pattern.draw_graph(node_distance=(1,0.4))


# %%
# reducing the size further
pattern.perform_pauli_measurements()
pattern.draw_graph(node_distance=(1,0.6))

# %%
# For linear optical QPUs with single photons, such a resource state can be generated by fusing the follwoing microcluster states:
from graphix.extraction import get_fusion_network_from_graph
nodes, edges = pattern.get_graph()
from graphix import GraphState
gs = GraphState(nodes=nodes, edges=edges)
get_fusion_network_from_graph(gs, max_ghz=4, max_lin=4)

# %%
16 changes: 6 additions & 10 deletions examples/qft_with_tn.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ def cp(circuit, theta, control, target):
circuit.cnot(control, target)


def swap(circuit, a, b):
circuit.cnot(a, b)
circuit.cnot(b, a)
circuit.cnot(a, b)


def qft_rotations(circuit, n):
circuit.h(n)
for qubit in range(n + 1, circuit.width):
Expand All @@ -38,7 +32,7 @@ def qft_rotations(circuit, n):

def swap_registers(circuit, n):
for qubit in range(n // 2):
swap(circuit, qubit, n - qubit - 1)
circuit.swap(qubit, n - qubit - 1)
return circuit


Expand All @@ -49,9 +43,9 @@ def qft(circuit, n):


# %%
# We will simulate 45-qubit QFT, which requires graph states with more than 10000 nodes.
# We will simulate 55-qubit QFT, which requires graph states with more than 10000 nodes.

n = 45
n = 55
print("{}-qubit QFT".format(n))
circuit = Circuit(n)

Expand All @@ -60,7 +54,7 @@ def qft(circuit, n):
qft(circuit, n)

# standardize pattern
pattern = circuit.transpile()
pattern = circuit.transpile(opt=True)
pattern.standardize()
pattern.shift_signals()
nodes, edges = pattern.get_graph()
Expand Down Expand Up @@ -89,3 +83,5 @@ def qft(circuit, n):
print("amplitude of |00...0> is ", value)
print("1/2^n (true answer) is", 1 / 2**n)
print("approximate execution time in seconds: ", t2 - t1)

# %%
2 changes: 1 addition & 1 deletion graphix/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.2.9"
__version__ = "0.2.10"

0 comments on commit cc33ca9

Please sign in to comment.