将对称矩阵与对角矩阵相乘的原因返回非对称矩阵

时间:2016-07-12 15:13:31

标签: scala matrix eigenvalue scala-breeze

我在使用Breeze时遇到了一个奇怪的问题,我想知道可能的原因。

我有a symmetric matrix,只包含小的正值。我需要得到归一化矩阵的特征值和特征向量,因此我正在使用:

val dataset = new File(getClass.getResource("/matrix.csv").getPath())
val a = breeze.linalg.csvread(dataset)
val diagA = diag(pow(sum(a(*, ::)), -0.5))
val b = diagA * a * diagA // Multiplying a symmetric matrix with a diagonal matrix should still give a diagonal matrix.
println(eigSym(b)) 

这样做会返回[error] (run-main-0) breeze.linalg.MatrixNotSymmetricException: Matrix is not symmetric

如果我从eigSym(a)阅读a之后计算matrix.csv它会起作用,因此我确信a是对称的。

为了找到错误的位置,我在创建a的随机版本时尝试了计算,在这种情况下它可以工作:

// Creation of a big symmetric matrix.
var a = DenseMatrix.rand(240, 240)
var row, col = 0
for (row <- 0 until a.rows) {
    for (col <- row until a.cols) {
        if (col == row) {
            a(row, col) = 0.0
        } else {
            a(col, row) = a(row, col)
        }
    }
}

println(eigSym(a)) // Works.

// Same diagA as before.
val diagA = diag(pow(sum(a(*, ::)), -0.5))
val b = diagA * a * diagA
println(eigSym(b)) // Also works.

我用来使计算失败的原始对称矩阵有什么问题?

1 个答案:

答案 0 :(得分:0)

假设sum()产生零。将其提高到-0.5的功率会在对角矩阵中产生浮点无穷大;随后的产物产生含有NaN的基质。从技术上讲,这个矩阵是对称的,但是要测试的实际代码不能成功,因为它会测试NaN与NaN的相等性,NaN总是返回FALSE。

关于随机检查:请注意,随机矩阵不太可能在sum()中产生零。