(define (bits-of-len n)
(cond ((< n 1) (error "Invalid bits length, must be >= 1"))
((= n 1) '((0) (1)))
(else (let ([lower-bits (bits-of-len (- n 1))])
(for*/list ([i (range 2)]
[x lower-bits])
(cons i x))))))
(define (qubit a b)
(if (e-equal? (+ (* (magnitude a) (magnitude a))
(* (magnitude b) (magnitude b)))
1.0)
(col-matrix [a b])
(error "Cannot create qubit, bad probabilities")))
(define (measure-mat m)
(let* ([len (matrix-num-rows m)]
[blen (exact-round (log len 2))]
[obs (bits-of-len blen)]
[ampls (matrix->list m)]
[scaled-probs (map (λ (x) (* x x 100)) ampls)]
[roll (random 100)])
(range-map 0 scaled-probs obs roll 0 len)))
(define ((apply-op op-matrix) q)
(matrix* op-matrix q))
(define pauli-x (matrix [[0 1]
[1 0]]))
(define gX (apply-op pauli-x))
(define hadamard (matrix [[h-factor h-factor]
[h-factor (- h-factor)]]))
(define gH (apply-op hadamard))
(define (tensor* m1 m2)
(define (mat->list m1 m2)
(matrix->list*
(matrix-map
(λ (x) (matrix->list*
(matrix-map (λ (y) (* x y)) m2)))
m1)))
(define (list->mat m)
(let ([rows '()])
(for ([row m])
(for ([i (range (length (first row)))])
(let ([row-line '()])
(for ([m row])
(set! row-line
(append row-line (list-ref m i))))
(set! rows (append rows (list row-line))))))
rows))
(let* ([m (mat->list m1 m2)]
[l (list->mat m)])
(list*->matrix l)))
(define (make-circuit matrices
#:assembler [assembler G*])
(let ([ops (map (λ (gs)
(if (list? gs)
(apply assembler gs)
(apply-op gs)))
matrices)])
(λ (input-qbits)
(for/fold ([sv input-qbits])
([f ops])
(f sv)))))
(define (qubits n)
(apply t* (for/list ([i (range n)]) q0)))
(define c1 (make-circuit
(list (list (I 2) X)
(list H H))))
(counts (c1 (qubits 2)))
circuit = QuantumCircuit(2)
circuit.x(1)
circuit.barrier()
circuit.h(0)
circuit.h(1)
circuit.draw('mpl')