しかし、ことモンテカルロ法においては主に収束速度を早める目的として、擬似乱数ではなく低食い違い量列(Low-Discrepancy Sequence, LDS)と呼ばれる数列が用いられる場合がある。これを用いると低次元での積分計算の際に収束速度を大きく改善することができ、具体的には従来のモンテカルロ法で(1/√N)だった収束速度が約(1/N)くらいにまで落とすことができる。
さて、このような低食い違い量列をBoost.Randomで用いるためにはエンジン部分を製作すればいいだけで、実際には以下のような形で実装すれば良い。今回は簡単なHalton列を用いて実装を行った:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <boost/cstdint.hpp> | |
#include <boost/config.hpp> | |
#include <cmath> | |
namespace aoba { | |
struct halton_sequence_engine { | |
public: | |
typedef double result_type; | |
halton_sequence_engine(): m_index(1), m_base(2) {} | |
halton_sequence_engine(uint32_t index): m_index(index), m_base(2) {} | |
halton_sequence_engine(uint32_t index, uint32_t base) | |
: m_index(index), m_base(base) {} | |
result_type operator()() { | |
result_type result = 0; | |
result_type f = 1 / static_cast<result_type>(m_base); | |
uint32_t i = m_index; | |
while(i > 0) { | |
const uint32_t div_i_base = i / m_base; | |
const uint32_t mod_i_base = i % m_base; | |
result = result + f*mod_i_base; | |
i = div_i_base; | |
f = f / m_base; | |
} | |
++m_index; | |
return result; | |
} | |
void seed(uint32_t index) { m_index = index; } | |
static result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; } | |
static result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return 1; } | |
private: | |
uint32_t m_index; | |
uint32_t m_base; | |
}; | |
} // namespace aoba |
- X::result_typeにoperator()が返す型を指定
- operator()にエンジン部分を記述
- min(), max()にエンジンが生成する分布の最小値、最大値を指定
さらに、対象のファンクタが上述の内容に加えPseudo-Random Number Generatorのコンセプトを満たすためには:
するだけで良い。後はBoost側が良きに計らってくれる。非常に便利だと思う。- X()にデフォルトの状態で生成されるようなコンストラクタを指定
- X(...)にユーザ指定の状態で生成されるコンストラクタを指定
- seed(...)にエンジンの状態を変更するためのメンバ関数を指定
余談
C++0xには同等のstd::randomが付属しているため、これを利用すればいいのではという声もあるとは思うが、std::uniform_real_distribution<>にこのLDSを食わせたところ、どうみてもLDSではない値が出力される結果となった。恐らくresult_typeがdoubleという一般の擬似乱数ではない型を指定しているために起こる現象だと思うが、ソースを見ていないので一先ずは従来のBoost.Randomの手法を用いることにする。
3 件のコメント:
昔のエントリーで大変恐縮なのですが、2008/06/07付の『ランダムフォレスト(Random Forest)法を用いて株価予測を行ってみた。-03 』にて、「でも結局『なんだかんだやっても予測はできない』で終わらせるのは正直微妙なので、ちょっとあるデータを加工して再び解析を行ってみたら、今度はけっこうおもしろい結果が出るようになりました。でももうこれ以上書いてしまうと長くなってくるので、続きは次回」とおっしゃておりましたが、その後のエントリーをツブサに見ても、当該のエントリーが見つかりませんでした。もの凄く気になるのでいつのエントリーに続きが書いてあるか教えていただけますでしょうか?
コメントが遅くなってしまい申し訳ありません。
該当の記事ですが、もう少し温めてからきちんとした形で公開しようとしていたらいつの間にか時間が立ってしまいました。気になるような書き方をしてしまい、その点についてもお詫び申し上げます。
しかしながら、自分が言う「面白い結果」というのは非常に些細なもので、一介の理系の大学生が気づいたという程度のことは恐らく他の方々も容易に気づいているものです。
結局は既に現在の価格の中に織り込まれているものと予想されますし、
正直なところ今からきちんとした研究をしてそれなりの結果が出たとしても、
現状の自分としてのメリットはあまりないので書く気にはならないのです。すみません。
わざわざご丁寧な返信をいただきまして、どうもありがとうございます。気が付かなかったため、1か月近くもお礼が遅れてしまいました。申し訳ありません。
コメントを投稿