2014/11/24(月)kv-0.4.13

kvライブラリを0.4.13にアップデートしました。
今回は、やや重大なバグの修正です。ddの表示が正しくなかったというものです。
#include <kv/dd.hpp>

int main()
{
        kv::dd x;
        int i;
        std::cout.precision(34);

        for (i=1; i<9; i++) {
                x = i / (kv::dd)9;
                std::cout << x << "\n";
        }
}
の実行結果が、
0.1111111111111111111111111111111108
0.2222222222222222222222222222222215
0.3333333333333333333333333333333323
0.4444444444444444444444444444444431
0.5555555555555555833111311711844704
0.6666666666666666666666666666666646
0.7777777777777777916555655855922352
0.8888888888888888888888888888888861
となってしまっていました。5/9, 7/9の値がおかしいことが分かります。これは、内部では正しく計算していますが、double-doubleを表示(文字列変換)するときに一つ目と二つ目のdoubleの符号が違うとうまく表示されないというバグのせいです。

文字列変換部 (conv-dd.hpp) は、元々luaという言語で書いていて、それが正しく動くのを確認してC++に移植するという手順を踏んだのですが、負数に対する%(剰余演算子)のluaとC++での違いに起因するものでした。

修正して、ちゃんと
0.1111111111111111111111111111111108
0.2222222222222222222222222222222215
0.3333333333333333333333333333333323
0.4444444444444444444444444444444431
0.5555555555555555555555555555555569
0.6666666666666666666666666666666646
0.7777777777777777777777777777777785
0.8888888888888888888888888888888861
と表示されるようになりました。

こういうバグはすぐに修正せねばなりません。ついでに、affineにいくつか関数を追加したり、ソースコードをいくらかクリーンアップしたりしました。

2014/11/13(木)Intel Edison

IntelのEdisonとかいう謎アイテムを買ってみました。
切手くらいの大きさにx86 CPUと4Gストレージ、1Gメモリ、無線LANとBluetoothが載って単体でLinuxが動く。こういう変なものはとりあえず買うしかないでしょう。単体だと特殊コネクタしかなくて手も足も出ないので、USBとかのI/Fを引き出してくれるBreakoutボード付きのものを買いました。税込8640円。

IMG_5272.JPG


組み立ては差し込んでネジ止めするだけ。

IMG_5282.JPG
IMG_5283.JPG


以下は設定メモ。母艦としてubuntuの入ったPCを使った。
  • J3とPCをmicroUSBケーブルで繋ぐ。これはシリアル通信のためのもの。syslogを見るとttyUSB0として繋がってるっぽいので、
    sudo screen /dev/ttyUSB0 115200 -L
    
として繋ぐ。
  • さらに、J16とPCをmicroUSBケーブルで繋いで電源供給する。ログイン画面になるので、ID:rootでパス無しで入れることを確認。
  • 初期バージョンはバグだらけらしいので、https://communities.intel.com/docs/DOC-23242から"Edison Yocto complete image"をダウンロードし、https://communities.intel.com/docs/DOC-23200を見ながらアップデート。ドキュメントの最後に載ってる flashall.sh を使う方法でうまくいった。
  • シリアルで繋いだterminalから
    configure_edison --setup
    
    を実行。ホスト名、パスワード、Wi-Fiを設定し、これ以降は無線LAN経由でsshで操作できるようになる。
参考にしたサイトは、
あたり。

さて、sshで中を見ると、gcc 4.8.2が入っていて、セルフ開発出来そうです。とりあえずkvライブラリで精度保証ができるか試してみました。boostとkvライブラリを転送し、実行してみると、あっさり動きました。

とりあえず西先生の 5 solution の全解探索を実行してみると、
  • 5.7sec (core i7 4600U)
  • 137sec (Intel Edison)
となりました。さすがに速度差は歴然ですね。
Edisonは32bitにしか対応していないのですが、SSE2を持っているので-msse2 -mfpmath=sseをコンパイルオプションに指定すれば浮動小数点計算をSSEにやらせることができ、高速かつIEEE754準拠になります。

2014/11/12(水)kv-0.4.12

kvライブラリを0.4.12にアップデートしました。

先週の土曜日、kvライブラリを紹介する機会があって、何人かの人に使って頂くことが出来ました。そこで、affine<dd>のようにaffineにdouble以外の型を入れるとうまくコンパイル出来ない事例が見つかったので、修正しました。affineの内部型としては、rdouble.hppやrdd.hppを使って丸め付き演算の方法が与えられているような型を使えるように設計したつもりでしたが、実際に試してはいませんでした。
やはり、ライブラリは使われてこそ鍛えられますね。

ついでに、以前から書きたいと思っていたけど精度保証に直接関係がないので放置していた、ddを区間の端点でなく単体で使ったときのための数学関数(精度保証しない)を作成しました。

更に、そのddの数学関数でpowを実装しているときにふとした疑問を感じ、過去の実装を調べたところ、dd, psa, interval, autodifでpow(x, 2.5)のようにdouble型を指定した非整数乗の動作に問題があり、なんとintに切り捨てられてpow(x, 2)相当の動作をしていたことが判明しました。自分のライブラリ内でpowの第2引数にdoubleを使った例はありませんでしたが、online solverでこの機能を使った方がもしいれば、間違った結果を出していたことになります。

このように結果の信頼性に関わるバグが発見された時は即刻アップデートする方針なので、0.4.12としてアップデートしました。

2014/10/26(日)kv-0.4.11

というわけで、kvライブラリを0.4.11にアップデートしました。

前の記事に書いたように、rkf45を修正しました。
また、ベキ級数演算のhistory関連にバグがあって、sin等の数学関数のみから成る加減乗除を全く含まない右辺を持つ常微分方程式に対して、内部エラーで計算を行えなかった問題を修正しました。

2014/10/26(日)rkf45

kvライブラリに内に、rkf45.hppというファイルがあります。
これは、Runge–Kutta–Fehlberg法という有名なもので、6段5次の公式と5段4次の公式が同時に計算できるように工夫されていて、両者の差を観察することによって(大雑把ではあるが)混入した誤差の評価も出来るという優れものです。
この手法を使ったからと言って精度保証出来るわけでは無いのですが、楽しそうだったのでステップ幅調節らしきものも付けて試しに書いてみて、せっかくなのでkvライブラリ内に混ぜておいたものです。

先日、ちょうどオイラー法やルンゲクッタ法など、初期値問題の解法を講義でやったので、このrkf45を講義内で実演してみたら、なぜか精度が出ない! ステップ幅調整もしていない素の4段4次ルンゲクッタに負けてる! 講義中は、「やっぱデモやめた」と誤魔化して先へ進んだのですが、後でチェックしてみたら係数が一箇所間違ってました。精度がでないわけです。

精度保証とは関係ないところですが、ちょっと気分が悪いので、近日中にアップデートしてkv-0.4.11としたいと思います。
OK キャンセル 確認 その他