Load the Required Packages

library(pracma)

Functions

to_LaTeX <- function(A){
    rows <- apply(A, MARGIN=1, paste, collapse = " & ")
    matrix_string <- paste(rows, collapse = " \\\\ ")
    return(paste("\\begin{bmatrix}", matrix_string, "\\end{bmatrix}"))
}

get_properties <- function(A){
    m = nrow(A)
    n = ncol(A)
    if (m != n){
        square = FALSE
    }
    else{
        square = TRUE
    }
    equality <- c()
    if (square){
        for (i in 1:m){
            for (j in 1:n){
                if (A[i, j] == A[j, i]){
                    append(equality, TRUE)
                }else{
                    append(equality, FALSE)
                }
            }
        }
        symmetric <- isTRUE(all(equality == TRUE))
    }else{
        symmetric <- FALSE
    }
    t_A = t(A)
    t_A_m = nrow(t_A)
    t_A_n = ncol(t_A)
    properties <- list("A" = A, "A_rows" = m, "A_cols" = n, "square" =
                       square, "symmetric" = symmetric, "AT" = t_A,
                       "AT_rows" = t_A_m, "AT_cols" = t_A_n)
}

count_zero_rows <- function(A){
    properties <- get_properties(A)
    copy <- properties$A
    m <- properties$A_rows
    zero_row_count <- 0
    for (r in 1:m){
        s <- sum(copy[r, ])
        if (s == 0){
            zero_row_count <- zero_row_count + 1
        }else{
            next
        }

    }
    zero_row_count
}

move_all_zero_rows <- function(A){
    properties <- get_properties(A)
    copy <- properties$A
    m <- properties$A_rows
    n <- properties$A_cols
    zero_row_count <- 0
    checking <- TRUE
    while (checking){
        row_sums <- c()
        for (r in 1:(m - 1)){
            s <- sum(copy[r, ])
            if (s == 0){
                copy <- copy[-r, ]
                zero_row_count <- zero_row_count + 1
                break
            }else{
                next
            }
            row_sums <- append(row_sums, s)
        }
        if (all(row_sums > 0)){
            checking <- FALSE
        }
    }
    if (zero_row_count > 0){
        for (z in 1:zero_row_count){
            copy <- rbind(copy, rep(0, n))
        }
    }
    result <- list("copy" = copy, "zero_row_count" = zero_row_count)
}

perform_gauss_jordan_elimination <- function(A){
    properties <- get_properties(A)
    copy <- properties$A
    m <- properties$A_rows
    n <- properties$A_cols
    result <- move_all_zero_rows(copy)
    copy <- result$copy
    col <- 1
    row <- 0
    while (col < (n + 1) & (row + 1) <= m){
        if (sum(copy[(row + 1):m, col]) == 0){
            col <- col + 1
        }else{
            ind <- 0
            for (i in (row + 1):m){
                if (copy[i, col] != 0){
                    ind <- i
                    break
                }
            }
            row <- row + 1
            #swap row_i and row_r
            row_i <- copy[ind, ]
            row_r <- copy[row, ]
            copy[ind, ] <- row_r
            copy[row, ] <- row_i
            #make leading 1
            scalar <- 1 / copy[row, col]
            copy[row, ] <- copy[row, ] * scalar
            #make 0 entries
            for (k in 1:m){
                if (copy[k, col] != 0 & k != row){
                    scalar <- copy[k, col] / copy[row, col] 
                    copy[k, ] <- -1 * scalar * copy[row, ] + copy[k, ]
                }
            }
        col <- col + 1
        }
    }
    copy
}

Problem Set 1:

Question 1:

What is the rank of the matrix \(A\)?

A = rbind(c(1, 2, 3, 4),
          c(-1, 0, 1, 3),
          c(0, 1, -2, 1),
          c(5, 4, -2, -3))

Answer 1:

The rank of the matrix \(A\) is 4, which the function below determines by counting the non-zero rows in the reduced row-echelon form of the matrix \(A\).

compute_rank <- function(A){
    properties <- get_properties(A)
    copy <- properties$A
    m <- properties$A_rows
    print("Original matrix: ")
    print(copy)
    luA <- lu(copy)
    REF <- luA$U
    print("Reduced row-echelon form: ")
    print(REF)
    zero_row_count <- count_zero_rows(REF)
    rank <- m - zero_row_count
    print("Rank: ")
    print(rank)
    rank
}

A_rank <- compute_rank(A)
## [1] "Original matrix: "
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]   -1    0    1    3
## [3,]    0    1   -2    1
## [4,]    5    4   -2   -3
## [1] "Reduced row-echelon form: "
##      [,1] [,2] [,3]   [,4]
## [1,]    1    2    3  4.000
## [2,]    0    2    4  7.000
## [3,]    0    0   -4 -2.500
## [4,]    0    0    0  1.125
## [1] "Rank: "
## [1] 4

