C++11のstd::discrete_distributionでノンパラメトリックな分布の乱数生成

おさかなおさかなって言ってたらリアルにお魚好きになってしまったって話は前もしたと思うんですが,そのせいでホントに魚が食べたい今日このごろです.調理法としては,お刺身の次点くらいで焼き魚と酒蒸しが好きです.お刺身はそのままスーパーで買ってくればいいし(美味しいかと言われると微妙ですが),焼き魚も買ってきてグリルで焼くだけなので気軽にできるんですが,酒蒸しはちょっと自宅ではできなくて食卓が寂しいです.

さて,C++11では乱数関連のライブラリについてもboost由来の大幅強化がされまして,ホントに強力なものになっています.
まず乱数エンジンでは,よりよい擬似乱数アルゴリズムが豊富に取り揃えられており,さらにはハードウェアを利用した真の乱数も扱えます.
また生成される乱数の分布の点でも,通常の一様分布や各種の確率分布(GaussianやPoissonなど)が利用できます.

今日お話するのは分布の中でも,出力される各値の確率をユーザが指定できるノンパラメトリックな分布を実現するstd::discrete_distributionのお話.

なおboost::randomからstd::randomへは大きな設計変更がありましたけれども,今回の話に関しては普通にstd::discreted_distributionをboost::random::discrete_distributionとそのまま読み替えてもらっても大丈夫です.

Continue reading

標準入力の数値列から統計量(総和とか平均とか分散とか)を計算するコマンドaccを作った

問:カレントディレクトリより下の階層にある全ての.cppファイルの平均サイズをバイト単位で求めよ

解答例(こういうのあまり得意ではないのでヘンかもしれませんw許してくださいw):

% du -ab | grep "\.cpp\$" | grep -o "^[0-9]\+" | acc --mean -f "%.0f"

研究の仮のデータ集計とかにこういうUNIXライクな小さいプログラム,欲しかったけどありそうでなかったので書きました.
accコマンドと名付け,githubに公開しています.

https://github.com/sakanazensen/acc_command

入力は数値がずらずらとstdinにやってくればOK.double型の範囲を超えないように.
現時点では,総和,最小値,最大値,平均値,分散,中央値の出力ができるようになっています.
中ではboost::accumulatorに計算を丸なげしてるだけです.
よって,boost::accumulatorにない項目(最瀕値や標準偏差)には当面対応できません.
計算量等の問題についてはboost::accumulatorのマニュアルを参照してください.

当然無保証です.MITライセンスとします.
本記事コメントで対応はする考えはあります.pull requestがあれば反応するかもしれません.

実装に対するツッコミもあったら嬉しいかも.
あまり自分のコードを人に見せたことがなくてよくない.

boost::ublas::bounded_vectorを使うときは少し気をつけてねという話

この記事は,Boost Advent Calendar 2011の14日目の記事です.
(2時間近くも遅刻してすみません><)

スキルはまだまだですが,それでももうboostが無いと生きていけない体になってしまいました.
そういえば魔導書Vol2id:kikairoya先生の章(一番最後ですね)あたりは,ホントに「boostを使い倒す!」かんじがして最高に読み応えがありました.ぜひお読みください.

さて,本来はこのアドベでは無難に「あまり日本語情報の出回ってないライブラリを(ほとんど翻訳で)紹介する」つもりだったんですが,意外とネタ探しにつまづいたので,方針転換して僕が引っかかってしまった落とし穴を紹介することに.
筋違いなことを言ってたら,たぶん言ってますが,ツッコミをお願いします.
ホントに不当なdisがあったら全力で謝罪記事を書かせて頂きます….

(2011.12.15 12:30) 編集上のミスについて指摘をいただいたので訂正

Continue reading

boost::serializationでほげほげうまうま

オブジェクトをまるごとファイルに書きだしたりネットワークに送ったりしたいとき内容を直列化し再構築することやその仕組みをシリアライズと呼び,boostではserializationライブラリによって実現できます.
どのような形のデータ列に落としこむか?という話で,boost::serializationはテキスト,XML,バイナリの3種類がサポートされています.

Continue reading

boost::timerは少し困ったちゃんです

boost::timerは時間測定なんかに結構手軽で使いやすくてイイんですが,ちょっと困った現象がいくつか発生します.
僕の手元(Ubuntu 10.04 LTS x86 + gcc4.6.0 + boost 1.40)で再現できてるのは,

  • sleepするとおかしい

    • プロセスが消費したCPU時間なので,例えばsleep(1)の実行時間を計測しても,値は0です.
  • マルチスレッド化するとおかしい

    • 各スレッドでのCPU時間の総和が出るので,何倍かになるし,ちょうど何倍という値でもない.
  • 値の最大値が結構残念

    • (処理系依存であるものの)2147秒までしか測れない場合がある.

この理由はもう言うまでもないですね,内部実装にC標準関数のclock()を用いているからです.
移植性のためなのは理解できるんですが,ちょっとこれでは困ることも.

ということで,POSIXシステムコールのgettimeofdayを使って再実装してしまえ
…というテーマで記事を書こうとしたんですが,探したらあるもんですね.

POSIXではgettimeofdayを,WindowsではQueryPerformanceCounterを使えるように書いたものがありました.

http://pasokoniziri.blog32.fc2.com/?no=15

これに基づくprogress_timerやprogress_displayを作ろうかとも思いましたがそもそもあれはboostにしては珍しい誰得ライブラリなので放置.

ついでなので,gettimeofdayの精度についてのお話.

http://www.argv.org/~chome/blog/noisefactory/2008/02/gettimeofday.html

へー,おもしれー.

boost::variantのgetがメンバじゃない理由

先週名古屋にてBoost.勉強会#5が開催されました.

それとは直接関係ないのですが,行きの電車の中でBoost.Variantの仕様に関して疑問をもってTwitterでつぶやいたところ@cpp_akiraさんより回答をいただいて,それがすごく興味深い内容だったのでそのやりとりをこちらでメモ.

boost::variant<T1,T2,...>のオブジェクトtがあったときにt.get<T1>()と書きたいなぁ,とか…. boost::get<T1>(t)となってるのはどういう意図or理由なんでしょう.
@mrxptn
すずき

Continue reading