2009年2月28日土曜日

swig boost_random クリア!

 全部、クリアしました。という訳で、再度、告知します。


 gcc の typeinfo が返すアホな名前ですが、最終的には、std::map<std::string,std::string> によりマッピングを作成しておいて正しい名前に変換するという手法でクリアしました。これなら、どのコンパイラもクリアだと思いたい。

 cmake の TRY_RUN の挙動ですが、コンパイラ・オプションは別途指定しなければならないようです。"-I /usr/local/include/boost_1_38" というような追加情報は、COMPILE_DEFINITIONS に指定しなければなりませんでした。windows 上では環境変数 include に boost も指定していたので windows 上のみ作動していたという訳でした。

追伸:
 ツンデレのお題、俺、体育会系だし、わかんねーよ(Don't think, type. by BRUCE LEE 2nd)。
と思っていたのですが、typeid の返す名前をツンして、
  • gcc : typename コンバータ使ってね
  • msvc : 完璧ね
とデレするパターンを朝に閃きました。でも、こっちに夢中で時間切れとなりますた。

2009年2月27日金曜日

swig boost_random どないせーちゅーねん

 ニュートン法というのをご存知だろうか?解を求めるのに反復しながら近づくというものだ。このニュートン法のように、今日は windows (msvc) と ubuntu (gcc) を何度も往来した。

 まず、cmake の挙動が違う。TRY_RUN が windows 上では、うまく動作するのに、ubuntu 上ではエラーを吐いて止まる。

 次に、gcc_primitive_type_name_hack 中の int の扱いではまる。まさにニュートン法で発散する状況だ。msvc では、long 扱いでないと、boost::random のコンストラクタが動作しないものが出てくる。gcc では、その逆で int 扱いでないと、boost::random のコンストラクタが動作しないものが出てくる。困った事に sizeof(int) == sizeof(long) だ。だ。だ。だ。だ。だだだだだだだだだだだだだ。

 お願いだ、primitive type に関しては、typeinfo は、ちゃんとした名前を返してくれ~

2009年2月26日木曜日

swig boost_random gcc の typeinfo

 えー、ubuntu 上でも動作するようになりました。プリプロセッサだけでなく、gcc の typeid にもやられてました。しょうがないので、こんな関数を作って、お茶を濁すことに…。

const char* gcc_primitive_type_name_hack( size_t primitive_size, bool is_signed, bool is_modulo ) {
// std::cout << typeid( int ).name();
// i
// ... to be haniwa. (O o O)
if( !is_modulo ) {
if( primitive_size == sizeof(double) ) return "double";
else if( primitive_size == sizeof(float) ) return "float";
else if( primitive_size == sizeof(long double) ) return "long double";
} else {
if( is_signed ) {
if( primitive_size == sizeof(char) ) return "char";
else if( primitive_size == sizeof(int) ) return "int";
else if( primitive_size == sizeof(short) ) return "short";
else if( primitive_size == sizeof(long) ) return "long";
else if( primitive_size == sizeof(long long) ) return "long long";
} else {
if( primitive_size == sizeof(char) ) return "unsigned char";
else if( primitive_size == sizeof(int) ) return "unsigned int";
else if( primitive_size == sizeof(short) ) return "unsigned short";
else if( primitive_size == sizeof(long) ) return "unsigned long";
else if( primitive_size == sizeof(long long) ) return "unsigned long long";
}
}
return "unknown";
}

swig boost_random 移植性は難しい

 今度こそ、コンパイルも通るだろ…と思ったら、家の ubuntu 環境では、またもエラーになってしまった。その原因は、型のズレによるもの。よくよく考えたら、random_class_generator.cpp を作成したのは、プラットフォーム間の違いにより生じるソースの違いを動的に吸収しようと思っての事だったので、ubuntu 上でも random_class_generator.cpp からコンパイルして実行する事にした。

 コンパイルしてみると、preprocessor の部分で引っかかった。

BOOST_PP_CAT( "hoge_", BOOST_PP_STRINGIZE(x) ) であるが、x に fuga が渡された時、MSVC では、"hoge_fuga" に展開されるが、gcc では ""hoge_""fuga"" に展開されてしまいエラーになった。MSVC に逆戻りして、チェックしてみないと、なんとも言えないが、正しくは
BOOST_PP_STRINGIZE( BOOST_PP_CAT(hoge_, x) ) とすべきなのだろうか? 'hoge_' は文字通り展開され、'x' は 'fuga' に展開されて ## により結合されるので、心情的に、かなり気持ち悪い。

 今回の教訓。プリプロセッサ、面白かったけど、罠がいっぱい。できるならば使わない方が良い。

 他にも、いろいろと引っかかっている。一筋縄ではいかないもんだ・・・。これは、まだまだ完成しそうにない。

2009年2月25日水曜日

swig boost_random 意味がわからん

 ubuntu 環境でコンパイルしてみたら identifier before ‘&’ token というようなエラーになって、全く意味がわからなかった。
 どうやら、クラスのメンバ関数名に random() という名前を使ったのがお気に召さなかったらしい。include ガードとかも念のために追加して、また、手を加えたらポストします。

swig 欲張りすぎたかも

 とりあえず、active_perl では動作した。しかし、ほとんどテストはしていない。cmake 用の CMakeFiles.txt も適当に書いたので、そのまんまではコンパイルもままならないかもしれない。ここまでやったが、私がこれを使う事は、まず無いだろう(少々のコンバータとかでも、C++で書いちゃいますから~)。そんなわけで、一応、貼っときます。煮るなり、焼くなり、好きにしてください。



  • direct_* は直接呼出し
  • uniform_* は、[0,1) の一様確率
  • exp_* は 指数分布
  • norm_* はガウス分布
  • log_* は対数ガウス分布
となってます。コンパイルには、boost が必要です。

後で、もうちょっと CMakefilesCMakeLists.txt をまじめに書く予定だけど、移り気なので約束が果たされるかどうか…

追記: よく考えたら、余計なメンバを定義していたので無駄にサイズが増えて勿体無いお化けに怒られそう…という事で、ポストしてから、AM3:09には、修正したのをアップし直しました。
更に追記:Ubuntuでコンパイルが通らない。なんで~?

2009年2月24日火曜日

本日は研究会

 本日は、サイバーフィールド研究会。難しい話が多いけど、面白かった。帰りに巡回セールスマン問題の件で相談に行き、GAは捨てて違うアルゴリズムを採用することになった。先行きが楽しみだ。