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

Implement Kikuchi guiding state preparation #1504

Merged
merged 9 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
notebook
  • Loading branch information
anurudhp committed Dec 20, 2024
commit 6e2fdac9521b34d64f3e710f392bcc6419d494d0
1 change: 1 addition & 0 deletions docs/bloqs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Bloqs Library
arithmetic/permutation.ipynb
arithmetic/bitwise.ipynb
arithmetic/trigonometric/trigonometric.ipynb
arithmetic/lists/lists.ipynb

.. toctree::
:maxdepth: 2
Expand Down
380 changes: 380 additions & 0 deletions qualtran/bloqs/arithmetic/lists/lists.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,380 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "4b6002bc",
"metadata": {
"cq.autogen": "title_cell"
},
"source": [
"# List Functions"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "73f38d89",
"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": "75d1819f",
"metadata": {
"cq.autogen": "SortInPlace.bloq_doc.md"
},
"source": [
"## `SortInPlace`\n",
"Sort a list of $\\ell$ numbers in place using $\\ell \\log \\ell$ ancilla bits.\n",
"\n",
"Applies the map:\n",
"$$\n",
" |x_1, x_2, \\ldots, x_l\\rangle\n",
" |0^{\\ell \\log \\ell}\\rangle\n",
" \\mapsto\n",
" |x_{\\pi_1}, x_{\\pi_2}, \\ldots, x_{\\pi_\\ell})\\rangle\n",
" |\\pi_1, \\pi_2, \\ldots, \\pi_\\ell\\rangle\n",
"$$\n",
"where $x_{\\pi_1} \\le x_{\\pi_2} \\ldots \\le x_{\\pi_\\ell}$ is the sorted list,\n",
"and the ancilla are entangled.\n",
"\n",
"To apply this, we first use any sorting algorithm to output the sorted list\n",
"in a clean register. And then use the following algorithm from Lemma 4.12 of Ref [1]\n",
"that applies the map:\n",
"\n",
"$$\n",
" |x_1, ..., x_l\\rangle|x_{\\pi(1)}, ..., x_{\\pi(l)})\\rangle\n",
" \\mapsto\n",
" |x_l, ..., x_l\\rangle|\\pi(1), ..., \\pi(l))\\rangle\n",
"$$\n",
"\n",
"where $x_i \\in [n]$ and $\\pi(i) \\in [l]$.\n",
"This second algorithm (Lemma 4.12) has two steps, each with $l^2$ comparisons:\n",
"1. compute `pi(1) ... pi(l)` given `x_1 ... x_l` and `x_{pi(1)} ... x{pi(l)}`.\n",
"1. (un)compute `x_{pi(1)} ... x{pi(l)}` using `pi(1) ... pi(l)` given `x_1 ... x_l`.\n",
"\n",
"#### Parameters\n",
" - `l`: number of elements in the list\n",
" - `dtype`: type of each element to store `[n]`. \n",
"\n",
"#### Registers\n",
" - `input`: the entire input as a single register\n",
" - `ancilla`: the generated (entangled) register storing `pi`. \n",
"\n",
"#### References\n",
" - [Quartic quantum speedups for planted inference](https://arxiv.org/abs/2406.19378v1). Lemma 4.12. Eq. 122.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fcb6c012",
"metadata": {
"cq.autogen": "SortInPlace.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.arithmetic.lists import SortInPlace"
]
},
{
"cell_type": "markdown",
"id": "e878a52b",
"metadata": {
"cq.autogen": "SymmetricDifference.bloq_doc.md"
},
"source": [
"## `SymmetricDifference`\n",
"Given two sorted sets $S, T$ of unique elements, compute their symmetric difference.\n",
"\n",
"This accepts an integer `n_diff`, and marks a flag qubit if the symmetric difference\n",
"set is of size exactly `n_diff`. If the flag is marked (1), then the output of `n_diff`\n",
"numbers is the symmetric difference, otherwise it may be arbitrary.\n",
"\n",
"#### Parameters\n",
" - `n_lhs`: number of elements in $S$\n",
" - `n_rhs`: number of elements in $T$\n",
" - `n_diff`: expected number of elements in the difference $S \\Delta T$.\n",
" - `dtype`: type of each element. \n",
"\n",
"#### Registers\n",
" - `S`: list of `n_lhs` numbers.\n",
" - `T`: list of `n_rhs` numbers.\n",
" - `diff`: output register of `n_diff` numbers.\n",
" - `flag`: 1 if there are duplicates, 0 if all are unique. \n",
"\n",
"#### References\n",
" - [Quartic quantum speedups for planted inference](https://arxiv.org/abs/2406.19378v1). Theorem 4.17, proof para 3, page 38.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ccaa8a4b",
"metadata": {
"cq.autogen": "SymmetricDifference.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.arithmetic.lists import SymmetricDifference"
]
},
{
"cell_type": "markdown",
"id": "6cefce9f",
"metadata": {
"cq.autogen": "SymmetricDifference.example_instances.md"
},
"source": [
"### Example Instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b7ffc68f",
"metadata": {
"cq.autogen": "SymmetricDifference.symm_diff"
},
"outputs": [],
"source": [
"import sympy\n",
"\n",
"from qualtran.symbolics import bit_length\n",
"\n",
"n, k, c = sympy.symbols(\"n k c\", positive=True, integer=True)\n",
"dtype = QUInt(bit_length(n - 1))\n",
"symm_diff = SymmetricDifference(n_lhs=c * k, n_rhs=k, n_diff=c * k, dtype=dtype)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4da0b292",
"metadata": {
"cq.autogen": "SymmetricDifference.symm_diff_equal_size"
},
"outputs": [],
"source": [
"import sympy\n",
"\n",
"from qualtran.symbolics import bit_length\n",
"\n",
"n, k, c = sympy.symbols(\"n k c\", positive=True, integer=True)\n",
"dtype = QUInt(bit_length(n - 1))\n",
"symm_diff_equal_size = SymmetricDifference(n_lhs=c * k, n_rhs=c * k, n_diff=k, dtype=dtype)"
]
},
{
"cell_type": "markdown",
"id": "79bb967b",
"metadata": {
"cq.autogen": "SymmetricDifference.graphical_signature.md"
},
"source": [
"#### Graphical Signature"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fb210e38",
"metadata": {
"cq.autogen": "SymmetricDifference.graphical_signature.py"
},
"outputs": [],
"source": [
"from qualtran.drawing import show_bloqs\n",
"show_bloqs([symm_diff, symm_diff_equal_size],\n",
" ['`symm_diff`', '`symm_diff_equal_size`'])"
]
},
{
"cell_type": "markdown",
"id": "946e2cef",
"metadata": {
"cq.autogen": "SymmetricDifference.call_graph.md"
},
"source": [
"### Call Graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9a25a154",
"metadata": {
"cq.autogen": "SymmetricDifference.call_graph.py"
},
"outputs": [],
"source": [
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
"symm_diff_g, symm_diff_sigma = symm_diff.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
"show_call_graph(symm_diff_g)\n",
"show_counts_sigma(symm_diff_sigma)"
]
},
{
"cell_type": "markdown",
"id": "a78e7e32",
"metadata": {
"cq.autogen": "HasDuplicates.bloq_doc.md"
},
"source": [
"## `HasDuplicates`\n",
"Given a sorted list of `l` numbers, check if it contains any duplicates.\n",
"\n",
"Produces a single qubit which is `1` if there are duplicates, and `0` if all are disjoint.\n",
"It compares every adjacent pair, and therefore uses `l - 1` comparisons.\n",
"It then uses a single MCX on `l - 1` bits gate to compute the flag.\n",
"\n",
"#### Parameters\n",
" - `l`: number of elements in the list\n",
" - `dtype`: type of each element to store `[n]`. \n",
"\n",
"#### Registers\n",
" - `xs`: a list of `l` registers of `dtype`.\n",
" - `flag`: single qubit. Value is flipped if the input list has duplicates, otherwise stays same. \n",
"\n",
"#### References\n",
" - [Quartic quantum speedups for planted inference](https://arxiv.org/abs/2406.19378v1). Lemma 4.12. Eq. 122.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0707263c",
"metadata": {
"cq.autogen": "HasDuplicates.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.arithmetic.lists import HasDuplicates"
]
},
{
"cell_type": "markdown",
"id": "eae0fee2",
"metadata": {
"cq.autogen": "HasDuplicates.example_instances.md"
},
"source": [
"### Example Instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "588c7e8a",
"metadata": {
"cq.autogen": "HasDuplicates.has_duplicates_symb"
},
"outputs": [],
"source": [
"import sympy\n",
"\n",
"n = sympy.Symbol(\"n\")\n",
"has_duplicates_symb = HasDuplicates(4, QUInt(n))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d7d63e51",
"metadata": {
"cq.autogen": "HasDuplicates.has_duplicates"
},
"outputs": [],
"source": [
"has_duplicates = HasDuplicates(4, QUInt(3))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a12dbdf3",
"metadata": {
"cq.autogen": "HasDuplicates.has_duplicates_symb_len"
},
"outputs": [],
"source": [
"import sympy\n",
"\n",
"l, n = sympy.symbols(\"l n\")\n",
"has_duplicates_symb_len = HasDuplicates(l, QUInt(n))"
]
},
{
"cell_type": "markdown",
"id": "d189b98d",
"metadata": {
"cq.autogen": "HasDuplicates.graphical_signature.md"
},
"source": [
"#### Graphical Signature"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b905935f",
"metadata": {
"cq.autogen": "HasDuplicates.graphical_signature.py"
},
"outputs": [],
"source": [
"from qualtran.drawing import show_bloqs\n",
"show_bloqs([has_duplicates_symb, has_duplicates, has_duplicates_symb_len],\n",
" ['`has_duplicates_symb`', '`has_duplicates`', '`has_duplicates_symb_len`'])"
]
},
{
"cell_type": "markdown",
"id": "2156df99",
"metadata": {
"cq.autogen": "HasDuplicates.call_graph.md"
},
"source": [
"### Call Graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d05f52a0",
"metadata": {
"cq.autogen": "HasDuplicates.call_graph.py"
},
"outputs": [],
"source": [
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
"has_duplicates_symb_g, has_duplicates_symb_sigma = has_duplicates_symb.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
"show_call_graph(has_duplicates_symb_g)\n",
"show_counts_sigma(has_duplicates_symb_sigma)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}