12 min read

R与矩阵运算总结

1 矩阵基本操作

1.1创建向量

R里面有多种方法来创建向量(Vector),最简单的是用函数c()。例如:

X=c(1,2,3,4)

X
## [1] 1 2 3 4

当然,还有别的方法。例如:

X=1:4

X
## [1] 1 2 3 4

还有seq()函数。例如:

X=seq(1,4,length=4)

X
## [1] 1 2 3 4

注意一点,R中的向量默认为列向量,如果要得到行向量需要对其进行转置。

1.2创建矩阵

R中创建矩阵的方法也有很多。大致分为直接创建和由其它格式转换两种方法。

1.2.1直接创建矩阵

最简单的直接创建矩阵的方法是用matrix()函数,matrix()函数的使用方法如下:

args(matrix)
## function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) 
## NULL

其中,data参数输入的为矩阵的元素,不能为空;nrow参数输入的是矩阵的行数,默认为1;ncol参数输入的是矩阵的列数,默认为1;byrow参数控制矩阵元素的排列方式,TRUE表示按行排列,FALSE表示按列排列,默认为FALSE;dimnames参数输入矩阵的行名和列名,可以不输入,系统默认为NULL。例如:

matrix(1:6,nrow=2,ncol=3,byrow=FALSE)
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6

改变矩阵的行数和列数:

matrix(1:6,nrow=3,ncol=2,byrow=FALSE)
##      [,1] [,2]
## [1,]    1    4
## [2,]    2    5
## [3,]    3    6

改变byrow参数:

matrix(1:6,nrow=3,ncol=2,byrow=T)
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
## [3,]    5    6

设定矩阵的行名和列名:

matrix(1:6,nrow=3,ncol=2,byrow=T,dimnames=list(c("A","B","C"),c("boy","girl")))
##   boy girl
## A   1    2
## B   3    4
## C   5    6

1.2.2 由其它格式转换

也可以由其它格式的数据转换为矩阵,此时需要用到函数as.matrix()。

1.3 查看和改变矩阵的维数

矩阵有两个维数,即行维数和列维数。在R中查看矩阵的行维数和列维数可以用函数dim()。例如:

 X=matrix(1:12,ncol=3,nrow=4)

 X
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
 dim(X)
## [1] 4 3

只返回行维数:

 dim(X)[1]
## [1] 4

也可以用函数nrow()

nrow(X)
## [1] 4

只返回列维数:

 dim(X)[2]
## [1] 3

也可以用函数ncol():

 ncol(X)
## [1] 3

同时,函数dim()也可以改变矩阵的维数。例如:

dim(X)=c(2,6)

X
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    3    5    7    9   11
## [2,]    2    4    6    8   10   12

1.4矩阵行列的名称

查看矩阵的行名和列名分别用函数rownames()和函数colnames()。例如:

X=matrix(1:6,nrow=3,ncol=2,byrow=T,dimnames=list(c("A","B","C"),c("boy","girl")))

 X
##   boy girl
## A   1    2
## B   3    4
## C   5    6

查看矩阵的行名:

 rownames(X)
## [1] "A" "B" "C"

查看矩阵的列名:

 colnames(X)
## [1] "boy"  "girl"

同时也可以改变矩阵的行名和列名,比如:

rownames(X)=c("E","F","G")

 X
##   boy girl
## E   1    2
## F   3    4
## G   5    6
 colnames(X)=c("man","woman")

 X
##   man woman
## E   1     2
## F   3     4
## G   5     6

1.5 矩阵元素的查看及其重新赋值

查看矩阵的某个特定元素,只需要知道该元素的行坐标和列坐标即可,例如:

 X=matrix(1:12,nrow=4,ncol=3)

 X
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12

查看位于矩阵第二行、第三列的元素:

 X[2,3]
## [1] 10

也可以重新对矩阵的元素进行赋值,将矩阵第二行、第三列的元素替换为0:

 X[2,3]=0

 X
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6    0
## [3,]    3    7   11
## [4,]    4    8   12

R中有一个diag()函数可以返回矩阵的全部对角元素:

 X=matrix(1:9,ncol=3,nrow=3)

 X
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
diag(X)
## [1] 1 5 9

