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

Add two-qubit unitary decomposition for (inverse) sqrt-iSWAP #4213

Merged
merged 23 commits into from
Jul 3, 2021
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions cirq-core/cirq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@
SingleQubitCliffordGate,
SingleQubitGate,
SingleQubitPauliStringGateOperation,
SQRT_ISWAP,
SWAP,
SwapPowGate,
T,
Expand Down Expand Up @@ -326,6 +327,7 @@
SynchronizeTerminalMeasurements,
two_qubit_matrix_to_operations,
two_qubit_matrix_to_diagonal_and_operations,
two_qubit_matrix_to_sqrt_iswap_operations,
three_qubit_matrix_to_operations,
)

Expand Down
1 change: 1 addition & 0 deletions cirq-core/cirq/ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@
ISWAP,
ISwapPowGate,
riswap,
SQRT_ISWAP,
SWAP,
SwapPowGate,
)
Expand Down
19 changes: 18 additions & 1 deletion cirq-core/cirq/ops/swap_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
This module creates Gate instances for the following gates:
SWAP: the swap gate.
ISWAP: a swap gate with a phase on the swapped subspace.
SQRT_ISWAP: square root of the ISWAP gate.

Each of these are implemented as EigenGates, which means that they can be
raised to a power (i.e. cirq.ISWAP**0.5). See the definition in EigenGate.
raised to a power (i.e. SQRT_ISWAP=cirq.ISWAP**0.5). See the definition in
EigenGate.
"""

from typing import Optional, Tuple, TYPE_CHECKING, List
Expand Down Expand Up @@ -334,3 +336,18 @@ def riswap(rads: value.TParamVal) -> ISwapPowGate:
```
""",
)

SQRT_ISWAP = ISwapPowGate(exponent=0.5)
document(
SQRT_ISWAP,
"""The square root of iswap gate.

Matrix:
```
[[1, 0, 0, 0],
[0, 1/√2, i/√2, 0],
[0, i/√2, 1/√2, 0],
[0, 0, 0, 1]]
```
""",
)
14 changes: 14 additions & 0 deletions cirq-core/cirq/ops/swap_gates_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,20 @@ def test_iswap_unitary():
# yapf: enable


def test_sqrt_iswap_unitary():
# yapf: disable
balopat marked this conversation as resolved.
Show resolved Hide resolved
cirq.testing.assert_allclose_up_to_global_phase(
cirq.unitary(cirq.SQRT_ISWAP),
# Reference for the sqrt-iSWAP gate's matrix:
# https://arxiv.org/abs/2105.06074
np.array([[1, 0, 0, 0],
[0, 1/2**0.5, 1j/2**0.5, 0],
[0, 1j/2**0.5, 1/2**0.5, 0],
[0, 0, 0, 1]]),
atol=1e-8)
# yapf: enable


def test_repr():
assert repr(cirq.SWAP) == 'cirq.SWAP'
assert repr(cirq.SWAP ** 0.5) == '(cirq.SWAP**0.5)'
Expand Down
3 changes: 3 additions & 0 deletions cirq-core/cirq/optimizers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@
two_qubit_matrix_to_operations,
two_qubit_matrix_to_diagonal_and_operations,
)
from cirq.optimizers.two_qubit_to_sqrt_iswap import (
two_qubit_matrix_to_sqrt_iswap_operations,
)

from cirq.optimizers.two_qubit_to_fsim import (
decompose_two_qubit_interaction_into_four_fsim_gates,
Expand Down
4 changes: 2 additions & 2 deletions cirq-core/cirq/optimizers/two_qubit_decompositions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

"""Utility methods related to optimizing quantum circuits."""

from typing import Iterable, List, Tuple, Optional, cast, TYPE_CHECKING
from typing import Iterable, List, Sequence, Tuple, Optional, cast, TYPE_CHECKING

import numpy as np

Expand Down Expand Up @@ -161,7 +161,7 @@ def _xx_yy_zz_interaction_via_full_czs(
yield ops.H(q1)


def _cleanup_operations(operations: List[ops.Operation]):
def _cleanup_operations(operations: Sequence[ops.Operation]):
circuit = circuits.Circuit(operations)
merge_single_qubit_gates.merge_single_qubit_gates_into_phased_x_z(circuit)
eject_phased_paulis.EjectPhasedPaulis().optimize_circuit(circuit)
Expand Down