Ai đó có thể đưa ra mã R để vẽ một hình elip từ các giá trị riêng và các hàm riêng của ma trận sau
Ai đó có thể đưa ra mã R để vẽ một hình elip từ các giá trị riêng và các hàm riêng của ma trận sau
Câu trả lời:
Bạn có thể trích xuất các hàm riêng và giá trị thông qua eigen(A)
. Tuy nhiên, đơn giản hơn là sử dụng phân tách Cholesky. Lưu ý rằng khi vẽ các hình elip độ tin cậy cho dữ liệu, các trục hình elip thường được chia tỷ lệ để có độ dài = căn bậc hai của các giá trị riêng tương ứng và đây là những gì phân tách Cholesky mang lại.
ctr <- c(0, 0) # data centroid -> colMeans(dataMatrix)
A <- matrix(c(2.2, 0.4, 0.4, 2.8), nrow=2) # covariance matrix -> cov(dataMatrix)
RR <- chol(A) # Cholesky decomposition
angles <- seq(0, 2*pi, length.out=200) # angles for ellipse
ell <- 1 * cbind(cos(angles), sin(angles)) %*% RR # ellipse scaled with factor 1
ellCtr <- sweep(ell, 2, ctr, "+") # center ellipse to the data centroid
plot(ellCtr, type="l", lwd=2, asp=1) # plot ellipse
points(ctr[1], ctr[2], pch=4, lwd=2) # plot data centroid
library(car) # verify with car's ellipse() function
ellipse(c(0, 0), shape=A, radius=0.98, col="red", lty=2)
Chỉnh sửa: để vẽ sơ đồ các hàm riêng, bạn phải sử dụng cách tiếp cận phức tạp hơn. Điều này tương đương với câu trả lời của suncoolsu, nó chỉ sử dụng ký hiệu ma trận để rút ngắn mã.
eigVal <- eigen(A)$values
eigVec <- eigen(A)$vectors
eigScl <- eigVec %*% diag(sqrt(eigVal)) # scale eigenvectors to length = square-root
xMat <- rbind(ctr[1] + eigScl[1, ], ctr[1] - eigScl[1, ])
yMat <- rbind(ctr[2] + eigScl[2, ], ctr[2] - eigScl[2, ])
ellBase <- cbind(sqrt(eigVal[1])*cos(angles), sqrt(eigVal[2])*sin(angles)) # normal ellipse
ellRot <- eigVec %*% t(ellBase) # rotated ellipse
plot((ellRot+ctr)[1, ], (ellRot+ctr)[2, ], asp=1, type="l", lwd=2)
matlines(xMat, yMat, lty=1, lwd=2, col="green")
points(ctr[1], ctr[2], pch=4, col="red", lwd=3)
Tôi nghĩ rằng đây là mã R mà bạn muốn. Tôi đã mượn mã R từ chuỗi này trong danh sách gửi thư. Về cơ bản, ý tưởng là: nửa đường kính chính và phụ là hai giá trị riêng và bạn xoay hình elip theo số lượng góc giữa vectơ eigen đầu tiên và trục x
mat <- matrix(c(2.2, 0.4, 0.4, 2.8), 2, 2)
eigens <- eigen(mat)
evs <- sqrt(eigens$values)
evecs <- eigens$vectors
a <- evs[1]
b <- evs[2]
x0 <- 0
y0 <- 0
alpha <- atan(evecs[ , 1][2] / evecs[ , 1][1])
theta <- seq(0, 2 * pi, length=(1000))
x <- x0 + a * cos(theta) * cos(alpha) - b * sin(theta) * sin(alpha)
y <- y0 + a * cos(theta) * sin(alpha) + b * sin(theta) * cos(alpha)
png("graph.png")
plot(x, y, type = "l", main = expression("x = a cos " * theta * " + " * x[0] * " and y = b sin " * theta * " + " * y[0]), asp = 1)
arrows(0, 0, a * evecs[ , 1][2], a * evecs[ , 1][2])
arrows(0, 0, b * evecs[ , 2][3], b * evecs[ , 2][2])
dev.off()
asp=1
để có tỷ lệ khung hình là 1 và mũi tên vuông góc. Thay đổi mã của bạn để evs <- sqrt(eigens$values)
đưa ra hình elip giống như câu trả lời của tôi.