Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
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
7 changes: 7 additions & 0 deletions dev_tools/qualtran_dev_tools/notebook_specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,13 @@
qualtran.bloqs.cryptography.ecc.ec_add_r._EC_WINDOW_ADD_BLOQ_DOC,
],
),
NotebookSpecV2(
title='Coset Representation',
module=qualtran.bloqs.mod_arithmetic.coset_representation,
bloq_specs=[
qualtran.bloqs.mod_arithmetic.coset_representation._INIT_COST_REPRESENTATION_DOC
],
),
]

GF_ARITHMETIC = [
Expand Down
1 change: 1 addition & 0 deletions docs/bloqs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ Bloqs Library
cryptography/rsa/rsa.ipynb
cryptography/ecc/ec_add.ipynb
cryptography/ecc/ecc.ipynb
mod_arithmetic/coset_representation.ipynb

.. toctree::
:maxdepth: 2
Expand Down
1 change: 1 addition & 0 deletions qualtran/bloqs/mod_arithmetic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from .coset_representation import InitCosetRepresntation
from .mod_addition import CModAdd, CModAddK, CtrlScaleModAdd, ModAdd, ModAddK
from .mod_division import KaliskiModInverse
from .mod_multiplication import CModMulK, DirtyOutOfPlaceMontgomeryModMul, ModDbl
Expand Down
159 changes: 159 additions & 0 deletions qualtran/bloqs/mod_arithmetic/coset_representation.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "2feee875",
"metadata": {
"cq.autogen": "title_cell"
},
"source": [
"# Coset Representation"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4e5b47c0",
"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": "521a3742",
"metadata": {
"cq.autogen": "InitCosetRepresntation.bloq_doc.md"
},
"source": [
"## `InitCosetRepresntation`\n",
"A state initialization of an integer in the coset representation.\n",
"\n",
"The cost representation of an integer $k$ modulo $N$ with $c_{pad}$ bits is defined as\n",
"$$\n",
" \\frac{1}{\\sqrt{2^{c_{pad}}}}\\sum_{j=0}^{2^{c_{pad}}} \\ket{jN + k}\n",
"$$\n",
"\n",
"This bloq can be built of only clifford gates ... namely $c_{pad}$ `H` gates on the padding\n",
"qubitsfollowed by `CNOT` gates implementing the reversible operation $jN+k$.\n",
"\n",
"#### Parameters\n",
" - `c_pad`: The number of padding bits.\n",
" - `k_bitsize`: The number of bits used to represent $k$ ($\\geq$ the number of bits of $k$ and $N$).\n",
" - `k`: The value of $k$.\n",
" - `mod`: The value of $N$. \n",
"\n",
"#### Registers\n",
" - `x`: A k_bitsize+c_pad register output register containing the initialized state. \n",
"\n",
"#### References\n",
" - - [Shor's algorithm with fewer (pure) qubits](https://arxiv.org/abs/quant-ph/0601097) section 4. - [How to factor 2048 bit RSA integers in 8 hours using 20 million noisy qubits](https://arxiv.org/abs/1905.09749) section 2.4\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ecf59588",
"metadata": {
"cq.autogen": "InitCosetRepresntation.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.mod_arithmetic import InitCosetRepresntation"
]
},
{
"cell_type": "markdown",
"id": "e8233189",
"metadata": {
"cq.autogen": "InitCosetRepresntation.example_instances.md"
},
"source": [
"### Example Instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fcbe6508",
"metadata": {
"cq.autogen": "InitCosetRepresntation.init_coset_representation"
},
"outputs": [],
"source": [
"c_pad, k_bitsize = sympy.symbols('c k')\n",
"init_coset_representation = InitCosetRepresntation(c_pad, k_bitsize, k=1, mod=19)"
]
},
{
"cell_type": "markdown",
"id": "76acaa4c",
"metadata": {
"cq.autogen": "InitCosetRepresntation.graphical_signature.md"
},
"source": [
"#### Graphical Signature"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9859906c",
"metadata": {
"cq.autogen": "InitCosetRepresntation.graphical_signature.py"
},
"outputs": [],
"source": [
"from qualtran.drawing import show_bloqs\n",
"show_bloqs([init_coset_representation],\n",
" ['`init_coset_representation`'])"
]
},
{
"cell_type": "markdown",
"id": "b7764566",
"metadata": {
"cq.autogen": "InitCosetRepresntation.call_graph.md"
},
"source": [
"### Call Graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bce29566",
"metadata": {
"cq.autogen": "InitCosetRepresntation.call_graph.py"
},
"outputs": [],
"source": [
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
"init_coset_representation_g, init_coset_representation_sigma = init_coset_representation.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
"show_call_graph(init_coset_representation_g)\n",
"show_counts_sigma(init_coset_representation_sigma)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
86 changes: 86 additions & 0 deletions qualtran/bloqs/mod_arithmetic/coset_representation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from functools import cached_property
from typing import TYPE_CHECKING

import attrs
import sympy

from qualtran import Bloq, bloq_example, BloqDocSpec, QUInt, Register, Side, Signature
from qualtran.bloqs.basic_gates import CNOT, Hadamard
from qualtran.resource_counting import BloqCountDictT, SympySymbolAllocator

if TYPE_CHECKING:
from qualtran.symbolics import SymbolicInt


@attrs.frozen
class InitCosetRepresntation(Bloq):
r"""A state initialization of an integer in the coset representation.

The cost representation of an integer $k$ modulo $N$ with $c_{pad}$ bits is defined as
$$
\frac{1}{\sqrt{2^{c_{pad}}}}\sum_{j=0}^{2^{c_{pad}}} \ket{jN + k}
$$

This bloq can be built of only clifford gates ... namely $c_{pad}$ `H` gates on the padding
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comma instead of ellipses (...)

qubitsfollowed by `CNOT` gates implementing the reversible operation $jN+k$.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing space


Args:
c_pad: The number of padding bits.
k_bitsize: The number of bits used to represent $k$ ($\geq$ the number of bits of $k$ and $N$).
k: The value of $k$.
mod: The value of $N$.

Registers:
x: A k_bitsize+c_pad register output register containing the initialized state.

References:
- [Shor's algorithm with fewer (pure) qubits](https://arxiv.org/abs/quant-ph/0601097)
section 4.
- [How to factor 2048 bit RSA integers in 8 hours using 20 million noisy qubits](https://arxiv.org/abs/1905.09749)
section 2.4
Comment on lines +51 to +54
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reference format: use newline to separate entries. Don't use -. Include author and year

"""

c_pad: 'SymbolicInt'
k_bitsize: 'SymbolicInt'
k: 'SymbolicInt'
mod: 'SymbolicInt'

@cached_property
def signature(self) -> 'Signature':
return Signature([Register('x', QUInt(self.c_pad + self.k_bitsize), side=Side.RIGHT)])

def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
bitsize = self.k_bitsize + self.c_pad
return {
Hadamard(): self.c_pad,
# The matrix representing the reversible operation $jN+x$ consists of 0s and 1s.
# Thus it can be implemented using CNOTs using LUP decomposition or Gaussian elemenation
# utilizing at most $n(n-1)$ CNOTs.
CNOT(): bitsize * (bitsize - 1),
}


@bloq_example
def _init_coset_representation() -> InitCosetRepresntation:
c_pad, k_bitsize = sympy.symbols('c k')
init_coset_representation = InitCosetRepresntation(c_pad, k_bitsize, k=1, mod=19)
return init_coset_representation


_INIT_COST_REPRESENTATION_DOC = BloqDocSpec(
bloq_cls=InitCosetRepresntation, examples=[_init_coset_representation]
)
43 changes: 43 additions & 0 deletions qualtran/bloqs/mod_arithmetic/coset_representation_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import pytest
import sympy

import qualtran.testing as qlt_testing
from qualtran.bloqs.mod_arithmetic.coset_representation import (
_init_coset_representation,
InitCosetRepresntation,
)
from qualtran.resource_counting import get_cost_value, QECGatesCost


def test_init_cost_representation_cost():
sym_vars = sympy.symbols('c n k N')
c, n, k, N = sym_vars
blq = InitCosetRepresntation(c, n, k, N)
cost = get_cost_value(blq, QECGatesCost())
assert cost.total_toffoli_only() == 0
resolver = {v: 10**4 for v in sym_vars}
upper_bound = (c + n) * (c + n - 1) + c
assert cost.clifford.subs(resolver) <= upper_bound.subs(resolver) # type: ignore[union-attr]


def test_init_coset_representation(bloq_autotester):
bloq_autotester(_init_coset_representation)


@pytest.mark.notebook
def test_notebook():
qlt_testing.execute_notebook('coset_representation')
1 change: 1 addition & 0 deletions qualtran/serialization/resolver_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@
"qualtran.bloqs.data_loading.qroam_clean.QROAMCleanAdjoint": qualtran.bloqs.data_loading.qroam_clean.QROAMCleanAdjoint,
"qualtran.bloqs.data_loading.qroam_clean.QROAMCleanAdjointWrapper": qualtran.bloqs.data_loading.qroam_clean.QROAMCleanAdjointWrapper,
"qualtran.bloqs.data_loading.select_swap_qrom.SelectSwapQROM": qualtran.bloqs.data_loading.select_swap_qrom.SelectSwapQROM,
"qualtran.bloqs.mod_arithmetic.coset_representation.InitCosetRepresntation": qualtran.bloqs.mod_arithmetic.coset_representation.InitCosetRepresntation,
"qualtran.bloqs.mod_arithmetic.CModAddK": qualtran.bloqs.mod_arithmetic.CModAddK,
"qualtran.bloqs.mod_arithmetic.mod_addition.ModAdd": qualtran.bloqs.mod_arithmetic.mod_addition.ModAdd,
"qualtran.bloqs.mod_arithmetic.mod_addition.CModAdd": qualtran.bloqs.mod_arithmetic.mod_addition.CModAdd,
Expand Down