Linear Algebra Foundations #7 - The 1000th Power of a Matrix

Sort by

recency

|

19 Discussions

|

  • + 0 comments
    def matrix_mul(A, B):
        ROWS_A, COLS_A = len(A), len(A[0])
        ROWS_B, COLS_B = len(B), len(B[0])
        assert COLS_A == ROWS_B
        COMMON_D = ROWS_B
    
        # zeros for Rows-A x Cols-B
        M_TIMES = []
        for r in range(ROWS_A):
            M_TIMES.append( [0] * COLS_B )
    
        # Loop over Rows-A, then Cols-B, then the common dimension
        for rA in range(ROWS_A):
            for cB in range(COLS_B):
                for t in range(COMMON_D):
                    M_TIMES[rA][cB] += A[rA][t]*B[t][cB]
        return M_TIMES
        
    def print_matrix(M, skip_indexes=[]):
        ROWS, COLS = len(M), len(M[0])
        for r in range(ROWS):
            for c in range(COLS):
                if skip_indexes and skip_indexes[r][c]:
                    continue
                print(M[r][c])
                
    #####
    A = [[-2,-9],[1,4]]
    B = A
    EXP=1000
    for _ in range(EXP-1):
        B = matrix_mul(B, A)
    # print(B)
    print_matrix(B)
    
  • + 0 comments

    It may be solved programmatically:

    #include <array>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    static const array<long, 4> kIdentityMatrix = array<long, 4>{1, 0, 0, 1};
    
    void printMatrix(const array<long, 4>& matrix) {
        cout << matrix[0] << endl << matrix[1] << endl;
        cout << matrix[2] << endl << matrix[3] << endl;
    }
    
    array<long, 4> multiply(const array<long, 4>& matrix1, const array<long, 4>& matrix2) {
        return array<long, 4>{
            matrix1[0] * matrix2[0] + matrix1[1] * matrix2[2],
            matrix1[0] * matrix2[1] + matrix1[1] * matrix2[3],
            matrix1[2] * matrix2[0] + matrix1[3] * matrix2[2],
            matrix1[2] * matrix2[1] + matrix1[3] * matrix2[3]
        };
    }
    
    array<long, 4> power(const array<long, 4>& matrix, int powerValue) {
        array<long, 4> result = kIdentityMatrix;
        for (long i = 0; i < powerValue; ++i) {
            result = std::move(multiply(result, matrix));
        }
        return result;
    }
    

    int main() { array sourceMatrix {-2, -9, 1, 4}; printMatrix(power(sourceMatrix, 1000)); return 0; }

  • + 0 comments

    What makes this problem extra challenging is that the given matrix M is not diagonalizable. It has a single eigenvalue lambda = 1, and the corresponding eigenspace is unfortunately only one dimensional, spanned by the eigenvector v1 = (-3, 1).

    If we can't make M diagonal, we can at least make it upper triangular. Let's grow {v1} to a basis for R^2. For simplicity, let's choose our second basis vector v2 to be orthogonal to v1. I chose v2 = (1, 3). Now just work in this new basis and the calculation works out.

  • + 0 comments
    import math
    A = [[
        math.pow(2999,1/1000),
        math.pow(9000,1/1000),
        math.pow(1000,1/1000),
        math.pow(3001,1/1000)]]
    
    
    for i in A:
        for q in i[:2]:
            print(round(q**1000)*-1) #Change the sign and dataset(s) :)
        for q in i[2:]:
            print(round(q**1000))
    
  • + 0 comments
    def powerMatrix(A, k):
      '''kth power of a 2 x 2 square matrix'''
      if (k == 0):
        I2 = [[1, 0], [0, 1]] # 2 x 2 identity matrix
        return I2
      elif (k == 1): # base
        return A
      elif (k > 1): # recursive
        A_less_1 = powerMatrix(A, k-1)
        A_last = A
        B = [[0, 0], [0, 0]]
        for i in range(len(A_less_1)):
          for j in range(len(A_less_1[0])):
            for l in range(len(A_last)):
              B[i][j] += A_less_1[i][l] * A_last[l][j]
        return B
        
    if __name__ == "__main__":
      A = [[-2, -9], [1, 4]]
      A500 = powerMatrix(A, 500)
      A1000 = powerMatrix(A500, 2)
      [print(*i, sep='\n') for i in A1000]