“Không có kho báu nào quý bằng học thức. Hãy tích lũy nó bất cứ lúc nào có thể.”
Rudasky

Nói một cách đơn giản thì ma trận gồm nhiều vectơ có cùng kiểu và cùng độ dài gép lại với nhau theo dòng hoặc theo cột. Số dòng và số cột được gọi là số chiều của ma trận. Trong khi kích thước của vectơ được xác định bởi độ dài của nó thì kích thước của ma trận được xác định bởi số dòng nhân số cột.

\[\begin{equation*} A=\left[\begin{array}{cccc} a_{1,1} & a_{1,2} & \ldots & a_{1, n} \\ a_{2,1} & a_{2,2} & \ldots & a_{2, n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m, 1} & a_{m, 2} & \ldots & a_{m, n} \end{array}\right] \end{equation*}\]

Nhiều ma trận có cùng kiểu và cùng số chiều ghép lại với nhau thành nhiều lớp sẽ hình thành một một cấu trúc nhiều chiều hơn được gọi là mảng.
Mảng 3 chiều gồm hai ma trận 3 dòng 4 cột ghép lại thành 2 lớp [dòng, cột, lớp] = [3, 4, 2].

Mảng 3 chiều gồm hai ma trận 3 dòng 4 cột ghép lại thành 2 lớp [dòng, cột, lớp] = [3, 4, 2].

Chúng ta có thể xem vectơ và ma trận là mảng 1 chiều và 2 chiều tương ứng.

Ma trận trong R

Để tạo ma trận trong R, chúng ta dùng hàm matrix().

matrix(data = c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3, ncol = 3, byrow = FALSE)
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
matrix(data = c(1, 2, 3, 4, 5, 6, 7, 8, 9), nrow = 3, ncol = 3, byrow = TRUE)
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9

Mặt khác chúng ta cũng có thể dùng hàm rbind()cbind().

rbind(1:3, 4:6, 7:9)
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
cbind(c(1, 4, 7), c(2, 5, 8), c(3, 6, 9))
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9

Để xác định số dòng và số cột của một ma trận ta dùng hàm dim().

(mymat <- rbind(c(1,3,4),5:3,c(100,20,90),11:13))
##      [,1] [,2] [,3]
## [1,]    1    3    4
## [2,]    5    4    3
## [3,]  100   20   90
## [4,]   11   12   13
dim(mymat)
## [1] 4 3

Tuy nhiên chúng ta cũng có thể dùng hàm nrow()ncol() để xác định số dòng và cột tương ứng của một ma trận.

nrow(mymat)
## [1] 4
ncol(mymat)
## [1] 3

Trích xuất ma trận con

(A <- matrix(c(0.3,4.5,55.3,91,0.1,105.5,-4.2,8.2,27.9), nrow=3, ncol=3))
##      [,1]  [,2] [,3]
## [1,]  0.3  91.0 -4.2
## [2,]  4.5   0.1  8.2
## [3,] 55.3 105.5 27.9
A[3, 2] # trích phần tử ở dòng 3 cột 2
## [1] 105.5
A[, 2] # trích cột 2
## [1]  91.0   0.1 105.5
A[1,] # trích dòng 1
## [1]  0.3 91.0 -4.2
A[2:3,] # trích dòng 2 và 3
##      [,1]  [,2] [,3]
## [1,]  4.5   0.1  8.2
## [2,] 55.3 105.5 27.9
A[, c(3, 1)] # trích cột 3 và 1
##      [,1] [,2]
## [1,] -4.2  0.3
## [2,]  8.2  4.5
## [3,] 27.9 55.3
A[c(3, 1), 2:3] # trích các phần tử ở dòng 3, 1, cột 2 và 3
##       [,1] [,2]
## [1,] 105.5 27.9
## [2,]  91.0 -4.2
diag(A) # trích đường chéo của ma trận
## [1]  0.3  0.1 27.9
A[, -2] # lấy hết trừ cột 2
##      [,1] [,2]
## [1,]  0.3 -4.2
## [2,]  4.5  8.2
## [3,] 55.3 27.9
A[-1, 3:2] # lấy hết phần tử ở cột 3, 2 nhưng trừ dòng 1
##      [,1]  [,2]
## [1,]  8.2   0.1
## [2,] 27.9 105.5
A[-1, -c(2, 3)] # lấy hết trừ dòng 1 và cột 2, 3
## [1]  4.5 55.3

