函数不能处理大的n值(接近400) [英] function cannot handle big values of n (close to 400)

查看:96
本文介绍了函数不能处理大的n值(接近400)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是来自统计项目。我定义了下面的函数,但是当n增长到接近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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