library(stats)

Problem Set 1

(1) Show that A x At is not equal to At x A, in general cases, where At is the transposition of matrix A.

For Matrix A

A B
C D

And Matrix At

A C
B D

The product A*At is equal to

AA + BB AC + BD
CA + DB CC + DD

And At*A is equal to

AA+BB AB+CD
BA+DC CC+DD

For unique values of B and C, these are not equivalent.

A <- matrix(c(1,2,3,4),nrow = 2,byrow = 2)
At <- t(A)

AAt <- A%*%At
AtA <- At%*%A

identical(AAt,AtA)
## [1] FALSE

(2) For a special type of square matrix this is true. Under what conditions could this be true?

In cases where B=C, we see that both products are equal. Using the above example we see they are both equal to:

AA + BB AB + BD
BA + DB BB + DD

A more general form of this relationship, say for larger matrices, is the observation that the matrix must be equal to its transposition (At == A). This is to say, the matrix must be symmetrical.

x <- round(runif(6,min=0,max=9))
A <- matrix(data = c(x[1],x[2],x[3],x[2],x[4],x[5],x[3],x[5],x[6]),nrow=3)
At <- t(A)
identical(A,At)
## [1] TRUE
AAt <- A%*%At
AtA <- At%*%A
identical(AAt,AtA)
## [1] TRUE

Problem Set 2

Write an R function to factorize a square matrix A into LU or LDU, whichever you prefer. Assume the matrix used for testing will be smaller than 5x5.

LUDecomp <- function(M){

#Function provides original matrix, TRUE/FALSE value indicating successful factorization, upper and lower triangle matrix, in order.  

#Create L and U Matrix (Easy way to keep row count the same)
    L <- M
    U <- M
#Solve First Row in each Matrix (Row 1 of U is copied from M)
    L[1,] <- rep(0,ncol(M))
    L[1,1] <- 1 

#Solve Second Rows
    L[2,] <- rep(0,ncol(M))
    L[2,2]<- 1 
    
    L[2,1] <-  M[2,1]/M[1,1]
    U[2,] <- U[2,]-L[2,1]*U[1,]

#Below can be rewritten in general form using looping and relative reference (to solve any matrix size). For purposes of this exercise, this is cleaner as is: 
    

#Solve Third Row (If needed)
if(nrow(M) > 2){
  L[3,] <- rep(0,ncol(M))
  L[3,3] <- 1
  
  L[3,1] <- M[3,1]/M[1,1]
  U[3,] <- U[3,]-L[3,1]*U[1,]
  
  L[3,2] <- U[3,2]/U[2,2]
  U[3,] <- U[3,]-L[3,2]*U[2,]
    
}
  
#Solve Fourth Row (If needed)
if(nrow(M) > 3){
  L[4,] <- rep(0,ncol(M))
  L[4,4] <- 1
  
  L[4,1] <- M[4,1]/M[1,1]
  U[4,] <- U[4,]-L[4,1]*U[1,]
  
  L[4,2] <- U[4,2]/U[2,2]
  U[4,] <- U[4,]-L[4,2]*U[2,]
  
  L[4,3] <- U[4,3]/U[3,3]
  U[4,] <- U[4,]-L[4,3]*U[3,]
  
  
  
  
}
#Return:  
    MTest <- L%*%U
    print(M)
    print(identical(M,MTest))
    print(L)
    print(U)
    
    #print(L%*%U)

}
#Test 3X3

M <- matrix(data = c(1,4,-3,-2,8,5,3,4,7),nrow = 3, byrow = TRUE)

LUDecomp(M)
##      [,1] [,2] [,3]
## [1,]    1    4   -3
## [2,]   -2    8    5
## [3,]    3    4    7
## [1] TRUE
##      [,1] [,2] [,3]
## [1,]    1  0.0    0
## [2,]   -2  1.0    0
## [3,]    3 -0.5    1
##      [,1] [,2] [,3]
## [1,]    1    4 -3.0
## [2,]    0   16 -1.0
## [3,]    0    0 15.5
#Test 4x4

set.seed(321)
M <- matrix(data = round(runif(16,min=0,max = 9)),nrow=4)

LUDecomp(M)
##      [,1] [,2] [,3] [,4]
## [1,]    9    4    4    7
## [2,]    8    3    7    0
## [3,]    2    4    5    5
## [4,]    2    3    3    2
## [1] TRUE
##           [,1] [,2]      [,3] [,4]
## [1,] 1.0000000  0.0 0.0000000    0
## [2,] 0.8888889  1.0 0.0000000    0
## [3,] 0.2222222 -5.6 1.0000000    0
## [4,] 0.2222222 -3.8 0.6495726    1
##      [,1]       [,2]      [,3]       [,4]
## [1,]    9  4.0000000  4.000000   7.000000
## [2,]    0 -0.5555556  3.444444  -6.222222
## [3,]    0  0.0000000 23.400000 -31.400000
## [4,]    0  0.0000000  0.000000  -2.803419
#Test 2x2

set.seed(321)
M <- matrix(data = round(runif(4,min=0,max = 9)),nrow=2)

LUDecomp(M)
##      [,1] [,2]
## [1,]    9    2
## [2,]    8    2
## [1] TRUE
##           [,1] [,2]
## [1,] 1.0000000    0
## [2,] 0.8888889    1
##      [,1]      [,2]
## [1,]    9 2.0000000
## [2,]    0 0.2222222
#First draft of 3x3 test (Just as a reference)

LUDecomp3 <- function(M){
#Decomposes 3x3 Matrix into LU 
#Set Knowns 
  L = c(0,0)
  U = c(0,0)
  L[1] = 1
  L[2] = 0
  L[3] = 0
  L[5] = 1
  L[6] = 0
  L[9] = 1
  U[4] = 0
  U[7] = 0
  U[8] = 0
  U[1] = M[1,1]
  U[2] = M[1,2]
  U[3] = M[1,3]
  
#Solve others 
  #Second Row, Col 1
    L[4] <- M[2,1]/M[1,1]
    U[5] <- M[2,2] - M[1,2]*L[4]
    U[6] <- M[2,3] - M[1,3]*L[4]
    
  #Third Row, Col 1
    L[7] <- M[3,1]/M[1,1]
    U[8] <- M[3,2] - M[1,2]*L[7]
    U[9] <- M[3,3] - M[1,3]*L[7]
    
  #Third Row, Col 2
    L[8] <- U[8]/U[5]
    U[8] <- 0
    U[9] <- U[9] - L[8]*U[6]
    
LMatrix <- matrix(data = L,nrow = 3, byrow = TRUE)
UMatrix <- matrix(data = U,nrow=3,byrow = TRUE)


print(LMatrix)

print(UMatrix)
}