-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add qubits to PauliStringPhasor #5565
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
Merged
Merged
Changes from 3 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
a4e977f
Add qubits to PauliStringPhasor
dabacon 9f07b53
Merge branch 'master' into fixphaso
dabacon c3b5bf2
fix gate operation test
dabacon db7ffd1
Update cirq-core/cirq/ops/pauli_string_phasor.py
dabacon c714db1
Update cirq-core/cirq/ops/pauli_string_phasor.py
dabacon dafbf70
Update cirq-core/cirq/ops/pauli_string_phasor.py
dabacon 58b7f4d
Update cirq-core/cirq/ops/pauli_string_phasor.py
dabacon 11a8e00
review comments
dabacon 5517103
Merge branch 'master' into fixphaso
dabacon 0f3637f
Merge branch 'master' into fixphaso
dabacon a7e7cb0
Merge branch 'master' into fixphaso
dabacon e42f8b6
Merge branch 'master' into fixphaso
dabacon 52ca61a
Merge branch 'master' into fixphaso
dabacon faac9e1
Update cirq-core/cirq/ops/pauli_string_phasor.py
dabacon b648751
Update cirq-core/cirq/ops/pauli_string_phasor.py
dabacon 43a0095
review comments
dabacon 118b285
fix nits
dabacon c943d05
Merge branch 'fixphaso' of github.com:dabacon/Cirq into fixphaso
dabacon d65eb71
Merge branch 'master' into fixphaso
dabacon b471857
Merge branch 'master' into fixphaso
dabacon f79e319
fix lint
dabacon a7b98a0
fix
dabacon 798ba80
fix mypy
dabacon e80a822
Merge branch 'master' into fixphaso
dabacon 6cef047
Merge branch 'master' into fixphaso
dabacon File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -12,7 +12,18 @@ | |||||
# See the License for the specific language governing permissions and | ||||||
# limitations under the License. | ||||||
|
||||||
from typing import AbstractSet, cast, Dict, Iterable, Union, TYPE_CHECKING, Sequence, Iterator | ||||||
from typing import ( | ||||||
AbstractSet, | ||||||
cast, | ||||||
Dict, | ||||||
Iterable, | ||||||
Iterator, | ||||||
Optional, | ||||||
Sequence, | ||||||
TYPE_CHECKING, | ||||||
Union, | ||||||
) | ||||||
|
||||||
import numbers | ||||||
|
||||||
import sympy | ||||||
|
@@ -35,16 +46,25 @@ | |||||
|
||||||
@value.value_equality(approximate=True) | ||||||
class PauliStringPhasor(gate_operation.GateOperation): | ||||||
"""An operation that phases the eigenstates of a Pauli string. | ||||||
r"""An operation that phases the eigenstates of a Pauli string. | ||||||
|
||||||
This class takes `PauliString`, which is a sequence of non-identity | ||||||
Pauli operators, potentially with a $\pm 1$ valued coefficient, | ||||||
acting on qubits. | ||||||
|
||||||
The -1 eigenstates of the Pauli string will have their amplitude multiplied | ||||||
by e^(i pi exponent_neg) while +1 eigenstates of the Pauli string will have | ||||||
their amplitude multiplied by e^(i pi exponent_pos). | ||||||
|
||||||
The class also takes a list of qubits, which can be bigger than those | ||||||
provided acted on by `PauliString`. Those extra qubits are assumed to be | ||||||
dabacon marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
acted upon via identity. | ||||||
""" | ||||||
|
||||||
def __init__( | ||||||
self, | ||||||
pauli_string: ps.PauliString, | ||||||
qubits: Optional[Sequence['cirq.Qid']] = None, | ||||||
*, | ||||||
exponent_neg: Union[int, float, sympy.Expr] = 1, | ||||||
exponent_pos: Union[int, float, sympy.Expr] = 0, | ||||||
|
@@ -54,20 +74,36 @@ def __init__( | |||||
Args: | ||||||
pauli_string: The PauliString defining the positive and negative | ||||||
eigenspaces that will be independently phased. | ||||||
qubits: The qubits upon which the PauliStringPhasor acts. This | ||||||
can be different from the qubits of `pauli_string` but if | ||||||
it is not supplied it will use the qubits from `pauli_string`. | ||||||
dabacon marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
The `pauli_string` contains only the non-identity component | ||||||
of the phasor, while the qubits supplied here and not in | ||||||
`pauli_string` are acted upon by identity. The order of | ||||||
these qubits must match the order in `pauli_string`. | ||||||
exponent_neg: How much to phase vectors in the negative eigenspace, | ||||||
in the form of the t in (-1)**t = exp(i pi t). | ||||||
exponent_pos: How much to phase vectors in the positive eigenspace, | ||||||
in the form of the t in (-1)**t = exp(i pi t). | ||||||
|
||||||
Raises: | ||||||
ValueError: If coefficient is not 1 or -1. | ||||||
ValueError: If coefficient is not 1 or -1 or the qubits of | ||||||
`pauli_string` are not a subset of `qubits`. | ||||||
""" | ||||||
if qubits is not None: | ||||||
it = iter(qubits) | ||||||
if any(not any(q0 == q1 for q1 in it) for q0 in pauli_string.qubits): | ||||||
raise ValueError( | ||||||
f"PauliStringPhasor's pauli string qubits ({pauli_string.qubits}) " | ||||||
f"are not a subset of the explicit qubits ({qubits})." | ||||||
dabacon marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
) | ||||||
dabacon marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
gate = PauliStringPhasorGate( | ||||||
pauli_string.dense(pauli_string.qubits), | ||||||
pauli_string.dense(qubits or pauli_string.qubits), | ||||||
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.
Suggested change
|
||||||
exponent_neg=exponent_neg, | ||||||
exponent_pos=exponent_pos, | ||||||
) | ||||||
super().__init__(gate, pauli_string.qubits) | ||||||
super().__init__(gate, qubits or pauli_string.qubits) | ||||||
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.
Suggested change
|
||||||
it = iter(self.qubits) | ||||||
dabacon marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
self._pauli_string = gate.dense_pauli_string.on(*self.qubits) | ||||||
|
||||||
@property | ||||||
|
@@ -96,41 +132,54 @@ def exponent_relative(self) -> Union[int, float, sympy.Expr]: | |||||
return self.gate.exponent_relative | ||||||
|
||||||
def _value_equality_values_(self): | ||||||
return (self.pauli_string, self.exponent_neg, self.exponent_pos) | ||||||
return (self.pauli_string, self.qubits, self.exponent_neg, self.exponent_pos) | ||||||
|
||||||
def equal_up_to_global_phase(self, other): | ||||||
"""Checks equality of two PauliStringPhasors, up to global phase.""" | ||||||
if isinstance(other, PauliStringPhasor): | ||||||
rel1 = self.exponent_relative | ||||||
rel2 = other.exponent_relative | ||||||
return rel1 == rel2 and self.pauli_string == other.pauli_string | ||||||
return ( | ||||||
self.exponent_relative == other.exponent_relative | ||||||
and self.pauli_string == other.pauli_string | ||||||
and self.qubits == other.qubits | ||||||
) | ||||||
return False | ||||||
|
||||||
def map_qubits(self, qubit_map: Dict[raw_types.Qid, raw_types.Qid]): | ||||||
dabacon marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
"""Maps the qubits inside the PauliString.""" | ||||||
return PauliStringPhasor( | ||||||
self.pauli_string.map_qubits(qubit_map), | ||||||
pauli_string=self.pauli_string.map_qubits(qubit_map), | ||||||
qubits=[qubit_map[q] for q in self.qubits], | ||||||
tanujkhattar marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
exponent_neg=self.exponent_neg, | ||||||
exponent_pos=self.exponent_pos, | ||||||
) | ||||||
|
||||||
def can_merge_with(self, op: 'PauliStringPhasor') -> bool: | ||||||
"""Checks whether the underlying PauliStrings can be merged.""" | ||||||
return self.pauli_string.equal_up_to_coefficient(op.pauli_string) | ||||||
return ( | ||||||
self.pauli_string.equal_up_to_coefficient(op.pauli_string) and self.qubits == op.qubits | ||||||
) | ||||||
|
||||||
def merged_with(self, op: 'PauliStringPhasor') -> 'PauliStringPhasor': | ||||||
"""Merges two PauliStringPhasors.""" | ||||||
if not self.can_merge_with(op): | ||||||
raise ValueError(f'Cannot merge operations: {self}, {op}') | ||||||
pp = self.exponent_pos + op.exponent_pos | ||||||
pn = self.exponent_neg + op.exponent_neg | ||||||
return PauliStringPhasor(self.pauli_string, exponent_pos=pp, exponent_neg=pn) | ||||||
return PauliStringPhasor( | ||||||
self.pauli_string, qubits=self.qubits, exponent_pos=pp, exponent_neg=pn | ||||||
) | ||||||
|
||||||
def _circuit_diagram_info_( | ||||||
self, args: 'cirq.CircuitDiagramInfoArgs' | ||||||
) -> 'cirq.CircuitDiagramInfo': | ||||||
qubits = self.qubits if args.known_qubits is None else args.known_qubits | ||||||
syms = tuple(f'[{self.pauli_string[qubit]}]' for qubit in qubits) | ||||||
|
||||||
def sym(qubit): | ||||||
if qubit in self.pauli_string: | ||||||
return f'[{self.pauli_string[qubit]}]' | ||||||
return '[I]' | ||||||
|
||||||
syms = tuple(sym(qubit) for qubit in qubits) | ||||||
return protocols.CircuitDiagramInfo(wire_symbols=syms, exponent=self.exponent_relative) | ||||||
|
||||||
def pass_operations_over( | ||||||
|
@@ -170,6 +219,7 @@ def pass_operations_over( | |||||
def __repr__(self) -> str: | ||||||
return ( | ||||||
f'cirq.PauliStringPhasor({self.pauli_string!r}, ' | ||||||
f'qubits={self.qubits!r}, ' | ||||||
f'exponent_neg={proper_repr(self.exponent_neg)}, ' | ||||||
f'exponent_pos={proper_repr(self.exponent_pos)})' | ||||||
) | ||||||
|
@@ -182,7 +232,9 @@ def __str__(self) -> str: | |||||
return f'({self.pauli_string})**{self.exponent_relative}' | ||||||
|
||||||
def _json_dict_(self): | ||||||
return protocols.obj_to_dict_helper(self, ['pauli_string', 'exponent_neg', 'exponent_pos']) | ||||||
return protocols.obj_to_dict_helper( | ||||||
self, ['pauli_string', 'qubits', 'exponent_neg', 'exponent_pos'] | ||||||
) | ||||||
|
||||||
|
||||||
@value.value_equality(approximate=True) | ||||||
|
@@ -352,6 +404,7 @@ def on(self, *qubits: 'cirq.Qid') -> 'cirq.PauliStringPhasor': | |||||
"""Creates a PauliStringPhasor on the qubits.""" | ||||||
return PauliStringPhasor( | ||||||
self.dense_pauli_string.on(*qubits), | ||||||
qubits=qubits, | ||||||
exponent_pos=self.exponent_pos, | ||||||
exponent_neg=self.exponent_neg, | ||||||
) | ||||||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.