Skip to content

Commit 88f7f2d

Browse files
added sample_gates_test.py
1 parent c7fd8f7 commit 88f7f2d

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-4
lines changed

cirq-core/cirq/testing/sample_gates.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818

1919
class GateThatAllocatesAQubit(ops.Gate):
20+
r"""A gate that applies $Z^\theta$ indirectly through a clean ancilla."""
21+
2022
def __init__(self, theta: float) -> None:
2123
super().__init__()
2224
self._theta = theta
@@ -35,6 +37,8 @@ def target_unitary(self) -> np.ndarray:
3537

3638

3739
class GateThatAllocatesTwoQubits(ops.Gate):
40+
r"""A gate that applies $-j Z \otimes Z$ indirectly through two ancillas."""
41+
3842
def _num_qubits_(self):
3943
return 2
4044

@@ -53,16 +57,18 @@ def _decompose_(self, qs):
5357

5458
@classmethod
5559
def target_unitary(cls) -> np.ndarray:
56-
# Unitary = (-j I_2) \otimes Z
60+
# Unitary = -j Z \otimes Z
5761
return np.array([[-1j, 0, 0, 0], [0, 1j, 0, 0], [0, 0, 1j, 0], [0, 0, 0, -1j]])
5862

5963

6064
class GateThatDecomposesIntoNGates(ops.Gate):
61-
def __init__(self, n: int, sub_gate: ops.Gate, theta: float) -> None:
65+
r"""Applies $(Z^\theta)^{\otimes_n}$ on work qubits and `subgate` on $n$ borrowable ancillas."""
66+
67+
def __init__(self, n: int, subgate: ops.Gate, theta: float) -> None:
6268
super().__init__()
6369
self._n = n
64-
self._subgate = sub_gate
65-
self._name = str(sub_gate)
70+
self._subgate = subgate
71+
self._name = str(subgate)
6672
self._theta = theta
6773

6874
def _num_qubits_(self) -> int:
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Copyright 2023 The Cirq Developers
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import functools
15+
import pytest
16+
17+
import numpy as np
18+
from cirq.testing import sample_gates
19+
from cirq import protocols, ops
20+
21+
22+
@pytest.mark.parametrize('theta', np.linspace(0, 2 * np.pi, 20))
23+
def test_GateThatAllocatesAQubit(theta: float):
24+
g = sample_gates.GateThatAllocatesAQubit(theta)
25+
26+
want = np.array([[1, 0], [0, (-1 + 0j) ** theta]], dtype=np.complex128)
27+
# test unitary
28+
np.testing.assert_allclose(g.target_unitary(), want)
29+
30+
# test decomposition
31+
np.testing.assert_allclose(protocols.unitary(g), g.target_unitary())
32+
33+
34+
def test_GateThatAllocatesTwoQubits():
35+
g = sample_gates.GateThatAllocatesTwoQubits()
36+
37+
Z = np.array([[1, 0], [0, -1]])
38+
want = -1j * np.kron(Z, Z)
39+
# test unitary
40+
np.testing.assert_allclose(g.target_unitary(), want)
41+
42+
# test decomposition
43+
np.testing.assert_allclose(protocols.unitary(g), g.target_unitary())
44+
45+
46+
@pytest.mark.parametrize('n', [*range(1, 6)])
47+
@pytest.mark.parametrize('subgate', [ops.Z, ops.X, ops.Y, ops.T])
48+
@pytest.mark.parametrize('theta', np.linspace(0, 2 * np.pi, 5))
49+
def test_GateThatDecomposesIntoNGates(n: int, subgate: ops.Gate, theta: float):
50+
g = sample_gates.GateThatDecomposesIntoNGates(n, subgate, theta)
51+
52+
U = np.array([[1, 0], [0, (-1 + 0j) ** theta]], dtype=np.complex128)
53+
want = functools.reduce(np.kron, [U] * n)
54+
# test unitary
55+
np.testing.assert_allclose(g.target_unitary(), want)
56+
57+
# test decomposition
58+
np.testing.assert_allclose(protocols.unitary(g), g.target_unitary())

0 commit comments

Comments
 (0)