Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
28 changes: 14 additions & 14 deletions qualtran/bloqs/data_loading/qroam_clean.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"## Overview\n",
"The action of a QROM can be described as\n",
"$$\n",
" \\text{QROM}_{s_1, s_2, \\dots, s_K}^{d_1, d_2, \\dots, d_L}\n",
" \\mathrm{QROM}_{s_1, s_2, \\dots, s_K}^{d_1, d_2, \\dots, d_L}\n",
" |s_1\\rangle |s_2\\rangle \\dots |s_K\\rangle\n",
" |0\\rangle^{\\otimes b_1} |0\\rangle^{\\otimes b_2} \\dots |0\\rangle^{\\otimes b_L}\n",
" \\rightarrow\n",
Expand Down Expand Up @@ -72,8 +72,8 @@
"\n",
"1. Number of selection registers (eg: $i$, $j$) and their iteration lengths (eg: $N$, $M$).\n",
"2. Number of target registers, their quantum datatype and shape.\n",
" - Number of target registers: One for each classical dataset to load (eg: $\\text{data}[0]$\n",
" and $\\text{data}[1]$)\n",
" - Number of target registers: One for each classical dataset to load (eg: $\\mathrm{data}[0]$\n",
" and $\\mathrm{data}[1]$)\n",
" - QDType of target registers: Depends on `dtype` of the $i$'th classical dataset\n",
" - Shape of target registers: Depends on shape of classical data (eg: $(P, Q)$ and\n",
" $(R, S, T)$ above)\n",
Expand All @@ -87,10 +87,10 @@
"symbolic bloqs). The shape of the dataset is a union of the selection shape and target shape,\n",
"s.t.\n",
"$$\n",
" \\text{data[i].shape} = \\text{selection\\_shape} + \\text{target\\_shape[i]}\n",
" \\mathrm{data[i].shape} = \\mathrm{selection\\_shape} + \\mathrm{target\\_shape[i]}\n",
"$$\n",
"\n",
"Note that the $\\text{selection\\_shape}$ should be same across all classical datasets to be\n",
"Note that the $\\mathrm{selection\\_shape}$ should be same across all classical datasets to be\n",
"loaded and correspond to a tuple of iteration lengths of selection indices (i.e. $(N, M)$\n",
"in the example above).\n",
"\n",
Expand All @@ -100,35 +100,35 @@
"### Number of selection registers and their iteration lengths\n",
"As describe in the previous section, the number of selection registers and their iteration\n",
"lengths can be inferred from the shape of the classical dataset. All classical datasets\n",
"to be loaded must have the same $\\text{selection\\_shape}$, which is a tuple of iteration\n",
"to be loaded must have the same $\\mathrm{selection\\_shape}$, which is a tuple of iteration\n",
"lengths over each dimension of the dataset (i.e. the range for each nested for-loop).\n",
"\n",
"In order to load a data set with $\\text{selection\\_shape} == (P, Q, R, S)$ the QROM bloq\n",
"In order to load a data set with $\\mathrm{selection\\_shape} == (P, Q, R, S)$ the QROM bloq\n",
"needs four selection registers with bitsizes $(p, q, r, s)$ where each of\n",
"$p,q,r,s \\geq \\log_2{P}, \\log_2{Q}, \\log_2{R}, \\log_2{S}$.\n",
"\n",
"In general, to load $K$ dimensional data, we use $K$ named selection registers\n",
"$(\\text{selection}_0, \\text{selection}_1, ..., \\text{selection}_k)$ to index and\n",
"$(\\mathrm{selection}_0, \\mathrm{selection}_1, ..., \\mathrm{selection}_k)$ to index and\n",
"load the data. For the $i$'th selection register, its size is configured using\n",
"attribute $\\text{selection\\_bitsizes[i]}$ and the iteration range is configued\n",
"using $\\text{data\\_or\\_shape[0].shape[i]}$.\n",
"attribute $\\mathrm{selection\\_bitsizes[i]}$ and the iteration range is configued\n",
"using $\\mathrm{data\\_or\\_shape[0].shape[i]}$.\n",
"\n",
"### Number of target registers, their quantum datatype and shape\n",
"QROM bloq uses one target register for each entry corresponding to classical dataset in the\n",
"tuple `data_or_shape`. Thus, to load $L$ classical datsets, we use $L$ names target registers\n",
"$(\\text{target}_0, \\text{target}_1, ..., \\text{target}_L)$\n",
"$(\\mathrm{target}_0, \\mathrm{target}_1, ..., \\mathrm{target}_L)$\n",
"\n",
"Each named target register has a bitsize $b_{i}=\\text{target\\_bitsizes[i]}$ that represents\n",
"Each named target register has a bitsize $b_{i}=\\mathrm{target\\_bitsizes[i]}$ that represents\n",
"the size of the register and depends upon the maximum value of individual elements in the\n",
"$i$'th classical dataset.\n",
"\n",
"Each named target register has a shape that can be configured using attribute\n",
"$\\text{target\\_shape[i]}$ that represents the number of target registers if the output to load\n",
"$\\mathrm{target\\_shape[i]}$ that represents the number of target registers if the output to load\n",
"is multidimensional.\n",
"\n",
"#### Parameters\n",
" - `data_or_shape`: List of numpy ndarrays specifying the data to load. If the length of this list ($L$) is greater than one then we use the same selection indices to load each dataset. The shape of a classical dataset is a concatenation of selection_shape and target_shape[i]; i.e. `data_or_shape[i].shape = selection_shape + target_shape[i]`. Thus, each data set is required to have the same selection shape $(S_1, S_2, ..., S_K)$ and can have a different target shape given by `target_shapes[i]`. For symbolic QROMs, pass a list of `Shaped` objects instead with shape $(S_1, S_2, ..., S_K) + target_shape[i]$.\n",
" - `selection_bitsizes`: The number of bits used to represent each selection register corresponding to the size of each dimension of the selection_shape $(S_1, S_2, ..., S_K)$. Should be the same length as the selection shape of each of the datasets and $2**\\text{selection\\_bitsizes[i]} >= S_i$\n",
" - `selection_bitsizes`: The number of bits used to represent each selection register corresponding to the size of each dimension of the selection_shape $(S_1, S_2, ..., S_K)$. Should be the same length as the selection shape of each of the datasets and $2**\\mathrm{selection\\_bitsizes[i]} >= S_i$\n",
" - `target_shapes`: Shape of target registers for each classical dataset to be loaded. Must be consistent with `data_or_shape` s.t. `len(data_or_shape) == len(target_shapes)` and `data_or_shape[-len(target_shapes[i]):] == target_shapes[i]`.\n",
" - `target_bitsizes`: Bitsize (or qdtype) of the target registers for each classical dataset to be loaded. This can be deduced from the maximum element of each of the datasets. Must be consistent with `data_or_shape` s.t. `len(data_or_shape) == len(target_bitsizes)` and `target_bitsizes[i] >= max(data[i]).bitsize`.\n",
" - `num_controls`: The number of controls to instanstiate a controlled version of this bloq.\n"
Expand Down
38 changes: 19 additions & 19 deletions qualtran/bloqs/data_loading/qrom.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"## Overview\n",
"The action of a QROM can be described as\n",
"$$\n",
" \\text{QROM}_{s_1, s_2, \\dots, s_K}^{d_1, d_2, \\dots, d_L}\n",
" \\mathrm{QROM}_{s_1, s_2, \\dots, s_K}^{d_1, d_2, \\dots, d_L}\n",
" |s_1\\rangle |s_2\\rangle \\dots |s_K\\rangle\n",
" |0\\rangle^{\\otimes b_1} |0\\rangle^{\\otimes b_2} \\dots |0\\rangle^{\\otimes b_L}\n",
" \\rightarrow\n",
Expand Down Expand Up @@ -74,8 +74,8 @@
"\n",
"1. Number of selection registers (eg: $i$, $j$) and their iteration lengths (eg: $N$, $M$).\n",
"2. Number of target registers, their quantum datatype and shape.\n",
" - Number of target registers: One for each classical dataset to load (eg: $\\text{data}[0]$\n",
" and $\\text{data}[1]$)\n",
" - Number of target registers: One for each classical dataset to load (eg: $\\mathrm{data}[0]$\n",
" and $\\mathrm{data}[1]$)\n",
" - QDType of target registers: Depends on `dtype` of the $i$'th classical dataset\n",
" - Shape of target registers: Depends on shape of classical data (eg: $(P, Q)$ and\n",
" $(R, S, T)$ above)\n",
Expand All @@ -89,10 +89,10 @@
"symbolic bloqs). The shape of the dataset is a union of the selection shape and target shape,\n",
"s.t.\n",
"$$\n",
" \\text{data[i].shape} = \\text{selection\\_shape} + \\text{target\\_shape[i]}\n",
" \\mathrm{data[i].shape} = \\mathrm{selection\\_shape} + \\mathrm{target\\_shape[i]}\n",
"$$\n",
"\n",
"Note that the $\\text{selection\\_shape}$ should be same across all classical datasets to be\n",
"Note that the $\\mathrm{selection\\_shape}$ should be same across all classical datasets to be\n",
"loaded and correspond to a tuple of iteration lengths of selection indices (i.e. $(N, M)$\n",
"in the example above).\n",
"\n",
Expand All @@ -102,35 +102,35 @@
"### Number of selection registers and their iteration lengths\n",
"As describe in the previous section, the number of selection registers and their iteration\n",
"lengths can be inferred from the shape of the classical dataset. All classical datasets\n",
"to be loaded must have the same $\\text{selection\\_shape}$, which is a tuple of iteration\n",
"to be loaded must have the same $\\mathrm{selection\\_shape}$, which is a tuple of iteration\n",
"lengths over each dimension of the dataset (i.e. the range for each nested for-loop).\n",
"\n",
"In order to load a data set with $\\text{selection\\_shape} == (P, Q, R, S)$ the QROM bloq\n",
"In order to load a data set with $\\mathrm{selection\\_shape} == (P, Q, R, S)$ the QROM bloq\n",
"needs four selection registers with bitsizes $(p, q, r, s)$ where each of\n",
"$p,q,r,s \\geq \\log_2{P}, \\log_2{Q}, \\log_2{R}, \\log_2{S}$.\n",
"\n",
"In general, to load $K$ dimensional data, we use $K$ named selection registers\n",
"$(\\text{selection}_0, \\text{selection}_1, ..., \\text{selection}_k)$ to index and\n",
"$(\\mathrm{selection}_0, \\mathrm{selection}_1, ..., \\mathrm{selection}_k)$ to index and\n",
"load the data. For the $i$'th selection register, its size is configured using\n",
"attribute $\\text{selection\\_bitsizes[i]}$ and the iteration range is configued\n",
"using $\\text{data\\_or\\_shape[0].shape[i]}$.\n",
"attribute $\\mathrm{selection\\_bitsizes[i]}$ and the iteration range is configued\n",
"using $\\mathrm{data\\_or\\_shape[0].shape[i]}$.\n",
"\n",
"### Number of target registers, their quantum datatype and shape\n",
"QROM bloq uses one target register for each entry corresponding to classical dataset in the\n",
"tuple `data_or_shape`. Thus, to load $L$ classical datsets, we use $L$ names target registers\n",
"$(\\text{target}_0, \\text{target}_1, ..., \\text{target}_L)$\n",
"$(\\mathrm{target}_0, \\mathrm{target}_1, ..., \\mathrm{target}_L)$\n",
"\n",
"Each named target register has a bitsize $b_{i}=\\text{target\\_bitsizes[i]}$ that represents\n",
"Each named target register has a bitsize $b_{i}=\\mathrm{target\\_bitsizes[i]}$ that represents\n",
"the size of the register and depends upon the maximum value of individual elements in the\n",
"$i$'th classical dataset.\n",
"\n",
"Each named target register has a shape that can be configured using attribute\n",
"$\\text{target\\_shape[i]}$ that represents the number of target registers if the output to load\n",
"$\\mathrm{target\\_shape[i]}$ that represents the number of target registers if the output to load\n",
"is multidimensional.\n",
"\n",
"#### Parameters\n",
" - `data_or_shape`: List of numpy ndarrays specifying the data to load. If the length of this list ($L$) is greater than one then we use the same selection indices to load each dataset. The shape of a classical dataset is a concatenation of selection_shape and target_shape[i]; i.e. `data_or_shape[i].shape = selection_shape + target_shape[i]`. Thus, each data set is required to have the same selection shape $(S_1, S_2, ..., S_K)$ and can have a different target shape given by `target_shapes[i]`. For symbolic QROMs, pass a list of `Shaped` objects instead with shape $(S_1, S_2, ..., S_K) + target_shape[i]$.\n",
" - `selection_bitsizes`: The number of bits used to represent each selection register corresponding to the size of each dimension of the selection_shape $(S_1, S_2, ..., S_K)$. Should be the same length as the selection shape of each of the datasets and $2**\\text{selection\\_bitsizes[i]} >= S_i$\n",
" - `selection_bitsizes`: The number of bits used to represent each selection register corresponding to the size of each dimension of the selection_shape $(S_1, S_2, ..., S_K)$. Should be the same length as the selection shape of each of the datasets and $2**\\mathrm{selection\\_bitsizes[i]} >= S_i$\n",
" - `target_shapes`: Shape of target registers for each classical dataset to be loaded. Must be consistent with `data_or_shape` s.t. `len(data_or_shape) == len(target_shapes)` and `data_or_shape[-len(target_shapes[i]):] == target_shapes[i]`.\n",
" - `target_bitsizes`: Bitsize (or qdtype) of the target registers for each classical dataset to be loaded. This can be deduced from the maximum element of each of the datasets. Must be consistent with `data_or_shape` s.t. `len(data_or_shape) == len(target_bitsizes)` and `target_bitsizes[i] >= max(data[i]).bitsize`.\n",
" - `num_controls`: The number of controls to instanstiate a controlled version of this bloq.\n"
Expand All @@ -155,15 +155,15 @@
"\n",
"### T / Toffoli cost\n",
"The T/Toffoli cost of this QROM scales linearly with the product of iteration lengths over\n",
"all dimensions (i.e. $\\mathcal{O}(\\mathrm{np.prod(\\text{selection\\_shape})}$).\n",
"all dimensions (i.e. $\\mathcal{O}(\\mathrm{np.prod(\\mathrm{selection\\_shape})}$).\n",
"\n",
"### Clifford Cost\n",
"To load a classical dataset into a target register of bitsize $b$ and shape\n",
"$\\text{target\\_shape}$, the clifford cost of this QROM scales as\n",
"$\\mathcal{O}(b \\cdot \\text{np.prod(selection\\_shape+target\\_shape)})\n",
"=\\mathcal{O}(b \\cdot \\text{np.prod(data.shape)})$. This is because we need $\\mathcal{O}(b)$\n",
"$\\mathrm{target\\_shape}$, the clifford cost of this QROM scales as\n",
"$\\mathcal{O}(b \\cdot \\mathrm{np.prod(selection\\_shape+target\\_shape)})\n",
"=\\mathcal{O}(b \\cdot \\mathrm{np.prod(data.shape)})$. This is because we need $\\mathcal{O}(b)$\n",
"CNOT gates to load 1 classical data element in the target register and for each of the\n",
"$\\text{np.prod(selection\\_shape)}$ selection indices, we have $\\text{np.prod(target\\_shape)}$\n",
"$\\mathrm{np.prod(selection\\_shape)}$ selection indices, we have $\\mathrm{np.prod(target\\_shape)}$\n",
Comment on lines +158 to +166

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The LaTeX expressions in the cost section are malformed. Specifically:

  1. \mathrm is a command that expects its argument in curly braces {...}, not parentheses (...). Using \mathrm(...) only applies the font to the opening parenthesis.
  2. There are mismatched parentheses in the \mathcal{O}(...) expressions (e.g., line 158 and 163 are missing closing parentheses).
  3. The source file qrom.py, from which this section is autogenerated, has not been updated in this PR. Manual changes here will be lost upon the next documentation build. Please update qrom.py and regenerate the notebooks.