Giống như vectơ, chúng ta cũng có thể thay thế các phần tử của ma trận.

(B <- A) # Tạo B là copy của A
##      [,1]  [,2] [,3]
## [1,]  0.3  91.0 -4.2
## [2,]  4.5   0.1  8.2
## [3,] 55.3 105.5 27.9
B[2,] <- 1:3
B
##      [,1]  [,2] [,3]
## [1,]  0.3  91.0 -4.2
## [2,]  1.0   2.0  3.0
## [3,] 55.3 105.5 27.9
B[c(1, 3), 2] <- 900
B
##      [,1] [,2] [,3]
## [1,]  0.3  900 -4.2
## [2,]  1.0    2  3.0
## [3,] 55.3  900 27.9
B[, 3] <- B[3,]
B
##      [,1] [,2]  [,3]
## [1,]  0.3  900  55.3
## [2,]  1.0    2 900.0
## [3,] 55.3  900  27.9
B[c(1, 3), c(1, 3)] <- c(-7, 7)
B
##      [,1] [,2] [,3]
## [1,]   -7  900   -7
## [2,]    1    2  900
## [3,]    7  900    7
B[c(1, 3), 2:1] <- c(65, -65, 88, -88)
B
##      [,1] [,2] [,3]
## [1,]   88   65   -7
## [2,]    1    2  900
## [3,]  -88  -65    7
diag(B) <- rep(0, times = 3)
B
##      [,1] [,2] [,3]
## [1,]    0   65   -7
## [2,]    1    0  900
## [3,]  -88  -65    0

Bài tập 3.1

  1. Tạo và đặt tên ma trận cấp \(4\times 2\) từ các giá trị \(4.3, 3.1, 8.2, 8.2, 3.2, 0.9, 1.6\)\(6.54\) bằng cách điền theo dòng.
  2. Xác định số chiều của ma trận (a) sau khi đã bỏ đi bất kỳ một dòng nào đó.
  3. Thay thế cột thứ hai của ma trận (a) bằng chính giá trị của cột thứ hai nhưng đã được sắp theo thứ tự tăng dần.
  4. R cho ra kết quả gì nếu chúng ta loại bỏ dòng thứ tư và cột thứ nhất của ma trận (c)? Dùng hàm matrix() để đưa kết quả về dạng ma trận thay vì vectơ.
  5. Tạo ra một ma trận cấp \(2\times 2\) là bốn phần tử dưới cùng của ma trận (c).
  6. Thay thế theo thứ tự sau các phần tử của (c) tại các vị trí (4, 2), (1, 2), (4, 1) và (1, 1) bằng \(-\frac{1}{2}\) của 2 giá trị trên đường chéo của (e).

Ma trận chuyển vị.

Ma trận chuyển vị của ma trận \(A\) cấp \(m\times n\), ký hiệu \(A^T\), là ma trận cấp \(n\times m\) thu được bằng cách biển đổi dòng thành cột hoặc cột thành dòng.

Nếu \(A=\left[\begin{array}{lll} 2 & 5 & 2 \\ 6 & 1 & 4 \end{array}\right]\) thì \(A^{\top}=\left[\begin{array}{ll} 2 & 6 \\ 5 & 1 \\ 2 & 4 \end{array}\right]\).

A <- rbind(c(2,5,2),c(6,1,4))
A
##      [,1] [,2] [,3]
## [1,]    2    5    2
## [2,]    6    1    4
t(A)
##      [,1] [,2]
## [1,]    2    6
## [2,]    5    1
## [3,]    2    4
t(t(A))
##      [,1] [,2] [,3]
## [1,]    2    5    2
## [2,]    6    1    4

Ma trận đơn vị

