Skip to content

Commit

Permalink
Support arbitrary CtrlSpec to single qubit control (#1137)
Browse files Browse the repository at this point in the history
* CtrlSpec to single-qubit control

* add bloq notebook

* more examples

* mypy, lint

* regenerate notebook

* make `bits_to_ints` return `np.uint` (instead of `np.float`)

* add classical sim test

* rename to `CtrlSpecAnd`, elaborate constraints in docstring

* notebook: fix import

* revert changes to Partition

* only support integer types for now (as QFxp classical sim isn't fully supported yet)
  • Loading branch information
anurudhp authored Jul 17, 2024
1 parent 301e3cf commit 2c2866b
Show file tree
Hide file tree
Showing 9 changed files with 501 additions and 1 deletion.
6 changes: 6 additions & 0 deletions dev_tools/autogenerate-bloqs-notebooks-v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import qualtran.bloqs.factoring.mod_exp
import qualtran.bloqs.hamiltonian_simulation.hamiltonian_simulation_by_gqsp
import qualtran.bloqs.mcmt.and_bloq
import qualtran.bloqs.mcmt.ctrl_spec_and
import qualtran.bloqs.mod_arithmetic.mod_addition
import qualtran.bloqs.multiplexers.apply_gate_to_lth_target
import qualtran.bloqs.multiplexers.apply_lth_bloq
Expand Down Expand Up @@ -202,6 +203,11 @@
qualtran.bloqs.bookkeeping.cast._CAST_DOC,
],
),
NotebookSpecV2(
title='Control Specification (And)',
module=qualtran.bloqs.mcmt.ctrl_spec_and,
bloq_specs=[qualtran.bloqs.mcmt.ctrl_spec_and._CTRLSPEC_AND_DOC],
),
]


Expand Down
1 change: 1 addition & 0 deletions docs/bloqs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Bloqs Library
basic_gates/global_phase.ipynb
basic_gates/identity.ipynb
bookkeeping/bookkeeping.ipynb
mcmt/ctrl_spec_and.ipynb

.. toctree::
:maxdepth: 2
Expand Down
1 change: 1 addition & 0 deletions qualtran/bloqs/mcmt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

