-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add q helper function for constructing common qubit types. #5181
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
Changes from 5 commits
217c8e0
cdcdf61
1ebb3a2
2b3571e
5571c55
47780b1
b280896
e9395c4
06efe99
ef86059
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -291,6 +291,7 @@ | |
ProjectorString, | ||
ProjectorSum, | ||
RandomGateChannel, | ||
q, | ||
qft, | ||
Qid, | ||
QuantumFourierTransformGate, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -308,3 +308,5 @@ | |
) | ||
|
||
from cirq.ops.state_preparation_channel import StatePreparationChannel | ||
|
||
from cirq.ops.util import q |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# Copyright 2022 The Cirq Developers | ||
# | ||
# 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 typing import Optional, overload, TYPE_CHECKING, Union | ||
|
||
if TYPE_CHECKING: | ||
import cirq | ||
|
||
|
||
@overload | ||
def q(x: int) -> 'cirq.LineQubit': | ||
... | ||
|
||
|
||
@overload | ||
def q(x: int, y: int) -> 'cirq.GridQubit': | ||
... | ||
|
||
|
||
@overload | ||
def q(x: str) -> 'cirq.NamedQubit': | ||
... | ||
|
||
|
||
def q( | ||
x: Union[int, str], y: Optional[int] = None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we change the signature to accept There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I originally tried that but mypy wasn't happy with using
I haven't been able to figure out a way around this. However, from my perspective adding additional signatures in the future, as long as we keep these signatures working and can make mypy happy, would be a backwards-compatible change. One thing that's a bit unfortunate is I'd like to make these "positional-only" params so you can't do, say There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Success! The right incantation was to prefix arg names with double underscore in the overload definitions and then mypy treats them as positional-only and allows using |
||
) -> Union['cirq.LineQubit', 'cirq.GridQubit', 'cirq.NamedQubit']: | ||
"""Constructs a qubit id of the appropriate type based on args. | ||
|
||
This is shorthand for constructing qubit ids of common types: | ||
>>> cirq.q(1) == cirq.LineQubit(1) | ||
>>> cirq.q(1, 2) == cirq.GridQubit(1, 2) | ||
>>> cirq.q("foo") == cirq.NamedQubit("foo") | ||
|
||
Args: | ||
x: First arg. | ||
y: Second arg. | ||
|
||
Returns: | ||
cirq.LineQubit if called with one integer arg. | ||
cirq.GridQubit if called with two integer args. | ||
cirq.NamedQubit if called with one string arg. | ||
|
||
Raises: | ||
ValueError: if called with invalid arguments. | ||
""" | ||
import cirq # avoid circular import | ||
|
||
if y is None: | ||
if isinstance(x, int): | ||
return cirq.LineQubit(x) | ||
elif isinstance(x, str): | ||
return cirq.NamedQubit(x) | ||
else: | ||
if isinstance(x, int) and isinstance(y, int): | ||
return cirq.GridQubit(x, y) | ||
raise ValueError(f"Could not construct qubit: args={(x, y)}") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Copyright 2022 The Cirq Developers | ||
# | ||
# 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. | ||
|
||
import pytest | ||
|
||
import cirq | ||
|
||
|
||
def test_q() -> None: | ||
assert cirq.q(0) == cirq.LineQubit(0) | ||
assert cirq.q(1, 2) == cirq.GridQubit(1, 2) | ||
assert cirq.q("foo") == cirq.NamedQubit("foo") | ||
|
||
|
||
def test_q_invalid() -> None: | ||
# Ignore static type errors so we can test runtime typechecks. | ||
with pytest.raises(ValueError): | ||
cirq.q([1, 2, 3]) # type: ignore[call-overload] | ||
with pytest.raises(ValueError): | ||
cirq.q(1, "foo") # type: ignore[call-overload] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Can we give a better name to this module? util is too generic and it'll be hard to guess what's inside it by looking at the name. Maybe
ops/qid_util.py
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.