Ma trận đơn vị \(I_n\) có số chiều \(n\) là một ma trận \(n\times n\) trong đó mọi phần tử trên đường chéo chính bằng 1 và tất cả những phần tử khác đều bằng 0.

Cách đơn giản nhất để tạo ma trận đơn vị trong R là dùng hàm diag().

A <- diag(3)
A
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    1    0
## [3,]    0    0    1

Các phép toán trên ma trận

(A <- cbind(c(2,5,2),c(6,1,4)))
##      [,1] [,2]
## [1,]    2    6
## [2,]    5    1
## [3,]    2    4
(B <- cbind(c(-2,3,6),c(8.1,8.2,-9.8)))
##      [,1] [,2]
## [1,]   -2  8.1
## [2,]    3  8.2
## [3,]    6 -9.8
3*A # nhân một số với ma trận
##      [,1] [,2]
## [1,]    6   18
## [2,]   15    3
## [3,]    6   12
A + B # cộng 2 ma trận
##      [,1] [,2]
## [1,]    0 14.1
## [2,]    8  9.2
## [3,]    8 -5.8
A - B # hiệu 2 ma trận
##      [,1] [,2]
## [1,]    4 -2.1
## [2,]    2 -7.2
## [3,]   -4 13.8
A*B # nhân phần tử tương ứng
##      [,1]  [,2]
## [1,]   -4  48.6
## [2,]   15   8.2
## [3,]   12 -39.2

Để nhân 2 ma trận chúng ta dùng dấu %*%.

(A <- rbind(c(2,5,2),c(6,1,4)))
##      [,1] [,2] [,3]
## [1,]    2    5    2
## [2,]    6    1    4
(B <- cbind(c(3,-1,1),c(-3,1,5)))
##      [,1] [,2]
## [1,]    3   -3
## [2,]   -1    1
## [3,]    1    5
A%*%B
##      [,1] [,2]
## [1,]    3    9
## [2,]   21    3

Để tính định thức của một ma trận vuông (ma trận có số dòng bằng số cột) ta dùng hàm det().

(A <- matrix(data=c(3,4,1,2),nrow=2,ncol=2))
##      [,1] [,2]
## [1,]    3    1
## [2,]    4    2
det(A)
## [1] 2

Để tìm ma trận nghịch đảo của một ma trận vuông ta dùng hàm solve().

solve(A)
##      [,1] [,2]
## [1,]    1 -0.5
## [2,]   -2  1.5

Bài tập 3.2

  1. Tính \[\begin{equation*} \frac{2}{7}\left(\left[\begin{array}{ll} 1 & 2 \\ 2 & 4 \\ 7 & 6 \end{array}\right]-\left[\begin{array}{ll} 10 & 20 \\ 30 & 40 \\ 50 & 60 \end{array}\right]\right) \end{equation*}\]
  2. Tạo hai ma trận \[\begin{equation*} A=\left[\begin{array}{l} 1 \\ 2 \\ 7 \end{array}\right], \quad B=\left[\begin{array}{l} 3 \\ 4 \\ 8 \end{array}\right] \end{equation*}\] Phép nhân nào sau đây thực hiện được? Nếu được tìm kết quả.
    1. \(AB\)
    2. \(A^TB\)
    3. \(B^T(AA^T)\)
    4. \((AA^T)B^T\)
    5. \([BB^T + AA^T - 100I_3]^{-1}\)
  3. Cho ma trận \[\begin{equation} A=\left[\begin{array}{cccc} 2 & 0 & 0 & 0 \\ 0 & 3 & 0 & 0 \\ 0 & 0 & 5 & 0 \\ 0 & 0 & 0 & -1 \end{array}\right], \end{equation}\] hãy chỉ ra rằng \(A^{-1}A-I_4\) là ma trận không.

Mảng đa chiều

Để tạo mảng trong R chúng ta dùng hàm array().

