<jupyter_start><jupyter_text>Changing vectors to the eigenbasis**Motivation**: when applying a matrix transformation T to one vector (t) many times over and over (linear transformation - same transformation occurs each time), we need to multiply $\vec{t}_1$ with T, then  $\vec{t}_2$ with T and so on.$$ \vec{t}_1 = \vec{t}_0 * T$$$$ \vec{t}_2 = \vec{t}_1 * T$$==> $\vec{t}_2 = \vec{t}_0*T^2$An easier way to do this would be to have all the terms of the matrix = 0 **except** for the leading diagonal. When raising to a power, a diagonal matrix makes things a lot easier as each of the terms of the diagonal needs to be raised to the power of the number of times we are multiplying T with itself.$T^n = \begin{bmatrix}a^n & \dots & 0\\  \vdots & \ddots & \vdots & \\ 0 & \dots & d^n\end{bmatrix}$**EIGENBASIS** = change a matrix so it becomes with a leading diagonal and 0 in the restIf T is **not a diagonal matrix** change it with eigen-analysis so that T becomes diagonal. Then we can apply the power of n and transform the resulting matrix back again. !! Each column of our new transformation matrix represents the new location of the transformed unit vectors. So to build an eigen-bais conversion matrix, we plug in the eignvectos as columns:$$ C = \begin{bmatrix}eigenvector_1 & \dots & eigenvector_n\\  \vdots & \vdots & \vdots \end{bmatrix}$$Matrix D, contains the corresponding **eigenvalues** of the matrix T:$$ D = \begin{bmatrix}eigenvvalue_1 & \dots & 0\\  0 & eigenvalue_2 & \dots \\ \vdots & \ddots & \vdots & \\ 0 & \dots & eigenvalue_3 \end{bmatrix}$$Applying the transformation T, is just the same as converting to our eigenbasis, applying the diagonalized matrix and then converting back again. $$ T = CDC^-1$$$$ T^2 = CDC^-1CDC^-1$$$$ T^n = Cd^2C^-1 $$  Example (long way)Transformation matrix T = [[1, 1], [0,2]]. To v1 = [1, 1] and v2 = [-1, 1]- first column of T is [1,0] so that means that $\hat{i}$ will be unchanged- second column of T is [0, 2], which means that $\hat{j}$will be moving to coordinates 0,2- v1 will move at $T.v1$- v2 will move at $T.v2$<jupyter_code>import numpy as np
from numpy import linalg as la<jupyter_output><empty_output><jupyter_text>Instantiate the arrays<jupyter_code>T = np.array([[1, 1], [0,2]])
v1 = np.array([[1], [1]])
v2 = np.array([[-1], [1]])<jupyter_output><empty_output><jupyter_text>Multiply matrix T with vector v1<jupyter_code># T.v1
tv1 = np.dot(T, v1)
tv1<jupyter_output><empty_output><jupyter_text>Multiply matrix T with vector v2<jupyter_code># t . v2
tv2 = np.dot(T, v2)
tv2
# apply T again to the transformed vector v2
np.dot(T, tv2)<jupyter_output><empty_output><jupyter_text>If we start by thinking about the number of transformations, in this case 2, we start with multiplying T with itself ($T^2$)<jupyter_code># T squared
tsq = np.dot(T, T)
tsq<jupyter_output><empty_output><jupyter_text>By multiplying $T^2$ with the original vector v2, we should get the same result as multiplying v2 with T and then the results of that again with T.<jupyter_code># T squared multiplied with v2
np.dot(tsq, v2)<jupyter_output><empty_output><jupyter_text>Same example, using the eigenbasis approach:1. Find the eigenvectors2. Build the conversion matrix C3. Find the inverse of $C$ $Cinv = C^-1$4. Construct matrix D with the eigenvalues5. Apply the formula: $ T^n = CD^2C^-1 $ Calculate the eigenvalues and vectors using numpy<jupyter_code>def fill_diagonal(diagonal):
    source_array = np.zeros((len(diagonal), len(diagonal)), np.float64)
    copy = source_array.copy()
    np.fill_diagonal(copy, diagonal)
    return copy
def compute_Tn(n, transf_matrix):

    # C for the eigenvectors
    eigval, C = la.eig(transf_matrix)

    # Find the inverse of C
    Cinv = la.inv(C)

    # D is the eigenvalues on the diagonal
    D = fill_diagonal(eigval)

    # raise D to the power of n
    Dn = D**n
    
    # apply the formula
    Tn = la.multi_dot([C, Dn, Cinv])
    
    return Tn

compute_Tn(2, T)<jupyter_output><empty_output><jupyter_text>Practice QUIZ  Given matrix T and change of basis matrix C (whose columns are eigenvectors of T), calculate the diagonal matrix $D=C^-1TC)$<jupyter_code>T = np.array([[6, -1], [2, 3]])
C = np.array([[1,1], [1,2]])
def calculate_inverse(m):
    return la.inv(m)

def multi_dot_product(array_of_m):
    return la.multi_dot(array_of_m)

def calculate_d(c, t):
    cinv = calculate_inverse(c)
    return multi_dot_product([cinv, t, c])
calculate_d(C, T)<jupyter_output><empty_output><jupyter_text>Given the matrix T and change of basis matrix C, calculate the diagonal matrix D.<jupyter_code>T2 = np.array([[2, 7], [0,-1]])
C2 = np.array([[7,1], [-3,0]])
calculate_d(C2, T2)<jupyter_output><empty_output><jupyter_text>Given matrix T and change of basis matrix C, calculate the diagonal matrix D.<jupyter_code>T3 = np.array([[1, 0], [2,-1]])
C3 = np.array([[1,0], [1,1]])
calculate_d(C3, T3)<jupyter_output><empty_output><jupyter_text>Given a diagonal matrix D and change of basis matrix C with inverse C, calculate T.<jupyter_code>D4 = np.array(([1,0],[0,1]))
C4 = np.array(((1,2),(0,1)))
C4_inv = np.array(((1,-2),(0,1)))

multi_dot_product([C, D4, C4_inv])<jupyter_output><empty_output><jupyter_text>Given T, calculate $T^3$<jupyter_code>T = np.array( ((6, -1), (2,3)))
T_pow3 = la.matrix_power(T, 3)
T_pow3<jupyter_output><empty_output><jupyter_text>Given T, calculate $T^3$<jupyter_code>T6 = np.array( ((2, 7), (0, -1)))
T6_pow3 = la.matrix_power(T6, 3)
T6_pow3<jupyter_output><empty_output><jupyter_text>Given T, calculate $T^5$<jupyter_code>T7 = np.array( ((1, 0), (2, -1)))
T7_pow5 = la.matrix_power(T7, 5)
T7_pow5<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1364922206506365, 'fraction_numerical': 0.0297029702970297, 'mean_word_length': 4.862176165803109, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '417824', 'license': 'MIT', 'n_tokens_mistral': 2127, 'n_tokens_neox': 2027, 'n_words': 662, 'path': 'Week5/eigen_basis.ipynb', 'repo_name': 'kriystinne/math-ML-ImperialCollegeLondon', 'size': '5656'}