Suggested change
"all dimensions (i.e. $\\mathcal{O}(\\mathrm{np.prod(\\mathrm{selection\\_shape})}$).\n",
"\n",
"### Clifford Cost\n",
"To load a classical dataset into a target register of bitsize $b$ and shape\n",
"$\\text{target\\_shape}$, the clifford cost of this QROM scales as\n",
"$\\mathcal{O}(b \\cdot \\text{np.prod(selection\\_shape+target\\_shape)})\n",
"=\\mathcal{O}(b \\cdot \\text{np.prod(data.shape)})$. This is because we need $\\mathcal{O}(b)$\n",
"$\\mathrm{target\\_shape}$, the clifford cost of this QROM scales as\n",
"$\\mathcal{O}(b \\cdot \\mathrm{np.prod(selection\\_shape+target\\_shape)})\n",
"=\\mathcal{O}(b \\cdot \\mathrm{np.prod(data.shape)})$. This is because we need $\\mathcal{O}(b)$\n",
"CNOT gates to load 1 classical data element in the target register and for each of the\n",
"$\\text{np.prod(selection\\_shape)}$ selection indices, we have $\\text{np.prod(target\\_shape)}$\n",
"$\\mathrm{np.prod(selection\\_shape)}$ selection indices, we have $\\mathrm{np.prod(target\\_shape)}$\n",
"all dimensions (i.e. $\\mathcal{O}(\\mathrm{np.prod}(\\mathrm{selection\\_shape}))$).\n",
"\n",
"### Clifford Cost\n",
"To load a classical dataset into a target register of bitsize $b$ and shape\n",
"$\\mathrm{target\\_shape}$, the clifford cost of this QROM scales as\n",
"$\\mathcal{O}(b \\cdot \\mathrm{np.prod}(\\mathrm{selection\\_shape}+\\mathrm{target\\_shape}))$\n",
"$=\\mathcal{O}(b \\cdot \\mathrm{np.prod}(\\mathrm{data.shape}))$. This is because we need $\\mathcal{O}(b)$\n",
"CNOT gates to load 1 classical data element in the target register and for each of the\n",
"$\\mathrm{np.prod}(\\mathrm{selection\\_shape})$ selection indices, we have $\\mathrm{np.prod}(\\mathrm{target\\_shape})$\n"

