Skip to content

Commit

Permalink
Merge branch 'main' into general-unitaries
Browse files Browse the repository at this point in the history
  • Loading branch information
garrison committed Jul 5, 2023
2 parents 9a7121a + b76f9c6 commit 4232864
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 12 deletions.
60 changes: 52 additions & 8 deletions circuit_knitting/cutting/qpd/qpd.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,22 @@
RXGate,
RYGate,
RZGate,
PhaseGate,
CXGate,
CYGate,
CZGate,
CHGate,
CSGate,
CSdgGate,
CSXGate,
RXXGate,
RYYGate,
RZZGate,
CRXGate,
CRYGate,
CRZGate,
ECRGate,
CSXGate,
CPhaseGate,
SwapGate,
iSwapGate,
DCXGate,
Expand Down Expand Up @@ -214,6 +218,13 @@ def qpdbasis_from_gate(gate: Gate) -> QPDBasis:
- :class:`~qiskit.circuit.library.CYGate`
- :class:`~qiskit.circuit.library.CZGate`
- :class:`~qiskit.circuit.library.CHGate`
- :class:`~qiskit.circuit.library.CSXGate`
- :class:`~qiskit.circuit.library.CSGate`
- :class:`~qiskit.circuit.library.CSdgGate`
- :class:`~qiskit.circuit.library.CPhaseGate`
- :class:`~qiskit.circuit.library.SwapGate`
- :class:`~qiskit.circuit.library.iSwapGate`
- :class:`~qiskit.circuit.library.DCXGate`
The above gate names can also be determined by calling
:func:`supported_gates`.
Expand Down Expand Up @@ -461,13 +472,7 @@ def _(gate: RXXGate | RYYGate | RZZGate | CRXGate | CRYGate | CRZGate):
([r_minus], measurement_1),
]

# If theta is a bound ParameterExpression, convert to float, else raise error.
try:
theta = float(gate.params[0])
except TypeError as err:
raise ValueError(
f"Cannot decompose ({gate.name}) gate with unbound parameters."
) from err
theta = _theta_from_gate(gate)

if gate.name[0] == "c":
# Following Eq. (C.4) of https://arxiv.org/abs/2205.00016v2,
Expand Down Expand Up @@ -506,6 +511,28 @@ def _(gate: RXXGate | RYYGate | RZZGate | CRXGate | CRYGate | CRZGate):
return QPDBasis(maps, coeffs)


@_register_qpdbasis_from_gate("cs", "csdg")
def _(gate: CSGate | CSdgGate):
theta = np.pi / 2
rot_gate = TGate()
if gate.name == "csdg":
theta *= -1
rot_gate = rot_gate.inverse()
retval = qpdbasis_from_gate(CRZGate(theta))
for operations in unique_by_id(m[0] for m in retval.maps):
operations.insert(0, rot_gate)
return retval


@_register_qpdbasis_from_gate("cp")
def _(gate: CPhaseGate):
theta = _theta_from_gate(gate)
retval = qpdbasis_from_gate(CRZGate(theta))
for operations in unique_by_id(m[0] for m in retval.maps):
operations.insert(0, PhaseGate(theta / 2))
return retval


@_register_qpdbasis_from_gate("csx")
def _(gate: CSXGate):
retval = qpdbasis_from_gate(CRXGate(np.pi / 2))
Expand Down Expand Up @@ -565,6 +592,23 @@ def _(gate: ECRGate):
return retval


def _theta_from_gate(gate: Gate) -> float:
param_gates = {"rxx", "ryy", "rzz", "crx", "cry", "crz", "cp"}

# Internal function should only be called for supported gates
assert gate.name in param_gates

# If theta is a bound ParameterExpression, convert to float, else raise error.
try:
theta = float(gate.params[0])
except TypeError as err:
raise ValueError(
f"Cannot decompose ({gate.name}) gate with unbound parameters."
) from err

return theta


