枕草子 (My Favorite Things)
【第463回】 デバッグはやはりfprintfで(2001年1月10日)
- 夜中に何度も娘に薬を塗るために起きたが,さすがに23:00過ぎに就寝すると,6:00に快適な目覚めを迎えることができる。里芋と人参と長ネギがあったので,里芋と人参を皮を剥いて小さく切り,煮干しで出汁をとった鍋の水にぶちこんで煮込み,味噌を入れて味を調整してから長ネギを薄く切ったものを散らして味噌汁とした。我ながら上出来だった。娘の様子が気になったこともあるが,緑茶のでがらしが勿体ないので魔法瓶水筒につめて家を出たのは7:50を過ぎており,往路あさまは8:37発506号となった。
- 昨夜の復路ではコーディングの続きをしたのだが,尤度関数の最小化パラメータを求めるプログラム全体の形が決まったので,後はデバッグである。うまくすると,今日の往路で完成するかもしれない。
- 最初のうちparse errorとかをコンパイラが吐いてくれるのは,ほぼ100%,中括弧の対応がついていないというミスで,丹念に見れば気がつくのだが,問題はコンパイルが通った後である。今日も,実行してみるとwhileループの脱出条件を満たさない筈なのに2回しかループせずに終了してしまったのだ。こういうときは,やはりprintfデバッグが常道である。標準エラー出力するため,正確にはfprintfデバッグというべきかもしれない。デバッガを使ったところで,どうせぼくにできることはprintfデバッグと同様,変数の値やアドレスの値を途中で見ることくらいだし,文法エラーはないのでlintも役に立たないからである。以前はprintfデバッグをした後はコメントアウトしていたのだが,最近は#ifdef DEBUG〜#endifで囲むようにして,デバッグ中はgcc -DDEBUG (後略)とするようにしている。この方がうまく行った後ではソースコード自体に手を入れる必要がないし,キーワードを適当に何種類か使えば,デバッグレベルを変えて実行させることができて,後々便利だ。
- さて,今回の場合は,パラメータや与えるデータによってうまくいくこともあった。どうも尤度関数を計算するときに桁あふれを起こしているらしい。尤度関数の例外処理をきちんとやることで解決しそうであることがわかったが,どう例外処理をしたらうまくいくのか思いつかずデバッグが完了しないままに,もはや日が暮れそうである。
- 適当に例外処理をしていったら,データによってはすべての点が例外で終わるという最悪の結果になった。問題は,桁あふれするような実数2つの差をとると,おそらく小さな実数になるだろうと思われるのだが,それを正当に扱う方法が浮かばない点にある。こういうのは計算科学の素養がきちんとあれば身に付いているのだろうが,計算科学についてはほぼ完全に独学なので,いちいち本を参照しないとわからないというのが痛い。
- 帰りは終電1本前。
▼前【462】(新年最初の週末(2001年1月6日〜9日)
) ▲次【464】(寝坊(2001年1月11日)
) ●枕草子トップへ