haskell双精度下溢带repa

haskell双精度下溢带repa,haskell,double-precision,quickcheck,repa,Haskell,Double Precision,Quickcheck,Repa,我用repa写了一些: distance :: Int -> Int -> Mat -> Double distance aindx bindx arr = let a = slice arr (Any :. aindx :. All) b = slice arr (Any :. bindx :. All)- sqdiff = R.map (\x ->

我用repa写了一些:

distance :: Int -> Int -> Mat -> Double
distance aindx bindx arr = let a = slice arr (Any :. aindx :. All)
                               b = slice arr (Any :. bindx :. All)-
                               sqdiff = R.map (\x -> x*x) $ R.zipWith (-) a b 
                            in sqrt $ sumAllS sqdiff

buildDistanceMatrix :: Mat -> Mat 
buildDistanceMatrix m = let (Z :. height :. width) = R.extent m
                            cords = fromListUnboxed (Z :. (height * height) )  [ (x,y) | x <- [0..height-1], y <- [0..height-1]]
                            dist = R.smap (\(a,b) -> distance a b m) cords
                            dmat = R.reshape (Z :. height  :. height ) dist
                         in R.computeS dmat
换句话说,由距离D分隔的两个点应生成一个类似于[0,D,D,0]的距离矩阵。在我的临时手动测试中,确实如此。但是QuickCheck很快发现5.0e-324的距离会产生[0,0,0,0]的距离矩阵

distance matrix  *** Failed! Falsifiable (after 2 tests and 1074 shrinks):    
5.0e-324

这仅仅是因为双打的精确性吗?我是否需要钳制QuickCheck将发送的可能值?或者这是一个真正的错误?

您正在测试浮点数是否相等,通常应该避免这种情况(在任何语言中,这都不是Haskell特有的)。你也会得到一个溢出到无穷大的大倍。而且
sqrt(x*x)==x
通常不适用于那些没有溢出或下溢的双打。因此,您需要用一个检查来替换
==
,以确保差异最多是一些合理的ε,并限制可能的值(或检查属性中的溢出)。

您正在测试浮点数是否相等,这通常应该避免(在任何语言中,这不是Haskell特有的)。你也会得到一个溢出到无穷大的大倍。而且
sqrt(x*x)==x
通常不适用于那些没有溢出或下溢的双打。因此,您需要用一个检查来替换
==
,以确保差值至多是某个合理的ε,并限制可能的值(或检查属性中是否存在溢出)。

在应用平方根函数之前很久,天真地计算向量的L2范数可能会给出欠流或过流。我引用一位知情人士的话:“Fortran中两个范数的最健壮的计算有200多行代码,但那是25年前的事了。”。我建议搜索Fortran实现,然后利用可能出现错误的知识将其应用到Haskell实现中。数字运算很复杂;好消息是,大多数问题可能都在50年前用Fortran解决了。

在应用平方根函数之前很久,天真地计算向量的L2范数就可以给出欠流或过流。我引用一位知情人士的话:“Fortran中两个范数的最健壮的计算有200多行代码,但那是25年前的事了。”。我建议搜索Fortran实现,然后利用可能出现错误的知识将其应用到Haskell实现中。数字运算很复杂;好消息是,大多数问题可能都在大约50年前用Fortran解决了。

sqrt(x*x)==x中的溢出也称为中间溢出,其中
x
低于最大可表示值,但
x*x
溢出。当然!非常感谢。关于如何钳制QuickCheck发送的值,您可以分享一些线索吗?有两个选项:1。向属性添加一个前提条件,例如
x
2。通过自己的
gendouble
而不是
arbitral
生成的。有时确实需要测试浮点相等性,例如,在计算二项式pdf时,概率为浮点0。@DominicSteinitz这就是我说“一般”的原因。
sqrt(x*x)中的溢出==x
aka中间溢出,其中
x
低于最大可表示值,但
x*x
溢出。当然!非常感谢。关于如何钳制QuickCheck发送的值,您可以分享一些线索吗?有两个选项:1。向属性添加一个前提条件,例如
x
2。传递您自己的
gendouble
而不是由
arbitral
生成的。有时确实需要测试浮点相等性,例如,在计算二项式pdf时,概率为浮点0。@DominicSteinitz这就是我说“一般”的原因。很高兴知道。我对数字有点陌生——我甚至不知道我所做的被称为“L2规范”很好。我对数字有点陌生——我甚至不知道我所做的被称为“L2标准”
distance matrix  *** Failed! Falsifiable (after 2 tests and 1074 shrinks):    
5.0e-324