Skip to content
2 changes: 2 additions & 0 deletions dev_tools/qualtran_dev_tools/notebook_specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,8 @@
qualtran.bloqs.gf_arithmetic.gf2_multiplication._MULTIPLY_BY_CONSTANT_MOD_DOC,
qualtran.bloqs.gf_arithmetic.gf2_multiplication._MULTIPLY_POLY_BY_ONE_PLUS_XK_DOC,
qualtran.bloqs.gf_arithmetic.gf2_multiplication._BINARY_POLYNOMIAL_MULTIPLICATION_DOC,
qualtran.bloqs.gf_arithmetic.gf2_multiplication._GF2_SHIFT_RIGHT_MOD_DOC,
qualtran.bloqs.gf_arithmetic.gf2_multiplication._GF2_MUL_DOC,
],
),
NotebookSpecV2(
Expand Down
2 changes: 1 addition & 1 deletion qualtran/_infra/data_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -911,7 +911,7 @@ class QGF(QDType):
characteristic: SymbolicInt
degree: SymbolicInt
irreducible_poly: Optional['galois.Poly'] = attrs.field()
element_repr: Literal["int", "poly", "power"] = attrs.field(default='int')
element_repr: Literal["int", "poly", "power"] = attrs.field(default='int', eq=False)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please add a test to data_types_test.py with examples of which QGF types should be equal and which should be different.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also, can you remind me again why we needed to add element_repr to the QGF class in the first place? ]

It looks like its a property of the GF class that can be easily modified by calling gf_type.repr(int). If this is used mainly as a tool for debugging and visualizing the field elements, then its better to not have it as part of the QGF class and simply change the property on the underlying QGF.galois_field type wherever needed.

https://mhostetter.github.io/galois/v0.3.5/api/galois.FieldArray.element_repr/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

removed


