QuantumLib.Eigenvectors


This file contains more concepts relevent to quantum computing, as well as some more general linear algebra concepts such as Gram-Schmidt and eigenvectors/eigenvalues.

Require Import List.
Require Export Complex.
Require Export Quantum.
Require Import FTA.

Proving some indentities


Ltac Hhelper :=
   unfold Mmult;
   unfold big_sum;
   unfold I;
   simpl;
   C_field_simplify;
   try lca;
   C_field.

Lemma Y_eq_iXZ : σy = Ci .* σx × σz.
Lemma H_eq_Hadjoint : hadamard† = hadamard.

Hint Rewrite Y_eq_iXZ H_eq_Hadjoint : Q_db.

Lemma ItimesIid : I 2 × I 2 = I 2.
Lemma XtimesXid : σx × σx = I 2.
Lemma YtimesYid : σy × σy = I 2.
Lemma ZtimesZid : σz × σz = I 2.
Lemma HtimesHid : hadamard × hadamard = I 2.

Hint Rewrite ItimesIid XtimesXid YtimesYid ZtimesZid HtimesHid : Q_db.

Lemma ZH_eq_HX : σz × hadamard = hadamard × σx.
Lemma XH_eq_HZ : σx × hadamard = hadamard × σz.
Lemma SX_eq_YS : Sgate × σx = σy × Sgate.
Lemma SZ_eq_ZS : Sgate × σz = σz × Sgate.
Lemma cnotX1 : cnot × (σx ⊗ I 2) = (σx ⊗ σx) × cnot.
Lemma cnotX2 : cnot × (I 2 ⊗ σx) = (I 2 ⊗ σx) × cnot.
Lemma cnotZ1 : cnot × (σz ⊗ I 2) = (σz ⊗ I 2) × cnot.
Lemma cnotZ2 : cnot × (I 2 ⊗ σz) = (σz ⊗ σz) × cnot.

Hint Rewrite ZH_eq_HX XH_eq_HZ SX_eq_YS SZ_eq_ZS cnotX1 cnotX2 cnotZ1 cnotZ2 : Q_db.

Defining orthonormal matrix


Local Open Scope nat_scope.

Definition orthogonal {n m} (S : Matrix n m) : Prop :=
  ∀ i j, i ≠ j → inner_product (get_vec i S) (get_vec j S) = C0.

Definition orthonormal {n m} (S : Matrix n m) : Prop :=
  orthogonal S ∧ (∀ (i : nat), i < m → norm (get_vec i S) = 1%R).

Definition WF_Orthonormal {n m} (S : Matrix n m) : Prop :=
  WF_Matrix S ∧ orthonormal S.

Lemma inner_product_is_mult : ∀ {n} (i j : nat) (S : Square n),
  inner_product (get_vec i S) (get_vec j S) = (S† × S) i j.

Lemma inner_product_comm_conj : ∀ {n} (v u : Vector n),
  inner_product v u = Cconj (inner_product u v).

showing that all matrices have some eigenvector



Definition MatrixP (m n : nat) := nat → nat → Polynomial.

Notation SquareP n := (MatrixP n n).

Definition eval_matP {n m} (A : MatrixP n m) (c : C) : Matrix n m :=
  fun x y ⇒ (A x y)[[c]].

Definition reduceP {n} (A : SquareP (S n)) (row col : nat) : SquareP n :=
  fun x y ⇒ (if x <? row
              then (if y <? col
                    then A x y
                    else A x (1+y))
              else (if y <? col
                    then A (1+x) y
                    else A (1+x) (1+y))).

Lemma reduceP_eval_mat : ∀ {n} (A : SquareP (S n)) (c : C) (x y : nat),
  reduce (eval_matP A c) x y = eval_matP (reduceP A x y) c.

Fixpoint DeterminantP (n : nat) (A : SquareP n) : Polynomial :=
  match n with
  | 0 ⇒ [C1]
  | S 0 ⇒ A 0 0
  | S n' ⇒ (big_sum (fun i ⇒ [(parity i)] *, (A i 0) *, (DeterminantP n' (reduceP A i 0)))%C n)
  end.

Arguments DeterminantP {n}.

Lemma DetP_simplify : ∀ {n} (A : SquareP (S (S n))),
  DeterminantP A =
  (big_sum (fun i ⇒ [(parity i)] *, (A i 0) *, (DeterminantP (reduceP A i 0)))%C (S (S n))).

Lemma Peval_Det : ∀ {n} (A : SquareP n) (c : C),
  Determinant (eval_matP A c) = (DeterminantP A)[[c]].

