Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add TKET tips page #364

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ for more.
manual/manual_noise.rst
manual/manual_assertion.rst
manual/manual_zx.rst
manual/tket_tips.md

.. toctree::
:glob:
Expand Down
Binary file added docs/manual/images/phase_gadget_latex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/manual/manual_intro.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
*************
What is tket?
What is TKET?
*************

.. Two-sentence overview
Expand Down
173 changes: 173 additions & 0 deletions docs/manual/tket_tips.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---
file_format: mystnb
kernelspec:
name: python3
---


# TKET Tips

## 1. How do I take the tensor product between two circuits?

You can compose two circuits side by side by taking the tensor product with the `*` operator

```{code-cell} ipython3
---
tags: [skip-execution]
---
circ1 * circ2
```

Note that the two circuits need to have qubits with distinct names for the tensor product to be well defined.
See the docs on [circuit composition](https://tket.quantinuum.com/user-guide/manual/manual_circuit.html#composing-circuits).

## 2. How can I export an image of my circuit?

### Method 1: Using the circuit renderer

Firstly you can use the image export button in the interactive circuit renderer. Exporting to `.png`, `.jpeg`, and `.svg` images is supported.

Try clicking the export button in the top right of the circuit diagram below.

```{code-cell} ipython3
from pytket import Circuit
from pytket.circuit.display import render_circuit_jupyter as draw

circ = Circuit(2).CX(0, 1).Rz(0.61, 1).CX(0, 1) # Build circuit
draw(circ)
```

### Method 2: Generating a `.tex` file from the `Circuit`

You can also export pytket circuits to LaTeX with the [Circuit.to_latex_file](inv:#*.Circuit.to_latex_file) method. This is handy for using circuit images in papers if you like using the Quantikz library.

```{code-cell} ipython3
---
tags: [skip-execution]
---
from pytket import Circuit

circ = Circuit(2).CX(0, 1).Rz(0.61, 1).CX(0, 1) # Build circuit

circ.to_latex_file("phase_gadget.tex") # Generates a phase_gadget.tex file
```

This generates a `phase_gadget.tex` file in the working directory.

```latex
\documentclass[tikz]{standalone}
\usetikzlibrary{quantikz}
\begin{document}
\begin{quantikz}
\lstick{q[0]} & \ctrl{1} & \qw & \ctrl{1} & \qw \\
\lstick{q[1]} & \targ{} & \gate[1]{\text{$R_Z$(0.61)}} & \targ{} & \qw \\
\end{quantikz}
\end{document}
```

If we compile this LaTeX we get the following Quantikz image.


```{image} ./images/phase_gadget_latex.png
:align: center
:width: 400px
```

## 3. Can I do symbolic calculations in pytket?

Yes! You can use the `pytket.utils.symbolic` module to calculate symbolic unitaries and statevectors for small pytket circuits.
Here we can use the [circuit_to_symbolic_unitary](inv:#*.circuit_to_symbolic_unitary) function to calculate the unitary of a small parameterised circuit. If using a jupyter notebook we get a nice LaTeX rendering of the matrix (see image)

```{code-cell} ipython3
from pytket import Circuit
from pytket.circuit.display import render_circuit_jupyter as draw
from pytket.utils.symbolic import circuit_to_symbolic_unitary
from sympy import symbols

a, b = symbols("a b")
circ = Circuit(2)
circ.X(0).CRy(a, 0, 1).Rz(b, 0)

draw(circ) # Draw circuit diagram
circuit_to_symbolic_unitary(circ) # Get the symbolic unitary matrix
```

## 4. Do I have to use a jupyter notebook to use these interactive circuit diagrams?

No you don't have to! if you prefer using python scripts or the terminal instead of jupyter notebooks you can use the [view_browser](inv:#*.CircuitRenderer.view_browser) function to view the rendered circuit in a pop up browser window.

## 5. Clifford circuit basics in pytket

Clifford circuits are an important (non-universal) subclass of quantum circuits known to exhibit efficient classical simulation. The $\{H, S, CX\}$ gates are the typical Clifford generators. These circuits are particularly relevant for quantum error correction.

Its easy to check whether your pytket Circuit is Clifford by using the [CliffordCircuitPredicate](inv:#*.CliffordCircuitPredicate).


```{code-cell} ipython3
from pytket import Circuit
from pytket.predicates import CliffordCircuitPredicate
from pytket.circuit.display import render_circuit_jupyter as draw

circ = Circuit(2).H(0).CX(0, 1).CX(1, 0).S(1) # Build Clifford Circuit
draw(circ)

print("Is circuit Clifford?",
CliffordCircuitPredicate().verify(circ)) # prints True, circ is Clifford
```
Now, if we add a non-Clifford gate
```{code-cell} ipython3

circ.Rz(0.91, 0) # Add non-Clifford gate
draw(circ)
```


```{code-cell} ipython3
print("Is circuit Clifford?",
CliffordCircuitPredicate().verify(circ)) # prints False, circ is non-Clifford
```

Given an individual circuit operation, we can check whether it is Clifford by using the [Op.is_clifford](inv:#*.Op.is_clifford) method



```{code-cell} ipython3
for command in circ:
print(command.op, command.op.is_clifford())
# Only the Rz gate is non-Clifford
```

Finally if you want to simulate large Clifford circuits you can access the Stim and Simplex simulators from pytket through their extension modules.

pytket-stim - <https://github.com/CQCL/pytket-stim>

pytket-pysimplex - <https://github.com/CQCL/pytket-pysimplex>


## 6. How can I check two quantum circuits for unitary equivalence?


```{code-cell} ipython3
from pytket import Circuit
from pytket.utils import compare_unitaries

# Create two simple circuits
circ1 = Circuit(3).CX(0, 2).CX(1, 2).Rz(0.74, 2).CX(1, 2).CX(0, 2)
circ2 = Circuit(3).CX(0, 1).CX(1, 2).Rz(0.74, 2).CX(1, 2).CX(0, 1)

# Simulate circuits to calculate the unitaries
unitary1 = circ1.get_unitary()
unitary2 = circ2.get_unitary()


# Compare unitaries up to a global phase
print("Do the unitaries match?", compare_unitaries(unitary1, unitary2))
```








Loading