def _validate_qpd_instructions(
circuit: QuantumCircuit, instruction_ids: Sequence[Sequence[int]]
):
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ nbtest = [
"nbmake>=1.3.4"
]
style = [
"autoflake==2.1.1",
"autoflake==2.2.0",
"black[jupyter]==23.3.0",
"ruff>=0.0.246",
"nbqa>=1.6.0",
]
lint = [
"circuit-knitting-toolbox[style]",
"pydocstyle==6.3.0",
"mypy==1.3.0",
"mypy==1.4.1",
"reno>=3.4.0",
# pydocstyle prefers to parse our pyproject.toml, hence the following line
"toml",
Expand Down
6 changes: 5 additions & 1 deletion releasenotes/notes/additional-gates-f4ed6c0e8dc3a9be.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ features:
This release adds support for additional cut gates:
- :class:`~qiskit.circuit.library.CHGate`
- :class:`~qiskit.circuit.library.CYGate`
- :class:`~qiskit.circuit.library.SXGate`
- :class:`~qiskit.circuit.library.CSGate`
- :class:`~qiskit.circuit.library.CSXGate`
- :class:`~qiskit.circuit.library.CSdgGate`
- :class:`~qiskit.circuit.library.CPhaseGate`
- :class:`~qiskit.circuit.library.ECRGate`
- :class:`~qiskit.circuit.library.SwapGate`
- :class:`~qiskit.circuit.library.iSwapGate`
- :class:`~qiskit.circuit.library.DCXGate`
9 changes: 9 additions & 0 deletions test/cutting/qpd/test_qpd.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ def test_decompose_qpd_instructions(self):
(RYYGate(np.pi / 7), 1 + 2 * np.abs(np.sin(np.pi / 7))),
(RZZGate(np.pi / 7), 1 + 2 * np.abs(np.sin(np.pi / 7))),
(RZXGate(np.pi / 7), 1 + 2 * np.abs(np.sin(np.pi / 7))),
(CPhaseGate(np.pi / 7), 1 + 2 * np.abs(np.sin(np.pi / 14))),
(CSGate(), 1 + np.sqrt(2)),
(CSdgGate(), 1 + np.sqrt(2)),
(CSXGate(), 1 + np.sqrt(2)),
(SwapGate(), 7),
(iSwapGate(), 7),
(DCXGate(), 7),
Expand All @@ -269,6 +273,8 @@ def test_optimal_kappa_for_known_gates(self, instruction, gamma):
(CRXGate(np.pi / 7), 5, 5),
(CRYGate(np.pi / 7), 5, 5),
(CRZGate(np.pi / 7), 5, 5),
(CPhaseGate(np.pi / 7), 5, 5),
(ECRGate(), 5, 5),
(CXGate(), 5, 5),
(CZGate(), 5, 5),
(RZZGate(0), 1, 1),
Expand Down Expand Up @@ -307,6 +313,9 @@ def test_supported_gates(self):
"cz",
"ch",
"csx",
"cs",
"csdg",
"cp",
"ecr",
"swap",
"iswap",
Expand Down
9 changes: 8 additions & 1 deletion test/cutting/test_cutting_roundtrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@
CXGate,
CYGate,
CZGate,
CSGate,
CSdgGate,
CSXGate,
CRXGate,
CRYGate,
CRZGate,
CSXGate,
CPhaseGate,
ECRGate,
SwapGate,
iSwapGate,
Expand Down Expand Up @@ -67,6 +70,8 @@ def append_random_unitary(circuit: QuantumCircuit, qubits):
[CHGate()],
[ECRGate()],
[CSXGate()],
[CSGate()],
[CSdgGate()],
[RYYGate(0.0)],
[RZZGate(np.pi)],
[RXXGate(np.pi / 3)],
Expand All @@ -79,6 +84,8 @@ def append_random_unitary(circuit: QuantumCircuit, qubits):
[CRYGate(np.pi / 7)],
[CRZGate(np.pi / 11)],
[RXXGate(np.pi / 3), CRYGate(np.pi / 7)],
[CPhaseGate(np.pi / 3)],
[RXXGate(np.pi / 3), CPhaseGate(np.pi / 7)],
[UnitaryGate(random_unitary(2**2))],
[RZXGate(np.pi / 5)],
[XXPlusYYGate(7 * np.pi / 11)],
Expand Down

0 comments on commit 4232864

Please sign in to comment.