遊んでみる仕事に空きができたので、面白そうだけどフォローできていなかったライブラリやツールの調査をしている。Solver"が凄そうだ。非線形の最小二乗法ソルバーでgoogle社内の様々なプロジェクトでも利用されているようだ。Adjustmentのような複雑な例しかない。以下のような2D図形でゴニョゴニョするサンプルコードなんかがあるといいんだけど見つからない。そこで、習作としてひとまず2Dポリゴンの位置合わせなんかに使えないかなと実験してみた。アルゴリズムは単純なものにした。単純なICPのちょっと変形版で位置合わせを行うというものだ。平行移動(x,y)、スケール(x,y)、xy平面での回転の5つ。誤差関数は以下のような感じ。data_;};自動微分を使うために、operator()内の演算をすべてジェネリック型で行ったが、数値微分とあまり結果が変わらなかった。何か間違っているのだろうか?そして、自動微分なんて技術があるなんて初めて知った。用意された演算子や関数を使って関数書くだけで厳密な微分を行ってくれる。ceresだと普通にdoubleで計算してるみたいなコードで書ける。データ群の設定は以下の様な感じ。ICPに詳しくないのでここの論文を参考にしてみたが、論文では変位した変換元の点に対して、変換先の最近点を対にするだけで良いようだがこれではスケール成分が0になって変換先の1点に収束する現象が生じてしまった。仕方ないので逆方向の変換先の点に対して、変位した変換元の点も対として用いるようにした。}結果は以下のようになった。太い灰色線が求めるべき変換先のポリゴン、緑色線が変換元のポリゴン、赤い線がceresで求めた変換行列を緑色ポリゴンに施したもの。サンプリング点数は数百点ほど。スケール=(3.01447,0.79894)結構単純な方法だが結構良い精度で求まっているようだ。サンプリング点数を少なくすると、やはり変なところに収束してしまう。例2のサンプリング点数を50点ほどに少なくすると以下のようになる。例3ICPなんかをもっと勉強しないと実用するのは厳しそうか。Solver自体はいろんな用途で使えそうだ。githubから取得してVS2015でビルドしているのだが、ある日リポジトリから最新版を取得したところビルドが通らなくなった。RiftがらみのDLLやIntelのライブラリがリンクできなくなって、いろいろ試行錯誤したが一向に治らない。webで検索しても同じ症状の人がちらほら見つかるのだが、解決まで至っていない。結局原因は単純なもので、UE4のルートフォルダのSetup.batとGenerateProjectFiles.batを再実行していないことだった。ソースの更新内容によっては、これらの手順を再度踏まないといけないようだ。最初にビルドしてから時間が空いてたから、そんな手順があったってことすっかり忘れてた。同じ思いはしたくないのでメモ。ちなみにまだ簡単なサンプルでしか動作確認していないので注意。x64プラットフォームを作成する。MachineX86オプションが明示的に指定されているのでこれらを除去。これでx64のライブラリがビルドできるはず。gflagsをUnicode文字セットでビルドするのはソースをガシガシ書き換える必要がありそうなので諦めて、gflags自体はマルチバイト文字セットのままにする。gflagsをリンクし、google::ParseCommandLineFlags()で渡す引数をマルチバイトに変換して渡す。これで利用できるはずだが、VS2015ではロケールの扱い周りでバグがあるらしく(?)、std::cout、std::wcoutにどちらかしか日本語出力ができなかったり、mbstowcs系の関数がうまく動かなかったりでハマった。coutへの出力は諦めて対応。コードはざっと以下のような感じ。0;}実行するとこんな感じ。江添亮さんがC++11の解説本を公開してくれました!C++標準化委員会のメンバーで、最近はクッキーを増やすゲームのおそらく日本で一番面白いレビューを書いてくれた江添さんが、C++11の解説本をなんとコピーレフトで公開してくれました。途中までしか見ていませんが、簡潔で、かつ、プログラマの視点で重要な部分の説明に重点を置いた本ですね。仕様の背景にある考えも説明してくれていてありがたいです。重要で知っておくべきなのに、複雑だしあまり面白くないのがADLのあたりだと思いますが、この本ではかなり分りやすく書いてあるのでC++プログラマは必見だと思います。「オーバーロードの解決があいまいです」ってエラーがでてウガーッ!!!ってなると思いますが、ADLの仕様を知っておくと対処が楽になりますね。プログラミング2013年9月10日火曜日elevatedで使われている技術2009年にスペインのiq氏がelavatedという衝撃的なデモを発表した。4KBのプログラムで、リアルな山岳地帯の風景を3Dでリアルタイム描画し、音楽も鳴らすというものだ。それを読むと「天才ならこのぐらいはできるかもな」ぐらいには思えるようになる。iq氏の資料はココにまとまっている。地形は2D格子で、各格子点の高さはパーリンノイズで求める。(パーリンノイズについての詳細)通常のポリゴンベースの描画ではなく、ピクセルシェーダを使ったレイマーチン法でレンダリング。地形の法線ベクトルは隣のピクセルとの差分から算出するのではなく、パーリンノイズの式を微分して解析的に求める。影はフェイクで、ローパスフィルタをかけた地形の拡散光を影の成分とする。いった手法を使っているようだ。elevatedのShaderToy版もあり、簡易版ながらコードを見たり、いじることもできる。魔法がとけてよかった。プログラミング2013年1月13日日曜日しばらくみないうちにライフゲームもすごいことになってるんだな全9回のライフゲームの紹介動画。全部で1時間弱の素晴らしい動画だ。シリーズ後半の8回、9回あたりは見ていて鳥肌が立った。ライフゲームがチューリング完全とは聞いていたが実例を見ると、その機能美と、それを生み出した人間の知恵に感動して言葉を失う。values要素が約84万個大量に並んでいるもので、容量はおよそ100MB程度である。...</jps:CV_GridValuesMatrix>これを以下のようなコードで読み込ませてみると、数10分かかっても処理が終わらない。p->nextSibling;}プロファイルをとってみると、Gettext()関数が処理の大半を占めている。同じフォーマットで10MB程度のXMLは数秒で終わることから、どうやらGettext()がファイルサイズに対してO(N^2)のような処理オーダーになっている印象を受ける。呼ぶようにしたら処理は数秒で終わるようになった。これだけで数千倍も処理時間が違う。Gettext()は呼び出したらアウトのようだ。ちなみに今回の現象で悩んだ際にMSXML関連の情報をあさってみたが、以下のようなコードで遅いと言っている人もいた。...}これを上記のXMLでやると、このトラバースだけで数10分かかっても終わらない。DOMNodeListは線形リストの実装になっていて、ランダムアクセスにO(N)の時間がかかるためだろう。MS公式のFAQにも「こういうトラバースはしないで!」という情報があったが、だったら初めからGetitem()なんて関数用意しなきゃいいのに。