Skip to content

Commit f2619b8

Browse files
committed
Define meaningful types.
1 parent 00c4b62 commit f2619b8

File tree

1 file changed

+31
-27
lines changed

1 file changed

+31
-27
lines changed

dqvm/src/permutation.lisp

+31-27
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,17 @@
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
()
@@ -39,9 +47,9 @@
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

Comments
 (0)