Skip to content

Commit 00c4b62

Browse files
committed
Generate code for applying permutations.
1 parent 6afe4c8 commit 00c4b62

File tree

1 file changed

+55
-5
lines changed

1 file changed

+55
-5
lines changed

dqvm/src/permutation.lisp

+55-5
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ Note that in the example above, the transposition (0 2) was automatically added.
9090

9191
(declare (inline check-transposition))
9292

93-
(loop :for (a . b) :in transpositions :do
93+
(loop :for (a . b) :of-type alexandria:non-negative-fixnum :in transpositions :do
9494
(check-transposition a b)
9595
(unless (= a b)
9696
(pushnew (cons a b) transpositions*)
@@ -204,10 +204,11 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
204204
(let ((tau (slot-value permutation 'tau)))
205205
(declare (type (unsigned-byte 6) tau))
206206

207-
(rotatef (ldb (byte 1 0) address) (ldb (byte 1 tau) address))
208-
address))
207+
;; Swap bits 0 and TAU in ADDRESS.
208+
(let ((x (logxor (logand address 1) (logand (ash address (- tau)) 1))))
209+
(logxor address (logior x (ash x tau))))))
209210

210-
(defmethod apply-qubit-permutation ((permutation permutation) address)
211+
(defmethod apply-qubit-permutation ((permutation permutation-general) address)
211212
;; Alternatively, in-place permutations could be implemented following:
212213
;;
213214
;; F. Fich, J. Munro, and P. Poblete, “Permuting in Place,” SIAM
@@ -226,7 +227,7 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
226227
(dynamic-extent bit-vector))
227228

228229
(loop :for index :from 0
229-
:for transposition :in transpositions :do
230+
:for transposition :of-type transposition :in transpositions :do
230231
(setf (bit bit-vector index) (ldb (byte 1 (first transposition))
231232
address)))
232233

@@ -239,6 +240,55 @@ DQVM2> (write (apply-qubit-permutation (make-permutation '((2 . 0))) #b001) :bas
239240
address)))
240241
:finally (return address))))
241242

243+
(defgeneric generate-qubit-permutation-code (permutation)
244+
(:documentation "Generate lambda function equivalent to APPLY-QUBIT-PERMUTATION suitable to be compiled.")
245+
(declare #.qvm::*optimize-dangerously-fast*))
246+
247+
(defmethod generate-qubit-permutation-code ((permutation (eql nil)))
248+
(let ((address (gensym "ADDRESS-")))
249+
`(lambda (,address)
250+
(declare #.qvm::*optimize-dangerously-fast*)
251+
,address)))
252+
253+
(defmethod generate-qubit-permutation-code ((permutation permutation-transposition))
254+
(let* ((address (gensym "ADDRESS-"))
255+
(tau (slot-value permutation 'tau))
256+
(minus-tau (- tau)))
257+
`(lambda (,address)
258+
(declare #.qvm::*optimize-dangerously-fast*
259+
(type (unsigned-byte 64) ,address) ; Imposed maximum number of qubits.
260+
(values qvm:amplitude-address))
261+
262+
;; Swap bits 0 and TAU in ADDRESS.
263+
(let ((x (logxor (logand ,address 1) (logand (ash ,address ,minus-tau) 1))))
264+
(logxor ,address (logior x (ash x ,tau)))))))
265+
266+
(defmethod generate-qubit-permutation-code ((permutation permutation-general))
267+
(let ((address (gensym "ADDRESS-"))
268+
(transpositions (slot-value permutation 'transpositions))
269+
(number-of-transpositions (slot-value permutation 'number-of-transpositions)))
270+
`(lambda (,address)
271+
(declare #.qvm::*optimize-dangerously-fast*
272+
(type (or null permutation) permutation)
273+
(type (unsigned-byte 64) ,address)
274+
(values qvm:amplitude-address))
275+
276+
(let ((bit-vector (make-array ,number-of-transpositions :element-type 'bit)))
277+
(declare (dynamic-extent bit-vector))
278+
279+
,@(loop :for index :from 0
280+
:for transposition :of-type transposition :in transpositions
281+
:collect `(setf (bit bit-vector ,index) (ldb (byte 1 ,(first transposition))
282+
,address)))
283+
284+
,@(loop :for index :from 0
285+
:for transposition :of-type transposition :in transpositions
286+
:collect `(setf ,address (the qvm:amplitude-address
287+
(dpb (bit bit-vector ,index)
288+
(byte 1 (the (unsigned-byte 6) ,(rest transposition)))
289+
,address))))
290+
,address))))
291+
242292
(defun-inlinable apply-inverse-qubit-permutation (permutation address)
243293
(apply-qubit-permutation (inverse-permutation permutation) address))
244294

0 commit comments

Comments
 (0)