可靠地创建随机非奇异矩阵
create a random non-singular matrix reliably
如何创建保证非奇异的伪随机值矩阵?我尝试了下面的代码,但失败了。我想我可以循环直到我偶然得到一个,但如果有人有想法,我更喜欢更优雅的 "R-like" 解决方案。
library(matrixcalc)
exampledf<- matrix(ceiling(runif(16,0,50)), ncol=4)
is.singular.matrix(exampledf) #this may or may not return false
使用 while 循环:
exampledf<-NULL
library(matrixcalc)
while(is.singular.matrix(exampledf)!=TRUE){
exampledf<- matrix(ceiling(runif(16,0,50)), ncol=4)
}
这应该不太可能产生奇异矩阵:
Mat1 <- matrix(rnorm(100), ncol=4)
Mat2 <- matrix(rnorm(100), ncol=4)
crossprod(Mat1,Mat2)
[,1] [,2] [,3] [,4]
[1,] 0.8138 5.112 2.945 -5.003
[2,] 4.9755 -2.420 1.801 -4.188
[3,] -3.8579 8.791 -2.594 3.340
[4,] 7.2057 6.426 2.663 -1.235
solve( crossprod(Mat1,Mat2) )
[,1] [,2] [,3] [,4]
[1,] -0.11273 0.15811 0.05616 0.07241
[2,] 0.03387 0.01187 0.07626 0.02881
[3,] 0.19007 -0.60377 -0.40665 0.17771
[4,] -0.07174 -0.31751 -0.15228 0.14582
inv1000 <- replicate(1000, {
Mat1 <- matrix(rnorm(100), ncol=4)
Mat2 <- matrix(rnorm(100), ncol=4)
try(solve( crossprod(Mat1,Mat2)))} )
str(inv1000)
#num [1:4, 1:4, 1:1000] 0.1163 0.0328 0.3424 -0.227 0.0347 ...
max(inv1000)
#[1] 451.6
> inv100000 <- replicate(100000, {Mat1 <- matrix(rnorm(100), ncol=4)
+ Mat2 <- matrix(rnorm(100), ncol=4)
+ is.singular.matrix( crossprod(Mat1,Mat2))} )
> sum(inv100000)
[1] 0
我假设一种方法可以保证(不是很可能,但实际上保证)矩阵是非奇异的,是从一个已知的非奇异矩阵开始,应用基本线性运算,例如在高斯消元法中使用的:1. 从另一行中添加/减去一行的倍数,或 2. 将行乘以常数。
根据您希望矩阵的 "random" 和密度,您可以从单位矩阵开始并将所有元素乘以一个随机常数。之后,您可以从上面应用一组随机选择的操作,这将产生一个非奇异矩阵。您甚至可以应用一组预定义的操作,但在每一步使用随机选择的常量。
另一种方法是从主对角线元素的乘积不为零的上三角矩阵开始。这是因为三角矩阵的行列式是主对角线上元素的乘积。这有效地归结为生成 N 个随机数,将它们放在主对角线上,并将其余条目(主对角线上方)设置为您喜欢的任何值。如果您希望矩阵完全密集,请将第一行添加到矩阵的每隔一行。
当然,这种方法(就像任何其他方法一样)假设矩阵在数值上相对稳定并且奇点不会受到精度误差的影响(如您所知,所有编程语言中数据类型的精度都是有限的) .你最好避免非常小/非常大的值,这会使方法在数值上不稳定。
如何创建保证非奇异的伪随机值矩阵?我尝试了下面的代码,但失败了。我想我可以循环直到我偶然得到一个,但如果有人有想法,我更喜欢更优雅的 "R-like" 解决方案。
library(matrixcalc)
exampledf<- matrix(ceiling(runif(16,0,50)), ncol=4)
is.singular.matrix(exampledf) #this may or may not return false
使用 while 循环:
exampledf<-NULL
library(matrixcalc)
while(is.singular.matrix(exampledf)!=TRUE){
exampledf<- matrix(ceiling(runif(16,0,50)), ncol=4)
}
这应该不太可能产生奇异矩阵:
Mat1 <- matrix(rnorm(100), ncol=4)
Mat2 <- matrix(rnorm(100), ncol=4)
crossprod(Mat1,Mat2)
[,1] [,2] [,3] [,4]
[1,] 0.8138 5.112 2.945 -5.003
[2,] 4.9755 -2.420 1.801 -4.188
[3,] -3.8579 8.791 -2.594 3.340
[4,] 7.2057 6.426 2.663 -1.235
solve( crossprod(Mat1,Mat2) )
[,1] [,2] [,3] [,4]
[1,] -0.11273 0.15811 0.05616 0.07241
[2,] 0.03387 0.01187 0.07626 0.02881
[3,] 0.19007 -0.60377 -0.40665 0.17771
[4,] -0.07174 -0.31751 -0.15228 0.14582
inv1000 <- replicate(1000, {
Mat1 <- matrix(rnorm(100), ncol=4)
Mat2 <- matrix(rnorm(100), ncol=4)
try(solve( crossprod(Mat1,Mat2)))} )
str(inv1000)
#num [1:4, 1:4, 1:1000] 0.1163 0.0328 0.3424 -0.227 0.0347 ...
max(inv1000)
#[1] 451.6
> inv100000 <- replicate(100000, {Mat1 <- matrix(rnorm(100), ncol=4)
+ Mat2 <- matrix(rnorm(100), ncol=4)
+ is.singular.matrix( crossprod(Mat1,Mat2))} )
> sum(inv100000)
[1] 0
我假设一种方法可以保证(不是很可能,但实际上保证)矩阵是非奇异的,是从一个已知的非奇异矩阵开始,应用基本线性运算,例如在高斯消元法中使用的:1. 从另一行中添加/减去一行的倍数,或 2. 将行乘以常数。
根据您希望矩阵的 "random" 和密度,您可以从单位矩阵开始并将所有元素乘以一个随机常数。之后,您可以从上面应用一组随机选择的操作,这将产生一个非奇异矩阵。您甚至可以应用一组预定义的操作,但在每一步使用随机选择的常量。
另一种方法是从主对角线元素的乘积不为零的上三角矩阵开始。这是因为三角矩阵的行列式是主对角线上元素的乘积。这有效地归结为生成 N 个随机数,将它们放在主对角线上,并将其余条目(主对角线上方)设置为您喜欢的任何值。如果您希望矩阵完全密集,请将第一行添加到矩阵的每隔一行。
当然,这种方法(就像任何其他方法一样)假设矩阵在数值上相对稳定并且奇点不会受到精度误差的影响(如您所知,所有编程语言中数据类型的精度都是有限的) .你最好避免非常小/非常大的值,这会使方法在数值上不稳定。