"such data elements to load.\n",
"\n",
"### Ancilla cost\n",
Expand Down
10 changes: 5 additions & 5 deletions qualtran/bloqs/data_loading/qrom.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ class QROM(QROMBase, UnaryIterationGate): # type: ignore[misc]

### T / Toffoli cost
The T/Toffoli cost of this QROM scales linearly with the product of iteration lengths over
all dimensions (i.e. $\mathcal{O}(\mathrm{np.prod(\text{selection\_shape})}$).
all dimensions (i.e. $\mathcal{O}(\mathrm{np.prod(\mathrm{selection\_shape})}$).

### Clifford Cost
To load a classical dataset into a target register of bitsize $b$ and shape
$\text{target\_shape}$, the clifford cost of this QROM scales as
$\mathcal{O}(b \cdot \text{np.prod(selection\_shape+target\_shape)})
=\mathcal{O}(b \cdot \text{np.prod(data.shape)})$. This is because we need $\mathcal{O}(b)$
$\mathrm{target\_shape}$, the clifford cost of this QROM scales as
$\mathcal{O}(b \cdot \mathrm{np.prod(selection\_shape+target\_shape)})
=\mathcal{O}(b \cdot \mathrm{np.prod(data.shape)})$. This is because we need $\mathcal{O}(b)$
CNOT gates to load 1 classical data element in the target register and for each of the
$\text{np.prod(selection\_shape)}$ selection indices, we have $\text{np.prod(target\_shape)}$
$\mathrm{np.prod(selection\_shape)}$ selection indices, we have $\mathrm{np.prod(target\_shape)}$
such data elements to load.

### Ancilla cost
Expand Down
Loading
Loading