生成随机非奇异整数矩阵
作为合成噪声生成算法的一部分,我必须动态构建许多大型非奇异方阵
a i,j (i,j:1..n) / ∀ (i ,j) a i,j ε ℤ 且 0 ≤ a i,j ≤ k 且 Det[a] ≠ 0
但 a i,j 也应该是随机的,遵循 [0, k] 中的均匀分布。
在当前的版本中,问题有 n ≅ 300,k≅ 100。
在 Mathematica 中,我可以非常快地生成随机元素矩阵,但问题是我还必须检查奇点。我目前正在使用行列式值。
问题是,对于 300x300 矩阵,此检查需要近 2 秒的时间,而我负担不起。
当然,我可以通过选择随机的第一行然后构造连续的正交行来构造行,但我不确定如何保证这些行的元素遵循 [0,k] 中的均匀分布。
我正在 Mathematica 中寻找解决方案,但也欢迎更快的生成矩阵的算法。
注意> U[0,k] 条件意味着采用一组矩阵,该组中的每个位置 (i , j) 应遵循均匀分布。
As part of a synthetic noise generation algorithm, I have to construct on the fly a lot of large non-singular square matrices
a i,j (i,j:1..n) / ∀ (i,j) a i,j ∈ ℤ and 0 ≤ a i,j ≤ k and Det[a] ≠ 0
but the a i,j should also be random following a uniform distribution in [0, k].
In its current incarnation the problem has n ≅ 300, k≅ 100.
In Mathematica, I can generate random element matrices very fast, but the problem is that I must also check for singularity. I am currently using the Determinant value for this.
The problem is that this check, for the 300x300 matrices takes something near 2 seconds, and I can't afford that.
Of course I may construct the rows by selecting a random first row and then constructing successive orthogonal rows, but I'm not sure how to guarantee that those rows will have their elements following an uniform distribution in [0,k].
I am looking for a solution in Mathematica, but just a faster algorithm for generating the matrices is also welcome.
NB> The U[0,k] condition means that taken a set of matrices, each position (i , j) across the set should follow a uniform distribution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 Matlab 和 Octave 中,500x500 矩阵的行列式和 LU 分解基本上都是瞬时的。 Mathematica 是否有一种可以调用 LAPACK 或类似库的模式?您可能需要注释您的数组应被视为浮点数而不是符号;这可能会让速度快很多。作为比较,在我使用 Octave 的系统上,5000x5000 矩阵上的 LU 需要 8.66 秒; 500x500 应该比这个快 1000 倍左右。
In both Matlab and Octave, the determinant and LU factorization of a 500x500 matrix are basically instantaneous. Does Mathematica have a mode where it can call out to LAPACK or some similar library? You might need to annotate that your arrays should be treated as floating point numbers and not symbolically; that might make it a lot faster. As a point of comparison, LU on a 5000x5000 matrix takes 8.66 seconds on my system using Octave; 500x500 should be around 1000 times faster than that.
您可以使用
MatrixRank
代替。在我的机器上,对于大型 nxn 整数矩阵,速度大约快 n/10 倍。You could use
MatrixRank
instead. On my machine it's about n/10 times faster for large nxn integer matrices.如果在奇点测试中使用数值近似矩阵,您将获得更好的速度。
Out[57]= {6.8640000, False}
Out[58]= {0.0230000, False}
Out[59]= {0.1710000, False}
不幸的是,最快的测试并不可靠。但等级测试应该效果很好。这是一个简单的示例,其中我们用先前行的总和替换最后一行。
Out[70]= {9.4750000,True}
Out[69]= {0.0470000,False}
Out[71]= {0.1440000,True}
原则上,我认为排名测试给出假阴性的可能性很小。说是因为身体不好。由于您的使用可以更好地容忍误报(即,不正确的奇点声明),您可以改为测试素数模数的奇点。我认为这是其他人提出的建议之一。
继续上面的例子:
Out[77]= {0.6320000, 4054}
Out[78]= {0.6470000, 0}
这很慢,但比处理有理数更快。就其价值而言,对于大多数用途,我对通过 MatrixRank[N[matrix]] 进行更快测试的结果相当有信心。
丹尼尔·利希布劳
沃尔夫勒姆研究公司
If you use numeric approximate matrices in the singularity tests you will get much better speed.
Out[57]= {6.8640000, False}
Out[58]= {0.0230000, False}
Out[59]= {0.1710000, False}
Unfortunately that fastest test is not reliable. But the rank test should work well. Here is a quick example wherein we replace the last row by the sum of prior rows.
Out[70]= {9.4750000, True}
Out[69]= {0.0470000, False}
Out[71]= {0.1440000, True}
In principle I suppose there is a smallish chance that the rank test could give a false negative., say due to ill conditioning. As your usage will better tolerate false positives (that is, incorrect claims of singularity) you could instead test for singularity over a prime modulus. I think this was one of the recommendations others have made.
Continuing the above examples:
Out[77]= {0.6320000, 4054}
Out[78]= {0.6470000, 0}
This is slow but faster than working over the rationals. For what it's worth, for most usage I'd be fairly confident in the outcomes of the faster testing via MatrixRank[N[matrix]].
Daniel Lichtblau
Wolfram Research
这是我所做的评论的扩展。我同意 Dan 的观点,即数字版本返回误报的可能性极小。尽管如此,如果最小奇异值大于某个误差容限,您可以通过检查奇异值并可靠地返回 False 来避免这种情况。 (诚然,找到可证明的容差可能有点棘手。)如果最小奇异值小得令人不舒服,则可以将 Det 应用于整数矩阵。
对于大多数非奇异矩阵,这是一个应该快速返回 False 的函数。如果矩阵接近奇异,则执行更昂贵的整数计算。
这里有 200 个符合您描述的矩阵。中间的一个已被操纵为单一的。
现在,让我们一边观察一边找出所有奇异矩阵的索引。
Here's an expansion of a comment that I made a bit. I agree with Dan that it is highly improbable that the numerical version would return a false positive. Nonetheless, you can avoid that scenario by examining the singular values and returning False reliably, if the smallest singular value is larger than some error tolerance. (Admitedly, it might be a bit tricky to find a provable tolerance.) If the smallest singular value is uncomfortably small, you can apply Det to the integer matrix.
Here's a function that should quickly return False for most non-singular matrices. If the matrix is close to singular, a more expensive integer computation is performed.
Here are 200 matrices that meet your description. One in the middle has been rigged to be singular.
Now, let's find the indices of all the singular matrices, watching as we go.