Definition prep_mat {n} (A : Square n) : SquareP n :=
  (fun x y ⇒ if (x =? y) && (x <? n) then [A x y; -C1] else [A x y]).


Definition deg_elem_leq_1 {n} (A : SquareP n) : Prop :=
  ∀ i j, degree (A i j) ≤ 1.

Lemma del1_reduce : ∀ {n} (A : SquareP (S n)) (i j : nat),
  deg_elem_leq_1 A → deg_elem_leq_1 (reduceP A i j).

Lemma bound_deg_matP : ∀ {n} (A : SquareP n),
  deg_elem_leq_1 A → degree (DeterminantP A) ≤ n.

Lemma del1_prep_mat : ∀ {n} (A : Square n),
  deg_elem_leq_1 (prep_mat A).

Lemma reduce_prep_mat : ∀ {n} (A : Square (S n)),
  reduceP (prep_mat A) 0 0 = prep_mat (reduce A 0 0).

Lemma detP_deg : ∀ {n} (A : Square n),
  degree (DeterminantP (prep_mat A)) = n.

Lemma connect : ∀ (n : nat) (A : Square (S n)),
  ∃ (p : Polynomial), (Polynomial.degree p) > 0 ∧
    (∀ c : C, Determinant (A .+ (-c .* I (S n))) = p[[c]]).

Lemma connect2 : ∀ (n : nat) (A : Square (S n)),
  ∃ (c : C), det_eq_c C0 (A .+ (-c .* I (S n))).

Lemma exists_eigenvector : ∀ (n : nat) (A : Square (S n)),
  WF_Matrix A →
  ∃ (c : C) (v : Vector (S n)), WF_Matrix v ∧ v ≠ Zero ∧ A × v = c.* v.

Lemmas relating to forming bases


Definition form_basis {n} (v : Vector n) (non_zero : nat) : Matrix n n :=
  fun x y ⇒ if (y =? non_zero)
             then (v x 0)
             else (@e_i n y x 0).

Lemma WF_form_basis : ∀ {n} (v : Vector n) (x : nat),
  WF_Matrix v → x < n → WF_Matrix (form_basis v x).

Lemma get_v_in_basis : ∀ {n} (v : Vector n) (x : nat),
  WF_Matrix v → get_vec x (form_basis v x) = v.

Lemma get_ei_in_basis : ∀ {n} (v : Vector n) (x y : nat),
  y < n → y ≠ x → get_vec y (form_basis v x) = e_i y.

Lemma form_basis_ver : ∀ {n} (v : Vector n) (x : nat),
  v ≠ Zero → WF_Matrix v → v x 0 ≠ C0 → x < n →
  linearly_independent (form_basis v x) ∧ get_vec x (form_basis v x) = v.

Lemma lin_indep_out_of_v : ∀ {n} (v : Vector n),
  WF_Matrix v → v ≠ Zero →
  ∃ S : Square n, WF_Matrix S ∧ linearly_independent S ∧ get_vec 0 S = v.

Defining and verifying the gram_schmidt algorythm and proving v can be part of an onb


Definition proj {n} (u v : Vector n) : Vector n :=
  ((inner_product u v) / (inner_product u u)) .* u.

Definition proj_coef {n} (u v : Vector n) : C :=
  ((inner_product u v) / (inner_product u u)).

Lemma proj_inner_product : ∀ {n} (u v : Vector n),
  (norm u) ≠ 0%R → inner_product u (proj u v) = inner_product u v.

Definition gram_schmidt_on_v (n m : nat) (v : Vector n) (S : Matrix n m) :=
  v .+ (big_sum (fun i ⇒ (-C1) .* (proj (get_vec i S) v)) m).

Definition delta_T {n m} (T : Matrix n (S m)) (i : nat) : C :=
  match i =? m with
  | true ⇒ C1
  | _ ⇒ - (proj_coef (get_vec i T) (get_vec m T))
  end.

Definition gram_schmidt_on_T (n m : nat) (T : Matrix n (S m)) : Vector n :=
  big_sum (fun i ⇒ (delta_T T) i .* (get_vec i T)) (S m).

Lemma WF_gs_on_T : ∀ {n m} (T : Matrix n (S m)),
  WF_Matrix T → WF_Matrix (gram_schmidt_on_T n m T).

Lemma gram_schmidt_compare : ∀ {n m} (T : Matrix n (S m)),
  inner_product (get_vec m T) (get_vec m T) ≠ C0 →
  gram_schmidt_on_T n m T = gram_schmidt_on_v n m (get_vec m T) (reduce_col T m).

