MoMPy 0.0.1__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.
- mompy-0.0.1/LICENSE.md +19 -0
- mompy-0.0.1/PKG-INFO +25 -0
- mompy-0.0.1/README.md +9 -0
- mompy-0.0.1/pyproject.toml +28 -0
- mompy-0.0.1/src/MoMPy/MoM.py +356 -0
- mompy-0.0.1/src/MoMPy/__init__.py +8 -0
- mompy-0.0.1/tests/to_test_MoM.py +116 -0
mompy-0.0.1/LICENSE.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2018 The Python Packaging Authority
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
mompy-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: MoMPy
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Moment matrix generation package for SDP hierarchies
|
|
5
|
+
Project-URL: Homepage, https://github.com/pypa/sampleproject
|
|
6
|
+
Project-URL: Issues, https://github.com/pypa/sampleproject/issues
|
|
7
|
+
Author-email: Carles Roch i Carceller <chalswater@gmail.com>
|
|
8
|
+
License-File: LICENSE.md
|
|
9
|
+
Keywords: SDP hierarchy,moment matrix,semidefinite programming
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
|
+
Requires-Dist: numpy
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
MoMPy: Moment matrix generation and managing package for SDP hierarchies.
|
|
18
|
+
|
|
19
|
+
This is a package to generate moment matrices for SDP hierarchies. The package contains the following relevant functions:
|
|
20
|
+
|
|
21
|
+
- MomentMatrix: generates the moment matrix with operational equivalences already taken into account (except normalisation).
|
|
22
|
+
|
|
23
|
+
- normalisation_contraints: takes into account normalisation constraints. This is to be called inside the SDP and added as a constraint!
|
|
24
|
+
|
|
25
|
+
More information in the code files.
|
mompy-0.0.1/README.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MoMPy: Moment matrix generation and managing package for SDP hierarchies.
|
|
2
|
+
|
|
3
|
+
This is a package to generate moment matrices for SDP hierarchies. The package contains the following relevant functions:
|
|
4
|
+
|
|
5
|
+
- MomentMatrix: generates the moment matrix with operational equivalences already taken into account (except normalisation).
|
|
6
|
+
|
|
7
|
+
- normalisation_contraints: takes into account normalisation constraints. This is to be called inside the SDP and added as a constraint!
|
|
8
|
+
|
|
9
|
+
More information in the code files.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "MoMPy"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="Carles Roch i Carceller", email="chalswater@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
description = "Moment matrix generation package for SDP hierarchies"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.8"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
]
|
|
19
|
+
keywords = [
|
|
20
|
+
"semidefinite programming",
|
|
21
|
+
"moment matrix",
|
|
22
|
+
"SDP hierarchy"
|
|
23
|
+
]
|
|
24
|
+
dependencies = ["NumPy"]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/pypa/sampleproject"
|
|
28
|
+
Issues = "https://github.com/pypa/sampleproject/issues"
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Created on Thu Jun 27 22:41:00 2024
|
|
5
|
+
|
|
6
|
+
@author: carles
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
#------------------------------------------------------------------------------------------
|
|
12
|
+
#------------------------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
def Permute(v):
|
|
15
|
+
""" Cyclical permutation """
|
|
16
|
+
return [v[-1]] + v[:-1]
|
|
17
|
+
|
|
18
|
+
#------------------------------------------------------------------------------------------
|
|
19
|
+
#------------------------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def Commute(v,index):
|
|
22
|
+
""" Commute v[index] in v """
|
|
23
|
+
store = v[index]
|
|
24
|
+
|
|
25
|
+
v_copy = [ii for ii in v]
|
|
26
|
+
v_copy.remove(store)
|
|
27
|
+
|
|
28
|
+
out = []
|
|
29
|
+
entered = False
|
|
30
|
+
for jj in range(len(v)):
|
|
31
|
+
if jj == index + 1:
|
|
32
|
+
out += [store]
|
|
33
|
+
entered = True
|
|
34
|
+
else:
|
|
35
|
+
if entered == True:
|
|
36
|
+
out += [v_copy[jj-1]]
|
|
37
|
+
else:
|
|
38
|
+
if jj < len(v_copy):
|
|
39
|
+
out += [v_copy[jj]]
|
|
40
|
+
|
|
41
|
+
if len(out) < len(v):
|
|
42
|
+
out = [store] + out
|
|
43
|
+
|
|
44
|
+
return out
|
|
45
|
+
|
|
46
|
+
#------------------------------------------------------------------------------------------
|
|
47
|
+
#------------------------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
def fmap(table,i):
|
|
50
|
+
''' A funciton that maps a value on table[item][0] --> table[item][1] in the same row'''
|
|
51
|
+
found = False
|
|
52
|
+
for item in range(len(table)):
|
|
53
|
+
if i in table[item][0]: # For non-commuting variables, i is a vector!
|
|
54
|
+
found = True
|
|
55
|
+
item_saved = item
|
|
56
|
+
|
|
57
|
+
if found == True:
|
|
58
|
+
return table[item_saved][1]
|
|
59
|
+
else:
|
|
60
|
+
return 'ERROR: The value does not appear in the mapping rule'
|
|
61
|
+
|
|
62
|
+
#------------------------------------------------------------------------------------------
|
|
63
|
+
#------------------------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
def reverse_list(lista):
|
|
66
|
+
return[k for k in reversed(lista)]
|
|
67
|
+
|
|
68
|
+
#------------------------------------------------------------------------------------------
|
|
69
|
+
#------------------------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
def normalisation_contraints(element,list_identities_in):
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
Def:
|
|
75
|
+
List of elements which summed are equal to the last element in each list
|
|
76
|
+
|
|
77
|
+
Arguments:
|
|
78
|
+
|
|
79
|
+
element: list of elements that require normalisation
|
|
80
|
+
|
|
81
|
+
list_identities_in: lost of equivalences
|
|
82
|
+
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
# element: list of elements that require normalisation
|
|
86
|
+
# list_identities_in: list of exsisting equivalences
|
|
87
|
+
|
|
88
|
+
output_ct = []
|
|
89
|
+
already_counted = []
|
|
90
|
+
|
|
91
|
+
list_identities = list_identities_in[:]
|
|
92
|
+
|
|
93
|
+
for term in list_identities:
|
|
94
|
+
dd = 0
|
|
95
|
+
for pp in range(len(term[dd])):
|
|
96
|
+
yy = 0
|
|
97
|
+
string = []
|
|
98
|
+
if term[dd][pp] == element[yy]:
|
|
99
|
+
new_input = term[dd][:]
|
|
100
|
+
copy_without_element = new_input[:]
|
|
101
|
+
del copy_without_element[pp]
|
|
102
|
+
if len(copy_without_element) < 1:
|
|
103
|
+
copy_without_element += [0]
|
|
104
|
+
for hh in range(len(element)):
|
|
105
|
+
new_input[pp] = element[hh]
|
|
106
|
+
copy = new_input[:]
|
|
107
|
+
string += [copy]
|
|
108
|
+
string += [copy_without_element]
|
|
109
|
+
|
|
110
|
+
if len(string) > 1:
|
|
111
|
+
output_ct += [string]
|
|
112
|
+
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
Output:
|
|
116
|
+
|
|
117
|
+
list of indices which added are equal to the last one
|
|
118
|
+
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
return output_ct
|
|
122
|
+
|
|
123
|
+
#------------------------------------------------------------------------------------------
|
|
124
|
+
#------------------------------------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
def MomentMatrix(S_1,S_2,higher_order_elements,rank_1_projectors,orthogonal_projectors,commuting_elements,states):
|
|
127
|
+
|
|
128
|
+
"""
|
|
129
|
+
Generator of SDP hierarchy Moment matrix
|
|
130
|
+
|
|
131
|
+
S_1:
|
|
132
|
+
list of first order elements (zero order not included)
|
|
133
|
+
|
|
134
|
+
S_2:
|
|
135
|
+
list of elements to generate second order terms (zero order not included)
|
|
136
|
+
|
|
137
|
+
higher_order_elements:
|
|
138
|
+
list of specific elements of higher orders
|
|
139
|
+
|
|
140
|
+
rank_1_projectors:
|
|
141
|
+
list of rank-1 projectors
|
|
142
|
+
|
|
143
|
+
orthogonal_projectors:
|
|
144
|
+
lists of orthogonal projectors
|
|
145
|
+
|
|
146
|
+
commuting_elements:
|
|
147
|
+
list of elements that commute with everything EXCEPT with the states
|
|
148
|
+
|
|
149
|
+
states:
|
|
150
|
+
delcare what are your states that don't commute with anything (only used for commutation constraints)
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
S = []
|
|
154
|
+
for v in S_1:
|
|
155
|
+
S += [[v]] # Add first order monomials
|
|
156
|
+
|
|
157
|
+
for k in S_2:
|
|
158
|
+
for h in S_2:
|
|
159
|
+
S += [[h,k]] # Compute second order monomials
|
|
160
|
+
|
|
161
|
+
S += higher_order_elements # Add additional higher order elements
|
|
162
|
+
|
|
163
|
+
Mexp = [] # Here we store the matrix for all explicit elements
|
|
164
|
+
complete_list_explicit = [] # Here we store all explicit elements in a list
|
|
165
|
+
for r in range(len(S)+1):
|
|
166
|
+
Mexp += [[]]
|
|
167
|
+
for c in range(len(S)+1):
|
|
168
|
+
if r == 0 and c > 0:
|
|
169
|
+
Mexp[r] += [reverse_list(S[c-1])]
|
|
170
|
+
elif c == 0 and r > 0:
|
|
171
|
+
Mexp[r] += [S[r-1]]
|
|
172
|
+
elif c == 0 and r == 0:
|
|
173
|
+
Mexp[r] += [[0]]
|
|
174
|
+
else:
|
|
175
|
+
Mexp[r] += [S[r-1]+reverse_list(S[c-1])]
|
|
176
|
+
if r >= c:
|
|
177
|
+
complete_list_explicit += [ Mexp[r][c] ]
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# Detect the elemenets that are equal to zero by orthogonality rules
|
|
181
|
+
group_of_zeros = [] # Group of zeros
|
|
182
|
+
for r in range(len(S)+1):
|
|
183
|
+
for c in range(len(S)+1):
|
|
184
|
+
|
|
185
|
+
# Orthogonal projectors
|
|
186
|
+
if len(Mexp[r][c]) >= 2:
|
|
187
|
+
for ii in range(len(Mexp[r][c])):
|
|
188
|
+
for kk in range(len(orthogonal_projectors)):
|
|
189
|
+
if Mexp[r][c][ii] in orthogonal_projectors[kk] and Mexp[r][c][np.mod(ii+1,len(Mexp[r][c]))] in orthogonal_projectors[kk]:
|
|
190
|
+
if Mexp[r][c][ii] != Mexp[r][c][np.mod(ii+1,len(Mexp[r][c]))]:
|
|
191
|
+
new_vec = [Mexp[r][c][jj] for jj in range(len(Mexp[r][c]))]
|
|
192
|
+
if new_vec not in group_of_zeros: #if it is not in the list already, add it
|
|
193
|
+
group_of_zeros += [new_vec]
|
|
194
|
+
if Mexp[r][c] in complete_list_explicit:
|
|
195
|
+
complete_list_explicit.remove(Mexp[r][c]) # Remove element that was already taken into account
|
|
196
|
+
|
|
197
|
+
# Apply symmetry rules
|
|
198
|
+
id_elements = [] # list containing groups of identical elements
|
|
199
|
+
ss = 0
|
|
200
|
+
for element in complete_list_explicit:
|
|
201
|
+
|
|
202
|
+
print(f'\r Building Moment Matrix: {np.round(ss/(len(complete_list_explicit)),2)}%'+'\r',end=' ')
|
|
203
|
+
equivalences_vec = [] # vector of equivalent elements
|
|
204
|
+
|
|
205
|
+
missed_zero = False
|
|
206
|
+
|
|
207
|
+
# Identical elements by cyclic permutation in traces
|
|
208
|
+
new_vec = element[:]
|
|
209
|
+
for ii in range(len(element)+1):
|
|
210
|
+
if new_vec not in equivalences_vec: # if it is not in the list already, add it
|
|
211
|
+
equivalences_vec += [new_vec]
|
|
212
|
+
if new_vec in group_of_zeros:
|
|
213
|
+
missed_zero = True
|
|
214
|
+
new_vec = Permute(new_vec) # Permute members (monomials) of the element
|
|
215
|
+
|
|
216
|
+
# Identical elements by being rank-1 projectors (B^2 = B)
|
|
217
|
+
if len(element) >= 2:
|
|
218
|
+
for ii in range(len(element)):
|
|
219
|
+
if element[ii] in rank_1_projectors:
|
|
220
|
+
if element[ii] == element[np.mod(ii+1,len(element))]:
|
|
221
|
+
new_vec = [element[jj] for jj in range(len(element)) if jj != ii]
|
|
222
|
+
if new_vec not in equivalences_vec: #if it is not in the list already, add it
|
|
223
|
+
equivalences_vec += [new_vec]
|
|
224
|
+
if new_vec in group_of_zeros:
|
|
225
|
+
missed_zero = True
|
|
226
|
+
|
|
227
|
+
# Identical elements by commuting rules
|
|
228
|
+
# When you commute an element, you completely change the whole set of elements, and so one needs to re-check ciclicity and rank-1
|
|
229
|
+
new_vec = element[:]
|
|
230
|
+
new_lists = equivalences_vec
|
|
231
|
+
diff = len(commuting_elements) # if there are no commuting elements, we don't need to do this re-checking
|
|
232
|
+
already_counted = []
|
|
233
|
+
while diff > 0: # While we keep adding elements in "new_lists" we will do the following
|
|
234
|
+
len_ini = len(new_lists)
|
|
235
|
+
for term in new_lists:
|
|
236
|
+
if term not in already_counted:
|
|
237
|
+
already_counted += [term]
|
|
238
|
+
new_vec = term[:]
|
|
239
|
+
for hh in range(len(term)):
|
|
240
|
+
if term[hh] in commuting_elements: #if the element is in the list of commuting elements
|
|
241
|
+
for ii in range(len(new_vec)+1):
|
|
242
|
+
new_vec = Commute(new_vec,np.mod(hh+ii,len(new_vec))) # permute members (monomials) of the element
|
|
243
|
+
if new_vec not in new_lists:
|
|
244
|
+
new_lists += [new_vec]
|
|
245
|
+
if new_vec not in equivalences_vec:
|
|
246
|
+
equivalences_vec += [new_vec]
|
|
247
|
+
if new_vec in group_of_zeros:
|
|
248
|
+
missed_zero = True
|
|
249
|
+
|
|
250
|
+
new_vec = term[:]
|
|
251
|
+
for ii in range(len(new_vec)+1): # Include also the cyclic permutations of the new elements
|
|
252
|
+
if new_vec not in equivalences_vec: # if it is not in the list already, add it
|
|
253
|
+
equivalences_vec += [new_vec]
|
|
254
|
+
if new_vec in group_of_zeros:
|
|
255
|
+
missed_zero = True
|
|
256
|
+
new_vec = Permute(new_vec) # Permute members (monomials) of the element
|
|
257
|
+
|
|
258
|
+
new_vec = term[:]
|
|
259
|
+
if len(new_vec) >= 2:
|
|
260
|
+
for ii in range(len(new_vec)): # Also include all rank-1 element reductions that can happen
|
|
261
|
+
if new_vec[ii] in rank_1_projectors:
|
|
262
|
+
if new_vec[ii] == new_vec[np.mod(ii+1,len(new_vec))]:
|
|
263
|
+
new_vec_2 = [new_vec[jj] for jj in range(len(new_vec)) if jj != ii]
|
|
264
|
+
if new_vec_2 not in equivalences_vec: #if it is not in the list already, add it
|
|
265
|
+
equivalences_vec += [new_vec_2]
|
|
266
|
+
if new_vec_2 in group_of_zeros:
|
|
267
|
+
missed_zero = True
|
|
268
|
+
|
|
269
|
+
# Check if the new element is zero or not (and we did not count it initially)
|
|
270
|
+
new_vec = term[:]
|
|
271
|
+
if len(new_vec) >= 2:
|
|
272
|
+
for ii in range(len(new_vec)):
|
|
273
|
+
for kk in range(len(orthogonal_projectors)):
|
|
274
|
+
if new_vec[ii] in orthogonal_projectors[kk] and new_vec[np.mod(ii+1,len(new_vec))] in orthogonal_projectors[kk]:
|
|
275
|
+
if new_vec[ii] != new_vec[np.mod(ii+1,len(new_vec))]:
|
|
276
|
+
new_vec_2 = [new_vec[jj] for jj in range(len(new_vec))]
|
|
277
|
+
if new_vec_2 not in group_of_zeros: #if it is not in the list already, add it
|
|
278
|
+
group_of_zeros += [new_vec_2]
|
|
279
|
+
missed_zero = True
|
|
280
|
+
|
|
281
|
+
len_fin = len(new_lists)
|
|
282
|
+
diff = len_fin - len_ini
|
|
283
|
+
|
|
284
|
+
if missed_zero == True: # if we detected that an element is a zero, then all is zero
|
|
285
|
+
for el in equivalences_vec:
|
|
286
|
+
if el not in group_of_zeros:
|
|
287
|
+
group_of_zeros += [el]
|
|
288
|
+
else:
|
|
289
|
+
# Check if any of the elements in the equivalences is already accounted for
|
|
290
|
+
found_one = False
|
|
291
|
+
saved_id = []
|
|
292
|
+
for el in equivalences_vec:
|
|
293
|
+
for ids in id_elements:
|
|
294
|
+
if el in ids:
|
|
295
|
+
found_one = True
|
|
296
|
+
saved_id += [ids]
|
|
297
|
+
id_elements.remove(ids)
|
|
298
|
+
|
|
299
|
+
# If so, merge all elements in one without repetitions:
|
|
300
|
+
if found_one == True:
|
|
301
|
+
for tt in range(len(saved_id)):
|
|
302
|
+
for iss in saved_id[tt]:
|
|
303
|
+
if iss not in equivalences_vec:
|
|
304
|
+
equivalences_vec += [iss]
|
|
305
|
+
|
|
306
|
+
# Add the equivalences in a bigger list of identities
|
|
307
|
+
id_elements += [equivalences_vec]
|
|
308
|
+
ss += 1
|
|
309
|
+
|
|
310
|
+
# Add the zeros
|
|
311
|
+
id_elements += [group_of_zeros]
|
|
312
|
+
|
|
313
|
+
Moment_Matrix = np.zeros((len(Mexp),len(Mexp)),dtype=int) # This is the output Gama matrix with numbers in each element
|
|
314
|
+
map_table = [] # Table to map explicit elements to the number group of identities
|
|
315
|
+
already_counted = []
|
|
316
|
+
already_counted_2 = []
|
|
317
|
+
|
|
318
|
+
ll = 0
|
|
319
|
+
for l in range(int(len(id_elements))):
|
|
320
|
+
if id_elements[l] not in already_counted_2:
|
|
321
|
+
map_table += [[id_elements[l],ll]]
|
|
322
|
+
already_counted_2 += [id_elements[l]]
|
|
323
|
+
already_counted += id_elements[l]
|
|
324
|
+
ll += 1
|
|
325
|
+
|
|
326
|
+
for j in range(len(Mexp)):
|
|
327
|
+
for i in range(j,len(Mexp)):
|
|
328
|
+
Moment_Matrix[i][j] = fmap(map_table,Mexp[i][j])
|
|
329
|
+
Moment_Matrix[j][i] = Moment_Matrix[i][j]
|
|
330
|
+
|
|
331
|
+
list_of_eq_indices = np.unique(Moment_Matrix) # Unique elements in M
|
|
332
|
+
|
|
333
|
+
"""
|
|
334
|
+
Outputs:
|
|
335
|
+
|
|
336
|
+
Moment_Matrix:
|
|
337
|
+
Moment Matrix with indices of equivalent elements
|
|
338
|
+
|
|
339
|
+
map_table:
|
|
340
|
+
table used to map explicit elements to their equivalence index in Moment_Matrix
|
|
341
|
+
the last element in map_table are all the zeros emerging from orthogonality
|
|
342
|
+
|
|
343
|
+
S:
|
|
344
|
+
complete list of all elements
|
|
345
|
+
|
|
346
|
+
list_of_eq_indices:
|
|
347
|
+
list of all equivalence indices in Moment_Matrix
|
|
348
|
+
|
|
349
|
+
Mexp:
|
|
350
|
+
Moment matrix with all explicit elements
|
|
351
|
+
|
|
352
|
+
"""
|
|
353
|
+
|
|
354
|
+
return Moment_Matrix,map_table,S,list_of_eq_indices,Mexp
|
|
355
|
+
|
|
356
|
+
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Created on Thu Jun 27 23:02:24 2024
|
|
5
|
+
|
|
6
|
+
@author: carles roch i carceller
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
nX = 2 # number of state preparations
|
|
10
|
+
nY = 1 # number of measurement settings
|
|
11
|
+
nB = 2 # number of measurement outcomes
|
|
12
|
+
nK = 2 # number of photon states (for avg photon numbe nK => n_trunc + 1
|
|
13
|
+
|
|
14
|
+
#---------------------------------------------------------------------#
|
|
15
|
+
# Collect all monomials #
|
|
16
|
+
#---------------------------------------------------------------------#
|
|
17
|
+
|
|
18
|
+
# Track operators in the tracial matrix
|
|
19
|
+
w_R = [] # Prepared quantum state
|
|
20
|
+
w_B = [] # Measurement
|
|
21
|
+
w_P = [] # Observable (photon number projector)
|
|
22
|
+
|
|
23
|
+
S_1 = [] # List of first order elements
|
|
24
|
+
cc = 1
|
|
25
|
+
|
|
26
|
+
for x in range(nX):
|
|
27
|
+
S_1 += [cc]
|
|
28
|
+
w_R += [cc]
|
|
29
|
+
cc += 1
|
|
30
|
+
|
|
31
|
+
for y in range(nY):
|
|
32
|
+
w_B += [[]]
|
|
33
|
+
for b in range(nB):
|
|
34
|
+
S_1 += [cc]
|
|
35
|
+
w_B[y] += [cc]
|
|
36
|
+
cc += 1
|
|
37
|
+
|
|
38
|
+
for k in range(nK):
|
|
39
|
+
S_1 += [cc]
|
|
40
|
+
w_P += [cc]
|
|
41
|
+
cc += 1
|
|
42
|
+
|
|
43
|
+
# Additional higher order elements
|
|
44
|
+
S_high = [] # Some third order elements
|
|
45
|
+
|
|
46
|
+
for k in range(nK):
|
|
47
|
+
for x in range(nX):
|
|
48
|
+
for kk in range(nK):
|
|
49
|
+
S_high += [[w_P[k],w_R[x],w_P[kk]]]
|
|
50
|
+
|
|
51
|
+
for b in range(nB):
|
|
52
|
+
for k in range(nK):
|
|
53
|
+
for kk in range(nK):
|
|
54
|
+
for y in range(nY):
|
|
55
|
+
S_high += [[w_B[y][b],w_P[k],w_P[kk]]]
|
|
56
|
+
|
|
57
|
+
for x in range(nX):
|
|
58
|
+
for b in range(nB):
|
|
59
|
+
for bb in range(nB):
|
|
60
|
+
for y in range(nY):
|
|
61
|
+
for yy in range(nY):
|
|
62
|
+
S_high += [[w_R[x],w_B[y][b],w_B[yy][bb]]]
|
|
63
|
+
|
|
64
|
+
for x in range(nX):
|
|
65
|
+
for b in range(nB):
|
|
66
|
+
for k in range(nK):
|
|
67
|
+
for y in range(nY):
|
|
68
|
+
S_high += [[w_R[x],w_B[y][b],w_P[k]]]
|
|
69
|
+
S_high += [[w_B[y][b],w_R[x],w_P[k]]]
|
|
70
|
+
|
|
71
|
+
S_high = [] # Uncomment if we only allow up to some 2nd order elements in the hierarchy
|
|
72
|
+
|
|
73
|
+
# Second order elements
|
|
74
|
+
some_second = True
|
|
75
|
+
if some_second == True:
|
|
76
|
+
for x in range(nX):
|
|
77
|
+
for xx in range(nX):
|
|
78
|
+
S_high += [[w_R[x],w_R[xx]]]
|
|
79
|
+
|
|
80
|
+
for x in range(nX):
|
|
81
|
+
for b in range(nB):
|
|
82
|
+
for y in range(nY):
|
|
83
|
+
S_high += [[w_R[x],w_B[y][b]]]
|
|
84
|
+
|
|
85
|
+
for k in range(nK):
|
|
86
|
+
for b in range(nB):
|
|
87
|
+
for y in range(nY):
|
|
88
|
+
S_high += [[w_P[k],w_B[y][b]]]
|
|
89
|
+
|
|
90
|
+
for x in range(nX):
|
|
91
|
+
for k in range(nK):
|
|
92
|
+
S_high += [[w_P[k],w_R[x]]]
|
|
93
|
+
|
|
94
|
+
#S_high = []
|
|
95
|
+
|
|
96
|
+
# Set the operational rules within the SDP relaxation
|
|
97
|
+
list_states = [] # operators that do not commute with anything
|
|
98
|
+
rank_1_projectors = w_R
|
|
99
|
+
rank_1_projectors += [w_B[y][b] for y in range(nY) for b in range(nB)]
|
|
100
|
+
rank_1_projectors += [w_P[k] for k in range(nK)]
|
|
101
|
+
orthogonal_projectors = []
|
|
102
|
+
orthogonal_projectors += [ w_B[y] for y in range(nY)]
|
|
103
|
+
orthogonal_projectors += [ w_P ]
|
|
104
|
+
commuting_variables = [] # commuting elements (wxcept with elements in "list_states"
|
|
105
|
+
|
|
106
|
+
print('Rank-1 projectors',rank_1_projectors)
|
|
107
|
+
print('Orthogonal projectors',orthogonal_projectors)
|
|
108
|
+
print('commuting elements',commuting_variables)
|
|
109
|
+
|
|
110
|
+
[Moment_Matrix,map_table,S,list_of_eq_indices,Mexp] = MomentMatrix(S_1,[],S_high,rank_1_projectors,orthogonal_projectors,commuting_variables,list_states)
|
|
111
|
+
|
|
112
|
+
print('Matrix size:',np.shape(G_new))
|
|
113
|
+
|
|
114
|
+
print(Moment_Matrix)
|
|
115
|
+
for element in map_table:
|
|
116
|
+
print(element)
|