Skip to content

Commit

Permalink
syntax fix, added support for inp.integer, fixes #67
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesB-1qbit committed Dec 3, 2021
1 parent ac302ff commit 59699d8
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 14 deletions.
39 changes: 28 additions & 11 deletions tangelo/backendbuddy/gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

from typing import Union

from numpy import integer, ndarray

ONE_QUBIT_GATES = {"H", "X", "Y", "Z", "S", "T", "RX", "RY", "RZ", "PHASE"}
TWO_QUBIT_GATES = {"CNOT", "CX", "CY", "CZ", "CRX", "CRY", "CRZ", "CPHASE", "XX", "SWAP"}
THREE_QUBIT_GATES = {"CSWAP"}
Expand All @@ -40,27 +42,42 @@ class Gate(dict):
variational or not.
"""

def __init__(self, name: str, target: Union[int, list], control: Union[int, list] = None, parameter="", is_variational: bool = False):
def __init__(self, name: str, target: Union[int, integer, list, ndarray], control: Union[int, integer, list, ndarray] = None,
parameter="", is_variational: bool = False):
""" This gate class is basically a dictionary with extra methods. """

if not isinstance(target, (int, list)):
if not isinstance(target, (int, integer, list, ndarray)):
raise ValueError("Qubit index must be int or list of ints.")
else:
if isinstance(target, int):
target = [target]
if isinstance(target, (int, integer)):
target = [int(target)]
new_target = []
for t in target:
if not isinstance(t, int) or t < 0:
raise ValueError(f"Target {t} of input {target} is not a positive integer")
if isinstance(t, integer) and t >= 0:
new_target.append(int(t))
elif isinstance(t, int) and t >= 0:
new_target.append(t)
else:
raise ValueError(f"Target {t} of requested target={target} is not a positive integer")
target = new_target

if control is not None:
if not isinstance(control, (int, list)):
if name[0] != "C":
raise ValueError(f"Gate {name} was given control={control} but does not support controls. Try C{name}")
if not isinstance(control, (int, integer, list, ndarray)):
raise ValueError("Qubit index must be int or list of ints.")
else:
if isinstance(control, int):
control = [control]
if isinstance(control, (int, integer)):
control = [int(control)]
new_control = []
for c in control:
if not isinstance(c, int) or c < 0:
raise ValueError(f"Target {c} of input {control} is not a positive integer")
if isinstance(c, integer) and c >= 0:
new_control.append(int(c))
elif isinstance(c, int) and c >= 0:
new_control.append(c)
else:
raise ValueError(f"Control {c} of requested control={control} is not a positive integer")
control = new_control

self.__dict__ = {"name": name, "target": target, "control": control,
"parameter": parameter, "is_variational": is_variational}
Expand Down
13 changes: 12 additions & 1 deletion tangelo/backendbuddy/tests/test_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# limitations under the License.

import unittest

import numpy as np

from tangelo.backendbuddy import Gate


Expand All @@ -34,15 +37,23 @@ def test_some_gates(self):
RX_gate = Gate("RX", 1, parameter=2.)
# Create a parameterized rotation on qubit 1 , with an undefined angle, that will be variational
RZ_gate = Gate("RZ", 1, parameter="an expression", is_variational=True)
# Create a multi-controlled X gate with a numpy array
CCCX_gate = Gate("CX", 0, control=np.array([1, 2, 4], dtype=np.int32))

for gate in [H_gate, CNOT_gate, RX_gate, RZ_gate]:
for gate in [H_gate, CNOT_gate, RX_gate, RZ_gate, CCCX_gate]:
print(gate)

def test_incorrect_gate(self):
""" Test to catch a gate with inputs that do not make sense """

self.assertRaises(ValueError, Gate, "H", -1)
self.assertRaises(ValueError, Gate, "CNOT", 0, control=0.3)
self.assertRaises(ValueError, Gate, 'X', target=0, control=1)

def test_integer_types(self):
""" Test to catch error with incorrect target or control"""
self.assertRaises(ValueError, Gate, "CSWAP", target=[0, 'a'], control=np.array([1], dtype=np.int32))
self.assertRaises(ValueError, Gate, "X", target=0, control=[-1, 2, 3],)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion tangelo/backendbuddy/translator/translate_cirq.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def translate_cirq(source_circuit, noise_model=None):

# Maps the gate information properly. Different for each backend (order, values)
for gate in source_circuit._gates:
if gate.control is not None and gate.name is not 'CNOT':
if (gate.control is not None) and gate.name != 'CNOT':
control_list = []
num_controls = len(gate.control)
for c in gate.control:
Expand Down
2 changes: 1 addition & 1 deletion tangelo/backendbuddy/translator/translate_qdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def translate_qsharp(source_circuit, operation="MyQsharpOperation"):
# Generate Q# strings with the right syntax, order and values for the gate inputs
body_str = ""
for gate in source_circuit._gates:
if gate.control is not None and gate.name is not "CNOT":
if gate.control is not None and gate.name != "CNOT":
control_string = '['
num_controls = len(gate.control)
for i, c in enumerate(gate.control):
Expand Down

0 comments on commit 59699d8

Please sign in to comment.