Lemma gram_schmidt_orthogonal : ∀ {n m} (v : Vector n) (S : Matrix n m) (i : nat),
  orthonormal S → i < m → inner_product (get_vec i S) (gram_schmidt_on_v n m v S) = C0.

Definition f_to_vec (n : nat) (f : nat → C) : Vector n :=
  fun i j ⇒ if (j =? 0) && (i <? n) then f i else C0.

Lemma WF_f_to_vec : ∀ (n : nat) (f : nat → C), WF_Matrix (f_to_vec n f).

Lemma Msum_to_Mmult : ∀ {n m} (T : Matrix n (S m)) (f : nat → C),
  big_sum (fun i ⇒ f i .* get_vec i T) (S m) = T × (f_to_vec (S m) f).

Lemma gram_schmidt_non_zero : ∀ {n m} (T : Matrix n (S m)),
  linearly_independent T → gram_schmidt_on_T n m T ≠ Zero.

Lemma inner_product_zero_normalize : ∀ {n} (u v : Vector n),
  inner_product u v = C0 → inner_product u (normalize v) = C0.

Lemma get_vec_reduce_append_miss : ∀ {n m} (T : Matrix n (S m)) (v : Vector n) (i : nat),
  i < m → get_vec i (col_append (reduce_col T m) v) = get_vec i T.

Lemma get_vec_reduce_append_hit : ∀ {n m} (T : Matrix n (S m)) (v : Vector n),
  WF_Matrix v → get_vec m (col_append (reduce_col T m) v) = v.

Lemma get_vec_reduce_append_over : ∀ {n m} (T : Matrix n (S m)) (v : Vector n) (i : nat),
  WF_Matrix T → i > m →
  get_vec i (col_append (reduce_col T m) v) = Zero.

Lemma extend_onb_ind_step_part1 : ∀ {n m} (T : Matrix n (S m)),
  WF_Matrix T → linearly_independent T → orthonormal (reduce_col T m) →
  orthonormal (col_append (reduce_col T m) (normalize (gram_schmidt_on_T n m T))).

Definition delta_T' {n m} (T : Matrix n m) (v : Vector n) (size : nat) : nat → C :=
  fun i ⇒ if (i <? size)
           then - (proj_coef (get_vec i T) v)
           else C0.

