Skip to content

Commit

Permalink
Add SignExtend for two's complement sign extension (#1162)
Browse files Browse the repository at this point in the history
* Add `SignExtend` for two's complement sign extension

* move conversion bloqs to folder

* fix notebooks

* add SignTruncate

* on_classical_vals

* mypy

* fix import

* assert that truncated bits equal the new sign bit

* remove duplicate license

* add test to check that truncate classical sim raises on invalid inputs

* fix
  • Loading branch information
anurudhp authored Jul 25, 2024
1 parent 3ef97f8 commit c5456fd
Show file tree
Hide file tree
Showing 14 changed files with 1,110 additions and 220 deletions.
18 changes: 12 additions & 6 deletions dev_tools/autogenerate-bloqs-notebooks-v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,15 @@
qualtran.bloqs.arithmetic.comparison._LEQ_DOC,
],
),
NotebookSpecV2(
title='Integer Conversions',
module=qualtran.bloqs.arithmetic.conversions,
bloq_specs=[
qualtran.bloqs.arithmetic.conversions.ones_complement_to_twos_complement._SIGNED_TO_TWOS,
qualtran.bloqs.arithmetic.conversions.sign_extension._SIGN_EXTEND_DOC,
qualtran.bloqs.arithmetic.conversions.sign_extension._SIGN_TRUNCATE_DOC,
],
),
NotebookSpecV2(
title='Sorting',
module=qualtran.bloqs.arithmetic.sorting,
Expand All @@ -418,12 +427,9 @@
directory=f'{SOURCE_DIR}/bloqs/arithmetic/',
),
NotebookSpecV2(
title='Conversions',
module=qualtran.bloqs.arithmetic.conversions,
bloq_specs=[
qualtran.bloqs.arithmetic.conversions._SIGNED_TO_TWOS,
qualtran.bloqs.arithmetic.conversions._TO_CONTG_INDX,
],
title='Indexing',
module=qualtran.bloqs.arithmetic.conversions.contiguous_index,
bloq_specs=[qualtran.bloqs.arithmetic.conversions.contiguous_index._TO_CONTG_INDX],
),
NotebookSpecV2(
title='Permutations',
Expand Down
3 changes: 2 additions & 1 deletion docs/bloqs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ Bloqs Library
arithmetic/controlled_add_or_subtract.ipynb
arithmetic/multiplication.ipynb
arithmetic/comparison.ipynb
arithmetic/conversions/conversions.ipynb
arithmetic/sorting.ipynb
arithmetic/conversions.ipynb
arithmetic/conversions/contiguous_index.ipynb
arithmetic/permutation.ipynb
arithmetic/bitwise.ipynb

Expand Down
6 changes: 5 additions & 1 deletion qualtran/bloqs/arithmetic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@
LessThanEqual,
SingleQubitCompare,
)
from qualtran.bloqs.arithmetic.conversions import SignedIntegerToTwosComplement, ToContiguousIndex
from qualtran.bloqs.arithmetic.conversions import (
SignedIntegerToTwosComplement,
SignExtend,
ToContiguousIndex,
)
from qualtran.bloqs.arithmetic.hamming_weight import HammingWeightCompute
from qualtran.bloqs.arithmetic.multiplication import (
InvertRealNumber,
Expand Down
16 changes: 16 additions & 0 deletions qualtran/bloqs/arithmetic/conversions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright 2024 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 .contiguous_index import ToContiguousIndex
from .ones_complement_to_twos_complement import SignedIntegerToTwosComplement
from .sign_extension import SignExtend, SignTruncate
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
"cells": [
{
"cell_type": "markdown",
"id": "1d183aeb",
"id": "00b83a3b",
"metadata": {
"cq.autogen": "title_cell"
},
"source": [
"# Conversions"
"# Indexing"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "14109d45",
"id": "dff756fd",
"metadata": {
"cq.autogen": "top_imports"
},
Expand All @@ -30,111 +30,7 @@
},
{
"cell_type": "markdown",
"id": "eb2d037e",
"metadata": {
"cq.autogen": "SignedIntegerToTwosComplement.bloq_doc.md"
},
"source": [
"## `SignedIntegerToTwosComplement`\n",
"Convert a register storing the signed integer representation to two's complement inplace.\n",
"\n",
"#### Parameters\n",
" - `bitsize`: size of the register. \n",
"\n",
"#### Registers\n",
" - `x`: input signed integer (ones' complement) register.\n",
" - `y`: output signed integer register in two's complement. \n",
"\n",
"#### References\n",
" - [Fault-Tolerant Quantum Simulations of Chemistry in First Quantization](https://arxiv.org/abs/2105.12767). page 24, 4th paragraph from the bottom.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "90bb1bed",
"metadata": {
"cq.autogen": "SignedIntegerToTwosComplement.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.arithmetic import SignedIntegerToTwosComplement"
]
},
{
"cell_type": "markdown",
"id": "8f3c1147",
"metadata": {
"cq.autogen": "SignedIntegerToTwosComplement.example_instances.md"
},
"source": [
"### Example Instances"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2dfb8e27",
"metadata": {
"cq.autogen": "SignedIntegerToTwosComplement.signed_to_twos"
},
"outputs": [],
"source": [
"signed_to_twos = SignedIntegerToTwosComplement(bitsize=10)"
]
},
{
"cell_type": "markdown",
"id": "06ef9a13",
"metadata": {
"cq.autogen": "SignedIntegerToTwosComplement.graphical_signature.md"
},
"source": [
"#### Graphical Signature"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "325d1c85",
"metadata": {
"cq.autogen": "SignedIntegerToTwosComplement.graphical_signature.py"
},
"outputs": [],
"source": [
"from qualtran.drawing import show_bloqs\n",
"show_bloqs([signed_to_twos],\n",
" ['`signed_to_twos`'])"
]
},
{
"cell_type": "markdown",
"id": "de47d9a4",
"metadata": {
"cq.autogen": "SignedIntegerToTwosComplement.call_graph.md"
},
"source": [
"### Call Graph"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "da2e339e",
"metadata": {
"cq.autogen": "SignedIntegerToTwosComplement.call_graph.py"
},
"outputs": [],
"source": [
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
"signed_to_twos_g, signed_to_twos_sigma = signed_to_twos.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
"show_call_graph(signed_to_twos_g)\n",
"show_counts_sigma(signed_to_twos_sigma)"
]
},
{
"cell_type": "markdown",
"id": "8db78a21",
"id": "df9965c5",
"metadata": {
"cq.autogen": "ToContiguousIndex.bloq_doc.md"
},
Expand Down Expand Up @@ -165,18 +61,18 @@
{
"cell_type": "code",
"execution_count": null,
"id": "fc4d5d9b",
"id": "47dbd7bb",
"metadata": {
"cq.autogen": "ToContiguousIndex.bloq_doc.py"
},
"outputs": [],
"source": [
"from qualtran.bloqs.arithmetic import ToContiguousIndex"
"from qualtran.bloqs.arithmetic.conversions import ToContiguousIndex"
]
},
{
"cell_type": "markdown",
"id": "5f88c48f",
"id": "c8045139",
"metadata": {
"cq.autogen": "ToContiguousIndex.example_instances.md"
},
Expand All @@ -187,7 +83,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "f1b9eba4",
"id": "c8afdd6d",
"metadata": {
"cq.autogen": "ToContiguousIndex.to_contg_index"
},
Expand All @@ -198,7 +94,7 @@
},
{
"cell_type": "markdown",
"id": "6565d270",
"id": "7602c882",
"metadata": {
"cq.autogen": "ToContiguousIndex.graphical_signature.md"
},
Expand All @@ -209,7 +105,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "676836df",
"id": "ae5d88e2",
"metadata": {
"cq.autogen": "ToContiguousIndex.graphical_signature.py"
},
Expand All @@ -222,7 +118,7 @@
},
{
"cell_type": "markdown",
"id": "7ec6b833",
"id": "95bf5977",
"metadata": {
"cq.autogen": "ToContiguousIndex.call_graph.md"
},
Expand All @@ -233,7 +129,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "b7c7b076",
"id": "7094f64c",
"metadata": {
"cq.autogen": "ToContiguousIndex.call_graph.py"
},
Expand All @@ -253,16 +149,7 @@
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"name": "python"
}
},
"nbformat": 4,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023 Google LLC
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -11,23 +11,12 @@
# 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 Dict, Optional, Set, Tuple, TYPE_CHECKING

from attrs import frozen

from qualtran import (
Bloq,
bloq_example,
BloqDocSpec,
QInt,
QIntOnesComp,
QUInt,
Register,
Side,
Signature,
)
from qualtran import Bloq, bloq_example, BloqDocSpec, QUInt, Register, Signature
from qualtran.bloqs.basic_gates import Toffoli
from qualtran.cirq_interop.t_complexity_protocol import TComplexity
from qualtran.drawing import WireSymbol
Expand Down Expand Up @@ -108,45 +97,3 @@ def _to_contg_index() -> ToContiguousIndex:


_TO_CONTG_INDX = BloqDocSpec(bloq_cls=ToContiguousIndex, examples=[_to_contg_index])


@frozen
class SignedIntegerToTwosComplement(Bloq):
"""Convert a register storing the signed integer representation to two's complement inplace.
Args:
bitsize: size of the register.
Registers:
x: input signed integer (ones' complement) register.
y: output signed integer register in two's complement.
References:
[Fault-Tolerant Quantum Simulations of Chemistry in First Quantization](https://arxiv.org/abs/2105.12767).
page 24, 4th paragraph from the bottom.
"""

bitsize: int

@cached_property
def signature(self) -> Signature:
return Signature(
[
Register('x', QIntOnesComp(self.bitsize), side=Side.LEFT),
Register('y', QInt(self.bitsize), side=Side.RIGHT),
]
)

def build_call_graph(self, ssa: 'SympySymbolAllocator') -> Set['BloqCountT']:
# Take the sign qubit as a control and cnot the remaining qubits, then
# add it to the remaining n-1 bits.
return {(Toffoli(), (self.bitsize - 2))}


@bloq_example
def _signed_to_twos() -> SignedIntegerToTwosComplement:
signed_to_twos = SignedIntegerToTwosComplement(bitsize=10)
return signed_to_twos


_SIGNED_TO_TWOS = BloqDocSpec(bloq_cls=SignedIntegerToTwosComplement, examples=[_signed_to_twos])
Loading

0 comments on commit c5456fd

Please sign in to comment.