面向金融的R语言——Lecture6

本文介绍了R语言中面向金融的矩阵运算,包括矩阵的创建、 Hibert矩阵、特征值与特征向量、SVD和QR分解等。通过实例展示了如何构造矩阵、访问元素、求解线性系统,以及应用这些方法解决金融问题。
摘要由CSDN通过智能技术生成

面向金融的R语言——Lecture6

2018年11月15日 软微 金融信息服务 刘旭德

矩阵的创建、性质及运算

构造矩阵的三种方法

  1. 创建一个行列分别分 nrow, ncol 的矩阵
    matrix(data, nrow, ncol)
    data(列表)里面的数是由上而下排列的
  2. 利用cbind来实现
    cbind(d1, d2, d3, …, dm)
    其中 di 是列向量
  3. 利用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)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值