import numpy as np
from scipy.linalg import eig, inv
from diffmaps_util import k, diag, sort_eigens

m = np.array([.8, .2, .5, .5]).reshape(2,2)
m

u0 = np.array([0,1])
for i in range(0,50):
    u0 = u0.dot(m)
print u0

w, v = eig(m)
print w.real
print v

v.dot(inv(v).dot(u0))

"""
Explanation: Diagonalizing a Matrix
$
\mathbf{A} x_1 = \lambda_1 x_1 \
\mathbf{A} x_2 = \lambda_2 x_2 \
\mathbf{A} \times \begin{vmatrix} x_1 & x_2 \end{vmatrix} = \begin{vmatrix} \lambda_1 x_1 & \lambda_2 x_2 \end{vmatrix} = \begin{vmatrix} x_1 & x_2 \end{vmatrix} \times \begin{vmatrix} \lambda_1 & 0 \ 0 & \lambda_2 \end{vmatrix} \
THEN \
\mathbf{A} \mathbf{V} = \mathbf{V} \mathbf{\Lambda} \
SO \
\mathbf{V}^{-1} \mathbf{A} \mathbf{V} = \mathbf{\Lambda} \
AND \
\mathbf{A} = \mathbf{V} \mathbf{\Lambda} \mathbf{V}^{-1}
$
Powering
$
\mathbf{A}^2 = \mathbf{V} \mathbf{\Lambda} \mathbf{V}^{-1} \mathbf{V} \mathbf{\Lambda} \mathbf{V}^{-1} \
= \mathbf{V} \mathbf{\Lambda} \mathbf{\Lambda} \mathbf{V}^{-1} \
= \mathbf{V} \mathbf{\Lambda}^2 \mathbf{V}^{-1} \
$
Powering to n
$
\mathbf{A}^n = \mathbf{V} \mathbf{\Lambda} \mathbf{V}^{-1} \mathbf{V} \mathbf{\Lambda} \mathbf{V}^{-1} ... \
= \mathbf{V} \mathbf{\Lambda}^n \mathbf{V}^{-1} \
$
Source

https://www.youtube.com/watch?v=U8R54zOTVLw

Markov Matrix
$
p_1 = \mathbf{A} p_0, p_2 = \mathbf{A} p_1 \
p_2 = \mathbf{A} \mathbf{A} p_0 \
p_2 = \mathbf{A}^2 p_0 \
p_2 = \mathbf{V} \mathbf{\Lambda}^2 \mathbf{V}^{-1} p_0
$
<p>**If $p_{n+1} = \mathbf{A} p_n$ then $p_{n} = \mathbf{A}^n p_0 = \mathbf{V} \mathbf{\Lambda}^n \mathbf{V}^{-1} p_0$**</p>

Writing p_0 as combination of eigenvectors
$
p_0 = c_1 x_1 + c_2 x_2 ... c_n x_n => \mathbf{V}\mathbf{c} = p_0 => \mathbf{c} = \mathbf{V}^{-1} p_0\
\mathbf{A} p_0 = p_1 = c_1 \lambda_1 x_1 + c_2 \lambda_2 x_2 ... c_k \lambda_k x_k \
\mathbf{A}^n p_0 = p_n = c_1 \lambda_1^n x_1 + c_2 \lambda_2^n x_2 ... c_k \lambda_k^n x_k \
= p_n = \mathbf{c} \mathbf{V} \mathbf{\Lambda}^n \
= \mathbf{V} \mathbf{\Lambda}^n \mathbf{V}^{-1} p_0
$
Source

https://www.youtube.com/watch?v=xtMzTXHO_zA
End of explanation
"""


m = np.random.randn(9).reshape(3,3)
L = k(m, .7)
D = diag(L)
m = inv(D).dot(L)
print m

w, v = eig(m)
w = w.real
print w
print v

p0 = np.eye(len(m))

"""
Explanation: 
End of explanation
"""


lmbda = np.zeros((3,3))
np.fill_diagonal(lmbda, w)

"""
Explanation: Building a diagonal eigenvalue matrix
End of explanation
"""


p1 = p0.dot(m)
p1

"""
Explanation: $p_1 = p_0A$
End of explanation
"""


v.dot(lmbda).dot(inv(v)).dot(p0)

"""
Explanation: $p1 = \mathbf{V} \Lambda \mathbf{V}^{-1} p_0$
End of explanation
"""


p2 = p1.dot(m)
p2

"""
Explanation: $p2 = p1A$
End of explanation
"""


v.dot(lmbda ** 2).dot(inv(v)).dot(p0)

"""
Explanation: $p2 = \mathbf{V} \Lambda^2 \mathbf{V}^{-1} p_0$
End of explanation
"""


