Skip to content

Commit

Permalink
🐛 fix and streamline gate implementations
Browse files Browse the repository at this point in the history
Signed-off-by: burgholzer <[email protected]>
  • Loading branch information
burgholzer authored and KevinMTO committed Apr 28, 2024
1 parent 126ff07 commit 56aa9ab
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 93 deletions.
23 changes: 8 additions & 15 deletions src/mqt/qudits/quantum_circuit/gates/csum.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,17 @@ def __array__(self) -> np.ndarray:
ctrl_size = self.parent_circuit.dimensions[self._target_qudits[0]]
target_size = self.parent_circuit.dimensions[self._target_qudits[1]]

matrix = np.zeros(ctrl_size * target_size, dtype="complex")

x_gate = X(self.parent_circuit, None, self._target_qudits[1], target_size, None)

x_gate = X(self.parent_circuit, "x", self._target_qudits[1], target_size, None)
x_mat = x_gate.to_matrix(identities=0)
matrix = np.zeros((ctrl_size * target_size, ctrl_size * target_size), dtype="complex")
for i in range(ctrl_size):
temp = np.zeros(ctrl_size, dtype="complex")
mapmat = temp + np.outer(
np.array(from_dirac_to_basis([i], ctrl_size)), np.array(from_dirac_to_basis([i], ctrl_size))
)

Xmat = x_gate.to_matrix(identities=0)
Xmat_i = np.linalg.matrix_power(Xmat, i)

basis = np.array(from_dirac_to_basis([i], ctrl_size), dtype="complex")
mapmat = np.outer(basis, basis)
x_mat_i = np.linalg.matrix_power(x_mat, i)
if self._target_qudits[0] < self._target_qudits[1]:
matrix = matrix + np.kron(mapmat, Xmat_i)
matrix += np.kron(mapmat, x_mat_i)
else:
matrix = matrix + np.kron(Xmat_i, mapmat)

matrix += np.kron(x_mat_i, mapmat)
return matrix

def validate_parameter(self, parameter=None) -> bool:
Expand Down
29 changes: 8 additions & 21 deletions src/mqt/qudits/quantum_circuit/gates/h.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,17 @@ def __init__(
self.qasm_tag = "h"

def __array__(self) -> np.ndarray:
basis_states_projectors = [list(range(self._dimensions)), list(range(self._dimensions))]

matrix_array = np.outer([0 for x in range(self._dimensions)], [0 for x in range(self._dimensions)])
matrix = None

for e0, e1 in itertools.product(*basis_states_projectors):
matrix = np.zeros((self._dimensions, self._dimensions), dtype="complex")
for e0, e1 in itertools.product(range(self._dimensions), repeat=2):
omega = np.mod(2 / self._dimensions * (e0 * e1), 2)
omega = omega * np.pi * 1j
omega = np.e**omega

l1 = [0 for x in range(self._dimensions)]
l2 = [0 for x in range(self._dimensions)]
l1[e0] = 1
l2[e1] = 1

array1 = np.array(l1, dtype="complex")
array2 = np.array(l2, dtype="complex")

result = omega * np.outer(array1, array2)

matrix_array = matrix_array + result
matrix = (1 / np.sqrt(self._dimensions)) * matrix_array

return matrix
array0 = np.zeros(self._dimensions, dtype="complex")
array1 = np.zeros(self._dimensions, dtype="complex")
array0[e0] = 1
array1[e1] = 1
matrix += omega * np.outer(array0, array1)
return matrix * (1 / np.sqrt(self._dimensions))

def validate_parameter(self, parameter=None) -> bool:
return True
Expand Down
30 changes: 9 additions & 21 deletions src/mqt/qudits/quantum_circuit/gates/s.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,16 @@ def __init__(
self.qasm_tag = "s"

def __array__(self) -> np.ndarray:
dimension = self._dimensions
levels_list = list(range(dimension))
if dimension == 2:
if self._dimensions == 2:
return np.array([[1, 0], [0, 1j]])
matrix = np.outer([0 for x in range(dimension)], [0 for x in range(dimension)])

for lev in levels_list:
omega = np.e ** (2 * np.pi * 1j / dimension)
omega **= np.mod(lev * (lev + 1) / 2, dimension)

l1 = [0 for _ in range(dimension)]
l2 = [0 for _ in range(dimension)]
l1[lev] = 1
l2[lev] = 1

array1 = np.array(l1, dtype="complex")
array2 = np.array(l2, dtype="complex")

result = omega * np.outer(array1, array2)

matrix = matrix + result

matrix = np.zeros((self._dimensions, self._dimensions), dtype="complex")
for i in range(self._dimensions):
omega = np.e ** (2 * np.pi * 1j / self._dimensions)
omega **= np.mod(i * (i + 1) / 2, self._dimensions)
array = np.zeros(self._dimensions, dtype="complex")
array[i] = 1
result = omega * np.outer(array, array)
matrix += result
return matrix

def validate_parameter(self, parameter=None) -> bool:
Expand Down
24 changes: 7 additions & 17 deletions src/mqt/qudits/quantum_circuit/gates/x.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,14 @@ def __init__(
self.qasm_tag = "x"

def __array__(self) -> np.ndarray:
basis_states_list = list(range(self._dimensions))

matrix = np.outer([0 for x in range(self._dimensions)], [0 for x in range(self._dimensions)])

for i in basis_states_list:
matrix = np.zeros((self._dimensions, self._dimensions), dtype="complex")
for i in range(self._dimensions):
i_plus_1 = np.mod(i + 1, self._dimensions)

l1 = [0 for x in range(self._dimensions)]
l2 = [0 for x in range(self._dimensions)]
l1[i_plus_1] = 1
l2[i] = 1

array1 = np.array(l1, dtype="complex")
array2 = np.array(l2, dtype="complex")

result = np.outer(array1, array2)
matrix = matrix + result

array1 = np.zeros(self._dimensions, dtype="complex")
array2 = np.zeros(self._dimensions, dtype="complex")
array1[i_plus_1] = 1
array2[i] = 1
matrix += np.outer(array1, array2)
return matrix

def validate_parameter(self, parameter=None) -> bool:
Expand Down
26 changes: 7 additions & 19 deletions src/mqt/qudits/quantum_circuit/gates/z.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,15 @@ def __init__(
self.qasm_tag = "z"

def __array__(self) -> np.ndarray:
dimension = self._dimensions
levels_list = list(range(dimension))

matrix = np.outer([0 for x in range(dimension)], [0 for x in range(dimension)])

for level in levels_list:
omega = np.mod(2 * level / dimension, 2)
matrix = np.zeros((self._dimensions, self._dimensions), dtype="complex")
for i in range(self._dimensions):
omega = np.mod(2 * i / self._dimensions, 2)
omega = omega * np.pi * 1j
omega = np.e**omega

l1 = [0 for _ in range(dimension)]
l2 = [0 for _ in range(dimension)]
l1[level] = 1
l2[level] = 1

array1 = np.array(l1, dtype="complex")
array2 = np.array(l2, dtype="complex")
proj = np.outer(array1, array2)
result = omega * proj

matrix = matrix + result
array = np.zeros(self._dimensions, dtype="complex")
array[i] = 1
result = omega * np.outer(array, array)
matrix += result

return matrix

Expand Down

0 comments on commit 56aa9ab

Please sign in to comment.