17
17
; ;; more than three times faster than the equivalent application of a
18
18
; ;; PERMUTATION-GENERAL object).
19
19
20
+ (defconstant +qubit-index-length+ (ceiling (log qvm ::+max-nat-tuple-cardinality+ 2 ))
21
+ " Number of bits required to represent a qubit index." )
22
+
23
+ (defconstant +max-number-of-transpositions+ (* 2 #. qvm::+max-nat-tuple-cardinality+ )
24
+ " Upper bound on the number of transpositions defining an arbitrary permutation." )
25
+
26
+ (deftype qubit-index ()
27
+ ' (unsigned-byte #. +qubit-index-length+))
28
+
20
29
(deftype transposition ()
21
- ' (or null (cons alexandria :non-negative-fixnum
22
- alexandria :non-negative-fixnum)))
30
+ ' (or null (cons qubit-index qubit-index)))
23
31
24
32
(defclass permutation ()
25
33
()
39
47
:transpositions nil )
40
48
(:documentation " Arbitrary permutation acting on sets of qubit indices." ))
41
49
42
- (defclass permutation-transposition ()
50
+ (defclass permutation-transposition (permutation )
43
51
((tau
44
- :type ( unsigned-byte 6 ) ; Implies a maximum of 2⁶ = 64 qubits.
52
+ :type qubit-index
45
53
:initarg :tau
46
54
:initform (error-missing-initform :tau )
47
55
:documentation " Positive value of τ in π = (0 τ)." ))
@@ -81,7 +89,7 @@ Note that in the example above, the transposition (0 2) was automatically added.
81
89
(codomain nil ))
82
90
83
91
(flet ((check-transposition (a b)
84
- (declare (type alexandria :non-negative-fixnum a b))
92
+ (declare (type qubit-index a b))
85
93
(let ((x (assoc a transpositions*))
86
94
(y (rassoc b transpositions*)))
87
95
(alexandria :when-let ((z (or x y)))
@@ -90,17 +98,15 @@ Note that in the example above, the transposition (0 2) was automatically added.
90
98
91
99
(declare (inline check-transposition))
92
100
93
- (loop :for (a . b) :of-type alexandria :non-negative-fixnum :in transpositions :do
101
+ (loop :for (a . b) :of-type qubit-index :in transpositions :do
94
102
(check-transposition a b)
95
103
(unless (= a b)
96
104
(pushnew (cons a b) transpositions*)
97
105
(pushnew a domain)
98
106
(pushnew b codomain))))
99
107
100
- (loop :for a :of-type alexandria :non-negative-fixnum
101
- :in (set-difference codomain domain)
102
- :for b :of-type alexandria :non-negative-fixnum
103
- :in (set-difference domain codomain)
108
+ (loop :for a :of-type qubit-index :in (set-difference codomain domain)
109
+ :for b :of-type qubit-index :in (set-difference domain codomain)
104
110
:unless (= a b) :do
105
111
(pushnew (cons a b) transpositions* :test #' equal ))
106
112
@@ -159,7 +165,7 @@ If PERMUTATIONS is the list π₁, π₂, ..., πₛ, then the result is the com
159
165
(loop :for permutation :in permutations :when permutation :do
160
166
(loop :for transposition :of-type transposition :in (permutation-transpositions permutation) :do
161
167
(let ((a (first transposition)))
162
- (declare (type alexandria :non-negative-fixnum a))
168
+ (declare (type qubit-index a))
163
169
(pushnew a domain))))
164
170
165
171
; ; Now map each domain element to obtain transpositions.
@@ -169,8 +175,8 @@ If PERMUTATIONS is the list π₁, π₂, ..., πₛ, then the result is the com
169
175
(setf (aref codomain i)
170
176
(apply-permutation permutation (aref codomain i))))
171
177
:finally
172
- (loop :for a :of-type alexandria :non-negative-fixnum :in domain
173
- :for b :of-type alexandria :non-negative-fixnum :across codomain
178
+ (loop :for a :of-type qubit-index :in domain
179
+ :for b :of-type qubit-index :across codomain
174
180
:unless (= a b) :do
175
181
(pushnew (cons a b) transpositions :test #' equal )))
176
182
@@ -196,13 +202,12 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
196
202
197
203
(defmethod apply-qubit-permutation ((permutation permutation-transposition) address)
198
204
(declare #. qvm::*optimize-dangerously-fast*
199
- (type (or null permutation) permutation)
200
- ; ; (type qvm:amplitude-address address)
201
- (type (unsigned-byte 64 ) address) ; Imposed maximum number of qubits.
205
+ (type permutation permutation)
206
+ (type qvm :amplitude-address address)
202
207
(values qvm :amplitude-address))
203
208
204
209
(let ((tau (slot-value permutation ' tau)))
205
- (declare (type ( unsigned-byte 6 ) tau))
210
+ (declare (type qubit-index tau))
206
211
207
212
; ; Swap bits 0 and TAU in ADDRESS.
208
213
(let ((x (logxor (logand address 1 ) (logand (ash address (- tau)) 1 ))))
@@ -215,15 +220,14 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
215
220
; ; J. Comput., vol. 24, no. 2, pp. 266–278, Apr. 1995.
216
221
217
222
(declare #. qvm::*optimize-dangerously-fast*
218
- (type (or null permutation) permutation)
219
- ; ; (type qvm:amplitude-address address)
220
- (type (unsigned-byte 64 ) address) ; Imposed maximum number of qubits.
223
+ (type permutation permutation)
224
+ (type qvm :amplitude-address address)
221
225
(values qvm :amplitude-address))
222
226
223
227
(let* ((transpositions (slot-value permutation ' transpositions))
224
228
(number-of-transpositions (slot-value permutation ' number-of-transpositions))
225
229
(bit-vector (make-array number-of-transpositions :element-type ' bit)))
226
- (declare (type (integer 0 128 ) number-of-transpositions)
230
+ (declare (type (integer 0 #. +max-number-of-transpositions+ ) number-of-transpositions)
227
231
(dynamic-extent bit-vector ))
228
232
229
233
(loop :for index :from 0
@@ -235,8 +239,7 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
235
239
:for transposition :of-type transposition :in transpositions :do
236
240
(setf address (the qvm :amplitude-address
237
241
(dpb (bit bit-vector index)
238
- (byte 1 (the (unsigned-byte 6 ) (rest transposition))) ; Enable this for speed (assumes a maximum of 64 qubits).
239
- ; ; (byte 1 (rest transposition))
242
+ (byte 1 (the qubit-index (rest transposition)))
240
243
address)))
241
244
:finally (return address))))
242
245
@@ -256,7 +259,8 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
256
259
(minus-tau (- tau)))
257
260
` (lambda (, address)
258
261
(declare #. qvm::*optimize-dangerously-fast*
259
- (type (unsigned-byte 64 ) , address) ; Imposed maximum number of qubits.
262
+ (type permutation permutation)
263
+ (type qvm :amplitude-address , address)
260
264
(values qvm :amplitude-address))
261
265
262
266
; ; Swap bits 0 and TAU in ADDRESS.
@@ -269,8 +273,8 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
269
273
(number-of-transpositions (slot-value permutation ' number-of-transpositions)))
270
274
` (lambda (, address)
271
275
(declare #. qvm::*optimize-dangerously-fast*
272
- (type ( or null permutation) permutation)
273
- (type ( unsigned-byte 64 ) , address)
276
+ (type permutation permutation)
277
+ (type qvm :amplitude-address , address)
274
278
(values qvm :amplitude-address))
275
279
276
280
(let ((bit-vector (make-array , number-of-transpositions :element-type ' bit)))
@@ -285,7 +289,7 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
285
289
:for transposition :of-type transposition :in transpositions
286
290
:collect ` (setf , address (the qvm :amplitude-address
287
291
(dpb (bit bit-vector , index)
288
- (byte 1 (the ( unsigned-byte 6 ) , (rest transposition)))
292
+ (byte 1 (the qubit-index , (rest transposition)))
289
293
, address))))
290
294
, address))))
291
295
0 commit comments