前のページ次のページ2020/02/12(水)kv-0.4.50精度保証kvライブラリを0.4.50にアップデートしました。今回は、卒論修論のシーズンが終わって、学生たちがライブラリを使うことで発見してくれた問題点の解決が主な内容です。利用して下さり、問題点を見つけてくれた学生のみなさまに感謝します。(double-double)用のfrexpが、入力が2のベキ乗よりも僅かに小さい値のときに正しく動作していなかったバグの修正。(例えばdd)、logがごく稀に正しい値を返していなかったバグの修正。ddの(精度保証付きでない)sinとcosで、引き戻し処理が雑だったのを修正。2番目は精度保証が破れている可能性があるため、重大な修正です。2iを満たすようなyとiを計算してくれる関数で、(IEEE754の指数部とは1ずれるが)指数部を取り出してくれる関数としてよく用いられます。&i);のように同様に使える関数を用意していました。}のようなものでした。-2-54)のように2のベキ乗よりわずかに小さく、2のベキ乗と小さな負の数の和で表現されている場合、指数部を正しく取り出すことが出来ません。}のように修正する必要がありました。完全に作者の見落としであり、これを見つけてくれた学生には感謝しかないです。このバグが発生する確率は非常に低いので、かなりしつこく追い込まないと見つからない種類のバグだと思います。0のように正しく計算されるようになりました。interval<dd>のlogのバグ前のddのfrexp問題に対処しているうちに、ある問題点に気付きました。1+2-1074みたいな上位と下位の数が非常に離れたdd数に対して、誤差無しでfrexpを実行することが不可能であるという問題です。1となるべきですが、2-1075を今のdoubleで表現することは出来ません。よって、必然的に誤差が生じることになります。frexpなんてあまり使わないし、誤差が生じることを断っておけばいいか、くらいに思ったのですが、ライブラリ内でfrexpを使っている箇所を探していたらありました、数学関数logです。log(x)を計算するのに、x=y×2iのように分解する方法を使っていました。frexpに誤差が発生する可能性を考慮しておらず、frexpの戻り値を信用してそのまま計算していました。実際、doubleやmpfrではfrexpで誤差が発生することは無いのですが、ddだとこれが問題になります。実際、log(1+2-1074)をinterval<dd>で計算すると、[0,0]のように誤った(真値を含まない)値が計算されました。frexpは、返却値のうち仮数部yが問題であり、指数部iは信頼できるので、指数部iのみ使って、yは改めて区間演算するように精度保証付きlogの計算方法を改めることで対処しました。これで、[0,9.88131291682493088353137585736442744730119605228649528851171365001351014540417503730599672723271984759593129390891435461853313420711879592797549592021563756252601426380622809055691634335697964207377437272113997461446100012774818307129968774624946794546339230280063430770796148252477131182342053317113373536374079120621249863890543182984910658610913088802254960259419999083863978818160833126649049514295738029453560318710477223100269607052986944038758053621421498340666445368950667144166486387218476578691673612021202301233961950615668455463665849580996504946155275185449574931216955640746893939906729403594535543517025132110239826300978220290207572547633450191167477946719798732961988232841140527418055848553508913045817507736501283943653106689453125e-324]のように正しい値を含む区間が返されるようになりました。一応表現可能とはいえ、1+2-1074のような上位と下位が大きく離れたdd数が生成されることは稀であり、このバグに遭遇する確率は極めて低そうですが、可能性がゼロでない限り精度保証付き数値計算のライブラリとしては大きな問題と言えます。発見できて幸運でした。ddのsin,cosの引き戻し問題こちらは、精度保証付きのsin,cosでなく、sin,cosにintervalでない素のddを入れたときの問題です。ddに数学関数は実装されていなかったのですが、近似計算とはいえあれば便利だろうと、後で割と雑に実装したものです。sin,cosの引数を0近辺に引き戻すのに、2πを何度も引き算するようなあまりに雑な実装になっていました。後で直そうとして忘れていたものと思われます。精度保証は何も考えていない部分ですが、これだと大きな引数のときに計算時間が問題になりそうです。割り算するように直しました。おわりにddは本当に鬼門で、何度も予想もしないバグに遭遇します。精度保証付き数値計算のライブラリは、バグがあれば当然精度保証にならないわけで、プログラムにバグがないことをどうやって保証するのか、という宿命的な問題を抱えています。数学の定理の自動証明や、プログラムの自動検証を行うような研究もなされています。(将来は分かりませんが)現在のところ、数学の定理が正しいかどうかは、多くの数学者が証明を検証してどうやら正しそうだ、と思えたら正しい、という段階のようです。プログラムも同じことで、大勢の人が使い、またソースコードを見て、どうやら正しそうだと思えたら正しい、とするしかないように思います。そのために、精度保証付き数値計算のプログラムは必ずオープンでなければならないし、また大勢の人に使われなければならないと考えています。18.04にnvidia-dockerをインストールしたときのメモです。機械学習などでCUDAの実行環境が必要になることは多いかと思います。自分は囲碁AIを動かすのに必要となりました。ところが、環境構築がかなり複雑で、また使いたいソフトウェアによってcudaやcudnnの必要なversionが異なることも多く、苦労させられます。VMwareやVirtualBoxなどの仮想化環境を使いたくなりますが、残念ながらそれらの仮想マシンからはGPUは見えません。WSLからもGPUは見えません。そこで解決策の一つとして考えられるのが、nvidia-dockerです。dockerはコンテナ型の仮想環境を提供するもので、VMwareなどに比べて例えばメモリ空間を共用できるなど、とても軽いものです。nvidia-dockerはNvidiaのGPUを仮想化して共有することが出来ます。NvidiaのGPUでいろいろなソフトウェアを試したいとき、これはとても便利です。cudaやcudnnがインストールされた状態のイメージも公開されているため、それをダウンロードすればインストールの手間も省けます。GPUに対応したため、19.03以降は普通にdockerを入れた後に追加のパッケージを入れるように変更されました。18.04にnvidia-dockerをインストールしたときの様子をメモしておきます。(GTX-1060搭載小型デスクトップ、2019年12月に実行)です。18.04を入れたまっさらな状態です。GPUのためのドライバを入れます。これだけはホストマシンに入れる必要があります。devicesとして使用可能なドライバを検索します。(2019年12月)。updateのようにPPAの追加が必要でした。これが、ハードの違いによるものか、実行した時期の違いによるものかは検証していません。builtinのように表示されるようになりました。builtinとなったので、実行する時期によって内容は異なるようです。これらを見て、"recommended"なドライバをインストールしました。nvidia-driver-435いったん再起動し、動作確認は、nvidia-smiを実行します。|+-----------------------------------------------------------------------------+のように表示されれば正常に動作しています。次に、dockerをインストールします。19.03以降でないとnvidia-docker化はできないので、本家から最新のものを入れます。本家のページに従いました。https://docs.docker.com/get-started/のようなメッセージが表示されれば成功です。次に、nvidia-docker化を行います。これも、本家のページの通りです。docker動作確認は、コンテナの中でnvidia-smiを実行してみましょう。||=============================================================================|+-----------------------------------------------------------------------------+のようにcuda入りイメージのダウンロード後、コンテナの中でnvidia-smiが実行できたら成功です。all"を付ければnvidia-dockerとして、付けなければただのdockerとして振る舞うようです。ご参考になれば幸いです。dockerの使い方はまるで分かってなくて適当に検索しながら使ってるので、備忘録として。bashとしてその中に入って作業を行いました。Dockerfileとかを使わない、ダメな使い方だと思いますが、これで十分役に立っています。久しぶりに、kvライブラリを0.4.49にアップデートしました。一点に特異性を持つ2変数関数の二重積分を精度保証付きで行う機能を追加しました。言葉で書くと簡単そうですが苦労しています。数値積分のページの第5,6節とか、辺及び一点にベキ型特異性を持つ2変数関数の二重積分を見て下さい。コメント(0件)2019/04/10(水)kv-0.4.48精度保証kvライブラリを0.4.48にアップデートしました。今回は、区間演算の非常に基本的な部分の更新を含んでいます。[-\infty,\infty]のような無限区間を表現することが出来るように設計されています。\inftyのような範囲を意味します。\inftyに注意する必要があります。適切に場合分けを行っていればNaNの危険はありませんが、乗算だけはきちんと考慮する必要があります。\end{eqnarray*}のような計算をしていました。[0,0]になるべきものです。今回の0.4.48でこれを修正しました。福井大学の石井大輔先生のご指摘によります。ありがとうございました。(matplotlib.hpp)の記事で書いたmatplotlib.hppですが、長方形を描画する関数rectにバグがあって正しい位置に描画されていなかったのを直しました。応用数理セミナーで講演してきました。年末恒例のセミナーですが、9月に行った「精度保証付き数値計算の基礎」チュートリアルの続編という意味合いもあります。9月の第4章のチュートリアルに続いて、第7章のチュートリアルでした。そこでつかったスライドを上げておきます。40分では少し駆け足になってしまったのが反省点。Arithmeticは常微分方程式の精度保証でかなり重要な役割を果たしているにもかかわらず、教科書のどこにも説明がないのが大きな問題点だなあと感じました。コメント(0件)前のページ次のページInformation精度保証付き数値計算のことなど、いろいろつぶやく予定。