前回学習したガウス-ジョルダン法のアルゴリズムをJava言語で実装しましょう。少々長いサンプルコードですが、「コード・リーディング」の訓練だと思ってじっくり読み込んでから演習に取り組んでみてください。
問題 ガウス-ジョルダン法で連立一次方程式を解く次のプログラムを完成させましょう。
ガウス-ジョルダン法によるプログラムを次に示します。肝心のピボット処理、掃き出し処理のメソッドが未完成です。不足を補って完成させましょう。ソースコードにはスモークテスト[1]が含まれています。未完成版をそのままコンパイルしても、一応動作し次のような出力を得ることが出来ます。
正しくコードを完成させると、次のような出力を得ることが出来るでしょう。
先ずは未完成版のソースをじっくり読んで、大まかなコードの流れをつかみましょう。それが出来たら、ピボット処理、掃き出し処理のメソッドを順に完成させてください。コツは「常に動作するようにコードを加えていくこと」です。コードを加えてはコンパイルし、実行するのです。コードが動かないというのは、非常にモチベーションを奪います。しかし、コードが動いているうちは何となく気持ちが前向きです。投げ出さずに続けるための、自分のためのサプリメントだと思ってください。では、健闘を祈ります!
解説
コードの不足していた二つのメソッドのみを示します。完成後はサンプルコードで示したテストデータ以外の様々な値で計算させてみると良いでしょう。
ガウス-ジョルダン法の注意点
ガウス-ジョルダン法に限らないことですが、浮動小数点数を用いた計算の結果は近似値です。必ず誤差を含んでいます。今回の問題のために用意した係数行列・定数行列は、解として整数値が得られるような行儀の良いものを準備しました。ですからテストがおとなしく終了したのです。ところが、そのほかの値を用いたとき、期待する結果が1なのに、得られた計算結果が0.9999になるかもしれません。人間の目から見れば、ほぼ同じ値、まあ、計算誤差だろう、と推察できるのですが、コンピュータにとっては異なる値にしか見えません。テストは失敗だ、と判定してしまうことでしょう。妥当なテストを行うためには、コンピュータにどの程度の誤差を許容させるかという条件付けを指示してやる必要があります。実数型を用いた計算では、常にこの誤差の存在を忘れないようにしましょう。プログラムが正しく動作しているのに、バグを疑う無駄をしてしまいかねません。
今回はここまで
今回の課題はいかがだったでしょうか。ほんのわずかなコード追加なのですが、正しく動作させるまでにはずいぶん努力を要したことでしょう。解説に示したコードはまだまだ改善の余地が多々残されています。オーバーフロー、アンダーフローといった計算に関する問題を回避すること、メモリの節約に関すること、考えれば数多くあることでしょう。皆さんがガウス-ジョルダン法を実際に利用したい場合には、この解説で示したコードで満足することなく、さらなる正確性、パフォーマンスアップを追い求めてください。