interferometer 1.1__tar.gz → 1.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {interferometer-1.1 → interferometer-1.1.2}/PKG-INFO +5 -2
- {interferometer-1.1 → interferometer-1.1.2}/interferometer/main.py +27 -15
- {interferometer-1.1 → interferometer-1.1.2}/interferometer.egg-info/PKG-INFO +5 -2
- {interferometer-1.1 → interferometer-1.1.2}/interferometer.egg-info/SOURCES.txt +2 -1
- {interferometer-1.1 → interferometer-1.1.2}/pyproject.toml +1 -1
- interferometer-1.1.2/tests/test_interferometer.py +17 -0
- {interferometer-1.1 → interferometer-1.1.2}/LICENSE +0 -0
- {interferometer-1.1 → interferometer-1.1.2}/README.md +0 -0
- {interferometer-1.1 → interferometer-1.1.2}/interferometer/__init__.py +0 -0
- {interferometer-1.1 → interferometer-1.1.2}/interferometer.egg-info/dependency_links.txt +0 -0
- {interferometer-1.1 → interferometer-1.1.2}/interferometer.egg-info/requires.txt +0 -0
- {interferometer-1.1 → interferometer-1.1.2}/interferometer.egg-info/top_level.txt +0 -0
- {interferometer-1.1 → interferometer-1.1.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: interferometer
|
|
3
|
-
Version: 1.1
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: Algorithms for universal interferometers
|
|
5
5
|
Author-email: "William R. Clements" <mail@william-clements.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/clementsw/interferometer
|
|
@@ -13,6 +13,9 @@ Classifier: Topic :: Scientific/Engineering :: Physics
|
|
|
13
13
|
Requires-Python: >=3.7
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
|
+
Requires-Dist: numpy
|
|
17
|
+
Requires-Dist: matplotlib
|
|
18
|
+
Dynamic: license-file
|
|
16
19
|
|
|
17
20
|
# Interferometer package
|
|
18
21
|
|
|
@@ -84,10 +84,10 @@ class Interferometer:
|
|
|
84
84
|
complex-valued 2D numpy array representing the interferometer
|
|
85
85
|
"""
|
|
86
86
|
N = int(self.count_modes())
|
|
87
|
-
U = np.eye(N, dtype=np.
|
|
87
|
+
U = np.eye(N, dtype=np.complex128)
|
|
88
88
|
|
|
89
89
|
for BS in self.BS_list:
|
|
90
|
-
T = np.eye(N, dtype=np.
|
|
90
|
+
T = np.eye(N, dtype=np.complex128)
|
|
91
91
|
T[BS.mode1 - 1, BS.mode1 - 1] = np.exp(1j * BS.phi) * np.cos(BS.theta)
|
|
92
92
|
T[BS.mode1 - 1, BS.mode2 - 1] = -np.sin(BS.theta)
|
|
93
93
|
T[BS.mode2 - 1, BS.mode1 - 1] = np.exp(1j * BS.phi) * np.sin(BS.theta)
|
|
@@ -185,9 +185,9 @@ def triangle_decomposition(U):
|
|
|
185
185
|
for ii in range(N-1):
|
|
186
186
|
for jj in range(N-1-ii):
|
|
187
187
|
modes = [N - jj - 1, N - jj]
|
|
188
|
-
theta =
|
|
189
|
-
phi = -
|
|
190
|
-
invT = np.eye(N, dtype=np.
|
|
188
|
+
theta = custom_arctan(U[ii, N - 1 - jj], U[ii, N - 2 - jj])
|
|
189
|
+
phi = -custom_angle(-U[ii, N - 1 - jj], U[ii, N - 2 - jj])
|
|
190
|
+
invT = np.eye(N, dtype=np.complex128)
|
|
191
191
|
invT[modes[0]-1, modes[0]-1] = np.exp(-1j * phi) * np.cos(theta)
|
|
192
192
|
invT[modes[0]-1, modes[1]-1] = np.exp(-1j * phi) * np.sin(theta)
|
|
193
193
|
invT[modes[1]-1, modes[0]-1] = -np.sin(theta)
|
|
@@ -216,9 +216,9 @@ def square_decomposition(U):
|
|
|
216
216
|
if np.mod(ii, 2) == 0:
|
|
217
217
|
for jj in range(ii+1):
|
|
218
218
|
modes = [ii - jj + 1, ii + 2 - jj]
|
|
219
|
-
theta =
|
|
220
|
-
phi =
|
|
221
|
-
invT = np.eye(N, dtype=np.
|
|
219
|
+
theta = custom_arctan(U[N-1-jj, ii-jj], U[N-1-jj, ii-jj+1])
|
|
220
|
+
phi = custom_angle(U[N-1-jj, ii-jj], U[N-1-jj, ii-jj+1])
|
|
221
|
+
invT = np.eye(N, dtype=np.complex128)
|
|
222
222
|
invT[modes[0]-1, modes[0]-1] = np.exp(-1j * phi) * np.cos(theta)
|
|
223
223
|
invT[modes[0]-1, modes[1]-1] = np.exp(-1j * phi) * np.sin(theta)
|
|
224
224
|
invT[modes[1]-1, modes[0]-1] = -np.sin(theta)
|
|
@@ -228,9 +228,9 @@ def square_decomposition(U):
|
|
|
228
228
|
else:
|
|
229
229
|
for jj in range(ii+1):
|
|
230
230
|
modes = [N+jj-ii-1, N+jj-ii]
|
|
231
|
-
theta =
|
|
232
|
-
phi =
|
|
233
|
-
T = np.eye(N, dtype=np.
|
|
231
|
+
theta = custom_arctan(U[N+jj-ii-1, jj], U[N+jj-ii-2, jj])
|
|
232
|
+
phi = custom_angle(-U[N+jj-ii-1, jj], U[N+jj-ii-2, jj])
|
|
233
|
+
T = np.eye(N, dtype=np.complex128)
|
|
234
234
|
T[modes[0]-1, modes[0]-1] = np.exp(1j * phi) * np.cos(theta)
|
|
235
235
|
T[modes[0]-1, modes[1]-1] = -np.sin(theta)
|
|
236
236
|
T[modes[1]-1, modes[0]-1] = np.exp(1j * phi) * np.sin(theta)
|
|
@@ -240,14 +240,14 @@ def square_decomposition(U):
|
|
|
240
240
|
|
|
241
241
|
for BS in np.flip(left_T, 0):
|
|
242
242
|
modes = [int(BS.mode1), int(BS.mode2)]
|
|
243
|
-
invT = np.eye(N, dtype=np.
|
|
243
|
+
invT = np.eye(N, dtype=np.complex128)
|
|
244
244
|
invT[modes[0]-1, modes[0]-1] = np.exp(-1j * BS.phi) * np.cos(BS.theta)
|
|
245
245
|
invT[modes[0]-1, modes[1]-1] = np.exp(-1j * BS.phi) * np.sin(BS.theta)
|
|
246
246
|
invT[modes[1]-1, modes[0]-1] = -np.sin(BS.theta)
|
|
247
247
|
invT[modes[1]-1, modes[1]-1] = np.cos(BS.theta)
|
|
248
248
|
U = np.matmul(invT, U)
|
|
249
|
-
theta =
|
|
250
|
-
phi =
|
|
249
|
+
theta = custom_arctan(U[modes[1]-1, modes[0]-1], U[modes[1]-1, modes[1]-1])
|
|
250
|
+
phi = custom_angle(U[modes[1]-1, modes[0]-1], U[modes[1]-1, modes[1]-1])
|
|
251
251
|
invT[modes[0]-1, modes[0]-1] = np.exp(-1j * phi) * np.cos(theta)
|
|
252
252
|
invT[modes[0]-1, modes[1]-1] = np.exp(-1j * phi) * np.sin(theta)
|
|
253
253
|
invT[modes[1]-1, modes[0]-1] = -np.sin(theta)
|
|
@@ -271,7 +271,7 @@ def random_unitary(N):
|
|
|
271
271
|
Returns:
|
|
272
272
|
complex-valued 2D numpy array representing the interferometer
|
|
273
273
|
"""
|
|
274
|
-
X = np.zeros([N, N], dtype=np.
|
|
274
|
+
X = np.zeros([N, N], dtype=np.complex128)
|
|
275
275
|
for ii in range(N):
|
|
276
276
|
for jj in range(N):
|
|
277
277
|
X[ii, jj] = (np.random.normal() + 1j * np.random.normal()) / np.sqrt(2)
|
|
@@ -281,3 +281,15 @@ def random_unitary(N):
|
|
|
281
281
|
U = np.matmul(q, r)
|
|
282
282
|
|
|
283
283
|
return U
|
|
284
|
+
|
|
285
|
+
def custom_arctan(x1, x2):
|
|
286
|
+
if x2 != 0:
|
|
287
|
+
return np.arctan(abs(x1/x2))
|
|
288
|
+
else:
|
|
289
|
+
return np.pi/2
|
|
290
|
+
|
|
291
|
+
def custom_angle(x1, x2):
|
|
292
|
+
if x2 != 0:
|
|
293
|
+
return np.angle(x1/x2)
|
|
294
|
+
else:
|
|
295
|
+
return 0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: interferometer
|
|
3
|
-
Version: 1.1
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: Algorithms for universal interferometers
|
|
5
5
|
Author-email: "William R. Clements" <mail@william-clements.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/clementsw/interferometer
|
|
@@ -13,6 +13,9 @@ Classifier: Topic :: Scientific/Engineering :: Physics
|
|
|
13
13
|
Requires-Python: >=3.7
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
|
+
Requires-Dist: numpy
|
|
17
|
+
Requires-Dist: matplotlib
|
|
18
|
+
Dynamic: license-file
|
|
16
19
|
|
|
17
20
|
# Interferometer package
|
|
18
21
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from unittest import TestCase
|
|
3
|
+
|
|
4
|
+
from interferometer import random_unitary, triangle_decomposition, square_decomposition
|
|
5
|
+
|
|
6
|
+
class TestInterferometer(TestCase):
|
|
7
|
+
|
|
8
|
+
def test_triangle_interferometer(self):
|
|
9
|
+
U = random_unitary(5)
|
|
10
|
+
I = triangle_decomposition(U)
|
|
11
|
+
self.assertTrue(abs(np.max(I.calculate_transformation() - U)) < 1e-14)
|
|
12
|
+
|
|
13
|
+
def test_square_interferometer(self):
|
|
14
|
+
U = random_unitary(5)
|
|
15
|
+
I = square_decomposition(U)
|
|
16
|
+
self.assertTrue(abs(np.max(I.calculate_transformation() - U)) < 1e-14)
|
|
17
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|