面向金融的R语言——Lecture6
2018年11月15日 软微 金融信息服务 刘旭德
矩阵的创建、性质及运算
构造矩阵的三种方法
- 创建一个行列分别分 nrow, ncol 的矩阵
matrix(data, nrow, ncol)
data(列表)里面的数是由上而下排列的 - 利用cbind来实现
cbind(d1, d2, d3, …, dm)
其中 di 是列向量 - 利用rbind来实现
rbind(d1, d2, d3, …, dn)
其中 di 是行向量
matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9), 3, 3)
cbind(c(1, 2, 3), c(4, 5, 6), c(7, 8, 9))
rbind(c(1, 4, 7), c(2, 5, 8), c(3, 6, 9))
out
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
其它使用方法
#作用 ncol = 或 nrow = 来指定相应的行、列数
matrix(seq(1, 12), ncol = 3)
out
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
hibert矩阵
hibert矩阵其Aij = 1 / (i + j - 1)
构造hibert 矩阵
hilbert.matrix <- function( n = 1){
element_vec <- numeric(n ^ 2)
Hilbert_matrix <- matrix(element_vec, ncol = n)
for(i in 1 : n)
for(j in 1 : n)
Hilbert_matrix[i, j] <- 1 / (i + j - 1)
return(Hilbert_matrix)
}
H3 <- hilbert.matrix(3)
H3
out
[,1] [,2] [,3]
[1,] 1.0000000 0.5000000 0.3333333
[2,] 0.5000000 0.3333333 0.2500000
[3,] 0.3333333 0.2500000 0.2000000
example:
Q1:构造Hankel矩阵
A1:
Hankel_matrix <- matrix(rep(seq(1 : 5), 5) + rep(seq(0 : 4), each = 5), ncol = 5)
print(Hankel_matrix)
#构造函数生成Hankel矩阵
Hankel_matrix <- function(n = 1){
hankel_matrix <- matrix(rep(seq(1 : n), n) +
rep(seq(0 : (n -1)), each = n), ncol = n)
return (hankel_matrix)
}
print(Hankel_matrix(10))
#第二种写法
Hankel_matrix <- function(n = 1){
#构造一个列表
L <- rep(1 : n , n) + rep(0 : (n - 1), each = n)
#将列表转化为矩阵
M <- matrix(L , ncol = n)
return(M)
}
print(Hankel_matrix(10))
out:
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 1 1 1
[2,] 2 2 2 2 2
[3,] 3 3 3 3 3
[4,] 4 4 4 4 4
[5,] 5 5 5 5 5
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 2 3 4 5 6 7 8 9 10 11
[2,] 3 4 5 6 7 8 9 10 11 12
[3,] 4 5 6 7 8 9 10 11 12 13
[4,] 5 6 7 8 9 10 11 12 13 14
[5,] 6 7 8 9 10 11 12 13 14 15
[6,] 7 8 9 10 11 12 13 14 15 16
[7,] 8 9 10 11 12 13 14 15 16 17
[8,] 9 10 11 12 13 14 15 16 17 18
[9,] 10 11 12 13 14 15 16 17 18 19
[10,] 11 12 13 14 15 16 17 18 19 20
Q2:使用rbind()构造矩阵
A2:
# rbind 里面不需要再定义ncol or nrow
# c()是列表,不能用[]表示
P <- rbind(c(0.1, 0.5, 0.0, 0.4),
c(0.2, 0.3, 0.5, 0.0),
c(0.3, 0.0, 0.5, 0.2),
c(0.2, 0.3, 0.2, 0.3))
print(P)
out:
[,1] [,2] [,3] [,4]
[1,] 0.1 0.5 0.0 0.4
[2,] 0.2 0.3 0.5 0.0
[3,] 0.3 0.0 0.5 0.2
[4,] 0.2 0.3 0.2 0.3
Q3:使用cbind()构造矩阵
A3:
P <- cbind(c(1, 1, 1, 1, 1, 1, 1),
c(2, 3, 4, 5, 6, 7, 8),
c(3, 7, 5, 6, 7, 5, 3))
print(P)
out:
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 3 7
[3,] 1 4 5
[4,] 1 5 6
[5,] 1 6 7
[6,] 1 7 5
[7,] 1 8 3
对矩阵元素的访问
以P矩阵为例
代码 | 含义 |
---|---|
P[i, j] | 访问 P 矩阵的第 i 行, 第 j 列元素 |
P[i, ] | P矩阵的第 i 行 |
P[ , j] | P矩阵的第 j 列 |
P[i, , drop = FALSE] | 保留维度信息 |
colnames ( P ) <- c(“c1” ,“c2” ,… ,“cn”) | 为每一列命名 |
rownames ( P ) <- c(“r1” ,“r2” ,… ,“rn”) | 为每一行命名 |
dim( P ) | 查看P矩阵的维数(行、列) |
det( P ) | 查看P 矩阵行列式的值 |
diag( P ) | 提取对角线元素 |
t( P ) | 对P矩阵进行转置 |
diag( P ) | 矩阵的对角线元素 |
diag(diag( P )) | 矩阵的对角线元素构成的矩阵 |
lower.tri( P ) | |
upper.tri( P ) |
矩阵的代数运算:
矩阵的 + - * 运算都是同型矩阵相应元素作运算
两矩阵的乘法要使用: X % * % Y
Y <- X * 2
# 定义两个矩阵a, b
b <- rbind(c(1, 2, 3),
c(4, 5, 6),
c(7, 8, 9))
a <- rbind(c(1, 0, 0),
c(1, 0, 0),
c(1, 0, 0))
# 两矩阵相应元素相乘
a * b
# 两矩阵相乘
a %*% b
#对 a 转置后相乘
t(a) %*% b
#对a 转置后相乘
crossprod(a, b)
out
> # 定义两个矩阵a, b
> b <- rbind(c(1, 2, 3),
+ c(4, 5, 6),
+ c(7, 8, 9))
> a <- rbind(c(1, 0, 0),
+ c(1, 0, 0),
+ c(1, 0, 0))
>
> # 两矩阵相应元素相乘
> a * b
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 4 0 0
[3,] 7 0 0
> # 两矩阵相乘
> a %*% b
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 2 3
[3,] 1 2 3
> #对 a 转置后相乘
> t(a) %*% b
[,1] [,2] [,3]
[1,] 12 15 18
[2,] 0 0 0
[3,] 0 0 0
> #对a 转置后相乘
> crossprod(a, b)
[,1] [,2] [,3]
[1,] 12 15 18
[2,] 0 0 0
[3,] 0 0 0
矩阵的逆:
利用solve() 或者 qr.solve()
a <- rbind(c(1, 1, 1),
c(0, 1, 1),
c(0, 0, 1))
# 求 a 行列式的值
det(a)
# 求 a 的逆
a.inv <- solve(a)
a.inv
# 另一种求法
a.inv <- qr.solve(a)
a.inv
out
> a <- rbind(c(1, 1, 1),
+ c(0, 1, 1),
+ c(0, 0, 1))
> # 求 a 行列式的值
> det(a)
[1] 1
> # 求 a 的逆
> a.inv <- solve(a)
> a.inv
[,1] [,2] [,3]
[1,] 1 -1 0
[2,] 0 1 -1
[3,] 0 0 1
> # 另一种求法
> a.inv <- qr.solve(a)
> a.inv
[,1] [,2] [,3]
[1,] 1 -1 0
[2,] 0 1 -1
[3,] 0 0 1
矩阵的线性求解:
利用solve(a, b),可以求出 ax = b的解
a <- rbind(c(1, 1, 1),
c(0, 1, 1),
c(0, 0, 1))
b <- c(1, 2, 3)
# 求解 a * x = b
x <- solve(a, b)
x
out
> a <- rbind(c(1, 1, 1),
+ c(0, 1, 1),
+ c(0, 0, 1))
> b <- c(1, 2, 3)
> # 求解 a * x = b
> x <- solve(a, b)
> x
[1] -1 -1 3
example:
Q1:构造体型矩阵
A1:
(a)ABv、(AB)v和A(Bv) 在数学上有差别吗?
答:有差别。前两种的运算顺序为从左到右,第三种先计算括号中的内容。
(b)解释为什么第三种计算比其他两种用更少的时间。
答:B与v相乘后得到一个1000×1的列向量,再与A相乘,与前两种计算相比,减少了A×B的矩阵运算量。
A <- matrix(rep(1,1000000), nrow = 1000)
B <- A
# v是一个列向量,所以才可以与矩阵 A B 相乘
v <- rep(1, 1000)
system.time(A %*% B %*% v)
system.time((A %*% B) %*% v)
system.time(A %*% (B %*% v))
out:
> A <- matrix(rep(1,1000000), nrow = 1000)
> B <- A
> v <- rep(1, 1000)
> system.time(A %*% B %*% v)
用户 系统 流逝
0.69 0.00 0.68
> system.time((A %*% B) %*% v)
用户 系统 流逝
0.66 0.00 0.65
> system.time(A %*% (B %*% v))
用户 系统 流逝
0.02 0.00 0.02
特征值及特征向量
特征值与特征向量的求法
eigen( x ) x矩阵的特征值特征向量
a <- rbind(c(1, 0, 1),
c(0, 1, 1),
c(0, 0, 1))
# 求矩阵的特征值与特征向量
A <- eigen(a)
A
# 特征值 * 相应的特征向量
A $ value[1] * A $ vector[,2]
# 矩阵 * 特征向量
a %*% A$vector[,2]
out
> a <- rbind(c(1, 0, 1),
+ c(0, 1, 1),
+ c(0, 0, 1))
> # 求矩阵的特征值与特征向量
> A <- eigen(a)
> A
eigen() decomposition
$`values`
[1] 1 1 1
$vectors
[,1] [,2] [,3]
[1,] 1 0 -7.071068e-01
[2,] 0 1 -7.071068e-01
[3,] 0 0 1.570092e-16
> # 特征值 * 相应的特征向量
> A $ value[1] * A $ vector[,2]
[1] 0 1 0
> # 矩阵 * 特征向量
> a %*% A$vector[,2]
[,1]
[1,] 0
[2,] 1
[3,] 0
example:
Q1:构造体型矩阵
A1:
X <- matrix(c(1, 2, 3, 1, 4, 9), ncol = 2)
H <- X %*% solve((t(X) %*% X)) %*% t(X)
H
# 求特征值与特征向量
eigen(H)
# 求对角线的和
trace <- function(H)sum(diag(H))
trace(H)
# 求特征值之和
sum(eigen(H)$value)
# 矩阵行列式的值
det(H)
X
H
# X 与 H的乘积是 X
H %*% X
out:
> X <- matrix(c(1, 2, 3, 1, 4, 9), ncol = 2)
> H <- X %*% solve((t(X) %*% X)) %*% t(X)
> H
[,1] [,2] [,3]
[1,] 0.5263158 0.4736842 -0.1578947
[2,] 0.4736842 0.5263158 0.1578947
[3,] -0.1578947 0.1578947 0.9473684
> # 求特征值与特征向量
> eigen(H)
eigen() decomposition
$`values`
[1] 1.000000e+00 1.000000e+00 6.661338e-16
$vectors
[,1] [,2] [,3]
[1,] 0.0000000 -0.7254763 0.6882472
[2,] 0.3162278 -0.6529286 -0.6882472
[3,] 0.9486833 0.2176429 0.2294157
> # 求对角线的和
> trace <- function(H)sum(diag(H))
> trace(H)
[1] 2
> # 求特征值之和
> sum(eigen(H)$value)
[1] 2
> # 矩阵行列式的值
> det(H)
[1] -1.752984e-17
> X
[,1] [,2]
[1,] 1 1
[2,] 2 4
[3,] 3 9
> H
[,1] [,2] [,3]
[1,] 0.5263158 0.4736842 -0.1578947
[2,] 0.4736842 0.5263158 0.1578947
[3,] -0.1578947 0.1578947 0.9473684
> # X 与 H的乘积是 X
> H %*% X
[,1] [,2]
[1,] 1 1
[2,] 2 4
[3,] 3 9
Q2:
创建6×6希尔伯特矩阵,并计算其特征值和特征向量。计算矩阵的逆。逆矩阵的特征值与原矩阵的特征值之间是否存在关系?应该有关系吗?在7×7希尔伯特矩阵上重复上述分析。
答:逆矩阵的特征值为原矩阵特征值的倒数(1/λ)。
# 建立一个Hibert 矩阵
H <- function(n = 1){
h <- numeric(n ^ 2)
m <- matrix(h, ncol = n)
for(i in 1 : n)