B Linear algebra
Reading materials: STA108_LinearAlgebra_S20.pdf.
B.1 Vector
x = c(1,2,4,2.5,-1.7,1) # creates a vector (you can use "<-" instead of "=")
length(x) # check the length of x
class(x) # class of the object; you can also check typeof()
### Try z=list(); class(z);
x[ 3 ] # extract one element in x..
x[c(1,2,3)]
x[2:4]
z<-numeric(10)
### Transpose:
x.t=t(x);
length(x.t)
x.t
x
y = x^2
### Q: what is the length of y?
length(y)
### The "default" operation in R is elementwise:
x/y # elementwise division
y-x*x # all elementwise..
### There are other operators..
x %o% y # outer product of x and y
x %*% y # Matrix product. Q: what is R doing here?
sum(x*y)
B.2 Matrix
M = matrix(0,2,3) # matrix with 2 rows and 3 columns with all entries 0
# ?matrix
Xmat1 = matrix(x,2,3) # 2 x 3 matrix formed by elements of vector x,
### ordered in *column-wise* manner
Xmat2 = matrix(x,2,3,byrow=T) # ordered row-wise
M<- Xmat1;
dimnames(M)
rownames(M) = c("first","second")
colnames(M) = c("a","b","c")
dimnames(M)
typeof(dimnames(M))
### access elements through names of rows/columns
M[,"a"]
M[,1]
M[,c("a","c")]
M[,c(1,3)]
M %*% c(4,-3,1) # multiply matrix M to vector c(4,-3,1)
M + c(1,-2) # add the column vector c(1,-2) to each column of M
M2 = cbind(M,c(4,5)) # create matrix M2 by appending column c(4,5) to M
### How to append row to M2?
new_row = c(1,3,5,7)
#?cbind
#?rbind
### What if we call length() on a matrix?
length(M)
dim(M)
### Transpose of the matrix
M.t=t(M);
identical(t(M.t),M)
### Diagonal and identity matrix
## Identity matrix
diag(5)
## Diagonal matrix
diag(c(1,2,3,4,5))
## Symmatric matrix
A= matrix(rnorm(9),3,3);
A=A+t(A); # To make sure it is symmetric
identical(A,t(A))
### Trace of a matrix:
sum(diag(A))
## Define a tr() function to match the common convention
tr<-function(x){
out=sum(diag(x));
return(out)
}
tr(A)
## Verify some properties of the trace
B= matrix(rnorm(9),3,3);
tr(A)
tr(t(A))
tr(A+B)
tr(A)+tr(B)
tr(A%*%B)
tr(B%*%A) # if the dimensions check out..
tr(A)
sum(eigen(A)$values)
### Matrix-vector product:
Xmat1 = matrix(rnorm(6),2,3)
xvec1=rnorm(3)
Xmat1%*%xvec1
### elementwise product of Xmat1 and Xmat2
Xmat1*Xmat2
### Matrix multiplication
# Xmat1%*%Xmat2
dim(Xmat1)
dim(Xmat2)
Xmat1%*%t(Xmat2)
### Verify another property of transpose:
t( Xmat1%*%t(Xmat2) )
Xmat2%*%t(Xmat1)
# solve(Xmat1) # what does the error message say?
### Inverse of a marix
# set.seed(1)
# A= matrix(rnorm(9),3,3);
# set.seed(): specify the random seed for generating random numbers
# Because a computer (if not a quantum one) can only generate pseudorandomness
# set.seed(1)
# B=matrix(rnorm(9),3,3);
# identical(A,B)
set.seed(1)
A= matrix(rnorm(9),3,3);
A.inv=solve(A);
A.inv%*%A
A%*%A.inv
B=matrix(rnorm(9),3,3);
identical(A,B)
B.inv=solve(B);
AB.inv=solve(A%*%B)
B.inv%*%A.inv
AB.inv
max(abs(B.inv%*%A.inv-AB.inv))
# Why?
# This is because
# (A%*%B)%*%AB.int= I if AB.inv is the inverse of AB=A%*%B
# and that
# A%*%B %*%B.inv%*%A.inv=A%*%(B%*%B.inv)%*%A.inv =A%*%A.inv=I
### Projection matrix
set.seed(12)
X = matrix(rnorm(6),3,2)
P=X%*%solve(t(X)%*%X)%*%t(X)
P%*%X
X
(diag(3)-P)%*%X
### Rank of a matrix:
qr(X)$rank # Check out the qr() function yourself!
# The rank of X is 2 when the dimension of X is 3 by 2
# This means that the matrix X is full rank
## How about x.transpose times X?
XtX=t(X)%*%X
dim(XtX)
qr(XtX)$rank
# This is a full rank matrix
## How about X times X.transpose?
XXt=X%*%t(X)
dim(XXt)
qr(XXt)$rank
# This is NOT a full rank matrix
# Rank and inverse
solve(XtX)
# solve(XXt)
### Determinants
det(A)
1/det(solve(A))
det(A%*%B)
det(A)%*%det(B)
det(3*A)
A.symm = (A+t(A))/2;
det(A.symm)
A.symm.eigenvalues=eigen(A.symm)$values
prod(A.symm.eigenvalues)
# Trace: summation of eigenvalues
# Determinant: product of eigenvalues (for symmetric matrix only!)
### Eigenvalue and eigenvector
A.symm.eigenvectors=eigen(A.symm)$vectors
A.symm%*%A.symm.eigenvectors[,1]
A.symm.eigenvalues[1]*A.symm.eigenvectors[,1]
A.symm.eigenvalues
qr(A.symm)$rank
qr(XXt)$rank
eigen(XXt) # the last eigenvalue equals zero, with some numerical error
### Matrix definiteness
eigen(XtX)
eigen(P)
### Eigenvalue decomposition
A.symm.eigenvectors%*%diag(A.symm.eigenvalues)%*%t(A.symm.eigenvectors)
A.symm
### Singular value decomposition
svd(X) # singular value decomposition of X
B.3 Other operations on vectors and matrices
### How does R handle mathematically invalid operations?
### Example 1:
x = c(1,2,4,2.5,-1.7,1)
w =1:3 # short-handed for c(1,2,3)
### Q: What is the length of w?
x + w # no error displayed, but not quite a mathematically valid operation
### Q: what did R just do???
c(x[1:3]+w, x[4:6]+w)
### What if...
# Create a vector of length 4 (from 1 to 4)
n<-1:4;
x+n
### Example 2:
z = sin(x) + x^{1.5}* exp(-x^3)
### What is (-1.7)^{1.5}???
### How did R handle this?
x[5]
z[5]
B.3.1 Array
### Arrays, a.k.a. tensors
### A matrix is a two-way array
# ?array # check for R documentation on array
A = array(rnorm(2*3*4),dim=c(2,3,4)) # creates an array with entries that are i.i.d. N(0,1)
#?rnorm
dim(A) # checks the dimension of A
A[,1,] # returns the 2 x 4 matrix formed by restricting the second dimension index to 1
### What is the dimension of A[,1,]?
A[2,,] # returns the 3 x 4 matrix formed by restricting the first dimension index to 2
A[2,1,2]
A[A<0]
B.3.2 Datasets as matrices
library(AER) # install.packages('AER')
data("Fatalities")
#?Fatalities
data("CreditCard")
dat.CC=CreditCard
#?CreditCard
dim(dat.CC)
head(dat.CC)
Y.CC=dat.CC[,1]=='yes';
X.CC=as.matrix(dat.CC[,c('reports','age','income','share','expenditure','dependents','months','majorcards','active')])
# Check the rank of the covariates:
qr(X.CC)$rank
dim(X.CC) # full rank, i.e., no multicolinearity
# Linear regression:
fit.CC=lm(Y.CC~X.CC-1);
summary(fit.CC)
# Fitted coefficients:
beta.hat=solve(t(X.CC)%*%X.CC)%*%t(X.CC)%*%Y.CC;
fit.CC$coefficients-beta.hat
# Hat matrix:
P.CC=X.CC%*%solve(t(X.CC)%*%X.CC)%*%t(X.CC)
# Fitted Y
Yhat.CC=P.CC%*%Y.CC
# Compare with the fits from lm()
max(abs(fit.CC$fitted.values-Yhat.CC))