Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Created September 12, 2010 18:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/576320 to your computer and use it in GitHub Desktop.
Save anonymous/576320 to your computer and use it in GitHub Desktop.
(ns qgame
(:require [clojure.contrib.math :as math]
[clojure.set :as set])
(:gen-class))
(use '(incanter core))
(defstruct quantum-system-struct
:number-of-qubits ;number of qubits in the system
:amplitudes ;an array of amplitudes
:prior-probability ;the prob. of having reached this
;system in the first place
:oracle-count ;number of oracle calls throughout
;the system's history
:measurement-history ;a list of measurements and their
;results in the history of this system
:instruction-history
:program
:qubit-numbers
:amplitude-address
)
(defn quantum-system
"Initializes and returns quantum-system-struct."
[number-of-qubits]
(struct-map quantum-system-struct
:number-of-qubits number-of-qubits
:amplitudes (let [dim (math/expt 2 number-of-qubits)]
(vec (cons 1.0 (repeat (dec dim) 0.0))))
:qubit-numbers (range number-of-qubits)
:amplitude-address (vec (repeat number-of-qubits 0))
))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; quantum computer manipulation utilities
(defn set-address-components
"return (qsys :amplitude-address) to refer to a particular amplitude, as
indicated by the bits in count."
[qsys cnt qubits]
(let [old-addr (qsys :amplitude-address)]
(dbg
(assoc qsys :amplitude-address
(eval
(conj
(for [i qubits]
`(assoc ~i
(if (bit-test ~cnt ~i) 1 0)))
old-addr
'->))))))
(defn map-qubit-combinations
"Calls function once for each of the 1/0 combinations of the provided
qubits, with the right-most qubit varying the most
NOTE: function must take and return a qsys"
[qsys function qubits]
(let [num-iterations (math/expt 2 (count qubits))
qubits-reversed (reverse qubits)]
(eval
(conj
(interleave
(for [i (range num-iterations)] `(set-address-components ~i '~qubits-reversed))
(repeat num-iterations function))
'qsys
'->))))
(defn addressed-amplitude-index
"Returns the index of the currently addressed amplitude."
[qsys]
(apply + (for [i (range (qsys :number-of-qubits))]
(if (not (zero? (nth (qsys :amplitude-address) i)))
(math/expt 2 i)
0))))
(defn get-addressed-amplitude
"Returns the amplitude currently addressed."
[qsys]
(nth (qsys :amplitudes) (addressed-amplitude-index qsys)))
(defn set-addressed-amplitude
"Sets the amplitude currently addressed to new-value"
[qsys new-value]
(assoc qsys :amplitudes
(assoc (qsys :amplitudes) (addressed-amplitude-index qsys) new-value)))
(defn extract-column
"Returns a column from the amplitudes obtained by varying the listed qubits,
with the right-most qubit varying the fastest."
[qsys qubits-to-vary]
(reverse
(:col
(map-qubit-combinations
qsys
(fn [qsys]
(assoc qsys :col (conj (qsys :col) (get-addressed-amplitude qsys))))
qubits-to-vary))))
;TODO: get rid of mutable var 'c'
(def c '())
(defn install-column
"Installs the given column in the amplitude positions obtained by varying the
listed qubits, with the right-most qubit varying the fastest."
[qsys column qubits-to-vary]
(binding [c column]
(map-qubit-combinations
qsys
(fn [q]
(let [f (first c)]
(set! c (rest c))
(set-addressed-amplitude q f)))
qubits-to-vary)))
(defn apply-operator
"Applies the given matrix-form operator to the given qubits."
[qsys operator qubits]
(map-qubit-combinations
qsys
(fn [q]
(let [pre-column (extract-column q qubits)
post-column (mmult operator pre-column)]
(install-column q post-column qubits)))
(seq (set/difference
(set (qsys :qubit-numbers))
(set qubits)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; other quantum gates
(def s (/ 1 (sqrt 2)))
(defn qnot
"Quantum NOT gate"
[qsys q]
(apply-operator qsys
(matrix [[0 1]
[1 0]])
(list q)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment