比较Java和matlab中的Mersenne Twister算法

5
我在比较Java和Matlab中的Mersenne Twister(梅森旋转算法),并使用相同的种子。但问题是,当我从两个数值生成器(在Java和Matlab中运行的Mersenne Twister)中打印出十个数字时,生成的输出似乎不匹配。 Matlab版本的输出数据会跳过Java程序中的每隔一个数字。
Java的输出为: 0.417、0.997、0.720、0.932、0.0001..
Matlab的输出为: 0.417、0.720、0.0001..
请问有谁能指导我如何找出原因呢?
Java:
public class TestRand {
    static MersenneTwister r = new MersenneTwister(1);

    public static void main(String[] args) {

        int ant = 10;
        float[] randt = new float[ant];

        for (int i = 0; i < ant; i++){
            randt[i] = r.nextFloat()*1;
            System.out.println(randt[i]);    
        }
        System.out.println("------------twist");
    }
}

Matlab:

s = RandStream('twister','Seed',1)
RandStream.setGlobalStream(s);

r = 1 .* rand(1,10);

我正在使用MatLab中的Mersenne Twister标准实现,我使用的Java版本可以在这里找到:这里

你从哪里获取了Java的实现? - Denis Tulskiy
1
Mersenne Twister 有32位和64位的变体,它们会产生不同的数列 - 或许 Java 使用其中一个变体而 Matlab 使用另一个变体? - DNA
抱歉,在最初的帖子中我好像忽略了那个信息。现在已经更新了。Java版本可以从这里获取。 - user2072220
我猜这可能与算法的不同实现有关。最好的解决方案是联系Java类的作者(http://www.cs.gmu.edu/~sean/research/)或联系Mathworks,因为他们实现随机数生成器的确切细节可能不对公众开放。 - slayton
1
请注意,Java代码仅生成单精度值,因此每个生成的值只需要24位随机流。 我猜测Java代码中的每个样本使用从MT生成的下一个32位值,而Matlab中每个(可能是双精度)值由两个连续的32位MT值构成。 - Mark Dickinson
我可以确认所呈现的输出与64位MATLAB 2012b生成的相符。有人能否尝试32位版本? - Dennis Jaheruddin
1个回答

2
Matlab中的rand()函数返回的是64位double类型的值。但是你正在调用Java中MersenneTwister的nextFloat()函数来获取32位值。请检查Java源代码- nextDouble函数使用了两倍于nextFloat的随机性,需要调用两次next()函数。将TestRand Java代码中的nextFloat()替换为nextDouble(),你的结果应该会更加准确。

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