Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve generic select documentation #105

Merged
merged 8 commits into from
Nov 7, 2022
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
39 changes: 21 additions & 18 deletions cirq_qubitization/generic_select.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"cq.autogen": "title_cell"
},
"source": [
"# Generic Select"
"# Generic Select\n",
"\n",
"Gates for applying generic selected unitaries."
]
},
{
Expand Down Expand Up @@ -35,12 +37,21 @@
},
"source": [
"## `GenericSelect`\n",
"Gate that implements SELECT for a Hamiltonian expressed as an LCU.\n",
"A SELECT gate for selecting and applying operators from an array of `PauliString`s.\n",
"\n",
"$$\n",
"\\mathrm{SELECT} = \\sum_{l}|l \\rangle \\langle l| \\otimes U_l\n",
"$$\n",
"\n",
"Where $U_l$ is a member of the Pauli group.\n",
"\n",
"Recall: SELECT = \\sum_{l}|l><l| \\otimes U_{l}\n",
"This gate uses the unary iteration scheme to apply `select_unitaries[selection]` to `target`\n",
"controlled on the single-bit `control` register.\n",
"\n",
"The first log(L) qubits is the index register and the last M qubits are the system\n",
"register U_{l} is applied to"
"#### Parameters\n",
" - `selection_bitsize`: The size of the indexing `select` register. This should be at least `log2(len(select_unitaries))`\n",
" - `target_bitsize`: The size of the `target` register.\n",
" - `select_unitaries`: List of `DensePauliString`s to apply to the `target` register. Each dense pauli string must contain `target_bitsize` terms.\n"
]
},
{
Expand All @@ -53,21 +64,13 @@
"outputs": [],
"source": [
"from cirq_qubitization.generic_select import GenericSelect\n",
"from cirq_qubitization.generic_select_test import get_1d_ising_hamiltonian\n",
"\n",
"num_sites = 4\n",
"target_bitsize = num_sites\n",
"num_select_unitaries = 2 * num_sites\n",
"\n",
"# PBC Ising in 1-D has num_sites ZZ operations and num_sites X operations.\n",
"# Thus, 2 * num_sites Pauli ops\n",
"selection_bitsize = int(np.ceil(np.log(num_select_unitaries)))\n",
"\n",
"target = cirq.LineQubit.range(target_bitsize) # placeholder\n",
"ham = get_1d_ising_hamiltonian(target, 1, 1)\n",
"dense_ham = [tt.dense(target) for tt in ham]\n",
"target_bitsize = 4\n",
"us = ['XIXI', 'YIYI', 'ZZZZ', 'ZXYZ']\n",
"us = [cirq.DensePauliString(u) for u in us]\n",
"selection_bitsize = int(np.ceil(np.log2(len(us))))\n",
"g = cq_testing.GateHelper(\n",
" GenericSelect(selection_bitsize, target_bitsize, select_unitaries=dense_ham)\n",
" GenericSelect(selection_bitsize, target_bitsize, select_unitaries=us)\n",
")\n",
"\n",
"display_gate_and_compilation(g, vertical=True)"
Expand Down
31 changes: 16 additions & 15 deletions cirq_qubitization/generic_select.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Gates for applying generic selected unitaries."""
from typing import Sequence, List, Tuple
from functools import cached_property
import cirq
Expand All @@ -6,12 +7,23 @@


class GenericSelect(unary_iteration.UnaryIterationGate):
r"""Gate that implements SELECT for a Hamiltonian expressed as an LCU.
r"""A SELECT gate for selecting and applying operators from an array of `PauliString`s.

Recall: SELECT = \sum_{l}|l><l| \otimes U_{l}
$$
\mathrm{SELECT} = \sum_{l}|l \rangle \langle l| \otimes U_l
$$

The first log(L) qubits is the index register and the last M qubits are the system
register U_{l} is applied to
Where $U_l$ is a member of the Pauli group.

This gate uses the unary iteration scheme to apply `select_unitaries[selection]` to `target`
controlled on the single-bit `control` register.
tanujkhattar marked this conversation as resolved.
Show resolved Hide resolved

Args:
selection_bitsize: The size of the indexing `select` register. This should be at least
`log2(len(select_unitaries))`
target_bitsize: The size of the `target` register.
select_unitaries: List of `DensePauliString`s to apply to the `target` register. Each
dense pauli string must contain `target_bitsize` terms.
"""

def __init__(
Expand All @@ -20,17 +32,6 @@ def __init__(
target_bitsize: int,
select_unitaries: List[cirq.DensePauliString],
):
"""An implementation of the SELECT unitary using the `UnaryIterationGate`

Args:
selection_bitsize: Number of qubits needed for select register. This is ceil(log2(len(select_unitaries)))
target_bitsize: number of qubits in the target register.
select_unitaries: List of DensePauliString's to apply to target register. Each dense
pauli string must contain `target_bitsize` terms.

Raises:
ValueError if any(len(dps) != target_bitsize for dps in select_unitaries).
"""
if any(len(dps) != target_bitsize for dps in select_unitaries):
raise ValueError(
f"Each dense pauli string in `select_unitaries` should contain "
Expand Down
18 changes: 5 additions & 13 deletions cirq_qubitization/jupyter_autogen_factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,12 @@ def _make_MultiTargetCSwapApprox():

def _make_GenericSelect():
from cirq_qubitization.generic_select import GenericSelect
from cirq_qubitization.generic_select_test import get_1d_ising_hamiltonian

num_sites = 4
target_bitsize = num_sites
num_select_unitaries = 2 * num_sites

# PBC Ising in 1-D has num_sites ZZ operations and num_sites X operations.
# Thus, 2 * num_sites Pauli ops
selection_bitsize = int(np.ceil(np.log(num_select_unitaries)))

target = cirq.LineQubit.range(target_bitsize) # placeholder
ham = get_1d_ising_hamiltonian(target, 1, 1)
dense_ham = [tt.dense(target) for tt in ham]
return GenericSelect(selection_bitsize, target_bitsize, select_unitaries=dense_ham)
target_bitsize = 4
us = ['XIXI', 'YIYI', 'ZZZZ', 'ZXYZ']
us = [cirq.DensePauliString(u) for u in us]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Reusing same variable would lead to a mypy error?

Suggested change
us = [cirq.DensePauliString(u) for u in us]
us_dps = [cirq.DensePauliString(u) for u in us]

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

xref: quantumlib/Cirq#3832

  • we can configure mypy to be fine with this
  • it will probably be the default anyways
  • I think it's way better to re-use existing name than having hungarian variable names and the previous version still hanging around that you could accidentally use instead.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sounds good, maybe open an issue to make sure we update the mypy config to add the flag so it doesn't complain. Right now, the config is basically copied from Cirq.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll add to #30

selection_bitsize = int(np.ceil(np.log2(len(us))))
return GenericSelect(selection_bitsize, target_bitsize, select_unitaries=us)


def _make_GenericSubPrepare():
Expand Down