函数不能处理大的n值(接近400) [英] function cannot handle big values of n (close to 400)
问题描述
import Math.Combinatorics .Exact.Binomial - 来自`exact-combinatorics`包
probaMet :: [Integer] - >浮子>整数 - > Float
probaMet [i,j] p n = sum [(p ** fromInteral1)*(fromIntegral(n`select`l))*((1-p)** fromIngral(n-1) l< - [i,i + 1..j]]
indices :: [Int] - >浮子> Int - > [Int]
indices [] _ _ = [1,2]
indices [i,j] p n
| probaMet [toInteger i,toInteger j] p(toInteger n)> = beta = [i,j]
|否则= indices [(i-1),(j + 1)] pn
我应该用n = 500进行计算,所以任何帮助都会很大。这是发生了什么
Main> indexEstadisticos [24,25] 0.25 100
[24,25]
* Main> indexEstadisticos [24,25] 0.25 250
[19,30]
*主要> indexEstadisticos [24,25] 0.25 400
,完全改变我的答案:
你的问题是你正在使用 结果,你的总和变得太低了,在某些情况下这么低,以至于没有发现超过的间隔您的 如果使用双精度 附录:我再次想到,而我之前的推理还是有点偏离。问题还包括二项系数变得太大 Float
,它只有单浮点精度,并且已经 0.25 ** 100 :: Float
等于 0
,这意味着没有具有该高指数的项给这个总额的任何贡献。 0.75 == 1 - 0.25
会持续一段时间,但 0.75 ** 400 :: Float
也是<$ c
beta
,导致无限递归。
Double
代替,所有的测试用例都会运行,第二个测试用例会给出不同的答案。请注意,如果你进一步超过 500
,甚至 Double
开始给零。
[19,30]
时, probaMet
实际返回了 Infinity
值,而其他一些测试将太大或太小的测试结合起来,以致无法提供令人畏惧的 NaN
。不过,原因仍然是使用 Float
。
This is from a project for statistics. I defined the functions below, but the second is slow when n grows close to 400. The first method is fine (some people here have helped me in this question)
import Math.Combinatorics.Exact.Binomial -- from `exact-combinatorics` package
probaMet :: [Integer] -> Float-> Integer -> Float
probaMet [i,j] p n = sum [(p**fromIntegral l)*(fromIntegral(n `choose` l))*((1-p)**fromIntegral (n-l)) | l <- [i,i+1..j]]
indices :: [Int] -> Float-> Int -> [Int]
indices [] _ _ = [1,2]
indices [i,j] p n
| probaMet [toInteger i,toInteger j] p (toInteger n) >= beta = [i,j]
| otherwise = indices [(i-1),(j+1)] p n
I am supposed to make a computation with n=500, so any help would be great. This is what happens
Main> indexEstadisticos [24,25] 0.25 100
[24,25]
*Main> indexEstadisticos [24,25] 0.25 250
[19,30]
*Main> indexEstadisticos [24,25] 0.25 400
After a rethink, completely changing my answer:
Your problem is that you are using Float
, which only has single floating point precision, and already 0.25 ** 100 :: Float
is equal to 0
, which means no term with that high exponent will give any contribution to the sum. 0.75 == 1 - 0.25
lasts a little longer, but 0.75 ** 400 :: Float
is also 0
.
As a result, your sum becomes far too low, in some cases so low that no interval is found that exceeds your beta
, causing an infinite recursion.
If you use the double precision Double
instead, all your test cases will run, with the second one giving a different answer. Mind you, if you go just a little further above 500
, even Double
starts giving zeros.
Addendum: I thought again and my previous reasoning was still a bit off. The problem also involves the binomial coefficients becoming too large. When your original second case answered [19,30]
, probaMet
actually returned an Infinity
value, and some others tests combine both too large and too small to give the dreaded NaN
. The reason is still the use of Float
, though.
这篇关于函数不能处理大的n值(接近400)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!