2024-12-08 22:06:58 -08:00
|
|
|
;;;; High-level interface for building quantum circuits
|
2024-12-07 21:24:22 -08:00
|
|
|
(in-package :cl-quantum/circuit)
|
|
|
|
|
2024-12-08 09:41:05 -08:00
|
|
|
(defparameter *circuit-measure-places* 5
|
|
|
|
"The number of places to use with the :measure instruction in circuits.")
|
|
|
|
|
2024-12-08 22:06:58 -08:00
|
|
|
(defun circuit-arbitrary-gate (state operator gate target &optional control)
|
|
|
|
(declare (ignorable operator))
|
|
|
|
(if control
|
|
|
|
(napply-controlled-gate state gate target control)
|
|
|
|
(napply-gate state gate target)))
|
|
|
|
|
|
|
|
(defun circuit-matrix-operation (state operator target &optional control)
|
2024-12-07 21:24:22 -08:00
|
|
|
(let ((matrix (case operator
|
2024-12-08 09:41:05 -08:00
|
|
|
(:* +identity-2x2+)
|
|
|
|
(:x +pauli-x-gate+)
|
|
|
|
(:y +pauli-y-gate+)
|
|
|
|
(:z +pauli-z-gate+)
|
|
|
|
(:h +hadamard-gate+)
|
|
|
|
(:p +phase-gate+)
|
|
|
|
(:t +pi/8-gate+)
|
|
|
|
(:cnot +pauli-x-gate+)
|
|
|
|
(:cz +pauli-z-gate+))))
|
2024-12-08 22:06:58 -08:00
|
|
|
(if control
|
|
|
|
(napply-controlled-gate state matrix target control)
|
|
|
|
(napply-gate state matrix target))))
|
|
|
|
|
|
|
|
(defun circuit-n-controlled-gate (state operator target controls)
|
|
|
|
(let ((func (case operator
|
|
|
|
(:ntoff 'make-n-toffoli-operator)
|
|
|
|
(:ncz 'make-n-controlled-z-operator))))
|
|
|
|
(replace-state state (*mv (funcall func (state-bits state)
|
|
|
|
target controls)
|
|
|
|
state))))
|
2024-12-07 21:24:22 -08:00
|
|
|
|
|
|
|
(defparameter *circuit-operators*
|
2024-12-08 22:06:58 -08:00
|
|
|
;; Operator, # args, more args?, has output?, function
|
2024-12-07 21:24:22 -08:00
|
|
|
;; The output is always the last argument
|
2024-12-08 22:06:58 -08:00
|
|
|
`((:gate 2 nil nil circuit-arbitrary-gate)
|
|
|
|
(:cgate 3 nil nil circuit-arbitrary-gate)
|
|
|
|
(:* 1 nil nil circuit-matrix-operation)
|
|
|
|
(:x 1 nil nil circuit-matrix-operation)
|
|
|
|
(:y 1 nil nil circuit-matrix-operation)
|
|
|
|
(:z 1 nil nil circuit-matrix-operation)
|
|
|
|
(:h 1 nil nil circuit-matrix-operation)
|
|
|
|
(:p 1 nil nil circuit-matrix-operation)
|
|
|
|
(:t 1 nil nil circuit-matrix-operation)
|
|
|
|
(:cnot 2 nil nil circuit-matrix-operation)
|
|
|
|
(:cz 2 nil nil circuit-matrix-operation)
|
|
|
|
(:measure 2 nil t ,(lambda (state operator &rest args)
|
|
|
|
(declare (ignorable operator))
|
|
|
|
(nmeasure state (car args)
|
|
|
|
:places *circuit-measure-places*)))
|
|
|
|
(:ntoff 2 nil nil circuit-n-controlled-gate)
|
|
|
|
(:ncz 2 nil nil circuit-n-controlled-gate)))
|
2024-12-07 21:24:22 -08:00
|
|
|
|
|
|
|
(defun make-circuit ()
|
|
|
|
"Create a new blank circuit."
|
2024-12-08 22:06:58 -08:00
|
|
|
'(:circuit))
|
2024-12-07 21:24:22 -08:00
|
|
|
|
|
|
|
(defun add-to-circuit (circuit operator &rest args)
|
|
|
|
"Add OPERATOR to CIRCUIT."
|
2024-12-08 22:06:58 -08:00
|
|
|
(let ((entry (assoc operator *circuit-operators*)))
|
2024-12-07 21:24:22 -08:00
|
|
|
(unless entry
|
|
|
|
(error "Unknown circuit operator: ~s" operator))
|
2024-12-08 22:06:58 -08:00
|
|
|
(destructuring-bind (name arg-count has-rest &rest r) entry
|
2024-12-07 21:24:22 -08:00
|
|
|
(declare (ignorable name r))
|
2024-12-08 22:06:58 -08:00
|
|
|
(unless (or (and has-rest (>= (length args) arg-count))
|
|
|
|
(= (length args) arg-count))
|
|
|
|
(error "Operator ~s expects ~@[~*exactly ~]~s arg~:p, got ~s" operator
|
|
|
|
(not has-rest) arg-count (length args)))
|
2024-12-07 21:24:22 -08:00
|
|
|
(nconc circuit (list (cons operator args))))
|
|
|
|
circuit))
|
|
|
|
|
2024-12-08 09:41:05 -08:00
|
|
|
(defmacro with-build-circuit (&body body)
|
2024-12-07 21:24:22 -08:00
|
|
|
"Create a circuit using a simple DSL. BODY can be any valid Lisp forms, in
|
|
|
|
addition to function calls to functions named in `*circuit-operators*'."
|
2024-12-08 22:06:58 -08:00
|
|
|
(let ((circuit-var (gensym)))
|
|
|
|
`(let ((,circuit-var))
|
|
|
|
(macrolet
|
|
|
|
(,@(mapcar (lambda (oper)
|
|
|
|
(let ((arg (gensym))
|
|
|
|
(arg-list (loop repeat (second oper)
|
|
|
|
collect (gensym)))
|
|
|
|
(whole-arg (when (third oper)
|
|
|
|
(gensym))))
|
|
|
|
`(,(car oper) (&whole ,arg
|
|
|
|
,@arg-list
|
|
|
|
,@(when (third oper)
|
|
|
|
(list '&rest whole-arg)))
|
|
|
|
(declare (ignorable ,@arg-list
|
|
|
|
,@(when (third oper)
|
|
|
|
(list whole-arg))))
|
|
|
|
`(push (list ,@,arg) ,',circuit-var))))
|
|
|
|
*circuit-operators*))
|
|
|
|
,@body)
|
|
|
|
(cons :circuit (nreverse ,circuit-var)))))
|
2024-12-07 21:24:22 -08:00
|
|
|
|
|
|
|
(defun apply-circuit-operator-to-state (state operator args)
|
|
|
|
"Apply the circuit operator OPERATOR to STATE by calling its function with
|
|
|
|
ARGS."
|
2024-12-08 22:06:58 -08:00
|
|
|
(destructuring-bind (&optional name arg-count has-rest has-output function)
|
2024-12-07 21:24:22 -08:00
|
|
|
(assoc operator *circuit-operators*)
|
2024-12-08 22:06:58 -08:00
|
|
|
(declare (ignorable name arg-count has-rest))
|
2024-12-07 21:24:22 -08:00
|
|
|
(assert function ()
|
|
|
|
"Invalid circuit operator: ~s" operator)
|
|
|
|
(let ((output (apply function state operator args)))
|
|
|
|
(when has-output
|
|
|
|
(cons (car (last args)) output)))))
|
|
|
|
|
2024-12-08 22:06:58 -08:00
|
|
|
(defun run-circuit (circuit &key bits uniform coefficients probabilities (places 5))
|
2024-12-07 21:24:22 -08:00
|
|
|
"Run the circuit CIRCUIT and return the final state. The initial state can be
|
|
|
|
specified in one of three ways:
|
|
|
|
- BITS: the number of qbits
|
|
|
|
- COEFFICIENTS: the initial coefficients
|
|
|
|
- PROBABILITES: the initial probabilities"
|
2024-12-08 22:06:58 -08:00
|
|
|
(assert (= 1 (count-if 'identity (list bits coefficients probabilities uniform)))
|
2024-12-07 21:24:22 -08:00
|
|
|
()
|
2024-12-08 22:06:58 -08:00
|
|
|
"Exactly one of BITS, UNIFORM, COEFFICIENTS, and PROBABILITIES can ~
|
|
|
|
be present")
|
2024-12-07 21:24:22 -08:00
|
|
|
(let ((state (cond
|
2024-12-08 22:06:58 -08:00
|
|
|
(bits (make-zero-state bits))
|
|
|
|
(uniform (make-uniform-normal-state uniform))
|
2024-12-07 21:24:22 -08:00
|
|
|
(coefficients (coerce coefficients 'vector))
|
|
|
|
(probabilities (make-normal-state probabilities)))))
|
2024-12-08 22:06:58 -08:00
|
|
|
(values
|
|
|
|
state
|
|
|
|
(loop with *circuit-measure-places* = places
|
|
|
|
for element in (cdr circuit)
|
|
|
|
for name = (car element)
|
|
|
|
for args = (cdr element)
|
|
|
|
for result = (apply-circuit-operator-to-state state name args)
|
|
|
|
when result
|
|
|
|
collect result))))
|