from qualtran.bloqs.mcmt.and_bloq import And, MultiAnd
from qualtran.bloqs.mcmt.ctrl_spec_and import CtrlSpecAnd
from qualtran.bloqs.mcmt.multi_control_multi_target_pauli import (
MultiControlPauli,
MultiControlX,
Expand Down
210 changes: 210 additions & 0 deletions qualtran/bloqs/mcmt/ctrl_spec_and.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "0beec492",
"metadata": {
"cq.autogen": "title_cell"
},
"source": [
"# Control Specification (And)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4d31094e",
"metadata": {
"cq.autogen": "top_imports"
},
"outputs": [],
"source": [
"from qualtran import Bloq, CompositeBloq, BloqBuilder, Signature, Register\n",
"from qualtran import QBit, QInt, QUInt, QAny\n",
"from qualtran.drawing import show_bloq, show_call_graph, show_counts_sigma\n",
"from typing import *\n",
"import numpy as np\n",
"import sympy\n",
"import cirq"
]
},
{
"cell_type": "markdown",
"id": "12aba876",
"metadata": {
"cq.autogen": "CtrlSpecAnd.bloq_doc.md"
},
"source": [
"## `CtrlSpecAnd`\n",
"Computes a single qubit which is `1` iff the CtrlSpec of And clauses is satisfied.\n",
"\n",
"This reduces an arbitrary 'And' clause control spec to a single qubit, which can be used\n",
"to then control a bloq. Therefore, a bloq author is only required to implement a\n",
"single-controlled version of their bloq, and can be generalized to arbitrary controls.\n",
"\n",
"The control registers are passed through as-is. If the same control bit is required for\n",
"multiple bloqs, the user can use the `target` qubit of this bloq multiple times, and only\n",
"uncompute at the very end. For more custom strategies and trade-offs, see Ref. [1].\n",
"\n",
".. note::\n",
"\n",
" This only applies to CtrlSpec being a logical AND of all registers, and each register\n",
" being equal to a constant. See documentation for :class:`CtrlSpec` for more details.\n",
"\n",
"#### Parameters\n",
" - `ctrl_spec`: The control specification. \n",
"\n",
"#### Registers\n",
" - `ctrl_i`: The control register for the i-th ctrl dtype in the `ctrl_spec`.\n",
" - `junk [right]`: `ctrl_spec.num_qubits - 2` qubits that can be cleaned up by the inverse. Only present if the above size is non-zero.\n",
" - `target [right]`: The output bit storing the result of the `ctrl_spec`. \n",
"\n",
"#### References\n",
" - [Unqomp: synthesizing uncomputation in Quantum circuits](https://dl.acm.org/doi/10.1145/3453483.3454040). Paradis et. al. 2021.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "842307af",
"metadata": {
"cq.autogen": "CtrlSpecAnd.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.mcmt import CtrlSpecAnd"
]
},
{
"cell_type": "markdown",
"id": "76f2965f",
"metadata": {
"cq.autogen": "CtrlSpecAnd.example_instances.md"
},
"source": [
"### Example Instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "68a43214",
"metadata": {
"cq.autogen": "CtrlSpecAnd.ctrl_on_int"
},
"outputs": [],
"source": [
"from qualtran import CtrlSpec, QUInt\n",
"\n",
"ctrl_on_int = CtrlSpecAnd(CtrlSpec(qdtypes=QUInt(4), cvs=[0b0101]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "945fa4a4",
"metadata": {
"cq.autogen": "CtrlSpecAnd.ctrl_on_bits"
},
"outputs": [],
"source": [
"from qualtran import CtrlSpec, QBit\n",
"\n",
"ctrl_on_bits = CtrlSpecAnd(CtrlSpec(qdtypes=QBit(), cvs=[0, 1, 0, 1]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5e6374b2",
"metadata": {
"cq.autogen": "CtrlSpecAnd.ctrl_on_nd_bits"
},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"from qualtran import CtrlSpec, QBit\n",
"\n",
"ctrl_on_nd_bits = CtrlSpecAnd(CtrlSpec(qdtypes=QBit(), cvs=np.array([[0, 1], [1, 0]])))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2047fccf",
"metadata": {
"cq.autogen": "CtrlSpecAnd.ctrl_on_multiple_values"
},
"outputs": [],
"source": [
"from qualtran import CtrlSpec, QInt, QUInt\n",
"\n",
"ctrl_on_multiple_values = CtrlSpecAnd(\n",
" CtrlSpec(qdtypes=(QUInt(4), QInt(4)), cvs=([0b0101, 0b1100], [2, -2]))\n",
")"
]
},
{
"cell_type": "markdown",
"id": "55581cc0",
"metadata": {
"cq.autogen": "CtrlSpecAnd.graphical_signature.md"
},
"source": [
"#### Graphical Signature"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5ea9e6e5",
"metadata": {
"cq.autogen": "CtrlSpecAnd.graphical_signature.py"
},
"outputs": [],
"source": [
"from qualtran.drawing import show_bloqs\n",
"show_bloqs([ctrl_on_int, ctrl_on_bits, ctrl_on_nd_bits, ctrl_on_multiple_values],\n",
" ['`ctrl_on_int`', '`ctrl_on_bits`', '`ctrl_on_nd_bits`', '`ctrl_on_multiple_values`'])"
]
},
{
"cell_type": "markdown",
"id": "3f5bb7d6",
"metadata": {
"cq.autogen": "CtrlSpecAnd.call_graph.md"
},
"source": [
"### Call Graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f83e1715",
"metadata": {
"cq.autogen": "CtrlSpecAnd.call_graph.py"
},
"outputs": [],
"source": [
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
"ctrl_on_int_g, ctrl_on_int_sigma = ctrl_on_int.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
"show_call_graph(ctrl_on_int_g)\n",
"show_counts_sigma(ctrl_on_int_sigma)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading

0 comments on commit 2c2866b

Please sign in to comment.