Haskell 矩阵相等失败

Haskell Matrix equality failing

提问人:E.Zanca 提问时间:11/15/2017 更新时间:11/15/2017 访问量:201

问:

我正在使用 Haskell 来实现一些量子变换矩阵。我有一个函数,旨在通过构建逆矩阵和伴随矩阵,然后测试两者来测试方阵是否是酉矩阵。

该函数如下所示,其中 wrap 是一个简单的函数,用于测试从 Versus 返回的 Either 值。

isUnitary :: [[Copmlex Double]] -> Bool
isUnitary lists = let mat =  fromLists lists --Create matrix from lists
                      conjugateTranspose = fmap conjugate $ Data.Matrix.transpose mat --Conjugate Transpose Matrix
                      inverseMat = debug("ConjugateTranspose: \n" ++ show conjugateTranspose ++ "\n")
                                    wrap $ inverse mat --The inverse matrix
                      in if (conjugateTranspose) == inverseMat then debug("InverseMat: \n" ++ show inverseMat ++ "\n")
                                                                      True
                         else debug("InverseMat: \n" ++ show inverseMat ++ "\n")
                                False

对于一些简单的测试矩阵,它工作正常,在获得如下所示的矩阵时返回 True:

ConjugateTranspose:
(    1.0 :+ (-0.0)                   0.0 :+ (-0.0) )
(    0.0 :+ (-0.0)                   (-1.0) :+ (-0.0) )

InverseMat:
(    1.0 :+ 0.0                      0.0 :+ 0.0 )
(    0.0 :+ (-0.0)                   (-1.0) :+ (-0.0) )

我的问题是该函数为使用 ((1/sqrt(2) :+ 0) 和 ((-1/sqrt(2)) :+ 0)) 构建的 Hadamard 变换矩阵返回 False

ConjugateTranspose:
(    0.7071067811865475 :+ (-0.0)    0.7071067811865475 :+ (-0.0) )
(    0.7071067811865475 :+ (-0.0)    (-0.7071067811865475) :+ (-0.0) )

InverseMat:
(    0.7071067811865476 :+ 0.0       0.7071067811865476 :+ 0.0 )
(    0.7071067811865476 :+ 0.0       (-0.7071067811865476) :+ (-0.0) )

是什么原因导致第二对矩阵的相等性测试失败?有没有更正确的方法让我在代码中呈现复数?

Haskell 矩阵 相等

评论

2赞 Agnishom Chattopadhyay 11/15/2017
一个合理的原因是,由于堆积的误差,浮点运算可能会有一些问题?

答:

3赞 ephrion 11/15/2017 #1

Double是浮点数,而浮点数本质上是不准确的。 将执行精确的相等性检查,您可能需要“足够接近”的相等性检查。==

或者,您可以使用不同的数值类型,该数值类型可以 1) 具有固定精度(如 ,或 2) 无限内存使用以实现无限精度。科学是一个不错的选择,因为它是固定的。

评论

1赞 emmeowzing 11/15/2017
出于对 Haskell 新手的好奇,如果他要为 √2 编写一个表达式,它会通过评估该表达式来测试是否相等,还是“懒惰”地避免评估并看到一个表达式与另一个表达式相同?
1赞 ephrion 11/15/2017
@bjd2385 Haskell 并没有尝试基于生成 is 的表达式在项上实现相等。它将执行计算,然后检查是否相等。您可以定义一个表示算术表达式的数值类型,并将该类型的相等性定义为规范化表达式的相等性,但这不是:)的工作方式Double
0赞 E.Zanca 11/15/2017
啊哈,这就解释了。将每个 double 显式化为固定值可以解决问题。谢谢!