当然也可以对对角元素进行重新赋值:

 diag(X)=c(0,0,1)

 X
##      [,1] [,2] [,3]
## [1,]    0    4    7
## [2,]    2    0    8
## [3,]    3    6    1

当操作对象不是对称矩阵时,diag()也可以进行操作。

 X=matrix(1:12,nrow=4,ncol=3)

 X
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
 diag(X)
## [1]  1  6 11

diag()函数还能用来生成对角矩阵:

 diag(c(1,2,3))
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    2    0
## [3,]    0    0    3

也可以生成单位对角矩阵:

 diag(3)
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    1    0
## [3,]    0    0    1
 diag(4)
##      [,1] [,2] [,3] [,4]
## [1,]    1    0    0    0
## [2,]    0    1    0    0
## [3,]    0    0    1    0
## [4,]    0    0    0    1

查看矩阵的上三角部分:在R中查看矩阵的上三角和下三角部分很简单。可以通过lower.tri()和upper.tir()来实现:

 args(lower.tri)
## function (x, diag = FALSE) 
## NULL
 args(upper.tri)
## function (x, diag = FALSE) 
## NULL

查看上三角:

 X=matrix(1:12,nrow=4,ncol=3)

 X
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
 X[lower.tri(X)]
## [1]  2  3  4  7  8 12

改变赋值:

 X[lower.tri(X)]=0

 X
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    0    6   10
## [3,]    0    0   11
## [4,]    0    0    0

2 矩阵计算

2.1矩阵转置

R中矩阵的转置可以用t()函数完成,例如:

 X=matrix(1:12,nrow=4,ncol=3)

 X
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
 t(X)
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12

2.2矩阵的行和与列和及行平均值和列均值

在R中很容易计算一个矩阵的各行和和各列和以及各行的平均值和各列的平均值。例如:

 A=matrix(1:12,3,4)

 A
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
 rowSums(A)
## [1] 22 26 30
 rowMeans(A)
## [1] 5.5 6.5 7.5
 colSums(A)
## [1]  6 15 24 33
 colMeans(A)
## [1]  2  5  8 11

2.3行列式的值

R中的函数det()将计算方阵A的行列式。例如:

 X=matrix(rnorm(9),nrow=3,ncol=3)

 X
##            [,1]       [,2]       [,3]
## [1,] -0.6110769 -0.3434181 -1.1062389
## [2,] -1.9174083  0.1106630 -0.7469723
## [3,] -0.3393505  0.1931565  1.6372937
 det(X)
## [1] -0.9958889

2.4矩阵相加减

矩阵元素的相加减是指维数相同的矩阵,处于同行和同列的位置的元素进行加减。实现这个功能用“+”,“-”即可。例如:

 A=B=matrix(1:12,nrow=3,ncol=4)

 A+B
##      [,1] [,2] [,3] [,4]
## [1,]    2    8   14   20
## [2,]    4   10   16   22
## [3,]    6   12   18   24
 A-B
##      [,1] [,2] [,3] [,4]
## [1,]    0    0    0    0
## [2,]    0    0    0    0
## [3,]    0    0    0    0

2.5矩阵的数乘

矩阵的数乘是指一个常数与一个矩阵相乘。设A为 \(m\times n\) 矩阵,当 \(c\ne0\) 时,在R中求 \(c*A\) 的值,可以用符号“*”。例如:

 c=2

 A=matrix(1:12,nrow=3,ncol=4)

 A
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
 c*A
##      [,1] [,2] [,3] [,4]
## [1,]    2    8   14   20
## [2,]    4   10   16   22
## [3,]    6   12   18   24

结果矩阵与原矩阵的所有相应元素都差一个常数c。

2.6矩阵相乘

2.6.1矩阵的乘法

A为 \(m\times n\) 矩阵,B为 \(n\times k\) 矩阵,在R中求 \(A\times B\) ,可以符号“%*%”。例如:

 A=matrix(1:12,nrow=3,ncol=4)

 B=matrix(1:12,nrow=4,ncol=3)

 A%*%B
##      [,1] [,2] [,3]
## [1,]   70  158  246
## [2,]   80  184  288
## [3,]   90  210  330

