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

时间:2015-11-12 02:01:28

标签: r matrix matrix-multiplication matrix-inverse

如何创建一个保证非奇异的伪随机值矩阵?我尝试了下面的代码,但它失败了。我想我可以循环直到偶然得到一个,但如果有人有想法,我宁愿选择更优雅的“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)
}

2 个答案:

答案 0 :(得分:1)

我认为一种方法可以保证(不是很可能,但实际上保证)矩阵是非单数的,是从已知的非奇异开始矩阵并应用高斯消除中使用的基本线性运算:1。从另一行加/减一行的倍数或2.将行乘以常数。

根据您想要矩阵的“随机”和密度,您可以从单位矩阵开始,并将所有元素与随机常量相乘。之后,您可以应用从上面随机选择的一组操作,这将导致非奇异矩阵。您甚至可以应用一组预定义的操作,但在每一步使用随机选择的常量。

替代方案可以是从上三角矩阵开始,其中主对角线条目的乘积不为零。这是因为三角矩阵的行列式是主对角线上元素的乘积。这有效地归结为生成N个随机数,将它们放在主对角线上,并将其余条目(在主对角线上方)设置为您喜欢的任何内容。如果您希望矩阵完全密集,请将第一行添加到矩阵的每隔一行。

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

答案 1 :(得分:0)

这不太可能产生单一矩阵:

 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