在Java中计算多元正态分布函数的累积分布值

7
有没有人知道一个可靠、准确的库,可以在Java中计算多元正态(MVN)CDF?我需要像MATLAB的mvncdf函数这样的东西。我需要能够处理高达10个或更多维度。大多数统计/数学库都没有这个功能。能够计算对数概率是一个优点。
这篇文章中,似乎没有提到其他语言的免费实现。虽然直接的Java实现会很好,但我也接受其他语言的实现,这些实现不需要许可证(例如不是MATLAB或IMSL),并且可以在Java中轻松调用,开销最小。
(这个问题是从StackExchange math上的一篇帖子派生出来的,在那里我试图计算正态随机变量的排序概率...如果你有兴趣尝试使用其他数学方法直接解决这个问题,请去看看。)
2个回答

6
经过进一步研究,似乎以下是最合理的方法。
多元正态分布函数不容易计算(特别是对于大维数),已经有几篇学术论文写在这个主题上。Alan Genz教授有一堆Fortran-77子程序,可以计算各种多元密度和CDF,在他的页面上提供下载:http://www.math.wsu.edu/faculty/genz/software/software.html 从代码中可以看出,在另一种语言中重新实现并不容易,这也可能是为什么没有人这样做,除非有人付钱。大量的数学/数值编程是在研究领域用Fortran完成的,因此大多数最好的代码都在那里。
因此,为了获得最佳结果,最好直接使用JNI或JNA调用(本地编译的)Fortran子程序。 JNA似乎是最容易实现的,按照这些说明操作即可:http://www.javaforge.com/wiki/66061。使用它和其他参考资料,我已经实现了Java-JNA-Fortran链接,以便调用MVNEXP(期望值)和MVNDST(cdf)子例程。您可以在这里查看代码: 另外需要指出的是:对于一些双变量分布和其他在commons math中找不到的内容,存在本地Java代码;它是从上述源代码进行调整的:http://www.iro.umontreal.ca/~simardr/ssj/indexe.html。这是一个非常好的数学库,我直到现在才发现它。

如果您可以用R完成所需的工作,那么您可能可以使用http://www.rforge.net/JRI/从Java中调用R。 - GreyBeardedGeek
以上的R实现只是在调用原始的Fortran代码。我知道有几种从Java调用R的方法;它有点慢,除非你只需要使用一两次,否则不建议使用。 - Andrew Mao
1
如果你想要一个纯Java的解决方案,请尝试使用f2j(Fortran to Java)编译器:http://icl.cs.utk.edu/f2j/;除了一些小麻烦(比如数组从“1”开始而不是“0”),我发现它所生成的代码相当可用(例如这个minpack库:http://www1.fpl.fs.fed.us/optimization/LmderTest_f77.html)。如果你转换成功了,我会感兴趣的。 - Matt S.
@MattS. 看起来非常有前途,如果他们能够转换大部分的BLAS和LAPACK。如果我继续追求这个领域,我一定会去看看。你应该考虑将你的评论发布为答案;我会点赞的,我认为这对其他寻找类似信息的人也很有帮助。 - Andrew Mao
我正在寻找一个Scala的多元正态累积分布函数,但是Java也可以。我该如何使用你的代码?我能直接使用你的github文件吗?我需要那些Fortran文件,对吧?你能给我一些使用指南吗?你的github文档不是很详尽。谢谢。 - Make42

1
补充OP的解决方案(例如,最佳选择是Fortran代码,没有其他可行的方案),将纯Java库转换为f2j编译器(Fortran to Java)http://icl.cs.utk.edu/f2j。我发现它生成的代码相当可行(例如,像这个minpack库:http://www1.fpl.fs.fed.us/optimization/LmderTest_f77.html)。唯一的烦恼是数组从“1”开始而不是“0”,但可以使用简单的包装函数轻松处理(如果您关心的话)。@Andrew: 如果您转换它,我会很感兴趣!

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