Lemma gs_on_T_cols_add : ∀ {n m1 m2} (T1 : Matrix n m1) (T2 : Matrix n m2) (v : Vector n),
  WF_Matrix v →
  smash (col_append T1 (gram_schmidt_on_T n m1 (col_append T1 v))) T2 =
  @col_add_many n ((S m1) + m2) m1 (f_to_vec (m1 + m2) (delta_T' T1 v m1))
                             (smash (col_append T1 v) T2).

Lemma smash_scale : ∀ {n m1 m2} (T1 : Matrix n m1) (T2 : Matrix n m2) (v : Vector n),
  smash (col_append T1 (normalize v)) T2 =
  col_scale (smash (col_append T1 v) T2) m1 (/ norm v).

Lemma extend_onb_ind_step_part2 : ∀ {n m1 m2} (T1 : Matrix n m1) (T2 : Matrix n m2)
                                                   (v : Vector n),
  WF_Matrix T1 → WF_Matrix T2 → WF_Matrix v → v ≠ Zero →
  linearly_independent (smash (col_append T1 v) T2) →
  linearly_independent (smash (col_append T1
                                    (normalize (gram_schmidt_on_T n m1 (col_append T1 v)))) T2).

Lemma extend_onb_ind_step : ∀ {n m1 m2} (T1 : Matrix n m1) (T2 : Matrix n m2) (v : Vector n),
  WF_Matrix T1 → WF_Matrix T2 → WF_Matrix v →
  linearly_independent (smash (col_append T1 v) T2) → orthonormal T1 →
  ∃ v1, WF_Matrix v1 ∧ orthonormal (col_append T1 v1) ∧
             linearly_independent (smash (col_append T1 v1) T2).

Lemma extend_onb : ∀ (n m2 m1 : nat) (T1 : Matrix n (S m1)) (T2 : Matrix n m2),
  WF_Matrix T1 → WF_Matrix T2 →
  linearly_independent (smash T1 T2) → orthonormal T1 →
  ∃ T2' : Matrix n m2, WF_Matrix T2' ∧ orthonormal (smash T1 T2').

Lemma get_vec_vec : ∀ {n} (v : Vector n),
  WF_Matrix v → get_vec 0 v = v.

Lemma orthonormal_normalize_v : ∀ {n} (v : Vector n),
  v ≠ Zero → WF_Matrix v → orthonormal (normalize v).

Theorem onb_out_of_v : ∀ {n} (v : Vector n),
  WF_Matrix v → v ≠ Zero →
  ∃ T : Square n, WF_Orthonormal T ∧ get_vec 0 T = normalize v.

some useful facts about unitary matrices

We now define diagonal matrices and diagonizable matrices, proving basic lemmas


Definition WF_Diagonal {n : nat} (A : Square n) : Prop :=
  WF_Matrix A ∧ ∀ i j, i ≠ j → A i j = C0.

Lemma diag_Zero : ∀ n : nat, WF_Diagonal (@Zero n n).

Lemma diag_I : ∀ n : nat, WF_Diagonal (I n).

Lemma diag_I1 : WF_Diagonal (I 1).

Lemma diag_scale : ∀ {n : nat} (r : C) (A : Square n),
  WF_Diagonal A → WF_Diagonal (r .* A).

Lemma diag_plus : ∀ {n} (A B : Square n),
  WF_Diagonal A → WF_Diagonal B → WF_Diagonal (A .+ B).

Lemma diag_mult : ∀ {n : nat} (A B : Square n),
  WF_Diagonal A → WF_Diagonal B → WF_Diagonal (A × B).

Lemma div_mod_eq : ∀ (a b m : nat),
  m ≠ 0 → (a / m = b / m) → (a mod m = b mod m) → a = b.

Lemma diag_kron : ∀ {n m : nat} (A : Square n) (B : Square m),
                  WF_Diagonal A → WF_Diagonal B → WF_Diagonal (A ⊗ B).

Lemma diag_transpose : ∀ {n : nat} (A : Square n),
                     WF_Diagonal A → WF_Diagonal A⊤.

Lemma diag_adjoint : ∀ {n : nat} (A : Square n),
      WF_Diagonal A → WF_Diagonal A†.

Lemma diag_kron_n : ∀ (n : nat) {m : nat} (A : Square m),
   WF_Diagonal A → WF_Diagonal (kron_n n A).

Lemma diag_big_kron : ∀ n (l : list (Square n)),
                        (∀ A, In A l → WF_Diagonal A) →
                         WF_Diagonal (⨂ l).

Lemma diag_Mmult_n : ∀ n {m} (A : Square m),
   WF_Diagonal A → WF_Diagonal (Mmult_n n A).

defining what it means to be diagonalizable

Defining Cprod, similar to big_sum


Fixpoint Cprod (f : nat → C) (n : nat) : C :=
  match n with
  | 0 ⇒ C1
  | S n' ⇒ (Cprod f n' × f n')%C
  end.

Lemma Cprod_0_bounded : ∀ (f : nat → C) (n : nat),
  (∃ i, i < n ∧ f i = C0) → Cprod f n = C0.

Lemma Cprod_eq_bounded : ∀ (f g : nat → C) (n : nat),
  (∀ i : nat, i < n → f i = g i) → Cprod f n = Cprod g n.

Lemma Cprod_extend_r : ∀ (f : nat → C) (n : nat),
  (Cprod f n × f n)%C = Cprod f (S n).

Lemma Cprod_extend_l : ∀ (f : nat → C) (n : nat),
  (f 0 × (Cprod (fun x ⇒ f (S x)) n))%C = Cprod f (S n).

Lemma Cprod_product : ∀ (f g h : nat → C) (n : nat),
  (∀ i, i < n → h i = (f i × g i)%C) → ((Cprod f n) × (Cprod g n))%C = Cprod h n.

Defining upper triangular matrix


Definition upper_triangular {n} (A : Square n) : Prop :=
  ∀ i j, i > j → A i j = C0.

Lemma up_tri_Zero : ∀ n : nat, upper_triangular (@Zero n n).

Lemma up_tri_I : ∀ n : nat, upper_triangular (I n).

Lemma up_tri_I1 : upper_triangular (I 1).

Lemma up_tri_scale : ∀ {n : nat} (r : C) (A : Square n),
  upper_triangular A → upper_triangular (r .* A).

Lemma up_tri_plus : ∀ {n} (A B : Square n),
  upper_triangular A → upper_triangular B → upper_triangular (A .+ B).

Lemma up_tri_mult : ∀ {n : nat} (A B : Square n),
  upper_triangular A → upper_triangular B → upper_triangular (A × B).

Lemma up_tri_reduce_0 : ∀ {n : nat} (A : Square (S n)),
  upper_triangular A → upper_triangular (reduce A 0 0).

Lemma det_up_tri_diags : ∀ {n : nat} (A : Square n),
  upper_triangular A →
  Determinant A = Cprod (fun i ⇒ A i i) n.

Defining eignestates to be used in type system


Definition Eigenpair {n : nat} (U : Square n) (p : Vector n × C) : Prop :=
  U × (fst p) = (snd p) .* (fst p).

Lemma all_v_eigen_I : ∀ (n : nat) (v : Vector n),
   WF_Matrix v → Eigenpair (I n) (v, C1).

Lemma diags_have_basis_eigens : ∀ (n : nat) (U : Square n) (i : nat),
  (i < n) → WF_Diagonal U → Eigenpair U (e_i i, U i i).

Local Close Scope nat_scope.

Lemma eigen_scale : ∀ {n} (A : Square n) (v : Vector n) (c1 c2 : C),
  Eigenpair A (v, c1) → Eigenpair (c2 .* A) (v, c1 × c2).

Lemma eigen_scale_div : ∀ {n} (A : Square n) (v : Vector n) (c1 c2 : C),
  c2 ≠ C0 → Eigenpair (c2 .* A) (v, Cmult c2 c1) → Eigenpair A (v, c1).

Lemma eig_unit_invertible : ∀ {n} (v : Vector n) (c : C) (X X' B : Square n),
  WF_Matrix v → WF_Matrix X → WF_Matrix X' → X' × X = I n →
  Eigenpair B (X × v, c) → Eigenpair (X' × B × X) (v, c).

Lemma eig_unit_conv : ∀ {n} (v : Vector n) (c : C) (U B : Square n),
  WF_Matrix v → WF_Unitary U →
  Eigenpair B (U × v, c) → Eigenpair (U† × B × U) (v, c).

Lemma eig_unit_norm1 : ∀ {n} (U : Square n) (c : C),
  WF_Unitary U → (∃ v, WF_Matrix v ∧ v ≠ Zero ∧ Eigenpair U (v, c)) → (c × c^* = C1)%C.

Next, we show that unitary matrices are diagonalizable


Lemma unit_has_eigen : ∀ {n} (A : Square (S n)),
  WF_Unitary A →
  ∃ (c : C) (v : Vector (S n)), Eigenpair A (v, c) ∧ v ≠ Zero ∧ WF_Matrix v.

Lemma unitary_reduction_step1 : ∀ {n} (A : Square (S n)),
  WF_Unitary A →
  ∃ X, WF_Unitary X ∧
  (∃ c : C, get_vec 0 (X†×A×X) = c .* e_i 0).

Local Open Scope nat_scope.
Lemma unitary_reduction_step2 : ∀ {n} (A : Square (S n)),
  WF_Unitary A →
  (∃ c : C, get_vec 0 A = c .* e_i 0) →
  (∀ (i j : nat), (i = 0 ∨ j = 0) ∧ i ≠ j → A i j = C0).

Lemma unitary_reduction_step3 : ∀ {n} (A : Square (S n)),
  WF_Unitary A →
  (∀ (i j : nat), (i = 0 ∨ j = 0) ∧ i ≠ j → A i j = C0) →
  ∃ (A' : Square n), WF_Unitary A' ∧ pad1 A' (A 0 0) = A.

Lemma diagble_pad1 : ∀ {n} (A : Square n) (c : C),
  WF_Diagonalizable A → WF_Diagonalizable (pad1 A c).


Theorem unit_implies_diagble : ∀ {n} (A : Square n),
  WF_Unitary A → WF_Diagonalizable A.

Showing that certain types of matrices are equal when their eigenpairs are equal

Some actual examples/lemmas


Lemma EigenXp : Eigenpair σx (∣+⟩, C1).

Lemma EigenXm : Eigenpair σx (∣-⟩, -C1).

Lemma EigenYp : Eigenpair σy (∣R⟩, C1).

Lemma EigenYm : Eigenpair σy (∣L⟩, -C1).

Lemma EigenZp : Eigenpair σz (∣0⟩, C1).

Lemma EigenZm : Eigenpair σz (∣1⟩, -C1).

Lemma EigenXXB : Eigenpair (σx ⊗ σx) (∣Φ+⟩, C1).

#[export] Hint Resolve EigenXp EigenXm EigenYp EigenYm EigenZp EigenZm EigenXXB all_v_eigen_I : eig_db.