Skip to content

Commit

Permalink
use relative links
Browse files Browse the repository at this point in the history
  • Loading branch information
CalMacCQ committed Aug 7, 2024
1 parent 7bed23c commit cc2217e
Show file tree
Hide file tree
Showing 6 changed files with 2,360 additions and 7 deletions.
683 changes: 682 additions & 1 deletion docs/examples/algorithms_and_protocols/phase_estimation.ipynb

Large diffs are not rendered by default.

386 changes: 385 additions & 1 deletion docs/examples/algorithms_and_protocols/pytket-qujax_qaoa.ipynb

Large diffs are not rendered by default.

212 changes: 211 additions & 1 deletion docs/examples/circuit_compilation/contextual_optimisation.ipynb
Original file line number Diff line number Diff line change
@@ -1 +1,211 @@
{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Contextual optimisation"]}, {"cell_type": "markdown", "metadata": {}, "source": ["This notebook will illustrate the techniques of \"contextual optimisation\" available in TKET."]}, {"cell_type": "markdown", "metadata": {}, "source": ["See the user manaul for an introduction to the concept and methods. Here we will present an example showing how we can save some gates at the beginnning and end of a circuit, making no assumptions about the structure of the circuit."]}, {"cell_type": "markdown", "metadata": {}, "source": ["We will take as an example an ansatz circuit consisting of alternating layers of Ry and CX gates, where some proportion of the Ry angles are zero. This is a typical ansatz for variational algorithms, used for solving diagonal Hamiltonians for combinatorial optimisation."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.circuit import Circuit\n", "from random import random, randrange, seed"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["def random_sparse_ansatz(n_qubits, n_layers, p, rng_seed=None):\n", " seed(rng_seed)\n", " circ = Circuit(n_qubits)\n", " for q in range(n_qubits):\n", " if random() < p:\n", " circ.Ry(0.1 * randrange(20), q)\n", " for l in range(n_layers):\n", " for q in range(0, n_qubits - 1, 2):\n", " circ.CX(q, q + 1)\n", " for q in range(2 * (n_qubits // 2)):\n", " if random() < p:\n", " circ.Ry(0.1 * randrange(20), q)\n", " for q in range(1, n_qubits - 1, 2):\n", " circ.CX(q, q + 1)\n", " for q in range(2 * ((n_qubits - 1) // 2)):\n", " if random() < p:\n", " circ.Ry(0.1 * randrange(20), q + 1)\n", " circ.measure_all()\n", " return circ"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Let's examine a smallish example:"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.circuit import OpType\n", "from pytket.circuit.display import render_circuit_jupyter"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["c = random_sparse_ansatz(4, 3, 0.5, rng_seed=0)\n", "render_circuit_jupyter(c)\n", "print(\"Number of CX:\", c.n_gates_of_type(OpType.CX))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Contextual optimizations allow us to shave some gates from the beginning and end of the circuit. Those at the end get commuted through the Measure gates into a classical post-processing circuit, which we can then pass to `BackendResult` methods to have the postprocessing performed automatically."]}, {"cell_type": "markdown", "metadata": {}, "source": ["The `prepare_circuit()` method returns a pair of circuits, the first of which is what we actually run and the second of specifies the required postprocessing."]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.utils import prepare_circuit"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["c0, ppcirc = prepare_circuit(c)\n", "render_circuit_jupyter(c0)\n", "print(\"Number of CX:\", c0.n_gates_of_type(OpType.CX))"]}, {"cell_type": "markdown", "metadata": {}, "source": ["In this case, one CX has been shaved from the beginning of the circuit and two from the end."]}, {"cell_type": "markdown", "metadata": {}, "source": ["We can run the processed circuit on our backend:"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["from pytket.extensions.qiskit import AerBackend"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["b = AerBackend()\n", "c1 = b.get_compiled_circuit(c0)\n", "h = b.process_circuit(c1, n_shots=10)\n", "r = b.get_result(h)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["And finally get the counts or shots, accounting for the classical postprocessing:"]}, {"cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": ["counts = r.get_counts(ppcirc=ppcirc)\n", "print(counts)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["See the [pytket user manual](https://tket.quantinuum.com/user-guide/manual/manual_compiler.html#contextual-optimisations) for more details about contextual optimisations and how to apply them in TKET."]}], "metadata": {"kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"}, "language_info": {"codemirror_mode": {"name": "ipython", "version": 3}, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4"}}, "nbformat": 4, "nbformat_minor": 2}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Contextual optimisation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook will illustrate the techniques of \"contextual optimisation\" available in TKET."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See the user manaul for an introduction to the concept and methods. Here we will present an example showing how we can save some gates at the beginnning and end of a circuit, making no assumptions about the structure of the circuit."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We will take as an example an ansatz circuit consisting of alternating layers of Ry and CX gates, where some proportion of the Ry angles are zero. This is a typical ansatz for variational algorithms, used for solving diagonal Hamiltonians for combinatorial optimisation."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pytket.circuit import Circuit\n",
"from random import random, randrange, seed"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def random_sparse_ansatz(n_qubits, n_layers, p, rng_seed=None):\n",
" seed(rng_seed)\n",
" circ = Circuit(n_qubits)\n",
" for q in range(n_qubits):\n",
" if random() < p:\n",
" circ.Ry(0.1 * randrange(20), q)\n",
" for l in range(n_layers):\n",
" for q in range(0, n_qubits - 1, 2):\n",
" circ.CX(q, q + 1)\n",
" for q in range(2 * (n_qubits // 2)):\n",
" if random() < p:\n",
" circ.Ry(0.1 * randrange(20), q)\n",
" for q in range(1, n_qubits - 1, 2):\n",
" circ.CX(q, q + 1)\n",
" for q in range(2 * ((n_qubits - 1) // 2)):\n",
" if random() < p:\n",
" circ.Ry(0.1 * randrange(20), q + 1)\n",
" circ.measure_all()\n",
" return circ"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's examine a smallish example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pytket.circuit import OpType\n",
"from pytket.circuit.display import render_circuit_jupyter"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"c = random_sparse_ansatz(4, 3, 0.5, rng_seed=0)\n",
"render_circuit_jupyter(c)\n",
"print(\"Number of CX:\", c.n_gates_of_type(OpType.CX))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Contextual optimizations allow us to shave some gates from the beginning and end of the circuit. Those at the end get commuted through the Measure gates into a classical post-processing circuit, which we can then pass to `BackendResult` methods to have the postprocessing performed automatically."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `prepare_circuit()` method returns a pair of circuits, the first of which is what we actually run and the second of specifies the required postprocessing."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pytket.utils import prepare_circuit"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"c0, ppcirc = prepare_circuit(c)\n",
"render_circuit_jupyter(c0)\n",
"print(\"Number of CX:\", c0.n_gates_of_type(OpType.CX))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this case, one CX has been shaved from the beginning of the circuit and two from the end."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can run the processed circuit on our backend:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from pytket.extensions.qiskit import AerBackend"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"b = AerBackend()\n",
"c1 = b.get_compiled_circuit(c0)\n",
"h = b.process_circuit(c1, n_shots=10)\n",
"r = b.get_result(h)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And finally get the counts or shots, accounting for the classical postprocessing:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"counts = r.get_counts(ppcirc=ppcirc)\n",
"print(counts)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See the [pytket user manual](../user-guide/manual/manual_compiler.html#contextual-optimisations) for more details about contextual optimisations and how to apply them in TKET."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
1,080 changes: 1,079 additions & 1 deletion docs/examples/circuit_construction/circuit_generation_example.ipynb

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Now let’s draw a nice picture of the circuit with the circuit renderer
render_circuit_jupyter(ghz_circ)

See also the `Circuit
construction <https://tket.quantinuum.com/user-guide/manual/manual_circuit.html>`__
construction <../user-guide/manual/manual_circuit.html>`__
section of the user manual.

Build a ``Circuit`` from a QASM file
Expand Down Expand Up @@ -115,7 +115,7 @@ realistic cases a compiler will have to solve for the limited gateset of
the target backend as well as other backend requirements.

See the `Running on
Backends <https://tket.quantinuum.com/user-guide/manual/manual_backend.html>`__
Backends <../user-guide/manual/manual_backend.html>`__
section of the user manual and the `backends example
notebook <https://tket.quantinuum.com/examples/backends_example.html>`__
for more.
Expand Down
2 changes: 1 addition & 1 deletion docs/manual/manual_circuit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,7 @@ There are currently no simulators or devices that can run symbolic circuits alge

.. note:: There are some minor drawbacks associated with symbolic compilation. When using `Euler-angle equations <https://tket.quantinuum.com/api-docs/passes.html#pytket.passes.EulerAngleReduction>`_ or quaternions for merging adjacent rotation gates, the resulting angles are given by some lengthy trigonometric expressions which cannot be evaluated down to just a number when one of the original angles was parameterised; this can lead to unhelpfully long expressions for the angles of some gates in the compiled circuit. It is also not possible to apply the :py:class:`pytket.passes.KAKDecomposition` pass to simplify a parameterised circuit, so that pass will only apply to non-parameterised subcircuits, potentially missing some valid opportunities for optimisation.

.. seealso:: To see how to use symbolic compilation in a variational experiment, have a look at our `VQE (UCCSD) example <https://tket.quantinuum.com/user-guide/examples/algorithms_and_protocols/ucc_vqe.html>`_.
.. seealso:: To see how to use symbolic compilation in a variational experiment, have a look at our `VQE (UCCSD) example <../user-guide/examples/algorithms_and_protocols/ucc_vqe.html>`_.


Symbolic unitaries and states
Expand Down

0 comments on commit cc2217e

Please sign in to comment.