-
Notifications
You must be signed in to change notification settings - Fork 4
/
measurement.lean
357 lines (299 loc) · 10.4 KB
/
measurement.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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
import quantum_lemmas
open Matrix
open quantum
open_locale big_operators
------------------------------------------------------------------------------
-- Generalized measurement
section generalized_measurement
variables {n : ℕ}
variables (M : fin n → Square n) -- a set of measurement operators
variables (s : Vector n) -- state
/-- `Pr(m)` - the probability that we find measurement result `m`.
In other words, measuring the operator `M m` in the state `s`. -/
noncomputable
def gen_measure (m : fin n) : ℝ := ((s† ⬝ ((M m)† ⬝ (M m)) ⬝ s) 0 0).re
/-- The state after general measurement. -/
noncomputable
def state_after_gen_measure (m : fin n) := (1 / real.sqrt (gen_measure M s m)) • M m ⬝ s
end generalized_measurement
section generalized_measurement_lemmas
variables {n : ℕ}
variables {M : fin n → Square n} -- a set of measurement operators
variables {s : Vector n} -- state
variables {m : fin n} -- the index of the measurement operator in the set `M`
lemma gen_measure_eq_inner_product : s† ⬝ ((M m)† ⬝ (M m)) ⬝ s = ((M m) ⬝ s)† ⬝ ((M m) ⬝ s)
:= begin
rw adjoint_mul,
iterate 3 { rw matrix.mul_assoc },
end
-- `Pr(m) = ∥M m ⬝ s∥^2`
lemma gen_measure_eq_norm_sq_mul : gen_measure M s m = ∥(M m ⬝ s)∥^2
:= begin
unfold gen_measure,
rw gen_measure_eq_inner_product,
apply Matrix_inner_self_eq_norm_sq,
end
-- `√(Pr(m)) = ∥M m ⬝ s∥`
lemma sqrt_gen_measure_eq_norm_mul : real.sqrt (gen_measure M s m) = ∥(M m ⬝ s)∥
:= begin
rw gen_measure_eq_norm_sq_mul,
rw pow_two,
apply real.sqrt_mul_self,
apply matrix.norm_nonneg,
end
-- `Pr(m) = Tr(M m ⬝ ρ ⬝ (M m)†)`, where `ρ` is `proj s`.
example (m : fin n) : gen_measure M s m = Tr( M m ⬝ proj s ⬝ (M m)†).re
:= begin
unfold gen_measure proj,
congr' 1,
rw gen_measure_eq_inner_product,
rw <- trace_outer_eq_inner,
rw adjoint_mul,
repeat { rw matrix.mul_assoc },
end
-- `Pr(m) = Tr((M m)† ⬝ M m ⬝ ρ)`, where `ρ` is `proj s`.
example {m : fin n} : gen_measure M s m = Tr( (M m)† ⬝ M m ⬝ proj s).re
:= begin
unfold gen_measure proj,
congr' 1,
rw gen_measure_eq_inner_product,
rw <- trace_outer_eq_inner,
rw adjoint_mul,
have l: M m ⬝ s ⬝ (s† ⬝ M m†) = M m ⬝ (s ⬝ s†) ⬝ (M m)†,
{ repeat { rw matrix.mul_assoc }, },
rw l, clear l,
rw trace_mul_rotate_l (M m),
end
lemma state_after_gen_measure_unit {s : Vector n} {m : fin n}
: gen_measure M s m ≠ 0 → (state_after_gen_measure M s m).unit
:= begin
intros h,
rw norm_eq_one_iff_unit,
unfold state_after_gen_measure,
rw sqrt_gen_measure_eq_norm_mul, simp,
rw gen_measure_eq_norm_sq_mul at h,
have : ∥M m ⬝ s∥ ≠ 0,
{
intro c, apply h, clear h,
rw c, simp,
},
exact norm_smul_norm_inv_eq_one this,
end
end generalized_measurement_lemmas
------------------------------------------------------------------------------
-- Projective measurement
section projective_measurement
variables {n : ℕ}
variables (u : fin n → Vector n) -- a set of basis vectors to project
variables (s : Vector n) -- state
/-- `Pr(i)` - the probability that we find measurement result `i` in state `s`.
In other words, measuring the projection of basis `u i` in state `s`. -/
noncomputable
def proj_measure (i : fin n) : ℝ := ((s† ⬝ (proj (u i)) ⬝ s) 0 0).re
/-- The state after projective measurement -/
noncomputable
def state_after_proj_measure (i : fin n)
:= (1 / real.sqrt (proj_measure u s i)) • proj (u i) ⬝ s
end projective_measurement
section projective_measurement_lemmas
variables {n : ℕ}
variables {u : fin n → Vector n} -- a set of basis vectors to project
variables {s : Vector n} -- state
/-- The measurement operator computed from the basis vector `u i` -/
@[reducible] noncomputable
def proj_to_measure (u : fin n → Vector n) (i : fin n) := proj (u i)
/-- All projection vectors in the set `u` are unit. -/
@[reducible]
def proj_unit (u : fin n → Vector n) := ∀ i, (u i).unit
lemma proj_measure_eq_gen_measure_proj
: proj_unit u
→ proj_measure u = gen_measure (proj_to_measure u)
:= begin
intros h, ext s m,
unfold proj_measure gen_measure proj_to_measure,
rw proj_mul_adjoint_eq_self (h m),
end
variables {i : fin n} -- the index of the projection vector in the set `u`
lemma proj_measure_eq_inner_product : s† ⬝ (proj (u i)) ⬝ s = ((u i)† ⬝ s)† ⬝ ((u i)† ⬝ s)
:= begin
unfold proj,
rw adjoint_mul, simp,
iterate 3 { rw matrix.mul_assoc },
end
-- `Pr(i) = ∥(P i) ⬝ s∥^2`, where `P i` is `proj (u i)`.
-- Inherited property from gen_measure.
lemma proj_measure_eq_norm_sq_mul : proj_unit u → proj_measure u s i = ∥(proj (u i) ⬝ s)∥^2
:= begin
intro up,
rw proj_measure_eq_gen_measure_proj up,
apply gen_measure_eq_norm_sq_mul,
end
-- The Born rule
lemma proj_measure_eq_norm_sq_inner : proj_unit u → proj_measure u s i = ∥((u i)† ⬝ s)∥^2
:= begin
intro up,
rw proj_measure_eq_norm_sq_mul up,
iterate 2 { rw <- Matrix_inner_self_eq_norm_sq },
unfold proj,
congr' 1,
unfold inner inner_product,
iterate 3 { rw adjoint_mul }, simp,
have : s† ⬝ (u i ⬝ u i†) ⬝ (u i ⬝ u i† ⬝ s) = s† ⬝ u i ⬝ (u i† ⬝ u i) ⬝ (u i† ⬝ s),
{
repeat { rw matrix.mul_assoc },
},
rw this, clear this,
rw unfold_unit (up i), simp,
end
-- Inherited property from gen_measure.
lemma state_after_proj_measure_unit
: proj_unit u → proj_measure u s i ≠ 0 → (state_after_proj_measure u s i).unit
:= begin
intros up,
unfold state_after_proj_measure,
rw proj_measure_eq_gen_measure_proj up,
intros h,
apply state_after_gen_measure_unit h,
end
lemma proj_self_square_of_proj_unit : proj_unit u → (u i).proj ⬝ (u i).proj = (u i).proj
:= begin
intros up,
unfold proj,
have : u i ⬝ u i† ⬝ (u i ⬝ u i†) = u i ⬝ (u i† ⬝ u i) ⬝ u i†,
{ repeat { rw matrix.mul_assoc }, },
rw this, clear this,
rw unfold_unit (up i), simp,
end
-- Applying the same (projective) measurement operator has no effect.
lemma proj_measure_state_after_proj_measure
: proj_unit u
→ (u i).proj ⬝ state_after_proj_measure u s i = state_after_proj_measure u s i
:= begin
intros up,
unfold state_after_proj_measure,
rw Matrix.mul_real_smul,
rw <- matrix.mul_assoc,
rw proj_self_square_of_proj_unit up,
end
-- The probability of measuring again gives us the same result is 1.
lemma proj_measure_state_after_proj_measure_unit : proj_unit u → proj_measure u s i ≠ 0
→ proj_measure u (state_after_proj_measure u s i) i = 1
:= begin
intros up h,
rw proj_measure_eq_norm_sq_mul up,
rw proj_measure_state_after_proj_measure up,
have : (state_after_proj_measure u s i).unit,
{ apply state_after_proj_measure_unit; assumption },
rw <- Matrix_inner_self_eq_norm_sq,
unfold inner inner_product,
rw unfold_unit this, simp,
end
end projective_measurement_lemmas
------------------------------------------------------------------------------
-- Standard basis measurement as a projective measurement
section projective_measurement_in_std_basis
variables {n : ℕ} {s : Vector n}
@[simp]
lemma proj_unit_std_basis : @proj_unit n std_basis
:= begin
unfold proj_unit, intros i, simp,
end
lemma measure_eq_proj_measure
: ⟦s⟧ = proj_measure std_basis s
:= begin
ext m,
unfold quantum.measure,
rw proj_measure_eq_norm_sq_inner,
{
rw <- Matrix_inner_self_eq_norm_sq,
unfold inner inner_product,
rw matrix_mul_square_one, simp,
},
{
simp,
}
end
lemma state_after_measure_eq_state_after_proj_measure
: state_after_measure s = state_after_proj_measure std_basis s
:= begin
apply funext, intros m,
unfold state_after_proj_measure state_after_measure,
congr' 2,
rw measure_eq_proj_measure,
end
end projective_measurement_in_std_basis
------------------------------------------------------------------------------
-- Simulating projective measurement by measurement in the standard basis
section proj_measure_to_measure
variables {n : ℕ} {s : Vector n}
variables {u : fin n → Vector n} -- a set of basis to project
variables {m : fin n} -- the index of the projection vector in the set `u`
/-- A unitary operator that converts an arbitrary projective measurement to
the standard basis measuremnt. -/
noncomputable
def proj_measure_op (u : fin n → Vector n) : Square n := λ i, (u i)† 0
lemma proj_measure_to_measure : proj_unit u
→ proj_measure u s = ⟦proj_measure_op u ⬝ s⟧
:= begin
intros h,
ext m,
rw measure_eq_proj_measure,
rw proj_measure_eq_norm_sq_inner h,
rw proj_measure_eq_norm_sq_inner proj_unit_std_basis,
congr' 2,
rw <- matrix.mul_assoc,
congr' 1,
apply matrix.ext, intros i j,
have : i = 0, by simp, cases this, clear this,
simp,
rw matrix.mul_apply,
unfold proj_measure_op,
rw finset.sum_eq_single m; try {solve1 {simp}},
{
intros i ip ie,
rw std_basis_adjoint_apply,
rw std_basis_eq_zero ie, simp,
},
end
/-- The unitary operator that restores the state after projective measurement,
after simulating it with `proj_measure_op`. -/
noncomputable
def proj_measure_restore_op (u : fin n → Vector n) (m : fin n) := u m ⬝ (std_basis m)†
lemma state_after_proj_measure_to_measure
: proj_unit u
→ state_after_proj_measure u s m
= proj_measure_restore_op u m ⬝ state_after_measure (proj_measure_op u ⬝ s) m
:= begin
intros up,
unfold state_after_proj_measure state_after_measure,
rw proj_measure_to_measure up,
rw Matrix.mul_real_smul,
congr' 1,
unfold proj_measure_op proj_measure_restore_op,
rw <- matrix.mul_assoc,
unfold proj,
have : u m ⬝ std_basis m† ⬝ (std_basis m ⬝ std_basis m†)
= u m ⬝ std_basis m†,
{
rw matrix.mul_assoc,
rw <- matrix.mul_assoc ((std_basis m)†),
simp,
},
rw this, clear this,
rw matrix.mul_assoc,
rw matrix.mul_assoc,
congr' 1,
rw <- matrix.mul_assoc,
congr' 1,
apply matrix.ext, intros i j,
have : i = 0, by simp, cases this, clear this, simp,
rw matrix.mul_apply,
rw finset.sum_eq_single m; try { solve1 {simp} },
{
intros k k_in k_neq,
simp,
rw std_basis_eq_zero k_neq,
left, refl,
},
end
end proj_measure_to_measure