1717; ;; more than three times faster than the equivalent application of a
1818; ;; PERMUTATION-GENERAL object).
1919
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+
2029(deftype transposition ()
21- ' (or null (cons alexandria :non-negative-fixnum
22- alexandria :non-negative-fixnum)))
30+ ' (or null (cons qubit-index qubit-index)))
2331
2432(defclass permutation ()
2533 ()
3947 :transpositions nil )
4048 (:documentation " Arbitrary permutation acting on sets of qubit indices." ))
4149
42- (defclass permutation-transposition ()
50+ (defclass permutation-transposition (permutation )
4351 ((tau
44- :type ( unsigned-byte 6 ) ; Implies a maximum of 2⁶ = 64 qubits.
52+ :type qubit-index
4553 :initarg :tau
4654 :initform (error-missing-initform :tau )
4755 :documentation " Positive value of τ in π = (0 τ)." ))
@@ -81,7 +89,7 @@ Note that in the example above, the transposition (0 2) was automatically added.
8189 (codomain nil ))
8290
8391 (flet ((check-transposition (a b)
84- (declare (type alexandria :non-negative-fixnum a b))
92+ (declare (type qubit-index a b))
8593 (let ((x (assoc a transpositions*))
8694 (y (rassoc b transpositions*)))
8795 (alexandria :when-let ((z (or x y)))
@@ -90,17 +98,15 @@ Note that in the example above, the transposition (0 2) was automatically added.
9098
9199 (declare (inline check-transposition))
92100
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
94102 (check-transposition a b)
95103 (unless (= a b)
96104 (pushnew (cons a b) transpositions*)
97105 (pushnew a domain)
98106 (pushnew b codomain))))
99107
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)
104110 :unless (= a b) :do
105111 (pushnew (cons a b) transpositions* :test #' equal ))
106112
@@ -159,7 +165,7 @@ If PERMUTATIONS is the list π₁, π₂, ..., πₛ, then the result is the com
159165 (loop :for permutation :in permutations :when permutation :do
160166 (loop :for transposition :of-type transposition :in (permutation-transpositions permutation) :do
161167 (let ((a (first transposition)))
162- (declare (type alexandria :non-negative-fixnum a))
168+ (declare (type qubit-index a))
163169 (pushnew a domain))))
164170
165171 ; ; Now map each domain element to obtain transpositions.
@@ -169,8 +175,8 @@ If PERMUTATIONS is the list π₁, π₂, ..., πₛ, then the result is the com
169175 (setf (aref codomain i)
170176 (apply-permutation permutation (aref codomain i))))
171177 :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
174180 :unless (= a b) :do
175181 (pushnew (cons a b) transpositions :test #' equal )))
176182
@@ -196,13 +202,12 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
196202
197203(defmethod apply-qubit-permutation ((permutation permutation-transposition) address)
198204 (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)
202207 (values qvm :amplitude-address))
203208
204209 (let ((tau (slot-value permutation ' tau)))
205- (declare (type ( unsigned-byte 6 ) tau))
210+ (declare (type qubit-index tau))
206211
207212 ; ; Swap bits 0 and TAU in ADDRESS.
208213 (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
215220 ; ; J. Comput., vol. 24, no. 2, pp. 266–278, Apr. 1995.
216221
217222 (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)
221225 (values qvm :amplitude-address))
222226
223227 (let* ((transpositions (slot-value permutation ' transpositions))
224228 (number-of-transpositions (slot-value permutation ' number-of-transpositions))
225229 (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)
227231 (dynamic-extent bit-vector ))
228232
229233 (loop :for index :from 0
@@ -235,8 +239,7 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
235239 :for transposition :of-type transposition :in transpositions :do
236240 (setf address (the qvm :amplitude-address
237241 (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)))
240243 address)))
241244 :finally (return address))))
242245
@@ -256,7 +259,8 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
256259 (minus-tau (- tau)))
257260 ` (lambda (, address)
258261 (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)
260264 (values qvm :amplitude-address))
261265
262266 ; ; Swap bits 0 and TAU in ADDRESS.
@@ -269,8 +273,8 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
269273 (number-of-transpositions (slot-value permutation ' number-of-transpositions)))
270274 ` (lambda (, address)
271275 (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)
274278 (values qvm :amplitude-address))
275279
276280 (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
285289 :for transposition :of-type transposition :in transpositions
286290 :collect ` (setf , address (the qvm :amplitude-address
287291 (dpb (bit bit-vector , index)
288- (byte 1 (the ( unsigned-byte 6 ) , (rest transposition)))
292+ (byte 1 (the qubit-index , (rest transposition)))
289293 , address))))
290294 , address))))
291295
0 commit comments