source("../R/utilities.R")
c(1, 2)
, this vector represents a point’s position.c(1, 2)
and add c(-3, 1.5)
we move the x coordinate 3 units to the left, and the y coordinate 1.5 units up.makegrid(-5:5, main="Vectors represent position.\nVector addition represents movement.", xlab="", ylab="")
points(1, 2, cex=2, pch=19, col="red")
points(1-3, 2+1.5, cex=2, pch=19, col="blue")
arrows(1, 2, 1-3, 2+1.5, lty=1, lwd=2)
text(1, 2, expression(c(1,2)), pos=1, col="red")
text(1-3, 2+1.5, expression(c(1,2) + c(-3, 1.5)), pos=3, col="blue")
D <- diag(c(0.75, 0.25), 2, 2)
and print it.%*%
represents matrix multiplication. It is a different operation than *
.c(1,1)
by D
. You get a row vector if you use c(1,1) %*% D
and a column vector if you use D %*% c(1,1)
. Note the correspondence between the resulting coordinates and the matrix diagonals.D <- diag(c(0.75, 0.25), 2, 2)
D
## [,1] [,2]
## [1,] 0.75 0.00
## [2,] 0.00 0.25
D %*% c(1,1)
## [,1]
## [1,] 0.75
## [2,] 0.25
D
.makegrid(seq(-2, 2, by=1), main="Scaling a circle by D", major_axes=FALSE)
circle <- ellipse(1)
polygon(circle, lwd=2)
polygon(circle %*% D, lwd=2, border="red")
temp <- seq(0, 2*pi, by=pi/4)
arrows(cos(temp), sin(temp), D[1,1]*cos(temp), D[2,2]*sin(temp), lwd=2, col="blue", len=sqrt(sum(par("fin")^2))/100)
text(-1.5, 0, "D[1,1]*x", col="blue")
text(0, 1, "D[2,2]*y", pos=3, col="blue")
D
, makes a circle into an ellipse. But D
only has two non-zero entries. What are its other entries for?# NOTE: To display this as a plot use something like
plot(0:1, 0:1, type='n', xlab="", ylab="", xaxt="n", yaxt="n", bty="n")
text(.5,.5, expression(U == bgroup("[", atop(list(cos(theta), -sin(theta)), list(sin(theta), cos(theta))),"]")), cex=3)
p <- c(1,0)
, we’ll repeatedly set p <- U %*% p
and plot the result of each iteration.U <- matrix(c(cos(pi/3), sin(pi/3), -sin(pi/3), cos(pi/3)), 2, 2)
makegrid(-2:2, main="Rotation matrix")
p <- c(1,0)
text(1,1.5, expression(U == bgroup("[", atop(list(cos(theta), -sin(theta)), list(sin(theta), cos(theta))),"]")), cex=1)
for(i in 1:6){
points(p[1], p[2], cex=2, pch=19, col="red")
text(p[1], p[2], as.character(i-1), pos=2)
ptemp <- U %*% p
p <- ptemp
Sys.sleep(.25) # Make a movie
}
U2 <- U %*% U
, and suppose we repeat the process with U2.U2 <- U %*% U
makegrid(-2:2, main="Rotation matrix squared")
p <- c(1,0)
for(i in 1:6){
points(p[1], p[2], cex=2, pch=19, col="red")
p <- U %*% p
}
p <- c(1,0)
for(i in 1:3){
points(p[1], p[2], cex=3, pch=21, col="blue", lwd=3)
text(p[1]-.1, p[2], as.character(i-1), pos=2)
p <- U2 %*% p
Sys.sleep(.5)
}
circle <- ellipse(1)
makegrid(-2:2, major_axes=FALSE, main="Matrices: order matters")
polygon(circle, lwd=2)
# Function polygon expects a matrix whose rows contain the x and y coordinates
# of vertices. Hence the use of transpose.
# TODO: clean up the use of left and right multiplication by matrices.
polygon(t(D %*% U %*% t(circle)), lwd=2, border="red")
text(0, 1.5, "D %*% U %*% circle", cex=1.5, col="red")
polygon(t(U %*% D %*% t(circle)), lwd=2, border="blue")
text(0, -1.5, "U %*% D %*% circle", cex=1.5, col="blue")
U %*% circle = circle
. So, D %*% U %*% circle
gives the same result as D %*% circle.
D %*% U != U %*% D
. (They are almost transposes but not quite.)svd
function.svd
will perform a singular value decomposition. For illustration, form a random 2x2 matrix, N, as follows N <- matrix(rnorm(4), 2, 2)
, and let s <- svd(N)
. Inspect s
, compare s$u %*% s$d %*% s$v
with N
, and so on.t
, will form the transpose of a matrix. See what happens when you multiply R %*% t(R)
and t(R) %*% R
.iD <- matrix(c(1/D[1,1], 0, 0, 1/D[2,2]))
and look at the matrices D %*% iD
and iD %*% D
.solve(M)
which returns the inverse of M
.# NOTE: To display this as a plot use something like
plot(0:1, 0:1, type='n', xlab="", ylab="", xaxt="n", yaxt="n", bty="n", main="Linearity", cex.main=2)
text(0, .9, expression(paste("For any matrix, ", M, ",")), cex=1.5, pos=4)
text(0, .8, expression(paste("and any vectors, ", hat(u)," and ", hat(v), ",")), cex=1.5, pos=4)
text(0, .7, expression(paste("and any numbers, ", alpha," and ", beta, ",")), cex=1.5, pos=4)
text(.5, .4, expression(M %*% bgroup("(", alpha*hat(u)+beta*hat(v),")") == alpha*M%*%hat(u)+beta*M%*%hat(v)), cex=2)
text(0, .1, "where x means matrix multiplication.", cex=1.5, pos=4)
# NOTE: To display this as a plot use something like
plot(0:1, 0:1, type='n', xlab="", ylab="", xaxt="n", yaxt="n", bty="n", main="Linearity", cex.main=2)
text(.5, .5, expression(bgroup("[", atop(list(M[1][1], M[1][2]), list(M[2][1], M[2][2])),"]") %*% bgroup("[", atop(x, y), "]") == bgroup("[", atop(M[1][1]*x+M[1][2]*y, M[2][1]*x + M[2][2]*y), "]")), cex=2)
I had originally planned to include quadratic forms and distance in this unit, but I now think it makes more sense to cut off the visual introductions to calculus and linear algebra at this point for fear of overdoing it. More advanced topics can always be illustrated with visual examples later on.