ソラマメブログ
プロフィール
ぺんぎん
ぺんぎん
どもっす( ◎v◎ )
ぺんぎんっす。

「ぺんぎんさん」でいいっす。
「ぺんさん」でもOKっすよ。
何だって良いんっすけどね。
[個体名:Naoya Bellic]
(非商用)
読者登録
メールアドレスを入力して登録する事で、このブログの新着エントリーをメールでお届けいたします。解除は→こちら
現在の読者数 1人

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);
  }
}


相変わらず見にくいっすね・・・
中身重視ということで、ひとつ・・・
[使い方]
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でも何とかなりそうっす。
「無理やり何とかした」感は否めないっすけど・・・


同じカテゴリー(スクリプト)の記事画像
位置判定っす
同じカテゴリー(スクリプト)の記事
 久しぶりの新関数っす (2011-04-23 23:19)
 11日(土)のオフィスアワーっす (2010-12-10 23:49)
 C#プロジェクトは凍結みたいっす (2010-07-01 22:35)
 4月24日のスクリプターズ・カフェっす (2010-04-27 19:06)
 潜入!1.38サーバーっす (2010-03-09 22:25)
 風の観測で分かったことっす (2009-08-16 22:11)

Posted by ぺんぎん at 00:40│Comments(0)スクリプト
上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。