AR <- array(data = 1:24, dim = c(3, 4, 2)) # mảng 3 chiều
AR
## , , 1
## 
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
## 
## , , 2
## 
##      [,1] [,2] [,3] [,4]
## [1,]   13   16   19   22
## [2,]   14   17   20   23
## [3,]   15   18   21   24
BR <- array(data = rep(1:24, times = 3), dim = c(3, 4, 2, 3)) # mảng 4 chiều
BR
## , , 1, 1
## 
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
## 
## , , 2, 1
## 
##      [,1] [,2] [,3] [,4]
## [1,]   13   16   19   22
## [2,]   14   17   20   23
## [3,]   15   18   21   24
## 
## , , 1, 2
## 
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
## 
## , , 2, 2
## 
##      [,1] [,2] [,3] [,4]
## [1,]   13   16   19   22
## [2,]   14   17   20   23
## [3,]   15   18   21   24
## 
## , , 1, 3
## 
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
## 
## , , 2, 3
## 
##      [,1] [,2] [,3] [,4]
## [1,]   13   16   19   22
## [2,]   14   17   20   23
## [3,]   15   18   21   24

Trích xuất và thay thế các phần tử của mảng

Việc trích xuất và thay thế các phần tử của mảng cũng được thực hiện tương tự như vectơ và ma trận.

AR[2,,2]
## [1] 14 17 20 23
AR[2,c(3,1),2]
## [1] 20 14
AR[1,,]
##      [,1] [,2]
## [1,]    1   13
## [2,]    4   16
## [3,]    7   19
## [4,]   10   22
BR[2,1,1,3]
## [1] 2
BR[1,,,1]
##      [,1] [,2]
## [1,]    1   13
## [2,]    4   16
## [3,]    7   19
## [4,]   10   22
BR[,,2,]
## , , 1
## 
##      [,1] [,2] [,3] [,4]
## [1,]   13   16   19   22
## [2,]   14   17   20   23
## [3,]   15   18   21   24
## 
## , , 2
## 
##      [,1] [,2] [,3] [,4]
## [1,]   13   16   19   22
## [2,]   14   17   20   23
## [3,]   15   18   21   24
## 
## , , 3
## 
##      [,1] [,2] [,3] [,4]
## [1,]   13   16   19   22
## [2,]   14   17   20   23
## [3,]   15   18   21   24
BR[3:2,4,,]
## , , 1
## 
##      [,1] [,2]
## [1,]   12   24
## [2,]   11   23
## 
## , , 2
## 
##      [,1] [,2]
## [1,]   12   24
## [2,]   11   23
## 
## , , 3
## 
##      [,1] [,2]
## [1,]   12   24
## [2,]   11   23
BR[2,,1,]
##      [,1] [,2] [,3]
## [1,]    2    2    2
## [2,]    5    5    5
## [3,]    8    8    8
## [4,]   11   11   11

Bài tập 3.3

  1. Tạo và đặt tên một mảng ba chiều gồm 6 lớp của ma trận \(4\times 2\) với các giá trị lấy từ dãy giảm dần các giá trị trong khoảng từ \(4.8\) đến \(0.1\).
  2. Tạo một đối tượng mới bằng cách trích các phần tử ở dòng thứ tư và thứ nhất của cột thứ hai của tất cả các lớp của (a).
  3. Tạo một mảng với kích thước \(2\times 2\times 2\times 3\) với các phần tử lấy từ việc lặp lại 4 lần dòng thứ 2 của ma trận (b).
  4. Tạo một mảng mới bằng cách loại bỏ lớp thứ 6 của (a).
  5. Thay thế các phần tử ở dòng thứ 2 và 4 của cột thứ 2 của các lớp 1, 3, 5 của (d) bằng -99.

Tóm tắt

Hàm/Toán tử Chức năng
matrix() Tạo ma trận
rbind() Tạo ma trận (ghép theo dòng)
cbind() Tạo ma trận (ghép theo cột)
dim() Xác định số chiều ma trận
nrow() Xác định số dòng
ncol() Xác định số cột
diag() Trích phần tử đường chéo/Tạo ma trận đơn vị
t() Chuyển vị ma trận
%*% Nhân ma trận
det() Tính định thức
solve() Tìm ma trận nghịch đảo
array() Tạo mảng

Tài liệu tham khảo

Davies, Tilman M. 2016. The Book of R: A First Course in Programming and Statistics. No Starch Press.