Question 2:

Given an \(mxn\) matrix where \(m > n\), what can be the maximum rank? The minimum rank, assuming that the matrix is non-zero?

Answer 2:

The maximum rank for a matrix is the lesser of the number of rows and columns, so here the maximum rank would be \(n\). The minimum rank, since we’re assuming the matrix has at least one non-zero element, would be 1.

Question 3:

What is the rank of the matrix \(B\)?

B = rbind(c(1, 2, 1),
          c(3, 6, 3),
          c(2, 4, 2))

Answer 3:

The rank of the matrix \(B\) is 1. The compute_rank function I used previously for the matrix \(A\) only works if a matrix can be LU factorized. The matrix \(B\) cannot be LU factorized because two of its leading minors, the determinants for its second and third submatrices, are both 0. It can still be put in reduced row-echelon form though, so an alternate rank computing function is defined below to account for that.

compute_rank_when_LU_factorization_fails <- function(A){
    properties <- get_properties(A)
    copy <- properties$A
    m <- properties$A_rows
    print("Original matrix: ")
    print(copy)
    REF <- perform_gauss_jordan_elimination(copy)
    print("Reduced row-echelon form: ")
    print(REF)
    zero_row_count <- count_zero_rows(REF)
    rank <- m - zero_row_count
    print("Rank: ")
    print(rank)
    rank
}
    
B_rank <- compute_rank_when_LU_factorization_fails(B)
## [1] "Original matrix: "
##      [,1] [,2] [,3]
## [1,]    1    2    1
## [2,]    3    6    3
## [3,]    2    4    2
## [1] "Reduced row-echelon form: "
##      [,1] [,2] [,3]
## [1,]    1    2    1
## [2,]    0    0    0
## [3,]    0    0    0
## [1] "Rank: "
## [1] 1

Problem Set 2:

Question 1:

Compute the eigenvalues and eigenvectors of the matrix \(A\). You’ll need to show your work. You’ll need to write out the characteristic polynomial and show your solution.

A = rbind(c(1, 2, 3),
          c(0, 4, 5),
          c(0, 0, 6))

I <- matrix(0, nrow = 3, ncol = 3)
diag(I) <- 1

A_print <- to_LaTeX(A)
I_print <- to_LaTeX(I)

Answer 1:

Finding the characteristic polynomial:

\(Det(\begin{bmatrix} 1 & 2 & 3 \\ 0 & 4 & 5 \\ 0 & 0 & 6 \end{bmatrix} - \lambda\begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}) = 0\)

B = rbind(c("1 - \U03BB", "2", "3"),
          c("0", "4 - \U03BB", "5"),
          c("0", "0", "6 - \U03BB"))

B_print <- to_LaTeX(B)

\(Det(\begin{bmatrix} 1 - λ & 2 & 3 \\ 0 & 4 - λ & 5 \\ 0 & 0 & 6 - λ \end{bmatrix}) = 0\)

characteristic_polynomial_step1 <- "((1 - \U03BB) * (((4 - \U03BB) * (6 - \U03BB)) - ((0))) - 0 + 0))"
characteristic_polynomial_step2 <- "(1 - \U03BB) * (24 - 4\U03BB - 6\U03BB + \U03BB^2)"
characteristic_polynomial_step3 <- "(1 - \U03BB) * (24 - 10\U03BB + \U03BB^2)"
characteristic_polynomial_step4 <- "24 - 10\U03BB + \U03BB^2 - 24\U03BB + 10\U03BB^2 - \U03BB^3"
characteristic_polynomial_step5 <- "-\U03BB^3 + 11\U03BB^2 - 34\U03BB + 24"

\(((1 - λ) * (((4 - λ) * (6 - λ)) - ((0))) - 0 + 0)) = 0\)

\((1 - λ) * (24 - 4λ - 6λ + λ^2) = 0\)

\((1 - λ) * (24 - 10λ + λ^2) = 0\)

\(24 - 10λ + λ^2 - 24λ + 10λ^2 - λ^3 = 0\)

\(-λ^3 + 11λ^2 - 34λ + 24 = 0\)

Finding the roots of the characteristic polynomial, which are the eigenvalues:

coefs <- c(24, -34, 11, -1)
roots <- Re(polyroot(coefs))

Eigenvalues: \([1, 4, 6]\)

Eigenvectors:

Finding the eigenvector for \(\lambda = 1\):

B_char = rbind(c("1 - 1", "2", "3"),
          c("0", "4 - 1", "5"),
          c("0", "0", "6 - 1"))

