-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* move `SU2RotationGate` to `basic_gates/` * add cirq_op and wire_symbol * add bloq_example * add tensor * add more bloq examples * add autotest, tensor test * support global shift, verify unitaries for examples * comment: can't use `lambda` for var name * add `from_matrix` * `_unitary_` + test * test T complexity * eps * support parameterized * regenerate notebook * use GlobalPhase bloq * 2024 * fix TComplexity for `cirq.GlobalPhaseGate` and `cirq.global_phase_operation` * test call graph * code cleanup
- Loading branch information
Showing
12 changed files
with
488 additions
and
69 deletions.
There are no files selected for viewing
This file contains 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 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 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 |
---|---|---|
@@ -0,0 +1,181 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "d6d914da", | ||
"metadata": { | ||
"cq.autogen": "title_cell" | ||
}, | ||
"source": [ | ||
"# SU2 Rotation" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "ded96bc8", | ||
"metadata": { | ||
"cq.autogen": "top_imports" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran import Bloq, CompositeBloq, BloqBuilder, Signature, Register\n", | ||
"from qualtran import QBit, QInt, QUInt, QAny\n", | ||
"from qualtran.drawing import show_bloq, show_call_graph, show_counts_sigma\n", | ||
"from typing import *\n", | ||
"import numpy as np\n", | ||
"import sympy\n", | ||
"import cirq" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "4b2a9c14", | ||
"metadata": { | ||
"cq.autogen": "SU2RotationGate.bloq_doc.md" | ||
}, | ||
"source": [ | ||
"## `SU2RotationGate`\n", | ||
"Implements an arbitrary SU(2) rotation.\n", | ||
"\n", | ||
"The rotation is represented by the matrix:\n", | ||
"\n", | ||
"$$\n", | ||
" e^{i \\alpha}\n", | ||
" \\begin{pmatrix}\n", | ||
" e^{i(\\lambda + \\phi)} \\cos(\\theta) & e^{i\\phi} \\sin(\\theta) \\\\\n", | ||
" e^{i\\lambda} \\sin(\\theta) & - \\cos(\\theta)\n", | ||
" \\end{pmatrix}\n", | ||
"$$\n", | ||
"\n", | ||
"#### Parameters\n", | ||
" - `theta`: rotation angle $\\theta$ in the above matrix.\n", | ||
" - `phi`: phase angle $\\phi$ in the above matrix.\n", | ||
" - `lambd`: phase angle $\\lambda$ in the above matrix.\n", | ||
" - `global_shift`: phase angle $\\alpha$, i.e. apply a global phase shift of $e^{i \\alpha}$. \n", | ||
"\n", | ||
"#### References\n", | ||
" - [Generalized Quantum Signal Processing](https://arxiv.org/abs/2308.01501). Motlagh and Wiebe. (2023). Equation 7.\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "950a1fe9", | ||
"metadata": { | ||
"cq.autogen": "SU2RotationGate.bloq_doc.py" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran.bloqs.basic_gates import SU2RotationGate" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "26277091", | ||
"metadata": { | ||
"cq.autogen": "SU2RotationGate.example_instances.md" | ||
}, | ||
"source": [ | ||
"### Example Instances" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "5d165eae", | ||
"metadata": { | ||
"cq.autogen": "SU2RotationGate.su2_rotation_gate" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"su2_rotation_gate = SU2RotationGate(np.pi / 4, np.pi / 2, np.pi / 2)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "6b034a9b", | ||
"metadata": { | ||
"cq.autogen": "SU2RotationGate.hadamard" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"hadamard = SU2RotationGate(np.pi / 4, 0, 0)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "baa38dac", | ||
"metadata": { | ||
"cq.autogen": "SU2RotationGate.t_gate" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"t_gate = SU2RotationGate(0, 3 * np.pi / 4, 0, -3 * np.pi / 4)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "e85d6f3f", | ||
"metadata": { | ||
"cq.autogen": "SU2RotationGate.graphical_signature.md" | ||
}, | ||
"source": [ | ||
"#### Graphical Signature" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "1469a240", | ||
"metadata": { | ||
"cq.autogen": "SU2RotationGate.graphical_signature.py" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran.drawing import show_bloqs\n", | ||
"show_bloqs([su2_rotation_gate, hadamard, t_gate],\n", | ||
" ['`su2_rotation_gate`', '`hadamard`', '`t_gate`'])" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "eb5742c2", | ||
"metadata": { | ||
"cq.autogen": "SU2RotationGate.call_graph.md" | ||
}, | ||
"source": [ | ||
"### Call Graph" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "1198abe9", | ||
"metadata": { | ||
"cq.autogen": "SU2RotationGate.call_graph.py" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran.resource_counting.generalizers import ignore_split_join\n", | ||
"su2_rotation_gate_g, su2_rotation_gate_sigma = su2_rotation_gate.call_graph(max_depth=1, generalizer=ignore_split_join)\n", | ||
"show_call_graph(su2_rotation_gate_g)\n", | ||
"show_counts_sigma(su2_rotation_gate_sigma)" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"name": "python" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,170 @@ | ||
# Copyright 2024 Google LLC | ||
# | ||
# 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 functools import cached_property | ||
from typing import Any, Dict, TYPE_CHECKING | ||
|
||
import cirq | ||
import numpy as np | ||
import sympy | ||
from attrs import frozen | ||
from numpy.typing import NDArray | ||
|
||
from qualtran import bloq_example, BloqDocSpec, GateWithRegisters, Signature | ||
from qualtran.bloqs.basic_gates import GlobalPhase, Ry, ZPowGate | ||
from qualtran.cirq_interop.t_complexity_protocol import TComplexity | ||
from qualtran.drawing import TextBox | ||
|
||
if TYPE_CHECKING: | ||
import quimb.tensor as qtn | ||
|
||
from qualtran import BloqBuilder, Soquet, SoquetT | ||
from qualtran.drawing import WireSymbol | ||
|
||
|
||
@frozen | ||
class SU2RotationGate(GateWithRegisters): | ||
r"""Implements an arbitrary SU(2) rotation. | ||
The rotation is represented by the matrix: | ||
$$ | ||
e^{i \alpha} | ||
\begin{pmatrix} | ||
e^{i(\lambda + \phi)} \cos(\theta) & e^{i\phi} \sin(\theta) \\ | ||
e^{i\lambda} \sin(\theta) & - \cos(\theta) | ||
\end{pmatrix} | ||
$$ | ||
Args: | ||
theta: rotation angle $\theta$ in the above matrix. | ||
phi: phase angle $\phi$ in the above matrix. | ||
lambd: phase angle $\lambda$ in the above matrix. | ||
global_shift: phase angle $\alpha$, i.e. apply a global phase shift of $e^{i \alpha}$. | ||
References: | ||
[Generalized Quantum Signal Processing](https://arxiv.org/abs/2308.01501) | ||
Motlagh and Wiebe. (2023). Equation 7. | ||
""" | ||
|
||
theta: float | ||
phi: float | ||
lambd: float # cannot use `lambda` as it is a python keyword | ||
global_shift: float = 0 | ||
eps: float = 1e-11 | ||
|
||
@cached_property | ||
def signature(self) -> Signature: | ||
return Signature.build(q=1) | ||
|
||
@cached_property | ||
def rotation_matrix(self) -> NDArray[np.complex_]: | ||
return np.exp(1j * self.global_shift) * np.array( | ||
[ | ||
[ | ||
np.exp(1j * (self.lambd + self.phi)) * np.cos(self.theta), | ||
np.exp(1j * self.phi) * np.sin(self.theta), | ||
], | ||
[np.exp(1j * self.lambd) * np.sin(self.theta), -np.cos(self.theta)], | ||
] | ||
) | ||
|
||
@staticmethod | ||
def from_matrix(mat: NDArray[np.complex_]) -> 'SU2RotationGate': | ||
theta = np.arctan2(np.abs(mat[1, 0]), np.abs(mat[0, 0])) | ||
if np.isclose(np.cos(theta), 0): | ||
alpha = 0 | ||
phi = np.angle(mat[0, 1] / np.sin(theta)) | ||
lambd = np.angle(mat[1, 0] / np.sin(theta)) | ||
else: | ||
alpha = np.angle(-mat[1, 1] / np.cos(theta)) | ||
if np.isclose(np.sin(theta), 0): | ||
phi = np.angle(mat[0, 0] / np.cos(theta) * np.exp(-1j * alpha)) | ||
lambd = 0 | ||
else: | ||
phi = np.angle(mat[0, 1] / np.sin(theta) * np.exp(-1j * alpha)) | ||
lambd = np.angle(mat[1, 0] / np.sin(theta) * np.exp(-1j * alpha)) | ||
|
||
return SU2RotationGate(theta, phi, lambd, alpha) | ||
|
||
def add_my_tensors( | ||
self, | ||
tn: 'qtn.TensorNetwork', | ||
tag: Any, | ||
*, | ||
incoming: Dict[str, 'SoquetT'], | ||
outgoing: Dict[str, 'SoquetT'], | ||
): | ||
import quimb.tensor as qtn | ||
|
||
tn.add( | ||
qtn.Tensor( | ||
data=self.rotation_matrix, | ||
inds=(outgoing['q'], incoming['q']), | ||
tags=[self.short_name(), tag], | ||
) | ||
) | ||
|
||
def _unitary_(self): | ||
if self._is_parameterized_(): | ||
return None | ||
return self.rotation_matrix | ||
|
||
def build_composite_bloq(self, bb: 'BloqBuilder', q: 'SoquetT') -> Dict[str, 'SoquetT']: | ||
pi = sympy.pi if self._is_parameterized_() else np.pi | ||
exp = sympy.exp if self._is_parameterized_() else np.exp | ||
|
||
bb.add(GlobalPhase(coefficient=-exp(1j * self.global_shift), eps=self.eps / 4)) | ||
q = bb.add(ZPowGate(exponent=1 - self.lambd / pi, global_shift=-1, eps=self.eps / 4), q=q) | ||
q = bb.add(Ry(angle=2 * self.theta, eps=self.eps / 4), q=q) | ||
q = bb.add(ZPowGate(exponent=-self.phi / pi, global_shift=-1, eps=self.eps / 4), q=q) | ||
return {'q': q} | ||
|
||
def pretty_name(self) -> str: | ||
return 'SU_2' | ||
|
||
def wire_symbol(self, soq: 'Soquet') -> 'WireSymbol': | ||
return TextBox( | ||
f"{self.pretty_name()}({self.theta}, {self.phi}, {self.lambd}, {self.global_shift})" | ||
) | ||
|
||
def _t_complexity_(self) -> TComplexity: | ||
return TComplexity(rotations=3) | ||
|
||
def _is_parameterized_(self) -> bool: | ||
return cirq.is_parameterized((self.theta, self.phi, self.lambd, self.global_shift)) | ||
|
||
|
||
@bloq_example | ||
def _su2_rotation_gate() -> SU2RotationGate: | ||
su2_rotation_gate = SU2RotationGate(np.pi / 4, np.pi / 2, np.pi / 2) | ||
return su2_rotation_gate | ||
|
||
|
||
@bloq_example | ||
def _hadamard() -> SU2RotationGate: | ||
hadamard = SU2RotationGate(np.pi / 4, 0, 0) | ||
return hadamard | ||
|
||
|
||
@bloq_example | ||
def _t_gate() -> SU2RotationGate: | ||
t_gate = SU2RotationGate(0, 3 * np.pi / 4, 0, -3 * np.pi / 4) | ||
return t_gate | ||
|
||
|
||
_SU2_ROTATION_GATE_DOC = BloqDocSpec( | ||
bloq_cls=SU2RotationGate, | ||
import_line='from qualtran.bloqs.basic_gates import SU2RotationGate', | ||
examples=[_su2_rotation_gate, _hadamard, _t_gate], | ||
) |
Oops, something went wrong.