-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
two-qubit decomposition into sqrt(iSWAP) + approximation #9375
base: main
Are you sure you want to change the base?
Changes from 21 commits
9d475cb
c9ac910
d10f8c5
c6eb038
84853cd
6d00e34
071f070
ccb293c
d9dde5d
9930079
c523180
cc0b349
e4f8b35
88b0757
0160592
48ce32c
8797d81
e018148
512a86a
51b42f4
83ea3b6
ae38e99
5ae2fb3
52c7798
99b2c1f
eac72e4
ecbb3b1
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 |
---|---|---|
|
@@ -110,6 +110,7 @@ | |
SdgGate | ||
SwapGate | ||
iSwapGate | ||
SiSwapGate | ||
SXGate | ||
SXdgGate | ||
TGate | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,77 @@ | ||||||
# This code is part of Qiskit. | ||||||
# | ||||||
# (C) Copyright IBM 2017, 2023. | ||||||
# | ||||||
# This code is licensed under the Apache License, Version 2.0. You may | ||||||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||||||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||||||
# | ||||||
# Any modifications or derivative works of this code must retain this | ||||||
# copyright notice, and modified files need to carry a notice indicating | ||||||
# that they have been altered from the originals. | ||||||
|
||||||
"""sqrt(iSWAP) gate.""" | ||||||
|
||||||
import numpy as np | ||||||
from qiskit.circuit.gate import Gate | ||||||
|
||||||
|
||||||
class SiSwapGate(Gate): | ||||||
r"""sqrt(iSWAP) gate. | ||||||
|
||||||
A 2-qubit symmetric gate from the iSWAP (or XY) family. | ||||||
It has Weyl chamber coordinates (π/8, π/8, 0). | ||||||
|
||||||
Can be applied to a :class:`~qiskit.circuit.QuantumCircuit` | ||||||
with the :meth:`~qiskit.circuit.QuantumCircuit.SiSwap` method. | ||||||
|
||||||
.. parsed-literal:: | ||||||
|
||||||
┌────────────┐┌────────────┐ | ||||||
q_0: ┤0 ├┤0 ├ | ||||||
│ Rxx(-π/4) ││ Ryy(-π/4) │ | ||||||
q_1: ┤1 ├┤1 ├ | ||||||
└────────────┘└────────────┘ | ||||||
|
||||||
.. math:: | ||||||
B\ q_0, q_1 = | ||||||
ajavadia marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
\begin{pmatrix} | ||||||
1 & 0 & 0 & 0 \\ | ||||||
0 & \frac{1}{\sqrt{2}} & \frac{i}{\sqrt{2}} & 0 \\ | ||||||
0 & \frac{i}{\sqrt{2}} & \frac{1}{\sqrt{2}} & 0 \\ | ||||||
0 & 0 & 0 & 1 | ||||||
\end{pmatrix} | ||||||
""" | ||||||
|
||||||
def __init__(self): | ||||||
"""Create new SiSwap gate.""" | ||||||
super().__init__("siswap", 2, []) | ||||||
|
||||||
def _define(self): | ||||||
""" | ||||||
gate siswap a, b { rxx(-pi/4) a, b; ryy(-pi/4) a, b; } | ||||||
""" | ||||||
# pylint: disable=cyclic-import | ||||||
from qiskit.circuit.quantumcircuit import QuantumRegister, QuantumCircuit | ||||||
from .rxx import RXXGate | ||||||
from .ryy import RYYGate | ||||||
|
||||||
q = QuantumRegister(2, "q") | ||||||
qc = QuantumCircuit(q, name=self.name) | ||||||
rules = [(RXXGate(-np.pi / 4), [q[0], q[1]], []), (RYYGate(-np.pi / 4), [q[0], q[1]], [])] | ||||||
for instr, qargs, cargs in rules: | ||||||
qc._append(instr, qargs, cargs) | ||||||
Comment on lines
+59
to
+63
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. If we're going to use the If you don't want to worry about it, it shouldn't really matter for performance to just use |
||||||
|
||||||
self.definition = qc | ||||||
|
||||||
def __array__(self, dtype=None): | ||||||
"""Return a numpy.array for the DCX gate.""" | ||||||
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
perhaps? |
||||||
return np.array( | ||||||
[ | ||||||
[1, 0, 0, 0], | ||||||
[0, 1 / np.sqrt(2), 1j / np.sqrt(2), 0], | ||||||
[0, 1j / np.sqrt(2), 1 / np.sqrt(2), 0], | ||||||
[0, 0, 0, 1], | ||||||
], | ||||||
dtype=dtype, | ||||||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,6 @@ | |
""" | ||
from __future__ import annotations | ||
import heapq | ||
import math | ||
from operator import itemgetter | ||
from typing import Callable | ||
|
||
|
@@ -27,31 +26,13 @@ | |
from qiskit.quantum_info.operators import Operator | ||
from qiskit.quantum_info.synthesis.one_qubit_decompose import ONE_QUBIT_EULER_BASIS_GATES | ||
from qiskit.quantum_info.synthesis.two_qubit_decompose import TwoQubitWeylDecomposition | ||
from qiskit.synthesis.su4.utils import average_infidelity | ||
|
||
from .circuits import apply_reflection, apply_shift, canonical_xx_circuit | ||
from .utilities import EPSILON | ||
from .polytopes import XXPolytope | ||
|
||
|
||
def _average_infidelity(p, q): | ||
""" | ||
Computes the infidelity distance between two points p, q expressed in positive canonical | ||
coordinates. | ||
""" | ||
|
||
a0, b0, c0 = p | ||
a1, b1, c1 = q | ||
|
||
return 1 - 1 / 20 * ( | ||
4 | ||
+ 16 | ||
* ( | ||
math.cos(a0 - a1) ** 2 * math.cos(b0 - b1) ** 2 * math.cos(c0 - c1) ** 2 | ||
+ math.sin(a0 - a1) ** 2 * math.sin(b0 - b1) ** 2 * math.sin(c0 - c1) ** 2 | ||
) | ||
) | ||
|
||
|
||
Comment on lines
+29
to
-54
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.
For right now, it might be a shade better just to eat this code duplication right now to avoid creating even larger circular import cycles - I saw you already hit one caused by this in a file above, because you had to make an import more specific. |
||
class XXDecomposer: | ||
""" | ||
A class for optimal decomposition of 2-qubit unitaries into 2-qubit basis gates of XX type | ||
|
@@ -155,7 +136,7 @@ def _best_decomposition(canonical_coordinate, available_strengths): | |
|
||
strength_polytope = XXPolytope.from_strengths(*[x / 2 for x in sequence]) | ||
candidate_point = strength_polytope.nearest(canonical_coordinate) | ||
candidate_cost = sequence_cost + _average_infidelity( | ||
candidate_cost = sequence_cost + average_infidelity( | ||
canonical_coordinate, candidate_point | ||
) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# This code is part of Qiskit. | ||
# | ||
# (C) Copyright IBM 2023. | ||
# | ||
# This code is licensed under the Apache License, Version 2.0. You may | ||
# obtain a copy of this license in the LICENSE.txt file in the root directory | ||
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. | ||
# | ||
# Any modifications or derivative works of this code must retain this | ||
# copyright notice, and modified files need to carry a notice indicating | ||
# that they have been altered from the originals. | ||
|
||
"""Two-qubit unitary synthesis methods.""" | ||
|
||
from .siswap_decompose import SiSwapDecomposer |
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.
The SiSwap Gate should also be added to the documentation in this init file, and removed from the docs in circuit/library/standard_gates.
See the following PR: #9668