Skip to content

Instantly share code, notes, and snippets.

@kaz

kaz/MT.pl

Created Jun 29, 2016
Embed
What would you like to do?
MersenneTwister
use strict;
# MT19937
my $w = 32;
my $n = 624;
my $m = 397;
my $r = 31;
my $u = 11;
my $s = 7;
my $t = 15;
my $l = 18;
my $a = 0x9908B0DF;
my $b = 0x9D2C5680;
my $c = 0xEFC60000;
# MT内部状態
my $i = 0;
my @x = ();
# ビットマスクの準備
my $mask_u = 0;
my $mask_l = 0;
for(my $j = 0; $j < $w; $j++){
$mask_u = ($mask_u << 1) + ($j < $w - $r);
$mask_l = ($mask_l << 1) + ($j >= $w - $r);
}
# seedを受け取ってxを初期化 (mt19937ar.cに準拠)
sub init_genrand {
my($seed) = @_;
$x[0] = $seed & 0xFFFFFFFF;
for(my $j = 1; $j < $n; $j++){
$x[$j] = (1812433253 * ($x[$j-1] ^ ($x[$j-1] >> 30)) + $j) & 0xFFFFFFFF;
}
}
# 乱数を生成
sub genrand_int {
# Step.1
my $z = ($x[$i] & $mask_u | $x[($i+1) % $n] & $mask_l);
# Step.2
$x[$i] = $x[($i+$m) % $n] ^ ($z >> 1) ^ (($z & 1) == 0 ? 0 : $a);
# Step.3
my $y = $x[$i];
$y = $y ^ ($y >> $u);
$y = $y ^ (($y << $s) & $b);
$y = $y ^ (($y << $t) & $c);
$y = $y ^ ($y >> $l);
# カウンタを変更して、生成した乱数を返す
$i = ($i+1) % $n;
return $y;
}
# 使ってみる
init_genrand(20150919);
for(my $j = 1; $j <= 1024; $j++){
print $j, ": ", genrand_int(), "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment