2009年02月23日
MT19937っす
「メルセンヌ・ツイスター」ってカッコイイ名前っすね。
周期219937-1の長周期な疑似乱数っす。
どうもぺんぎんっす( ◎v◎ )
SFMTではなく、MT19937っす。
ライセンスは元となったCのコードと同じく修正BSDライセンスっす。
説明は[続きを読む]で開くっす。
コードは半角スペース4つ→全角スペース2つになってるっす。
////////////////
// MT19937 -LSL-
/////////////////
// A C-program for MT19937, with initialization improved 2002/2/10.
// Coded by Takuji Nishimura and Makoto Matsumoto.
// This is a faster version by taking Shawn Cokus's optimization,
// Matthe Bellew's simplification, Isaku Wada's real version.
// A LSL for MT19937 coded by Naoya Bellic.
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
// All rights reserved.
// Copyright (c) 2009, Naoya Bellic
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. The names of its contributors may not be used to endorse or promote
// products derived from this software without specific prior written
// permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//////////////////
//----------
// グローバル変数 for MT19937
//----------
list lst_state; // state[]
integer pt_next; // *next
integer left = 1; // next_stateへの移行用カウンター
integer initf = FALSE;
//----------
// ユーザ関数 for MT19937
//----------
init_genrand(integer s) // initializes lst_state with a seed
{
integer j;
integer pt_j = s;
lst_state = [pt_j];
for(j = 1; j < 624; j++) // N = 624
{
lst_state += pt_j = 1812433253 * (pt_j ^ ((pt_j >> 30) & 0xfffffffc)) + j;
}
left = 1;
initf = TRUE;
}
integer twist(integer u, integer v) // MIXBIT and TWIST
{
if(v & 0x1)
{
return (((((u & 0x80000000) | (v & 0x7fffffff)) >> 1) & 0x7fffffff) ^ 0x9908b0df);
}
else
{
return ((((u & 0x80000000) | (v & 0x7fffffff)) >> 1) & 0x7fffffff);
}
}
next_state()
{
integer pt_p; // *p = state;
integer j;
list z = []; // 結果を一時的に保管
// if init_genrand() has not been called,
// a default initial seed is used
if(initf == FALSE)
{
init_genrand(5489);
}
left = 624; // N = 624
pt_next = 0;
for(j = 228; --j; pt_p++) // N-M+1 = 624-397+1 = 228
{
z += llList2Integer(lst_state, pt_p + 397) ^ twist(llList2Integer(lst_state, pt_p), llList2Integer(lst_state, pt_p + 1)); // M = 397
}
for(j = 397; --j; pt_p++) // M = 397
{
z += llList2Integer(lst_state, pt_p - 227) ^ twist(llList2Integer(lst_state, pt_p), llList2Integer(lst_state, pt_p + 1)); // N-M = 227
}
z += llList2Integer(lst_state, pt_p - 227) ^ twist(llList2Integer(lst_state, pt_p), llList2Integer(lst_state, 0));
lst_state = z; // 結果を置き換え
}
integer genrand_int32()
{
integer y;
if(--left == 0)
{
next_state();
}
y = llList2Integer(lst_state, pt_next++);
// Temparing
y = y ^ ((y >> 11) & 0x001fffff);
y = y ^ (y << 7) & 0x9d2c5680;
y = y ^ (y << 15) & 0xefc60000;
y = y ^ ((y >> 18) & 0x00003fff);
return y;
}
//************
// state default
//************
default
{
state_entry()
{
init_genrand(1234); // seed:1234
}
touch_start(integer total_number)
{
// test
integer i;
float time;
llResetTime();
for(i = 0; i < 10000; i++)
{
genrand_int32();
}
time = llGetTime();
llSay(0, (string)time);
}
}
相変わらず見にくいっすね・・・
中身重視ということで、ひとつ・・・
周期219937-1の長周期な疑似乱数っす。
どうもぺんぎんっす( ◎v◎ )
SFMTではなく、MT19937っす。
ライセンスは元となったCのコードと同じく修正BSDライセンスっす。
説明は[続きを読む]で開くっす。
コードは半角スペース4つ→全角スペース2つになってるっす。
////////////////
// MT19937 -LSL-
/////////////////
// A C-program for MT19937, with initialization improved 2002/2/10.
// Coded by Takuji Nishimura and Makoto Matsumoto.
// This is a faster version by taking Shawn Cokus's optimization,
// Matthe Bellew's simplification, Isaku Wada's real version.
// A LSL for MT19937 coded by Naoya Bellic.
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
// All rights reserved.
// Copyright (c) 2009, Naoya Bellic
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. The names of its contributors may not be used to endorse or promote
// products derived from this software without specific prior written
// permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//////////////////
//----------
// グローバル変数 for MT19937
//----------
list lst_state; // state[]
integer pt_next; // *next
integer left = 1; // next_stateへの移行用カウンター
integer initf = FALSE;
//----------
// ユーザ関数 for MT19937
//----------
init_genrand(integer s) // initializes lst_state with a seed
{
integer j;
integer pt_j = s;
lst_state = [pt_j];
for(j = 1; j < 624; j++) // N = 624
{
lst_state += pt_j = 1812433253 * (pt_j ^ ((pt_j >> 30) & 0xfffffffc)) + j;
}
left = 1;
initf = TRUE;
}
integer twist(integer u, integer v) // MIXBIT and TWIST
{
if(v & 0x1)
{
return (((((u & 0x80000000) | (v & 0x7fffffff)) >> 1) & 0x7fffffff) ^ 0x9908b0df);
}
else
{
return ((((u & 0x80000000) | (v & 0x7fffffff)) >> 1) & 0x7fffffff);
}
}
next_state()
{
integer pt_p; // *p = state;
integer j;
list z = []; // 結果を一時的に保管
// if init_genrand() has not been called,
// a default initial seed is used
if(initf == FALSE)
{
init_genrand(5489);
}
left = 624; // N = 624
pt_next = 0;
for(j = 228; --j; pt_p++) // N-M+1 = 624-397+1 = 228
{
z += llList2Integer(lst_state, pt_p + 397) ^ twist(llList2Integer(lst_state, pt_p), llList2Integer(lst_state, pt_p + 1)); // M = 397
}
for(j = 397; --j; pt_p++) // M = 397
{
z += llList2Integer(lst_state, pt_p - 227) ^ twist(llList2Integer(lst_state, pt_p), llList2Integer(lst_state, pt_p + 1)); // N-M = 227
}
z += llList2Integer(lst_state, pt_p - 227) ^ twist(llList2Integer(lst_state, pt_p), llList2Integer(lst_state, 0));
lst_state = z; // 結果を置き換え
}
integer genrand_int32()
{
integer y;
if(--left == 0)
{
next_state();
}
y = llList2Integer(lst_state, pt_next++);
// Temparing
y = y ^ ((y >> 11) & 0x001fffff);
y = y ^ (y << 7) & 0x9d2c5680;
y = y ^ (y << 15) & 0xefc60000;
y = y ^ ((y >> 18) & 0x00003fff);
return y;
}
//************
// state default
//************
default
{
state_entry()
{
init_genrand(1234); // seed:1234
}
touch_start(integer total_number)
{
// test
integer i;
float time;
llResetTime();
for(i = 0; i < 10000; i++)
{
genrand_int32();
}
time = llGetTime();
llSay(0, (string)time);
}
}
相変わらず見にくいっすね・・・
中身重視ということで、ひとつ・・・
[使い方]
init_genrandで初期化→genrand_int32で生成っす。
初期化を省略した場合、種5,489で初期化されるっす。
[性能]
バラツキは色々と解説ページがあるみたいなので省略っす。
速度は10,000個の生成に2.4[sec]ほどっす。
ちなみに速度は一様ではないっす。
関数next_stateが呼び出されると時間がかかるっす。
624個生成ごとっすね。
[コードについて補足]
各所に*stateっていうのが入ってるっす。
これは元のCで書かれたコードで使われている名前を
そのまま使っているためっす。
LSLだとちょっと気持ち悪いかもっすね。
関数next_stateではllListReplaceListを使ってないっす。
これは単純に遅くなったからっす。
list zで置き換えする場合と比較すると約2倍かかってたっす。
N,MはCのコードで使われている定数っす。(defineされてるっす)
LSLで書くにあたって、あらかじめ計算しておいたっす。
一応コメントは付けてあるっすから、元の式が分かるはずっす。
ポインタさえ何とかすれば、LSLでも何とかなりそうっす。
「無理やり何とかした」感は否めないっすけど・・・
init_genrandで初期化→genrand_int32で生成っす。
初期化を省略した場合、種5,489で初期化されるっす。
[性能]
バラツキは色々と解説ページがあるみたいなので省略っす。
速度は10,000個の生成に2.4[sec]ほどっす。
ちなみに速度は一様ではないっす。
関数next_stateが呼び出されると時間がかかるっす。
624個生成ごとっすね。
[コードについて補足]
各所に*stateっていうのが入ってるっす。
これは元のCで書かれたコードで使われている名前を
そのまま使っているためっす。
LSLだとちょっと気持ち悪いかもっすね。
関数next_stateではllListReplaceListを使ってないっす。
これは単純に遅くなったからっす。
list zで置き換えする場合と比較すると約2倍かかってたっす。
N,MはCのコードで使われている定数っす。(defineされてるっす)
LSLで書くにあたって、あらかじめ計算しておいたっす。
一応コメントは付けてあるっすから、元の式が分かるはずっす。
ポインタさえ何とかすれば、LSLでも何とかなりそうっす。
「無理やり何とかした」感は否めないっすけど・・・
Posted by ぺんぎん at 00:40│Comments(0)
│スクリプト