## Eigenvalues via the power method
using Random
Random.seed!(0)
A = randn(10,10)
# make it symmetric for simplicity
A = A + A'
using LinearAlgebra
maxlam = eigen(Symmetric(A)).values[end]
##
function power_method(A,niter=100)
  n = size(A,1)
  x = randn(n)
  lam = 0.0
  for i=1:niter
    y = A*x
    lam = y'*x
    x = y./norm(y)
  end
  return x, lam
end
power_method(A,100)
##
x,lam = power_method(A,1000)
## Check residual
norm(A*x - lam*x)
## If lam1 = lam2
A = [2 0 0 0 ;
     0 2 0 0;
     0 0 0.6 0.5;
    0 0 0.5 0.6 ]
eigvals(A)
##
x, lam = power_method(A, 100)
norm(A*x - lam*x)
##
function eigen_ascent(A,gamma=1.0,niter=100)
  n = size(A,1)
  x = randn(n)
  lam = 0.0
  for i=1:niter
    y = A*x
    lam = y'*x
    y = x + gamma*y
    x = y./norm(y)
  end
  return x, lam
end
@show eigen_ascent(A,1.0,100)
##
@show eigen_ascent(A,0.5,15)
## Let's look at this function after a few steps
Random.seed!(1)
x3 = eigen_ascent(A,0.5,3)[1]
@show norm(x3)
@show x3'*A*x3
y3 = A*x3
f3 = gamma -> ((x3 + gamma*y3)'*A*(x3 + gamma*y3)) / (norm((x3 + gamma*y3))^2)
gammas = 10.0.^range(-2, 3, length=100)
using LaTeXStrings
plot(gammas, f3.(gammas),xscale=:log10, label=L"$\gamma$")
plot!(gammas, f3.(-gammas),xscale=:log10, label=L"$-\gamma$")
xlabel!(L"$\gamma$")