@irreducible_poly.default
def _irreducible_poly_default(self):
Expand Down
2 changes: 2 additions & 0 deletions qualtran/bloqs/gf_arithmetic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
from qualtran.bloqs.gf_arithmetic.gf2_inverse import GF2Inverse
from qualtran.bloqs.gf_arithmetic.gf2_multiplication import (
BinaryPolynomialMultiplication,
GF2Mul,
GF2Multiplication,
GF2MultiplyByConstantMod,
GF2ShiftRightMod,
MultiplyPolyByOnePlusXk,
)
from qualtran.bloqs.gf_arithmetic.gf2_square import GF2Square
229 changes: 228 additions & 1 deletion qualtran/bloqs/gf_arithmetic/gf2_multiplication.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@
"mx = galois.Poly.Degrees([0, 1, 3]) # x^3 + x + 1\n",
"gf = galois.GF(2, 3, irreducible_poly=mx)\n",
"const = gf(5) # x^2 + 1\n",
"gf2_multiply_by_constant_modulu = GF2MultiplyByConstantMod(const, gf)"
"gf2_multiply_by_constant_modulu = GF2MultiplyByConstantMod(const, mx)"
]
},
{
Expand Down Expand Up @@ -521,6 +521,233 @@
"show_call_graph(binarypolynomialmultiplication_g)\n",
"show_counts_sigma(binarypolynomialmultiplication_sigma)"
]
},
{
"cell_type": "markdown",
"id": "b87fb848",
"metadata": {
"cq.autogen": "GF2ShiftRightMod.bloq_doc.md"
},
"source": [
"## `GF2ShiftRightMod`\n",
"Multiplies by $2^k$ (or $x^k$ for polynomials) modulu.\n",
"\n",
"Applies the transformation\n",
"$$\n",
" \\ket{f} \\rightarrow \\ket{x^k f \\mod m(x)}\n",
"$$\n",
"\n",
"Where the modulus $m(x)$ is the irreducible polynomial defining the galois field arithmetic.\n",
"\n",
"#### Parameters\n",
" - `m_x`: The irreducible polynomial that defines the galois field.\n",
" - `k`: The number of shifts (i.e. the exponent of $2$ or $x$). \n",
"\n",
"#### Registers\n",
" - `f`: The number (polynomial) to shift. \n",
"\n",
"#### References\n",
" - [Space-efficient quantum multiplication of polynomials for binary finite fields with sub-quadratic Toffoli gate count](https://arxiv.org/abs/1910.02849v2). Section 3.1\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e359bb95",
"metadata": {
"cq.autogen": "GF2ShiftRightMod.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.gf_arithmetic import GF2ShiftRightMod"
]
},
{
"cell_type": "markdown",
"id": "48528f04",
"metadata": {
"cq.autogen": "GF2ShiftRightMod.example_instances.md"
},
"source": [
"### Example Instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5de95a16",
"metadata": {
"cq.autogen": "GF2ShiftRightMod.gf2shiftrightmod"
},
"outputs": [],
"source": [
"m_x = [5, 2, 0] # x^5 + x^2 + 1\n",
"gf2shiftrightmod = GF2ShiftRightMod(m_x=m_x, k=3) # shift by 3"
]
},
{
"cell_type": "markdown",
"id": "d8716920",
"metadata": {
"cq.autogen": "GF2ShiftRightMod.graphical_signature.md"
},
"source": [
"#### Graphical Signature"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8b2a99b7",
"metadata": {
"cq.autogen": "GF2ShiftRightMod.graphical_signature.py"
},
"outputs": [],
"source": [
"from qualtran.drawing import show_bloqs\n",
"show_bloqs([gf2shiftrightmod],\n",
" ['`gf2shiftrightmod`'])"
]
},
{
"cell_type": "markdown",
"id": "30d7d6b7",
"metadata": {
"cq.autogen": "GF2ShiftRightMod.call_graph.md"
},
"source": [
"### Call Graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b083b133",
"metadata": {
"cq.autogen": "GF2ShiftRightMod.call_graph.py"
},
"outputs": [],
"source": [
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
"gf2shiftrightmod_g, gf2shiftrightmod_sigma = gf2shiftrightmod.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
"show_call_graph(gf2shiftrightmod_g)\n",
"show_counts_sigma(gf2shiftrightmod_sigma)"
]
},
{
"cell_type": "markdown",
"id": "ff7fda61",
"metadata": {
"cq.autogen": "GF2Mul.bloq_doc.md"
},
"source": [
"## `GF2Mul`\n",
"Multiplies two GF($2^n$) numbers (or binary polynomials) modulu.\n",
"\n",
"Applies the transformation\n",
"$$\n",
" \\ket{f}\\ket{g} \\rightarrow \\ket{f} \\ket{g} \\ket{f*g \\mod m(x)}\n",
"$$\n",
"\n",
"Where the modulus $m(x)$ is the irreducible polynomial defining the galois field arithmetic.\n",
"The toffoli complexity is $n^{\\log_2{3}}$\n",
"\n",
"#### Parameters\n",
" - `m_x`: The irreducible polynomial that defines the galois field.\n",
" - `uncompute`: Whether to compute or uncompute the product. \n",
"\n",
"#### Registers\n",
" - `f`: The first number (polynomial).\n",
" - `g`: The second number (polynomial).\n",
" - `h`: The result. \n",
"\n",
"#### References\n",
" - [Space-efficient quantum multiplication of polynomials for binary finite fields with sub-quadratic Toffoli gate count](https://arxiv.org/abs/1910.02849v2). Algorithm 4.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3fbbb423",
"metadata": {
"cq.autogen": "GF2Mul.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.gf_arithmetic import GF2Mul"
]
},
{
"cell_type": "markdown",
"id": "5080df63",
"metadata": {
"cq.autogen": "GF2Mul.example_instances.md"
},
"source": [
"### Example Instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "97fb47ec",
"metadata": {
"cq.autogen": "GF2Mul.gf2mul"
},
"outputs": [],
"source": [
"m_x = [5, 2, 0] # x^5 + x^2 + 1\n",
"gf2mul = GF2Mul(m_x=m_x)"
]
},
{
"cell_type": "markdown",
"id": "f7775fe5",
"metadata": {
"cq.autogen": "GF2Mul.graphical_signature.md"
},
"source": [
"#### Graphical Signature"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "55b3ab62",
"metadata": {
"cq.autogen": "GF2Mul.graphical_signature.py"
},
"outputs": [],
"source": [
"from qualtran.drawing import show_bloqs\n",
"show_bloqs([gf2mul],\n",
" ['`gf2mul`'])"
]
},
{
"cell_type": "markdown",
"id": "c41a8e24",
"metadata": {
"cq.autogen": "GF2Mul.call_graph.md"
},
"source": [
"### Call Graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fcccc225",
"metadata": {
"cq.autogen": "GF2Mul.call_graph.py"
},
"outputs": [],
"source": [
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
"gf2mul_g, gf2mul_sigma = gf2mul.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
"show_call_graph(gf2mul_g)\n",
"show_counts_sigma(gf2mul_sigma)"
]
}
],
"metadata": {
Expand Down
Loading