Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 47 additions & 43 deletions cirq-ionq/cirq_ionq/ionq_native_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@

@cirq.value.value_equality
class GPIGate(cirq.Gate):
"""The GPI gate is a single qubit gate.
r"""The GPI gate is a single qubit gate.
The unitary of this gate is
[[0, e^{-i\\phi}],
[e^{-i\\phi}, 0]]
[[0, e^{-i*2*\pi*\phi}],
[e^{-i*2*\pi*\phi}, 0]]
"""

def __init__(self, *, phi):
self.phi = phi

def _unitary_(self) -> np.ndarray:
top = cmath.exp(self.phi * 1j)
bot = cmath.exp(-self.phi * 1j)
top = cmath.exp(self.phi * 2 * math.pi * 1j)
bot = cmath.exp(-self.phi * 2 * math.pi * 1j)
return np.array([[0, top], [bot, 0]])

def __str__(self) -> str:
Expand Down Expand Up @@ -67,10 +67,10 @@ def _circuit_diagram_info_(
GPI = GPIGate(phi=0)
document(
GPI,
"""The GPI gate is a single qubit gate.
r"""The GPI gate is a single qubit gate.
The unitary of this gate is
[[0, e^{-i\\phi}],
[e^{-i\\phi}, 0]]
[[0, e^{-i*2*\pi*\phi}],
[e^{-i*2*\pi*\phi}, 0]]
It is driven by Rabi laser.
https://ionq.com/best-practices
""",
Expand All @@ -79,18 +79,18 @@ def _circuit_diagram_info_(

@cirq.value.value_equality
class GPI2Gate(cirq.Gate):
"""The GPI2 gate is a single qubit gate.
r"""The GPI2 gate is a single qubit gate.
The unitary of this gate is
\\frac{1}{/\\sqrt{2}}[[1, -i*e^{-i\\phi}],
[-i*e^{-i\\phi}, 1]]
\frac{1}{/\sqrt{2}}[[1, -i*e^{-i\phi}],
[-i*e^{-i\phi}, 1]]
"""

def __init__(self, *, phi):
self.phi = phi

def _unitary_(self) -> np.ndarray:
top = -1j * cmath.exp(self.phase * -1j)
bot = -1j * cmath.exp(self.phase * 1j)
top = -1j * cmath.exp(self.phase * 2 * math.pi * -1j)
bot = -1j * cmath.exp(self.phase * 2 * math.pi * 1j)
return np.array([[1, top], [bot, 1]]) / math.sqrt(2)

@property
Expand Down Expand Up @@ -121,10 +121,10 @@ def _value_equality_values_(self) -> Any:
GPI2 = GPI2Gate(phi=0)
document(
GPI2,
"""The GPI2 gate is a single qubit gate.
r"""The GPI2 gate is a single qubit gate.
The unitary of this gate is
\\frac{1}{/\\sqrt{2}}[[1, -i*e^{-i\\phi}],
[-i*e^{-i\\phi}, 1]]
\frac{1}{/\sqrt{2}}[[1, -i*e^{-i*2*\pi*\phi}],
[-i*e^{-i*2*\phi}, 1]]
It is driven by Rabi laser.
https://ionq.com/best-practices
""",
Expand All @@ -133,32 +133,36 @@ def _value_equality_values_(self) -> Any:

@cirq.value.value_equality
class MSGate(cirq.Gate):
"""The MS gate is a 2 qubit gate.
r"""The MS gate is a 2 qubit gate.
The unitary of this gate is
MS(\\phi_1 - \\phi_0) =
MS(t) =
\\frac{1}{\\sqrt{2}}
[[\\cos(t), 0, 0, -i*\\sin(t)],
[0, \\cos(t), -i*\\sin(t), 0],
[0, -i*\\sin(t), \\cos(t), 0],
[-i*\\sin(t), 0, 0, \\cos(t)]]
MS(\phi_0, \phi_1) q_0, q_1 =
\frac{1}{\sqrt{2}}
[[1, 0, 0, -i*e^{-i*2*\pi*(\phi_0+\phi_1}],
[0, 1, -i*e^{-i*2*\pi*(\phi_0-\phi_1}, 0],
[0, -i*e^{i*2*\pi*(\phi_0-\phi_1}, 1, 0],
[-i*e^{i*2*\pi*(\phi_0+\phi_1}, 0, 0, 1]]
"""

def __init__(self, *, phi1, phi2):
def __init__(self, *, phi0, phi1):
self.phi0 = phi0
self.phi1 = phi1
self.phi2 = phi2

def _unitary_(self) -> np.ndarray:
tee = self.phi2 - self.phi1
diag = math.cos(tee)
adiag = -1j * math.sin(tee)
diag = 1 / math.sqrt(2)
phi0 = self.phi0
phi1 = self.phi1
return np.array(
[[diag, 0, 0, adiag], [0, diag, adiag, 0], [0, adiag, diag, 0], [adiag, 0, 0, diag]]
[
[diag, 0, 0, diag * -1j * cmath.exp(-1j * 2 * math.pi * (phi0 + phi1))],
[0, diag, diag * -1j * cmath.exp(-1j * 2 * math.pi * (phi0 - phi1)), 0],
[0, diag * -1j * cmath.exp(1j * 2 * math.pi * (phi0 - phi1)), diag, 0],
[diag * -1j * cmath.exp(1j * 2 * math.pi * (phi0 + phi1)), 0, 0, diag],
]
)

@property
def phases(self) -> Sequence[float]:
return [self.phi1, self.phi2]
return [self.phi0, self.phi1]

def __str__(self) -> str:
return 'MS'
Expand All @@ -172,27 +176,27 @@ def _circuit_diagram_info_(
return protocols.CircuitDiagramInfo(wire_symbols=('MS',), exponent=self.phases)

def __repr__(self) -> str:
return f'cirq_ionq.MSGate(phi1={self.phi1!r}, phi2={self.phi2!r})'
return f'cirq_ionq.MSGate(phi0={self.phi0!r}, phi1={self.phi1!r})'

def _json_dict_(self) -> Dict[str, Any]:
return cirq.obj_to_dict_helper(self, ['phi1', 'phi2'])
return cirq.obj_to_dict_helper(self, ['phi0', 'phi1'])

def _value_equality_values_(self) -> Any:
return (self.phi1, self.phi2)
return (self.phi0, self.phi1)


MS = MSGate(phi1=0, phi2=0)
MS = MSGate(phi0=0, phi1=0)
document(
MS,
"""The MS gate is a 2 qubit gate.
r"""The MS gate is a 2 qubit gate.
The unitary of this gate is
MS(\\phi_1 - \\phi_0) =
MS(t) =
\\frac{1}{\\sqrt{2}}
[[\\cos(t), 0, 0, -i*\\sin(t)],
[0, \\cos(t), -i*\\sin(t), 0],
[0, -i*\\sin(t), \\cos(t), 0],
[-i*\\sin(t), 0, 0, \\cos(t)]]
.. math::
MS(\phi_0, \phi_1) q_0, q_1 =
\frac{1}{\sqrt{2}}
[[1, 0, 0, -i*e^{-i*(\phi_0+\phi_1}],
[0, 1, -i*e^{-i*(\phi_0-\phi_1}, 0],
[0, -i*e^{i*(\phi_0-\phi_1}, 1, 0],
[-i*e^{i*(\phi_0+\phi_1}, 0, 0, 1]]

https://ionq.com/best-practices
""",
Expand Down
6 changes: 3 additions & 3 deletions cirq-ionq/cirq_ionq/ionq_native_gates_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@


@pytest.mark.parametrize(
"gate,nqubits", [(GPIGate(phi=0.1), 1), (GPI2Gate(phi=0.2), 1), (MSGate(phi1=0.1, phi2=0.2), 2)]
"gate,nqubits", [(GPIGate(phi=0.1), 1), (GPI2Gate(phi=0.2), 1), (MSGate(phi0=0.1, phi1=0.2), 2)]
)
def test_gate_methods(gate, nqubits):
assert str(gate) != ""
Expand All @@ -30,7 +30,7 @@ def test_gate_methods(gate, nqubits):
assert cirq.protocols.circuit_diagram_info(gate) is not None


@pytest.mark.parametrize("gate", [GPIGate(phi=0.1), GPI2Gate(phi=0.2), MSGate(phi1=0.1, phi2=0.2)])
@pytest.mark.parametrize("gate", [GPIGate(phi=0.1), GPI2Gate(phi=0.2), MSGate(phi0=0.1, phi1=0.2)])
def test_gate_json(gate):
g_json = cirq.to_json(gate)
assert cirq.read_json(json_text=g_json) == gate
Expand Down Expand Up @@ -59,7 +59,7 @@ def test_gpi2_unitary(phase):
)
def test_ms_unitary(phases):
"""Tests that the MS gate is unitary."""
gate = MSGate(phi1=phases[0], phi2=phases[1])
gate = MSGate(phi0=phases[0], phi1=phases[1])

mat = cirq.protocols.unitary(gate)
numpy.testing.assert_array_almost_equal(mat.dot(mat.conj().T), numpy.identity(4))
4 changes: 2 additions & 2 deletions cirq-ionq/cirq_ionq/json_test_data/MSGate.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"cirq_type": "MSGate",
"phi1": 0.1,
"phi2": 0.55
"phi0": 0.1,
"phi1": 0.55
}
2 changes: 1 addition & 1 deletion cirq-ionq/cirq_ionq/json_test_data/MSGate.repr
Original file line number Diff line number Diff line change
@@ -1 +1 @@
cirq_ionq.MSGate(phi1=0.1, phi2=0.55)
cirq_ionq.MSGate(phi0=0.1, phi1=0.55)
2 changes: 1 addition & 1 deletion cirq-ionq/cirq_ionq/serializer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def test_serialize_native_gates():
q0, q1, q2 = cirq.LineQubit.range(3)
gpi = GPIGate(phi=0.1).on(q0)
gpi2 = GPI2Gate(phi=0.2).on(q1)
ms = MSGate(phi1=0.3, phi2=0.4).on(q1, q2)
ms = MSGate(phi0=0.3, phi1=0.4).on(q1, q2)
circuit = cirq.Circuit([gpi, gpi2, ms])
serializer = ionq.Serializer()
result = serializer.serialize(circuit)
Expand Down