Haskell矩阵相等性失败

5
我正在尝试使用Haskell来实现一些量子转换矩阵的功能。我设计了一个用于测试方阵是否为酉矩阵的函数,该函数通过构建逆矩阵和伴随矩阵然后进行测试来实现。
下面是该函数的代码,其中wrap是一个简单的函数,用于测试从inverse返回的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) )

什么可能导致第二组矩阵的等式测试失败?在代码中,有更正确的方法来表示复数吗?

2
一个可能的原因是浮点数算术可能存在一些问题,因为误差会积累起来。 - Agnishom Chattopadhyay
1个回答

3

Double 是浮点数,而浮点数本身就不太准确。使用 == 进行精确的等于判断时,你可能需要一个“足够接近”的相等判断。

另外,你可以使用不同的数字类型,这些类型要么 1) 具有固定精度(例如 fixed),要么 2) 具有无限精度的内存使用(例如 scientific)。scientific 是一个不错的选择,fixed 也是一种选择。


1
作为一个对 Haskell 感到好奇的新手,如果他要写一个关于 √2 的表达式,那么它会通过计算该表达式来测试相等性,还是“懒惰地”避免计算并看到其中一个与另一个相同的表达式? - bjd2385
1
@bjd2385 Haskell在对项进行相等性比较时,并不基于生成表达式。它会执行计算,然后检查相等性。你可以定义一个表示算术表达式的数字类型,并在该类型上定义相等性为规范化表达式的相等性,但这并不适用于Double类型 :) - ephrion
啊哈,这就解释了。将每个double显式地转换为fixed可以解决问题。谢谢! - E.Zanca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接