Skip to content

Commit b65ba6d

Browse files
authored
Add SparseMatrixHermitian block-encoding (#1479)
1 parent baad879 commit b65ba6d

File tree

7 files changed

+650
-0
lines changed

7 files changed

+650
-0
lines changed

dev_tools/qualtran_dev_tools/notebook_specs.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import qualtran.bloqs.block_encoding.phase
5252
import qualtran.bloqs.block_encoding.product
5353
import qualtran.bloqs.block_encoding.sparse_matrix
54+
import qualtran.bloqs.block_encoding.sparse_matrix_hermitian
5455
import qualtran.bloqs.block_encoding.tensor_product
5556
import qualtran.bloqs.block_encoding.unitary
5657
import qualtran.bloqs.bookkeeping
@@ -740,6 +741,13 @@
740741
module=qualtran.bloqs.block_encoding.sparse_matrix,
741742
bloq_specs=[qualtran.bloqs.block_encoding.sparse_matrix._SPARSE_MATRIX_DOC],
742743
),
744+
NotebookSpecV2(
745+
title='Sparse Matrix Hermitian',
746+
module=qualtran.bloqs.block_encoding.sparse_matrix_hermitian,
747+
bloq_specs=[
748+
qualtran.bloqs.block_encoding.sparse_matrix_hermitian._SPARSE_MATRIX_HERMITIAN_DOC
749+
],
750+
),
743751
NotebookSpecV2(
744752
title='Chebyshev Polynomial',
745753
module=qualtran.bloqs.block_encoding.chebyshev_polynomial,

docs/bloqs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ Bloqs Library
130130
block_encoding/phase.ipynb
131131
block_encoding/linear_combination.ipynb
132132
block_encoding/sparse_matrix.ipynb
133+
block_encoding/sparse_matrix_hermitian.ipynb
133134
block_encoding/chebyshev_polynomial.ipynb
134135
block_encoding/lcu_block_encoding.ipynb
135136

qualtran/bloqs/block_encoding/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@
2323
from qualtran.bloqs.block_encoding.phase import Phase
2424
from qualtran.bloqs.block_encoding.product import Product
2525
from qualtran.bloqs.block_encoding.sparse_matrix import SparseMatrix
26+
from qualtran.bloqs.block_encoding.sparse_matrix_hermitian import SparseMatrixHermitian
2627
from qualtran.bloqs.block_encoding.tensor_product import TensorProduct
2728
from qualtran.bloqs.block_encoding.unitary import Unitary
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "8e5e678f",
6+
"metadata": {
7+
"cq.autogen": "title_cell"
8+
},
9+
"source": [
10+
"# Sparse Matrix Hermitian"
11+
]
12+
},
13+
{
14+
"cell_type": "code",
15+
"execution_count": null,
16+
"id": "70980f2b",
17+
"metadata": {
18+
"cq.autogen": "top_imports"
19+
},
20+
"outputs": [],
21+
"source": [
22+
"from qualtran import Bloq, CompositeBloq, BloqBuilder, Signature, Register\n",
23+
"from qualtran import QBit, QInt, QUInt, QAny\n",
24+
"from qualtran.drawing import show_bloq, show_call_graph, show_counts_sigma\n",
25+
"from typing import *\n",
26+
"import numpy as np\n",
27+
"import sympy\n",
28+
"import cirq"
29+
]
30+
},
31+
{
32+
"cell_type": "markdown",
33+
"id": "8db414b7",
34+
"metadata": {
35+
"cq.autogen": "SparseMatrixHermitian.bloq_doc.md"
36+
},
37+
"source": [
38+
"## `SparseMatrixHermitian`\n",
39+
"Hermitian Block encoding of a sparse-access Hermitian matrix.\n",
40+
"\n",
41+
"Given column and entry oracles $O_c$ and $O_A$ for an $s$-sparse Hermitian matrix\n",
42+
"$A \\in \\mathbb{C}^{2^n \\times 2^n}$, i.e. one where each row / column has exactly $s$ non-zero\n",
43+
"entries, computes a $(s, n+1, \\epsilon)$-block encoding of $A$ as follows:\n",
44+
"```\n",
45+
" ┌────┐\n",
46+
"a |0> ─┤ ├─ |0> ───────────────────────X────────────────────\n",
47+
" │ │ ┌──┐ | ┌──┐\n",
48+
" │ U │ = │ n│ ┌────┐ ┌────┐ | ┌────┐ ┌────┐ │ n│\n",
49+
"l |0^n> ─┤ A ├─ |0^n> ─┤H ├─┤ O ├─┤ ├─X──|─┤ ├─┤ O* ├─┤H ├─\n",
50+
" │ │ └──┘ | c | │ │ | | │ │ | c | └──┘\n",
51+
" │ │ └────┘ │ O │ │ | │ O* │ └────┘\n",
52+
"b |0> ─┤ ├─ |0> ────────|────┤ A ├─|──X─┤ A ├───|─────────\n",
53+
" | | ┌────┐ | | | | | ┌────┐\n",
54+
" | | | O | | | | | | | O* |\n",
55+
"j |Psi> ─┤ ├─ |Psi> ──────┤ c ├─┤ ├─X────┤ ├─┤ c ├──────\n",
56+
" └────┘ └────┘ └────┘ └────┘ └────┘\n",
57+
"```\n",
58+
"\n",
59+
"To encode a matrix of irregular dimension, the matrix should first be embedded into one of\n",
60+
"dimension $2^n \\times 2^n$ for suitable $n$.\n",
61+
"To encode a matrix where each row / column has at most $s$ non-zero entries, some zeroes should\n",
62+
"be treated as if they were non-zero so that each row / column has exactly $s$ non-zero entries.\n",
63+
"\n",
64+
"For encoding a non-hermitian matrix, or a slightly more efficient (but non Hermitian-encoding)\n",
65+
"of a matrix, use :class:`SparseMatrix` instead.\n",
66+
"\n",
67+
"#### Parameters\n",
68+
" - `col_oracle`: The column oracle $O_c$. See `RowColumnOracle` for definition.\n",
69+
" - `entry_oracle`: The entry oracle $O_A$. See `EntryOracle` for definition.\n",
70+
" - `eps`: The precision of the block encoding.\n",
71+
" - `is_controlled`: if True, returns the controlled block-encoding. \n",
72+
"\n",
73+
"#### Registers\n",
74+
" - `ctrl`: The single qubit control register. (present only if `is_controlled` is `True`)\n",
75+
" - `system`: The system register.\n",
76+
" - `ancilla`: The ancilla register.\n",
77+
" - `resource`: The resource register (present only if `bitsize > 0`). \n",
78+
"\n",
79+
"#### References\n",
80+
" - [Lecture Notes on Quantum Algorithms for Scientific Computation](https://arxiv.org/abs/2201.08309). Lin Lin (2022). Ch. 6.5. Proposition 6.8, Fig 6.7.\n"
81+
]
82+
},
83+
{
84+
"cell_type": "code",
85+
"execution_count": null,
86+
"id": "f31bfd74",
87+
"metadata": {
88+
"cq.autogen": "SparseMatrixHermitian.bloq_doc.py"
89+
},
90+
"outputs": [],
91+
"source": [
92+
"from qualtran.bloqs.block_encoding import SparseMatrixHermitian"
93+
]
94+
},
95+
{
96+
"cell_type": "markdown",
97+
"id": "435f31d2",
98+
"metadata": {
99+
"cq.autogen": "SparseMatrixHermitian.example_instances.md"
100+
},
101+
"source": [
102+
"### Example Instances"
103+
]
104+
},
105+
{
106+
"cell_type": "code",
107+
"execution_count": null,
108+
"id": "720f3f9b",
109+
"metadata": {
110+
"cq.autogen": "SparseMatrixHermitian.sparse_matrix_symb_hermitian_block_encoding"
111+
},
112+
"outputs": [],
113+
"source": [
114+
"from qualtran.bloqs.block_encoding.sparse_matrix import TopLeftRowColumnOracle\n",
115+
"from qualtran.bloqs.block_encoding.sparse_matrix_hermitian import UniformSqrtEntryOracle\n",
116+
"\n",
117+
"n = sympy.Symbol('n', positive=True, integer=True)\n",
118+
"col_oracle = TopLeftRowColumnOracle(system_bitsize=n)\n",
119+
"entry_oracle = UniformSqrtEntryOracle(system_bitsize=n, entry=0.3)\n",
120+
"sparse_matrix_symb_hermitian_block_encoding = SparseMatrixHermitian(\n",
121+
" col_oracle, entry_oracle, eps=0\n",
122+
")"
123+
]
124+
},
125+
{
126+
"cell_type": "code",
127+
"execution_count": null,
128+
"id": "70e512ff",
129+
"metadata": {
130+
"cq.autogen": "SparseMatrixHermitian.sparse_matrix_hermitian_block_encoding"
131+
},
132+
"outputs": [],
133+
"source": [
134+
"from qualtran.bloqs.block_encoding.sparse_matrix import TopLeftRowColumnOracle\n",
135+
"from qualtran.bloqs.block_encoding.sparse_matrix_hermitian import UniformSqrtEntryOracle\n",
136+
"\n",
137+
"col_oracle = TopLeftRowColumnOracle(system_bitsize=2)\n",
138+
"entry_oracle = UniformSqrtEntryOracle(system_bitsize=2, entry=0.3)\n",
139+
"sparse_matrix_hermitian_block_encoding = SparseMatrixHermitian(col_oracle, entry_oracle, eps=0)"
140+
]
141+
},
142+
{
143+
"cell_type": "markdown",
144+
"id": "6e8d3efa",
145+
"metadata": {
146+
"cq.autogen": "SparseMatrixHermitian.graphical_signature.md"
147+
},
148+
"source": [
149+
"#### Graphical Signature"
150+
]
151+
},
152+
{
153+
"cell_type": "code",
154+
"execution_count": null,
155+
"id": "96d58575",
156+
"metadata": {
157+
"cq.autogen": "SparseMatrixHermitian.graphical_signature.py"
158+
},
159+
"outputs": [],
160+
"source": [
161+
"from qualtran.drawing import show_bloqs\n",
162+
"show_bloqs([sparse_matrix_symb_hermitian_block_encoding, sparse_matrix_hermitian_block_encoding],\n",
163+
" ['`sparse_matrix_symb_hermitian_block_encoding`', '`sparse_matrix_hermitian_block_encoding`'])"
164+
]
165+
},
166+
{
167+
"cell_type": "markdown",
168+
"id": "e0108dfc",
169+
"metadata": {
170+
"cq.autogen": "SparseMatrixHermitian.call_graph.md"
171+
},
172+
"source": [
173+
"### Call Graph"
174+
]
175+
},
176+
{
177+
"cell_type": "code",
178+
"execution_count": null,
179+
"id": "87933b2f",
180+
"metadata": {
181+
"cq.autogen": "SparseMatrixHermitian.call_graph.py"
182+
},
183+
"outputs": [],
184+
"source": [
185+
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
186+
"sparse_matrix_symb_hermitian_block_encoding_g, sparse_matrix_symb_hermitian_block_encoding_sigma = sparse_matrix_symb_hermitian_block_encoding.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
187+
"show_call_graph(sparse_matrix_symb_hermitian_block_encoding_g)\n",
188+
"show_counts_sigma(sparse_matrix_symb_hermitian_block_encoding_sigma)"
189+
]
190+
}
191+
],
192+
"metadata": {
193+
"kernelspec": {
194+
"display_name": "Python 3",
195+
"language": "python",
196+
"name": "python3"
197+
},
198+
"language_info": {
199+
"name": "python"
200+
}
201+
},
202+
"nbformat": 4,
203+
"nbformat_minor": 5
204+
}

0 commit comments

Comments
 (0)