B_num = rbind(c(0, 2, 3),
          c(0, 3, 5),
          c(0, 0, 5))

B_char_print <- to_LaTeX(B_char)
B_num_print <- to_LaTeX(B_num)
var <- as.matrix(rbind("x", "y", "z"))
z <- matrix(0, nrow = 3, ncol = 1)
var_print <- to_LaTeX(var)
z_print <- to_LaTeX(z)
eq1 <- "2y + 3z = 0"
eq2 <- "3y + 5z = 0"
eq3 <- "5z = 0"
sol <- "x = 1, y = z = 0"
evec <- as.matrix(rbind(1, 0, 0))
evec_print <- to_LaTeX(evec)

\(\begin{bmatrix} 1 - 1 & 2 & 3 \\ 0 & 4 - 1 & 5 \\ 0 & 0 & 6 - 1 \end{bmatrix} = \begin{bmatrix} 0 & 2 & 3 \\ 0 & 3 & 5 \\ 0 & 0 & 5 \end{bmatrix}\)

\(\begin{bmatrix} 0 & 2 & 3 \\ 0 & 3 & 5 \\ 0 & 0 & 5 \end{bmatrix} \begin{bmatrix} x \\ y \\ z \end{bmatrix} = \begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}\)

\(2y + 3z = 0\)

\(3y + 5z = 0\)

\(5z = 0\)

\(x = 1, y = z = 0\)

Eigenvector: \(\begin{bmatrix} 1 \\ 0 \\ 0 \end{bmatrix}\)

Finding the eigenvector for \(\lambda = 4\):

B_char = rbind(c("1 - 4", "2", "3"),
          c("0", "4 - 4", "5"),
          c("0", "0", "6 - 4"))

B_num = rbind(c(-3, 2, 3),
          c(0, 0, 5),
          c(0, 0, 2))

B_char_print <- to_LaTeX(B_char)
B_num_print <- to_LaTeX(B_num)
eq1 <- "-3x + 2y + 3z = 0"
eq2 <- "5z = 0"
eq3 <- "2z = 0"
sol <- "x = 2/3, y = 1, z = 0"
evec <- as.matrix(rbind("2/3", "1", "0"))
evec_print <- to_LaTeX(evec)

\(\begin{bmatrix} 1 - 4 & 2 & 3 \\ 0 & 4 - 4 & 5 \\ 0 & 0 & 6 - 4 \end{bmatrix} = \begin{bmatrix} -3 & 2 & 3 \\ 0 & 0 & 5 \\ 0 & 0 & 2 \end{bmatrix}\)

\(\begin{bmatrix} -3 & 2 & 3 \\ 0 & 0 & 5 \\ 0 & 0 & 2 \end{bmatrix} \begin{bmatrix} x \\ y \\ z \end{bmatrix} = \begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}\)

\(-3x + 2y + 3z = 0\)

\(5z = 0\)

\(2z = 0\)

\(x = 2/3, y = 1, z = 0\)

Eigenvector: \(\begin{bmatrix} 2/3 \\ 1 \\ 0 \end{bmatrix}\)

Finding the eigenvector for \(\lambda = 6\):

B_char = rbind(c("1 - 6", "2", "3"),
          c("0", "4 - 6", "5"),
          c("0", "0", "6 - 6"))

B_num = rbind(c(-5, 2, 3),
          c(0, -2, 5),
          c(0, 0, 0))

B_char_print <- to_LaTeX(B_char)
B_num_print <- to_LaTeX(B_num)
eq1 <- "-5x + 2y + 3z = 0"
eq2 <- "-2y + 5z = 0"
sol <- "x = 8/5, y = 5/2, z = 1"
evec <- as.matrix(rbind("8/5", "5/2", "1"))
evec_print <- to_LaTeX(evec)

\(\begin{bmatrix} 1 - 6 & 2 & 3 \\ 0 & 4 - 6 & 5 \\ 0 & 0 & 6 - 6 \end{bmatrix} = \begin{bmatrix} -5 & 2 & 3 \\ 0 & -2 & 5 \\ 0 & 0 & 0 \end{bmatrix}\)

\(\begin{bmatrix} -5 & 2 & 3 \\ 0 & -2 & 5 \\ 0 & 0 & 0 \end{bmatrix} \begin{bmatrix} x \\ y \\ z \end{bmatrix} = \begin{bmatrix} 0 \\ 0 \\ 0 \end{bmatrix}\)

\(-5x + 2y + 3z = 0\)

\(-2y + 5z = 0\)

\(x = 8/5, y = 5/2, z = 1\)

Eigenvector: \(\begin{bmatrix} 8/5 \\ 5/2 \\ 1 \end{bmatrix}\)