Zulip Chat Archive
Stream: new members
Topic: Simple eigenvector problem
MohanadAhmed (Apr 11 2023 at 22:30):
Hi everyone,
I am trying to prove that the vector [0,0,1]
is a an eigenvector of the matrix [2,0,0; 0, 1, 0; 0, 0, 1]
. I am stuck with the compositions of the vec_head and vec_tail functions as can be seen below. Lean seems to know how to evaluate them as you can see from the #eval
below them. Any help appreciated
import data.complex.basic
import data.matrix.basic
import data.fintype.card
import linear_algebra.matrix.to_lin
import linear_algebra.eigenspace
def M := !![(2:ℂ), 0, 0; 0, 1, 0; 0, 0, 1]
def v: (fin 3) → ℂ := ![0, 0, 1]
open module.End.eigenvalues
open module.End
open matrix
example : has_eigenvector (matrix.to_lin' M) (1:ℂ) v := begin
rw M, rw v,
rw module.End.has_eigenvector, split,
{
rw mem_eigenspace_iff, rw matrix.to_lin'_apply,
-- rw matrix.mul_vec_cons, rw zero_smul, rw one_smul,
-- rw zero_add, rw matrix.mul_vec_cons,
simp only [
matrix.mul_vec_cons, zero_smul, one_smul,
matrix.mul_vec_empty, add_zero, zero_add
],
sorry, -- Here is where the vec_head vec_tail compositions appear
},
simp only [ne.def, cons_eq_zero_iff, one_ne_zero, false_and, and_false, not_false_iff],
end
#check vec_head ∘ vec_tail ∘ vec_tail ∘ ![![2, 0, 0], ![0, 1, 0], ![0, 0, 1]]
#eval vec_head ∘ vec_tail ∘ vec_tail ∘ ![![2, 0, 0], ![0, 1, 0], ![0, 0, 1]]
Eric Wieser (Apr 11 2023 at 23:43):
Note you should write M
using !![2,0,0; ...]
not ![![2,0,0], ...]
; the latter has the wrong type.
Eric Wieser (Apr 11 2023 at 23:44):
What goal are you left with at the sorry
?
MohanadAhmed (Apr 12 2023 at 01:35):
Eric Wieser said:
Note you should write
M
using!![2,0,0; ...]
not![![2,0,0], ...]
; the latter has the wrong type.
The single exclamation mark "array of arrays" is the result of applying the simplifier i.e. after
simp only [
matrix.mul_vec_cons, zero_smul, one_smul,
matrix.mul_vec_empty, add_zero, zero_add
],
Eric Wieser said:
What goal are you left with at the
sorry
?
The goal at the sorry is
vec_head ∘ vec_tail ∘ vec_tail ∘ ![![2, 0, 0], ![0, 1, 0], ![0, 0, 1]]
After a lot of just trying stuff randomly and then using the simplifier, the code below seems to get it done.
The simplifier originally applied mul_vec_cons
. I replaced that with repeated application of cons_mul_vec
followed by vec3_dot_product
then calling the simplifier.
But this small problem cannot (or should not be!) that hard. What am I missing? Is the API to matrices and vectors too brittle or is the simplifier missing some lemmas?
Is there a shorter way?
import data.complex.basic
import data.matrix.basic
import data.matrix.notation
import data.fin.vec_notation
import data.fintype.vector
import data.fintype.card
import linear_algebra.matrix.to_lin
import linear_algebra.eigenspace
import tactic
def M := !![(2:ℂ), 0, 0; 0, 1, 0; 0, 0, 1]
def v: (fin 3) → ℂ := ![0, 0, 1]
open module.End.eigenvalues
open module.End
open matrix
open_locale matrix
example : has_eigenvector (matrix.to_lin' M) (1:ℂ) v := begin
rw M, rw v,
rw module.End.has_eigenvector, split,
{
rw mem_eigenspace_iff, rw matrix.to_lin'_apply,
rw matrix.cons_mul_vec,
rw matrix.cons_mul_vec,
rw matrix.cons_mul_vec,
rw vec3_dot_product,
rw vec3_dot_product,
rw vec3_dot_product,
simp only [ one_smul],
simp only [cons_val_zero, mul_zero, cons_val_one, head_cons, cons_vec_bit0_eq_alt0, cons_vec_append, empty_vec_append,
cons_vec_alt0, mul_one, zero_add, mul_vec_cons, empty_add_empty],
},
simp only [ne.def, cons_eq_zero_iff, one_ne_zero, false_and, and_false, not_false_iff],
end
Eric Wieser (Apr 12 2023 at 06:43):
MohanadAhmed said:
Eric Wieser said:
What goal are you left with at the
sorry
?The goal at the sorry is
vec_head ∘ vec_tail ∘ vec_tail ∘ ![![2, 0, 0], ![0, 1, 0], ![0, 0, 1]]
I don't believe you, that goal doesn't have an =
in it!
MohanadAhmed (Apr 12 2023 at 10:29):
Sorry I forgot to copy the RHS
vec_head ∘ vec_tail ∘ vec_tail ∘ ![![2, 0, 0], ![0, 1, 0], ![0, 0, 1]] = ![0, 0, 1]
I did the eval below it ,just to check if lean can calculate the LHS to be the same as the RHS.
MohanadAhmed (Apr 12 2023 at 10:30):
So #eval vec_head ∘ vec_tail ∘ vec_tail ∘ ![![2, 0, 0], ![0, 1, 0], ![0, 0, 1]]
evaluates to ![0, 0, 1]
Eric Wieser (Apr 12 2023 at 10:43):
The ones you used in #eval
are 0, 1, 2 : Nat
, not 0, 1, 2 : R
; lean doesn't know what R
is so can't evaluate it
Eric Wieser (Apr 12 2023 at 10:44):
At any rate, I think ext, simp
should make progress
Eric Wieser (Apr 13 2023 at 15:45):
With #18805 (edit: ), you can prove it as
example : has_eigenvector (matrix.to_lin' M) (1:ℂ) v := begin
rw [module.End.has_eigenvector],
split,
{ rw [mem_eigenspace_iff, matrix.to_lin'_apply],
have : M.mul_vec v = ![2*0 + 0*0 + 0*1, 0*0 + 1*0 + 0*1, 0*0 + 0*0 + 1*1] :=
(mul_vecᵣ_eq _ _).symm,
rw [this, v],
simp },
simp only [v, ne.def, cons_eq_zero_iff, one_ne_zero, false_and, and_false, not_false_iff],
end
matrix.mul_vecᵣ_eq
does all the boring expansion into the form you expect; you just have to write out the target expression.
Kevin Buzzard (Apr 13 2023 at 21:59):
Could this be a job for norm_num
?
Eric Wieser (Apr 13 2023 at 23:04):
Perhaps. Note that with #15738 it's just a job for rw
Last updated: Dec 20 2023 at 11:08 UTC