Java中的数值计算

时间:2009-12-04 19:37:51

标签: java

好的,所以我正在尝试使用Apache Commons Math库来计算双积分,但它们都是从负无穷大(到1左右)并且需要花费很长时间来计算。在java中有没有其他方法可以执行此类操作?或者它应该“更快”运行(我的意思是我可以在我死前的某一天看到结果)并且我做错了什么?

编辑:好的,谢谢你的答案。至于我一直试图计算的是高斯Copula: alt text

所以我们有一个标准的双变量正态累积分布函数,它将两个反标准正态累积分布函数作为参数,我需要整数来计算(我知道有一个Apache Commons Math函数用于标准正态累积分布,但我找不到逆和双变量版本。)

EDIT2:正如我的朋友曾经说过的那样“啊,是的,Java的美丽,不管你想做什么,有人已经做过了”我在这里找到了我所需要的一切http://www.iro.umontreal.ca/~simardr/ssj/非常好的库概率等等。

4 个答案:

答案 0 :(得分:2)

无限积分存在两个问题:收敛和收敛值。也就是说,积分是否会收敛?如果是这样,它会收敛到什么价值?有积分可以保证收敛,但其值无法准确确定(尝试从1到无穷大的整数e ^( - x ^ 2))。如果无法准确返回,那么在数学上不可能得到精确的答案,这只留下近似值。 Apache Commons使用了几种不同的近似方案,但都需要使用有限边界来保证正确性。

获得适当答案的最佳方法是重复评估有限积分,并且不断增加界限,并比较结果。在伪代码中,它看起来像这样:

double DELTA = 10^-6//your error threshold here
double STEP_SIZE = 10.0;
double oldValue=Double.MAX_VALUE;
double newValue=oldValue;
double lowerBound=-10; //or whatever you want to start with--for (-infinity,1), I'd
                       //start with something like -10
double upperBound=1;

do{
     oldValue = newValue;

     lowerBound-= STEP_SIZE;
     newValue = integrate(lowerBound,upperBound); //perform your integration methods here
}while(Math.abs(newValue-oldValue)>DELTA);

最终,如果积分收敛,那么你将获得足够的重要内容,因为扩大界限将不会产生有意义的信息。

对明智的一句话:如果积分不收敛,这种事情可能是爆炸性的。在这种情况下,可能出现以下两种情况之一:您的终止条件永远不会满足并且您陷入无限循环,或者积分值无限期地围绕某个值振荡,这可能导致您的终止条件被错误地满足(给出结果不正确)。

要避免第一种,最好的方法是在返回之前加入一些最大步骤数 - 这样做可以阻止可能产生的无限循环。

为了避免第二次,希望它不会发生或证明积分必须收敛(微积分2的三个欢呼,任何人?; - ))。

要正式回答你的问题,不,没有其他这样的方法可以在java中执行你的计算。事实上,使用任何算法,任何语言都无法保证这样做 - 数学只是不按我们想要的方式运行。然而,在实践中,实际积分的很多(尽管并非全部!)确实会收敛;根据我的经验,只有大约20次迭代会给你一个合理准确度的近似值,而Apache应该足够快地处理它而不需要花费太长时间。

答案 1 :(得分:2)

假设你将f(x)over -infinity积分为1,然后用x = 2 - 1 /(1-t)代替,并在0到1的范围内进行求值。注意检查数学文本是如何做的在这里,我有点生疏,而且太晚了。

答案 2 :(得分:1)

数值积分的结果,其中一个边界是无穷大,也很有可能成为无穷大。并且需要无限的时间来证明它;)

因此,您要么找到可以计算的等效公式(使用真实数学),要么用合理的大负值替换下限,看看是否可以得到积分的良好估计。

如果Apache Commons Math可以在有限时间内对具有无限边界的积分进行数值积分,那么它们就不会免费赠送; - )

答案 3 :(得分:0)

也许这是你的算法。

如果你像辛普森那样做一些天真的事情,可能需要很长时间。

如果你使用高斯或对数正交,你可能会有更好的运气。

您尝试整合的功能是什么,以及您使用的算法是什么?

相关问题