注意: \(B\times A\) 无意义,因其不符合矩阵的相乘规则。

若A为 \(n\times m\) 矩阵,B为 \(n\times k\) 矩阵,在R中求 \(A^{'}\times B\)

 A=matrix(1:12,nrow=4,ncol=3)

 B=matrix(1:12,nrow=4,ncol=3)

 t(A)%*%B
##      [,1] [,2] [,3]
## [1,]   30   70  110
## [2,]   70  174  278
## [3,]  110  278  446

也可以用函数crossprod()计算 \(A^{'}\times B\)

crossprod(A,B)
##      [,1] [,2] [,3]
## [1,]   30   70  110
## [2,]   70  174  278
## [3,]  110  278  446

2.6.2矩阵的Kronecker积

\(n\times m\) 的矩阵A和 \(h\times k\) 的矩阵B的Kronecker积是一个 \(nh\times mk\) 维矩阵,公式为:

$$ A \otimes B = \begin{bmatrix} a_{11}B & a_{12}B & \cdots & a_{1m}B \ a_{21}B & a_{22}B & \cdots & a_{2m}B \ \vdots & \vdots & \ddots & \vdots \ a_{n1}B & a_{n2}B & \cdots & a_{nm}B \end{bmatrix} $$

其中:

  • \(a_{ij}\) 表示矩阵A的第i行第j列元素
  • 每个分块 \(a_{ij}B\) 是原矩阵B的所有元素按 \(a_{ij}\) 比例缩放后的子矩阵
  • 最终结果矩阵的维度为 \((n \cdot h) \times (m \cdot k)\),即原矩阵行数乘积和新矩阵列数乘积

在R中Kronecker积可以用函数kronecher()来计算。例如:

 A=matrix(1:4,2,2)

 A
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
 B=matrix(rep(1,4),2,2)

 B
##      [,1] [,2]
## [1,]    1    1
## [2,]    1    1
 kronecker(A,B)
##      [,1] [,2] [,3] [,4]
## [1,]    1    1    3    3
## [2,]    1    1    3    3
## [3,]    2    2    4    4
## [4,]    2    2    4    4

2.7矩阵的伴随矩阵

求矩阵A的伴随矩阵可以用LoopAnalyst包中的函数make.adjoint()函数。例如:

 A=matrix(1:12,nrow=3,ncol=4)

 A
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
 make.adjoint(A)
##      [,1] [,2] [,3]
## [1,]   -3    6   -3
## [2,]    6  -12    6
## [3,]   -3    6   -3

2.8矩阵的逆和广义逆

2.8.1矩阵的逆

矩阵A的逆A-1可以用函数solve(),例如:

 A=matrix(rnorm(9),nrow=3,ncol=3)

 A
##            [,1]      [,2]       [,3]
## [1,]  0.1630739 0.6387177  0.5308319
## [2,] -0.8614037 0.3068824 -0.2521929
## [3,] -1.4320496 0.4783913 -0.6097321
 solve(A)
##            [,1]      [,2]      [,3]
## [1,]  0.6574602 -6.363927  3.204585
## [2,]  1.6228775 -6.535581  4.116074
## [3,] -0.2708487  9.818892 -5.937084

验证AA-1=1:

 A%*%solve(A)
##               [,1]          [,2]          [,3]
## [1,]  1.000000e+00  8.881784e-16 -4.440892e-16
## [2,] -6.938894e-17  1.000000e+00 -2.220446e-16
## [3,] -2.775558e-17 -8.881784e-16  1.000000e+00

用round函数可以更好的得到结果:

 round(A%*%solve(A))
##      [,1] [,2] [,3]
## [1,]    1    0    0
## [2,]    0    1    0
## [3,]    0    0    1

solve()函数也可以用来求解方程组ax=b。

2.8.2矩阵的广义逆(Moore-Penrose)

\(n \times m\) 矩阵 \(A^+\) 称为矩阵 \(A\) 的 Moore-Penrose 广义逆,当且仅当它同时满足以下四个条件:

1.相容性条件 $$ AA^+A = A $$
该条件保证了广义逆与原矩阵相乘后能保持原矩阵的核心结构不变。

2.弱相容性条件 $$ A^+AA^+ = A^+ $$
表明广义逆的迭代运算具有稳定性;

3.对称性条件 $$ (AA^+)^T = AA^+ $$
确保乘积矩阵 \(AA^+\) 是正交投影算子;

4.共轭对称性条件 $$ (A^+A)^T = A^+A $$
保证乘积矩阵 \(A^+A\) 同样是正交投影算子。

其核心特性包括:

  • 存在唯一性:任意矩阵都存在唯一的 Moore-Penrose 逆;
  • 退化特性:当 \(A\) 可逆时,$A^+ = A^{-1}$;
  • 计算方式:可通过奇异值分解实现 $$ A^+ = V\Sigma^+U^T $$ 其中 \(\Sigma^+\) 为奇异值矩阵的伪逆。

R中MASS包中的ginv()函数可以计算矩阵的Moore-Penrose逆。例如:

 library(MASS)

 A=matrix(1:12,nrow=3,ncol=4)

 A
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
 # solve(A)  #出错

 ginv(A)
##              [,1]        [,2]        [,3]
## [1,] -0.483333333 -0.03333333  0.41666667
## [2,] -0.244444444 -0.01111111  0.22222222
## [3,] -0.005555556  0.01111111  0.02777778
## [4,]  0.233333333  0.03333333 -0.16666667

验证性质1:

 A%*%ginv(A)%*%A
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12
 A
##      [,1] [,2] [,3] [,4]
## [1,]    1    4    7   10
## [2,]    2    5    8   11
## [3,]    3    6    9   12

验证性质2:

 ginv(A)%*%A%*%ginv(A)
##              [,1]        [,2]        [,3]
## [1,] -0.483333333 -0.03333333  0.41666667
## [2,] -0.244444444 -0.01111111  0.22222222
## [3,] -0.005555556  0.01111111  0.02777778
## [4,]  0.233333333  0.03333333 -0.16666667
 ginv(A)
##              [,1]        [,2]        [,3]
## [1,] -0.483333333 -0.03333333  0.41666667
## [2,] -0.244444444 -0.01111111  0.22222222
## [3,] -0.005555556  0.01111111  0.02777778
## [4,]  0.233333333  0.03333333 -0.16666667

验证性质3:

 A%*%ginv(A)
##            [,1]      [,2]       [,3]
## [1,]  0.8333333 0.3333333 -0.1666667
## [2,]  0.3333333 0.3333333  0.3333333
## [3,] -0.1666667 0.3333333  0.8333333
 t(A%*%ginv(A))
##            [,1]      [,2]       [,3]
## [1,]  0.8333333 0.3333333 -0.1666667
## [2,]  0.3333333 0.3333333  0.3333333
## [3,] -0.1666667 0.3333333  0.8333333

验证性质4:

 ginv(A)%*%A
##      [,1] [,2] [,3] [,4]
## [1,]  0.7  0.4  0.1 -0.2
## [2,]  0.4  0.3  0.2  0.1
## [3,]  0.1  0.2  0.3  0.4
## [4,] -0.2  0.1  0.4  0.7
 t(ginv(A)%*%A)
##      [,1] [,2] [,3] [,4]
## [1,]  0.7  0.4  0.1 -0.2
## [2,]  0.4  0.3  0.2  0.1
## [3,]  0.1  0.2  0.3  0.4
## [4,] -0.2  0.1  0.4  0.7

也可以不必如此麻烦来验证性质3和4,因为3和4只是表明 \(AA^+\)\(A^+A\) 是对称矩阵。

2.8.3 [X^‘X ]的逆

很多时候,我们需要计算形如 \(X^{'}X\) 的逆。这很容易实现,例如:

 x=matrix(rnorm(9),ncol=3,nrow=3)

 x
##            [,1]       [,2]       [,3]
## [1,]  1.8093460 1.26990532 -1.3654367
## [2,]  0.4774751 0.21718498  0.2193708
## [3,] -0.9058385 0.06350197  0.6108242
 solve(crossprod(x))
##           [,1]       [,2]      [,3]
## [1,]  2.112090 -1.0630514 1.9311835
## [2,] -1.063051  2.6346674 0.5414491
## [3,]  1.931184  0.5414491 3.2942094

R中的strucchange包中的函数solveCrossprod()也可完成:

 library(strucchange)
## 载入需要的程序包:zoo
## 
## 载入程序包:'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## 载入需要的程序包:sandwich
 args(solveCrossprod)
## function (X, method = c("qr", "chol", "solve")) 
## NULL
 solveCrossprod(x,method="qr")
##           [,1]       [,2]      [,3]
## [1,]  2.112090 -1.0630514 1.9311835
## [2,] -1.063051  2.6346674 0.5414491
## [3,]  1.931184  0.5414491 3.2942094
 solveCrossprod(x,method="chol")
##           [,1]       [,2]      [,3]
## [1,]  2.112090 -1.0630514 1.9311835
## [2,] -1.063051  2.6346674 0.5414491
## [3,]  1.931184  0.5414491 3.2942094
 solveCrossprod(x,method="solve")
##           [,1]       [,2]      [,3]
## [1,]  2.112090 -1.0630514 1.9311835
## [2,] -1.063051  2.6346674 0.5414491
## [3,]  1.931184  0.5414491 3.2942094

2.9矩阵的特征值和特征向量

矩阵的谱分解(或称特征分解)是将方阵分解为特征值和特征向量构成的正交投影矩阵的线性组合。设 \(A\)\(n \times n\)正规矩阵(例如实对称矩阵、Hermitian矩阵或酉矩阵),其谱分解公式为:

$$ A=\sum_{i=1}^{k}\lambda_{i}E_{i} $$

其中:

  • \(\lambda_i\)\(A\)互异特征值(共 \(k\) 个不同的特征值);
  • \(E_i\) 是到 \(\lambda_i\) 对应特征空间的正交投影矩阵,满足: -正交性:$E_i E_j = 0 \ (\forall i \neq j)$ -幂等性:$E_i^2 = E_i$ -单位分解:$\sum_{i=1}^k E_i = I_n$

关键条件与性质:

1.可对角化性:谱分解要求矩阵 \(A\) 可对角化,正规矩阵(如对称矩阵、Hermitian矩阵)一定满足此条件; 2.唯一性:分解形式唯一,由特征值和对应的正交投影矩阵完全确定; 3.几何意义:$E_i$ 将向量投影到 \(\lambda_i\) 的特征空间,$A$ 的作用相当于在不同特征方向上按 \(\lambda_i\) 缩放; 4.特殊情形:若 \(A\) 的特征值互异(无重复),则 \(E_i = v_i v_i^T / \|v_i\|^2\)($v_i$ 为标准正交特征向量)。

比如:

\(A = \begin{bmatrix} 2 & 1 \\ 1 & 2 \end{bmatrix}\),其特征值 \(\lambda_1=3\), \(\lambda_2=1\),对应投影矩阵:

$$ E_1 = \frac{1}{2}\begin{bmatrix} 1 & 1 \ 1 & 1 \end{bmatrix}, \quad E_2 = \frac{1}{2}\begin{bmatrix} 1 & -1 \ -1 & 1 \end{bmatrix} $$

则谱分解为:

$$ A = 3E_1 + 1E_2 $$

 args(eigen)
## function (x, symmetric, only.values = FALSE, EISPACK = FALSE) 
## NULL

其中,x参数输入矩阵;symmetric参数判断矩阵是否为对称矩阵,如果参数为空,系统将自动检测矩阵的对称性。例如:

 A=matrix(1:9,nrow=3,ncol=3)
 A
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
 Aeigen=eigen(A)

 Aeigen
## eigen() decomposition
## $values
## [1]  1.611684e+01 -1.116844e+00 -5.700691e-16
## 
## $vectors
##            [,1]       [,2]       [,3]
## [1,] -0.4645473 -0.8829060  0.4082483
## [2,] -0.5707955 -0.2395204 -0.8164966
## [3,] -0.6770438  0.4038651  0.4082483

得到矩阵A的特征值:

 Aeigen$values
## [1]  1.611684e+01 -1.116844e+00 -5.700691e-16

得到矩阵A的特征向量:

 Aeigen$vectors
##            [,1]       [,2]       [,3]
## [1,] -0.4645473 -0.8829060  0.4082483
## [2,] -0.5707955 -0.2395204 -0.8164966
## [3,] -0.6770438  0.4038651  0.4082483

3 矩阵高级操作

3.1 Choleskey分解

对于正定矩阵A,可以对其进行Choleskey分解,$A=P^{’}P$ ,其中P为上三角矩阵,在R中可以用函数chol()。例如:

 A=diag(3)+1

 A
##      [,1] [,2] [,3]
## [1,]    2    1    1
## [2,]    1    2    1
## [3,]    1    1    2
 chol(A)
##          [,1]      [,2]      [,3]
## [1,] 1.414214 0.7071068 0.7071068
## [2,] 0.000000 1.2247449 0.4082483
## [3,] 0.000000 0.0000000 1.1547005

验证$A=P^{’}P$ :

 t(chol(A))%*%chol(A)
##      [,1] [,2] [,3]
## [1,]    2    1    1
## [2,]    1    2    1
## [3,]    1    1    2

也可以用crossprod()函数:

 crossprod(chol(A),chol(A))
##      [,1] [,2] [,3]
## [1,]    2    1    1
## [2,]    1    2    1
## [3,]    1    1    2

可以用Choleskey分解来计算矩阵的行列式:

 prod(diag(chol(A))^2)
## [1] 4
 det(A)
## [1] 4

也可以用Choleskey分解来计算矩阵的逆,这时候可以用到函数chol2inv():

 chol2inv(chol(A))
##       [,1]  [,2]  [,3]
## [1,]  0.75 -0.25 -0.25
## [2,] -0.25  0.75 -0.25
## [3,] -0.25 -0.25  0.75
 solve(A)
##       [,1]  [,2]  [,3]
## [1,]  0.75 -0.25 -0.25
## [2,] -0.25  0.75 -0.25
## [3,] -0.25 -0.25  0.75

3.2 奇异值分解

A为$m\times n$ 矩阵,矩阵的秩为r。A可以分解为$A=UDV^{’}$ ,其中:$U^{’}U=V^{’}V=I$ 。在R中可以用函数svd()来完成奇异值分解。

例如:

 A=matrix(1:18,3,6)

 A
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    4    7   10   13   16
## [2,]    2    5    8   11   14   17
## [3,]    3    6    9   12   15   18
 svd(A)
## $d
## [1] 4.589453e+01 1.640705e+00 1.366522e-15
## 
## $u
##            [,1]        [,2]       [,3]
## [1,] -0.5290354  0.74394551  0.4082483
## [2,] -0.5760715  0.03840487 -0.8164966
## [3,] -0.6231077 -0.66713577  0.4082483
## 
## $v
##             [,1]        [,2]       [,3]
## [1,] -0.07736219 -0.71960032 -0.4076688
## [2,] -0.19033085 -0.50893247  0.5745647
## [3,] -0.30329950 -0.29826463 -0.0280114
## [4,] -0.41626816 -0.08759679  0.2226621
## [5,] -0.52923682  0.12307105 -0.6212052
## [6,] -0.64220548  0.33373889  0.2596585
 svd(A)$u%*%diag(svd(A)$d)%*%t(svd(A)$v)
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    4    7   10   13   16
## [2,]    2    5    8   11   14   17
## [3,]    3    6    9   12   15   18

3.3 QR分解

A为$m\times n$ 矩阵可以进行QR分解:$A=QR$ ,其中$Q^{’}Q=I$ ,在R中可以用函数qr()来完成这个过程,例如:

 A=matrix(1:12,4,3)

 qr(A)
## $qr
##            [,1]        [,2]          [,3]
## [1,] -5.4772256 -12.7801930 -2.008316e+01
## [2,]  0.3651484  -3.2659863 -6.531973e+00
## [3,]  0.5477226  -0.3781696  1.601186e-15
## [4,]  0.7302967  -0.9124744 -5.547002e-01
## 
## $rank
## [1] 2
## 
## $qraux
## [1] 1.182574 1.156135 1.832050
## 
## $pivot
## [1] 1 2 3
## 
## attr(,"class")
## [1] "qr"

Rank返回的是矩阵的秩。Qr项包含了Q矩阵和R矩阵的信息。要想得到Q矩阵和R矩阵,可以用qr.Q()函数和qr.R()函数:

qr.Q(qr(A))
##            [,1]          [,2]       [,3]
## [1,] -0.1825742 -8.164966e-01 -0.4000874
## [2,] -0.3651484 -4.082483e-01  0.2546329
## [3,] -0.5477226 -1.665335e-16  0.6909965
## [4,] -0.7302967  4.082483e-01 -0.5455419
qr.R(qr(A))
##           [,1]       [,2]          [,3]
## [1,] -5.477226 -12.780193 -2.008316e+01
## [2,]  0.000000  -3.265986 -6.531973e+00
## [3,]  0.000000   0.000000  1.601186e-15

4 解方程组

4.1普通方程组

解普通方程组可以用函数solve(),solve()的基本用法是solve(A,b),其中,A为方程组的系数矩阵,b为方程组的右端。例如:

已知方程组:

$$ \begin{cases} 2x_1+2x_3=1\ 2x_1+x_2+2x_3=2\ 2x_1+x_2=3 \end{cases} $$

解法如下:

A=matrix(
c(2,0,2,
  2,1,2,
  2,1,0),
  byrow=TRUE,nrow=3
)

b=1:3

b

solve(A,b)

即$x_1=1$ ,$x_2=1$ ,$x_3=-0.5$ 。

4.2 特殊方程组

对于系数矩阵是上三角矩阵和下三角矩阵的方程组。R中提供了backsolve()和fowardsolve()来解决这个问题。

backsolve(r, x, k=ncol(r), upper.tri=TRUE, transpose=FALSE)

forwardsolve(l, x, k=ncol(l), upper.tri=FALSE, transpose=FALSE)

这两个函数都是符合操作的函数,大致可以分为三个步骤:

  1. 通过将系数矩阵的上三角或者下三角变为0的到新的系数矩阵,这通过upper.tri参数来实现,若upper.tri=TRUR,上三角不为0。

  2. 通过将对步骤1中得到的新系数矩阵进行转置得到新的系数矩阵,这通过transpose参数实现,若transpose=FALSE,则步骤1中得到的系数矩阵将被转置。

  3. 根据步骤2得到的系数矩阵来解方程组。

$$ \begin{cases} X_1+4X_2+7X_3=1\ 2X_1+5X_2+8X_3=2\ 3X_1+6X_2+9X_3=3 \end{cases} $$

方程组的系数矩阵为:

A <- matrix(
  c(1,4,7,
    2,5,8,
    3,6,9),
  byrow=TRUE,
  nrow = 3
)

b=1:3

backsolve(A,b,upper.tri=T,transpose=F)
## [1] -0.8000000 -0.1333333  0.3333333

过程分解:

  • upper.tri=T,说明系数矩阵的上三角不为0。
B=A

B[lower.tri(B)]=0

B
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    0    5    8
## [3,]    0    0    9
  • transpose=F说明系数矩阵未被转置。

  • 解方程:

solve(B,b)
## [1] -0.8000000 -0.1333333  0.3333333

5 其它

5.1矩阵的向量化

将矩阵向量化有时候是必要的。矩阵的向量化可以通过as.vector()来实现:

A <- matrix(1:9,nrow=3)

A
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9

将矩阵元素向量化:

as.vector(A)
## [1] 1 2 3 4 5 6 7 8 9
A
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9

将矩阵的方阵部分元素向量化:

as.vector(A[1:min(dim(A)),1:min(dim(A))])
## [1] 1 2 3 4 5 6 7 8 9

5.2矩阵的合并

5.2.1矩阵的列合并

矩阵的列合并可以通过cbind()来实现。

A
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
B=1:3

cbind(A,B)
##            B
## [1,] 1 4 7 1
## [2,] 2 5 8 2
## [3,] 3 6 9 3

5.2.2矩阵的行合并

矩阵的行合并可以通过rbind()来实现。

A
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
B=1:3

rbind(A,B)
##   [,1] [,2] [,3]
##      1    4    7
##      2    5    8
##      3    6    9
## B    1    2    3