-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClassic_generators.py
More file actions
127 lines (80 loc) · 2.84 KB
/
Classic_generators.py
File metadata and controls
127 lines (80 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
from Classic_algebra import *
import numpy as np
import sys
np.set_printoptions(threshold=sys.maxsize)
def sev(A,B):
set = []
taille = np.shape(A)
n = taille[0]
F2n = F2_n(n) #O(2**n)
C = np.concatenate((A,B),axis=1)
for comblin in F2n:
#on parcourt les vecteurs (ei)
#2**n calls
row = np.zeros(2*n, int)
for i in range(n): #n calls
#on ajoute ei*ci
#n calls
row += int(comblin[i])*C[i]
set.append(row)
set = np.remainder(set,2)
return np.array(set)
def are_equivalent(M, N):
# M, N are two matrices of Mnx2n(F2)
# We want to know if they generate the same subspace
# This happens if all the lines of N belong to the subspace generated by M and of the lines of M belong to the subspace generated by N
# O(N*2**N) complexity
taille = np.shape(M)
n = taille[0]
M1 = M[:,:n]
M2 = M[:,n:]
SM = sev(M1,M2) #O(n*2**n)
for generatorsN in N: #N calls
is_elementM = False
for elements in SM : #2**N calls
if np.array_equal(generatorsN,elements): #O(1)
is_elementM = True
if not is_elementM :
return False
N1 = N[:,:n]
N2 = N[:,n:]
SN = sev(N1,N2) #O(N*2**N)
for generatorsM in M: #N call
is_elementN = False
for elements in SN : #2**N calls
if np.array_equal(generatorsM,elements): #O(1)
is_elementN=True
if not is_elementN :
return False
return True
def pauli_ordre_2(i,j):
#les matrices de Pauli sont codées de manière binaire
#00 : I
#10 : X
#01 : Y
#11 : Z
#O(1) complexity
if i%2==0 and j%2==0:
return 'I'
elif i%2==1 and j%2==0 :
return 'X'
elif i%2==0 and j%2==1 :
return 'Z'
else :
return 'Y'
def sub_pauli(A,B):
#on traduit le sous-espace vectoriel engendré par les lignes de la matrice (A,B) en matrice de Pauli selon la fonction précédente
#O(N*2**N) complexity
set = sev(A,B) # O(N*2**N)
taille = np.shape(A)
n = taille[0]
paulisubset = []
for row in set: #N calls
#pour chaque ligne du sous-espace vectoriel
#on définit une matrice de pauli à n qubit
pauli_ordre_n = ''
for i in range(n): #N calls
#la ième matrice d'ordre 2 du n-qubit est donnée par les valeurs en position i et n+i de la ligne du sous-ensemble
pauli_ordre_n += pauli_ordre_2(row[i],row[n+i])
paulisubset.append(pauli_ordre_n)
return paulisubset