Skip to content

Commit

Permalink
[mod_arithmetic] Organize modular addition (#907)
Browse files Browse the repository at this point in the history
* [mod_arithmetic] Organize modular addition

* C[AddK] -> AddK with cvs and fixes

* format and minimize changes

* mark notebook test

* revert tcompl removal

* reconcile with ecc commit

* format

* Don't test notebooks twice

* fix merge conflict: wire symbol

* fixes (typing, generally)

* format

* merge conflicts

* lint

* more mergy issues
  • Loading branch information
mpharrigan authored May 17, 2024
1 parent 32ad347 commit 05504ce
Show file tree
Hide file tree
Showing 26 changed files with 780 additions and 610 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
pip install -r dev_tools/requirements/envs/pytest.env.txt
pip install --no-deps -e .
- run: |
check/pytest -m 'not notebooks'
check/pytest -m 'not notebook'
pytest-dev-tools:
runs-on: ubuntu-latest
Expand Down
14 changes: 13 additions & 1 deletion dev_tools/autogenerate-bloqs-notebooks-v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,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.mod_arithmetic.mod_addition
import qualtran.bloqs.multiplexers.apply_gate_to_lth_target
import qualtran.bloqs.multiplexers.select_pauli_lcu
import qualtran.bloqs.phase_estimation.lp_resource_state
Expand Down Expand Up @@ -291,7 +292,6 @@
bloq_specs=[
qualtran.bloqs.arithmetic.addition._ADD_DOC,
qualtran.bloqs.arithmetic.addition._ADD_OOP_DOC,
qualtran.bloqs.arithmetic.addition._SIMPLE_ADD_K_DOC,
qualtran.bloqs.arithmetic.addition._ADD_K_DOC,
],
),
Expand Down Expand Up @@ -367,6 +367,17 @@
),
]

MOD_ARITHMETIC = [
NotebookSpecV2(
title='Modular Addition',
module=qualtran.bloqs.mod_arithmetic.mod_addition,
bloq_specs=[
qualtran.bloqs.mod_arithmetic.mod_addition._MOD_ADD_DOC,
qualtran.bloqs.mod_arithmetic.mod_addition._MOD_ADD_K_DOC,
],
)
]


ROT_QFT_PE = [
# --------------------------------------------------------------------------
Expand Down Expand Up @@ -544,6 +555,7 @@
('Basic Gates', BASIC_GATES),
('Chemistry', CHEMISTRY),
('Arithmetic', ARITHMETIC),
('Modular Arithmetic', MOD_ARITHMETIC),
('Rotations', ROT_QFT_PE),
('Other', OTHER),
]
Expand Down
6 changes: 6 additions & 0 deletions docs/bloqs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ Bloqs Library
factoring/ecc/ecc.ipynb
factoring/ecc/ec_add.ipynb

.. toctree::
:maxdepth: 2
:caption: Modular Arithmetic:

mod_arithmetic/mod_addition.ipynb

.. toctree::
:maxdepth: 2
:caption: Rotations:
Expand Down
10 changes: 2 additions & 8 deletions qualtran/bloqs/arithmetic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from qualtran.bloqs.arithmetic.addition import (
Add,
AddConstantMod,
OutOfPlaceAdder,
SimpleAddConstant,
Subtract,
)
from qualtran.bloqs.arithmetic.addition import Add, AddK, OutOfPlaceAdder, Subtract
from qualtran.bloqs.arithmetic.comparison import (
BiQubitsMixer,
EqualsAConstant,
Expand All @@ -41,4 +35,4 @@
)
from qualtran.bloqs.arithmetic.sorting import BitonicSort, Comparator

from ._shims import AddK, CHalf, Lt, MultiCToffoli, Negate, Sub
from ._shims import CHalf, Lt, MultiCToffoli, Negate, Sub
10 changes: 0 additions & 10 deletions qualtran/bloqs/arithmetic/_shims.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,6 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> Set['BloqCountT']:
return {(Toffoli(), self.n - 2)}


@frozen
class AddK(Bloq):
n: int
k: int

@cached_property
def signature(self) -> 'Signature':
return Signature([Register('x', QUInt(self.n))])


