可靠地创建随机非奇异矩阵

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 个随机数,将它们放在主对角线上,并将其余条目(主对角线上方)设置为您喜欢的任何值。如果您希望矩阵完全密集,请将第一行添加到矩阵的每隔一行。

当然,这种方法(就像任何其他方法一样)假设矩阵在数值上相对稳定并且奇点不会受到精度误差的影响(如您所知,所有编程语言中数据类型的精度都是有限的) .你最好避免非常小/非常大的值,这会使方法在数值上不稳定。