-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathquantum.lean
199 lines (141 loc) · 4.47 KB
/
quantum.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
import matrix
open_locale big_operators
open Matrix
------------------------------------------------------------------------------
-- Matrix helpers for measurement definitions
namespace Matrix
variables {n m : ℕ} (s : Vector n)
/-- Projection operator onto the state `s` (aka "observable").
`proj s` can be read as `|ψ⟩⟨ψ|`, when `|ψ⟩ = s`. -/
noncomputable
def proj : Square n := s ⬝ (s†)
/-- Trace of square matrix -/
noncomputable
def trace (A : Square n) : ℂ := ∑ i, A i i
notation `Tr(` x `)` := trace x
/-- `n × n` partial traces of `m × m` subcomponents of
`(n * m) × (n * m)` square matrix. -/
noncomputable
def partial_trace (M : Square (n * m)) : Square n
:= λ i j, ∑ k, M (kron_loc i k) (kron_loc j k)
notation `Tr'(` x `)` := partial_trace x
end Matrix
------------------------------------------------------------------------------
-- Measurement
namespace quantum
open Matrix
variables {n m : ℕ} (s : Vector n)
/-- Measurement in the standard basis -/
def measure (m : fin n) : ℝ := complex.norm_sq (s m 0)
notation `⟦` x `⟧` := measure x
/-- state after measurement (using `measure`) -/
noncomputable
def state_after_measure (m : fin n)
:= (1 / real.sqrt (⟦s⟧ m)) • proj (std_basis m) ⬝ s
/-- Partial measurement in the standard basis -/
noncomputable
def partial_measure (v : Vector (n * m)) (i : fin n) : ℝ := |v.proj.partial_trace i i|
notation `⦃` x `⦄` := partial_measure x
end quantum
------------------------------------------------------------------------------
-- Common constant numerals
notation `√2` := real.sqrt 2
-- `1/√2` is not allowed as a notation in Lean. So, use `/√2`, instead.
notation `/√2` := (1 / (real.sqrt 2) : ℂ)
notation `i/√2` := complex.I / (real.sqrt 2)
------------------------------------------------------------------------------
-- Common states
-- |0⟩ and |1⟩ using `std_basis`
def ket0 : Vector 2 := std_basis 0
def ket1 : Vector 2 := std_basis 1
notation `|0⟩` := ket0
notation `|1⟩` := ket1
-- |00⟩~|11⟩ using `std_basis`
-- In `ketXY` and `|XY⟩`, `Y` is the least significant bit.
def ket00 : Vector 4 := std_basis 0
def ket01 : Vector 4 := std_basis 1
def ket10 : Vector 4 := std_basis 2
def ket11 : Vector 4 := std_basis 3
notation `|00⟩` := ket00
notation `|10⟩` := ket10
notation `|01⟩` := ket01
notation `|11⟩` := ket11
noncomputable
def ket_plus : Vector 2 := ![
![ /√2 ],
![ /√2 ]]
noncomputable
def ket_minus : Vector 2 := ![
![ /√2 ],
![ -/√2 ]]
notation `|+⟩` := ket_plus
notation `|-⟩` := ket_minus
-- |00...0⟩ (= |0⟩ ⊗ ... ⊗ |0⟩ or the `n`-th tensor power of |0⟩).
-- Used for zero padding or ancillae qubits.
def ket_zeros (n : ℕ) : Vector (2^n) := std_basis ⟨0, by simp⟩
-- |Φ+⟩ : One of the four bell states
noncomputable
def ket_phi_plus : Vector 4 := ![
![ /√2 ],
![ 0 ],
![ 0 ],
![ /√2 ]]
notation `|Φ+⟩` := ket_phi_plus
------------------------------------------------------------------------------
-- Common gates
-- X gate (aka NOT gate)
def X : Square 2 := ![
![ 0, 1 ],
![ 1, 0 ]]
def Z : Square 2 := ![
![ 1, 0 ],
![ 0, -1 ]]
-- Hadamard gate
noncomputable
def H : Square 2 := ![
![ /√2, /√2 ],
![ /√2, -/√2 ]]
-- Controlled-NOT gate (aka CX gate)
def CNOT : Square 4 := ![
![ 1, 0, 0, 0 ],
![ 0, 1, 0, 0 ],
![ 0, 0, 0, 1 ],
![ 0, 0, 1, 0 ]]
-- Controlled-Z gate
def CZ : Square 4 := ![
![ 1, 0, 0, 0 ],
![ 0, 1, 0, 0 ],
![ 0, 0, 1, 0 ],
![ 0, 0, 0, -1 ]]
def SWAP : Square 4 :=
![ ![1, 0, 0, 0],
![0, 0, 1, 0],
![0, 1, 0, 0],
![0, 0, 0, 1]]
------------------------------------------------------------------------------
-- Controlled-U gates
section controlled_gate
variables {n : ℕ} (U : Square n)
/-- Controlled-U gate : |0⟩⟨0| ⊗ I + |1⟩⟨1| ⊗ U -/
noncomputable
def controlled_gate := |0⟩.proj ⊗ (I n) + |1⟩.proj ⊗ U
/-- Upside-down Controlled-U gate (2-qubit case)-/
noncomputable
def gate_controlled (U : Square 2) := SWAP ⬝ controlled_gate U ⬝ SWAP
end controlled_gate
------------------------------------------------------------------------------
-- Common projection operators
def P0 : Square 2 := ![
![ 1, 0 ],
![ 0, 0 ]]
def P1 : Square 2 := ![
![ 0, 0 ],
![ 0, 1 ]]
noncomputable
def P_plus : Square 2 := ![
![ 1/2, 1/2 ],
![ 1/2, 1/2 ]]
noncomputable
def P_minus : Square 2 := ![
![ 1/2, -(1/2) ],
![ -(1/2), 1/2 ]]