|
長周期の擬似乱数生成手法とメルセンヌ・ツイスタの無駄知識(?)の紹介は別のページにあります. 簡易な長周期擬似乱数の合成手法 知らなくても不都合は無いメルセンヌ・ツイスタの知識
オマケとしてページ末尾で32bit/64bit xorshift向けのレジスタ初期値(seed)生成プログラムをご紹介しています.
(2023.1.8 初期値生成に使っているM系列信号を性質の良いものに変えました)
特性の良い xorshift のパラメータ (a, b, c) |
視覚的に xorshift の特性の違いが分かるサンプル・プログラム |
/' (c) 2021 cepstrum.co.jp '/
' FreeBASIC GUI program
' >fbc -s gui
'--------------------------------------------------------------------------
' xorshift random number generator
function uint_xorshift(a as uinteger, b as uinteger, c as uinteger) as uinteger<32>
static r as uinteger<32> = &Hffffffff
r=r xor (r shl a)
r=r xor (r shr b)
r=r xor (r shl c)
return r
end function
'--------------------------------------------------------------------------
dim x as uinteger
dim y as uinteger
dim dotc as uinteger
dim a as uinteger = 5
dim b as uinteger = 17
dim c as uinteger = 13
dim shft as uinteger = 1
screenres 1024, 1024
sleep 300
while inkey$<>""
wend
while inkey$=""
x =(uint_xorshift(a, b, c) shr shft) mod 1024
y =(uint_xorshift(a, b, c) shr shft) mod 1024
dotc=(uint_xorshift(a, b, c) shr shft) mod 64
line (x, y)-(x, y), dotc
wend
メルセンヌ・ツイスタ(MT19937)が大きすぎて使えないというのなら、TinyMTを使えば良いのに |
40年前の論文の指摘 |
『良いパラメータ』の意味 |
M系列信号の常識・M系列信号を使っている人の常識 |
32bit/64bit xorshift向けのレジスタ初期値(seed)生成プログラム |
/* (c) 2023 cepstrum.co.jp */ #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> //----------------------------------------------------------------- // M-sequence generater, return value = 0/1 unsigned mseq16bit(unsigned seed) { static uint16_t reg16bit=0x5a5a; uint16_t msb; unsigned char b0, b2, b3, b5; if (seed!=0) reg16bit=seed&0xffff; // change seed value b0=reg16bit&0x1; b2=(reg16bit>>2)&0x1; b3=(reg16bit>>3)&0x1; b5=(reg16bit>>5)&0x1; msb=(b0^b2^b3^b5)&0x1; reg16bit=(reg16bit>>1)&0x7fff; reg16bit=reg16bit|(msb<<15); return msb; } //----------------------------------------------------------------- // generate 32bit seed (register initial value) for 32bit xorshift uint32_t gen32bit_seed(unsigned mseq_seed) { uint32_t seed; unsigned i; mseq16bit(mseq_seed); // set M-sequence seed seed=0; for (i=0; i<16; i=i+1) mseq16bit(0); for (i=0; i<16; i=i+1) seed=(seed<<1)|mseq16bit(0); for (i=0; i<16; i=i+1) mseq16bit(0); for (i=0; i<16; i=i+1) seed=(seed<<1)|mseq16bit(0); return seed; } //----------------------------------------------------------------- // generate 64bit seed (register initial value) for 64bit xorshift uint64_t gen64bit_seed(unsigned mseq_seed) { uint64_t seed; unsigned i; mseq16bit(mseq_seed); // set M-sequence seed seed=0; for (i=0; i<16; i=i+1) mseq16bit(0); for (i=0; i<16; i=i+1) seed=(seed<<1)|mseq16bit(0); for (i=0; i<16; i=i+1) mseq16bit(0); for (i=0; i<16; i=i+1) seed=(seed<<1)|mseq16bit(0); for (i=0; i<16; i=i+1) mseq16bit(0); for (i=0; i<16; i=i+1) seed=(seed<<1)|mseq16bit(0); for (i=0; i<16; i=i+1) mseq16bit(0); for (i=0; i<16; i=i+1) seed=(seed<<1)|mseq16bit(0); return seed; } //----------------------------------------------------------------- // test gen32bit_seed() function int main() { int i; int iteration=20; for (i=0; i<iteration; i=i+1) printf("A %3i %#010x\n", i, gen32bit_seed(0)); for (i=0; i<iteration; i=i+1) printf("B %3i %#010x\n", i, gen32bit_seed(i+1)); gen32bit_seed(123456); // set new M-sequence seed for (i=0; i<iteration; i=i+1) printf("C %3i %#010x\n", i, gen32bit_seed(0)); gen32bit_seed(time(NULL)&0xffff); // set new M-sequence seed for (i=0; i<iteration; i=i+1) printf("D %3i %#010x\n", i, gen32bit_seed(0)); /* for (i=0; i<iteration; i=i+1) printf("a %3i %10u\n", i, gen32bit_seed(0)); for (i=0; i<iteration; i=i+1) printf("b %3i %10u\n", i, gen32bit_seed(i+1)); gen32bit_seed(123456); // set new M-sequence seed for (i=0; i<iteration; i=i+1) printf("c %3i %10u\n", i, gen32bit_seed(0)); gen32bit_seed(time(NULL)&0xffff); // set new M-sequence seed for (i=0; i<iteration; i=i+1) printf("d %3i %10u\n", i, gen32bit_seed(0)); */ }
A 0 0x07e002b6 A 1 0xbad8c213 A 2 0x535dc645 A 3 0x4f9219fe A 4 0x071adb05 A 5 0x7c50eef1 A 6 0xf4c69145 A 7 0x8329dc05 A 8 0x14309aa3 A 9 0x2b1a36ed A 10 0xaa94f6ce A 11 0x2167f0f3 A 12 0x1b112949 A 13 0x90211f37 A 14 0xf8da28df A 15 0xdb1bc05b A 16 0x786e5c43 A 17 0x0b74b17f A 18 0x0c6977ce A 19 0x864d4450 B 0 0x045113d3 B 1 0x822889e9 B 2 0x86799a3a B 3 0x45455727 B 4 0x411444f4 B 5 0xc76ddece B 6 0xc33ccd1d B 7 0x26f33840 B 8 0x22a22b93 B 9 0xa4dbb1a9 B 10 0xa08aa27a B 11 0x63b66f67 B 12 0x67e77cb4 B 13 0xe19ee68e B 14 0xe5cff55d B 15 0x13791c20 B 16 0x17280ff3 B 17 0x915195c9 B 18 0x9500861a B 19 0x563c4b07 C 0 0x62c6e599 C 1 0x7b9844fd C 2 0x87cb24d6 C 3 0x08375b24 C 4 0x64cd2e6b C 5 0xfd68d0c5 C 6 0xf3c72124 C 7 0xd0dc9a24 C 8 0x41cf1321 C 9 0xdfb20298 C 10 0xd867da15 C 11 0x551c33f6 C 12 0x52cbe3d8 C 13 0x90fe59a4 C 14 0x7386b332 C 15 0x0d7454f2 C 16 0xdf4bd7d9 C 17 0x76068ca7 C 18 0xe47f4312 C 19 0xfcd45541 D 0 0x0de90ead D 1 0xf2856c55 D 2 0xd13e75bc D 3 0x677b22ba D 4 0x980b3692 D 5 0x62615ac4 D 6 0xaaba4791 D 7 0x396173d3 D 8 0xeea227e5 D 9 0x6a0754c5 D 10 0x7a7baf34 D 11 0x86d83c82 D 12 0xbdd97272 D 13 0x00a88064 D 14 0x1a6d907c D 15 0xf3b2ef70 D 16 0x0ea3c22a D 17 0x80bd5240 D 18 0xcaf31694 D 19 0x14efdc30
mseq_seed gen32bit_seed(mseq_seed) ----------------------------------- 0x0001 0x045113d3 0x0002 0x822889e9 0x0004 0x45455727 0x0008 0x26f33840 0x0010 0x13791c20 0x0020 0x8ded9dc3 0x0040 0x46f64ee1 0x0080 0xa37ba770 0x0100 0x51bdd3b8 0x0200 0x28dee9dc 0x0400 0x146ff4ee 0x0800 0x8a377a77 0x1000 0x451b3d3b 0x2000 0x228d9e9d 0x4000 0x11464f4e 0x8000 0x08a327a7
|
|
|