@frozen
class Sub(Bloq):
n: int
Expand Down
184 changes: 27 additions & 157 deletions qualtran/bloqs/arithmetic/addition.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -307,149 +307,19 @@
},
{
"cell_type": "markdown",
"id": "1df2fb29",
"id": "2813f173",
"metadata": {
"cq.autogen": "AddConstantMod.bloq_doc.md"
"cq.autogen": "AddK.bloq_doc.md"
},
"source": [
"## `AddConstantMod`\n",
"Applies U(add, M)|x> = |(x + add) % M> if x < M else |x>.\n",
"\n",
"Applies modular addition to input register `|x>` given parameters `mod` and `add_val` s.t.\n",
" 1. If integer `x` < `mod`: output is `|(x + add) % M>`\n",
" 2. If integer `x` >= `mod`: output is `|x>`.\n",
"\n",
"This condition is needed to ensure that the mapping of all input basis states (i.e. input\n",
"states |0>, |1>, ..., |2 ** bitsize - 1) to corresponding output states is bijective and thus\n",
"the gate is reversible.\n",
"\n",
"Also supports controlled version of the gate by specifying a per qubit control value as a tuple\n",
"of integers passed as `cvs`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5ef2dab4",
"metadata": {
"cq.autogen": "AddConstantMod.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.arithmetic import AddConstantMod"
]
},
{
"cell_type": "markdown",
"id": "ed3f3c05",
"metadata": {
"cq.autogen": "AddConstantMod.example_instances.md"
},
"source": [
"### Example Instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "195a8047",
"metadata": {
"cq.autogen": "AddConstantMod.add_k_symb"
},
"outputs": [],
"source": [
"n, m, k = sympy.symbols('n m k')\n",
"add_k_symb = AddConstantMod(bitsize=n, mod=m, add_val=k)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9c3f7fb3",
"metadata": {
"cq.autogen": "AddConstantMod.add_k_small"
},
"outputs": [],
"source": [
"add_k_small = AddConstantMod(bitsize=4, mod=7, add_val=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bdc82bc1",
"metadata": {
"cq.autogen": "AddConstantMod.add_k_large"
},
"outputs": [],
"source": [
"add_k_large = AddConstantMod(bitsize=64, mod=500, add_val=23)"
]
},
{
"cell_type": "markdown",
"id": "b6885dbb",
"metadata": {
"cq.autogen": "AddConstantMod.graphical_signature.md"
},
"source": [
"#### Graphical Signature"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "65773e01",
"metadata": {
"cq.autogen": "AddConstantMod.graphical_signature.py"
},
"outputs": [],
"source": [
"from qualtran.drawing import show_bloqs\n",
"show_bloqs([add_k_symb, add_k_small, add_k_large],\n",
" ['`add_k_symb`', '`add_k_small`', '`add_k_large`'])"
]
},
{
"cell_type": "markdown",
"id": "1a4bf832",
"metadata": {
"cq.autogen": "AddConstantMod.call_graph.md"
},
"source": [
"### Call Graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "61f1568e",
"metadata": {
"cq.autogen": "AddConstantMod.call_graph.py"
},
"outputs": [],
"source": [
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
"add_k_symb_g, add_k_symb_sigma = add_k_symb.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
"show_call_graph(add_k_symb_g)\n",
"show_counts_sigma(add_k_symb_sigma)"
]
},
{
"cell_type": "markdown",
"id": "9449e4e9",
"metadata": {
"cq.autogen": "SimpleAddConstant.bloq_doc.md"
},
"source": [
"## `SimpleAddConstant`\n",
"## `AddK`\n",
"Takes |x> to |x + k> for a classical integer `k`.\n",
"\n",
"Applies addition to input register `|x>` given classical integer 'k'.\n",
"\n",
"This is the simple version of constant addition because it involves simply converting the\n",
"classical integer into a quantum parameter and using quantum-quantum addition as opposed to\n",
"designing a bespoke circuit for constant addition based on the classical parameter.\n",
"This construction simply XORs the classical constant into a quantum register and\n",
"applies quantum-quantum addition. This is the lowest T-count algorithm at the expense\n",
"of $n$ auxiliary qubits. This construction also permits an inexpensive controlled version:\n",
"you only need to control the loading of the classical constant which can be done with\n",
"only clifford operations.\n",
"\n",
"#### Parameters\n",
" - `bitsize`: Number of bits used to represent each integer.\n",
Expand All @@ -461,26 +331,26 @@
" - `x`: A bitsize-sized input register (register x above). \n",
"\n",
"#### References\n",
" - [Improved quantum circuits for elliptic curve discrete logarithms](https://arxiv.org/abs/2001.09580). Fig 2a\n"
" - [Improved quantum circuits for elliptic curve discrete logarithms](https://arxiv.org/abs/2001.09580). Haner et. al. 2020. Section 3: Components. \"Integer addition\" and Fig 2a.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cd255bf9",
"metadata": {
"cq.autogen": "SimpleAddConstant.bloq_doc.py"
"cq.autogen": "AddK.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.arithmetic import SimpleAddConstant"
"from qualtran.bloqs.arithmetic import AddK"
]
},
{
"cell_type": "markdown",
"id": "7538f9a5",
"metadata": {
"cq.autogen": "SimpleAddConstant.example_instances.md"
"cq.autogen": "AddK.example_instances.md"
},
"source": [
"### Example Instances"
Expand All @@ -491,43 +361,43 @@
"execution_count": null,
"id": "4305289f",
"metadata": {
"cq.autogen": "SimpleAddConstant.simple_add_k_symb"
"cq.autogen": "AddK.add_k"
},
"outputs": [],
"source": [
"n, k = sympy.symbols('n k')\n",
"simple_add_k_symb = SimpleAddConstant(bitsize=n, k=k)"
"add_k = AddK(bitsize=n, k=k)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f6048819",
"metadata": {
"cq.autogen": "SimpleAddConstant.simple_add_k_small"
"cq.autogen": "AddK.add_k_small"
},
"outputs": [],
"source": [
"simple_add_k_small = SimpleAddConstant(bitsize=4, k=2, signed=False)"
"add_k_small = AddK(bitsize=4, k=2, signed=False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b67fd469",
"metadata": {
"cq.autogen": "SimpleAddConstant.simple_add_k_large"
"cq.autogen": "AddK.add_k_large"
},
"outputs": [],
"source": [
"simple_add_k_large = SimpleAddConstant(bitsize=64, k=-23, signed=True)"
"add_k_large = AddK(bitsize=64, k=-23, signed=True)"
]
},
{
"cell_type": "markdown",
"id": "b8b04228",
"metadata": {
"cq.autogen": "SimpleAddConstant.graphical_signature.md"
"cq.autogen": "AddK.graphical_signature.md"
},
"source": [
"#### Graphical Signature"
Expand All @@ -538,20 +408,20 @@
"execution_count": null,
"id": "e93e7f2e",
"metadata": {
"cq.autogen": "SimpleAddConstant.graphical_signature.py"
"cq.autogen": "AddK.graphical_signature.py"
},
"outputs": [],
"source": [
"from qualtran.drawing import show_bloqs\n",
"show_bloqs([simple_add_k_small, simple_add_k_large],\n",
" ['`simple_add_k_small`', '`simple_add_k_large`'])"
"show_bloqs([add_k, add_k_small, add_k_large],\n",
" ['`add_k`', '`add_k_small`', '`add_k_large`'])"
]
},
{
"cell_type": "markdown",
"id": "13552795",
"metadata": {
"cq.autogen": "SimpleAddConstant.call_graph.md"
"cq.autogen": "AddK.call_graph.md"
},
"source": [
"### Call Graph"
Expand All @@ -562,14 +432,14 @@
"execution_count": null,
"id": "d8d6584e",
"metadata": {
"cq.autogen": "SimpleAddConstant.call_graph.py"
"cq.autogen": "AddK.call_graph.py"
},
"outputs": [],
"source": [
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
"simple_add_k_small_g, simple_add_k_small_sigma = simple_add_k_small.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
"show_call_graph(simple_add_k_small_g)\n",
"show_counts_sigma(simple_add_k_small_sigma)"
"add_k_g, add_k_sigma = add_k.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
"show_call_graph(add_k_g)\n",
"show_counts_sigma(add_k_sigma)"
]
},
{
Expand Down
Loading

0 comments on commit 05504ce

Please sign in to comment.