大澤 洋祐
--------------
今回はJampackとJAMAのパッケージの評価をしてみた。 実験環境は以下のようになっている。
----------------------------------
OS Microsoft Windows2000 CPU AMD Athlon 800MHz MEMORY 128M JDK Java 2 SDK ver1.2.2 007 Windows95/98/2000/NT JAMA ver1.0.1 Jampack バージョンは確認できず Octave GNU Octave 2.1.31 on Cygwin32 4.90 なお、Jampack,JAMAとも添付のクラスパッケージをそのまま使用
----------------------------------
Jampackを使用した連立一次方程式のプログラムは以下のとおりである。
// Solve_Jampack.java
import java.util.*;
import Jampack.*;
public class Solve_Jampack{
public static void main(String[] args) throws JampackException{
int n = 1000;
Zmat A = new Zmat(Rand.ndary(n,n));
Zmat b = new Zmat(Rand.ndary(n,1));
Zmat x = new Zmat(n,1);
Date t1,t2; t1 = new Date();
x = Solve.aib(A,b);
t2 = new Date();
System.out.println((t2.getTime() - t1.getTime()) / 1000.0 +" sec");
}
}
一方、JAMAを使用した連立一次方程式のプログラムは以下のとおりである。
// Solve_JAMA.java
import java.util.*;
import Jama.*;
public class Solve_JAMA{
public static void main(String[] args){
int n = 1000;
Matrix A,x,b;
A = Matrix.random(n,n);
b = Matrix.random(n,1);
Date t1,t2;
t1 = new Date();
x = A.solve(b);
t2 = new Date();
System.out.println((t2.getTime() - t1.getTime()) / 1000.0 +" sec");
}
}
JampackとJAMAの多少の書式に違いがあるが、それ以外では同条件にしてある。
比較としてOctaveで使用した連立一次方程式のプログラムは以下のとおりである。
% axb.m n = 1000;
A = rand(n,n);
b = rand(n,1);
tic();x = A \ b;toc()
上記の3つのプログラムを実行して、連立一次方程式を解くのにかかる時間を3回ずつ測定した。
結果: Jampack:42.35sec 42.41sec 42.34sec
JAMA:13.13sec 12.59sec 13.11sec
Octave:11.97sec 12.19sec 11.53sec
この結果を見るに、Jampackが非常に遅い。添付のクラスパッケージをそのまま使用したのが 原因である可能性もあったので、クラスパッケージをコンパイルして測定してみたが 改善は見られなかった。 実行列についてのみ実装されているJAMAに対して、Jampackの行列クラス(Zmat)は 複素数行列をサポートしている分、実行列計算では不要な虚数部も含めて計算されることになるため 実行速度が劣ってしまうと考えられる。 次に、固有値問題について見てみる。 Jampackを使用した固有値問題のプログラムは以下のとおりである。
// Eig_Jampack.java
import java.util.*;
import Jampack.*;
public class Eig_Jampack{
public static void main(String[] args) throws JampackException{
double[][] d = {{3.0,4.0,5.0},{2.0,3.0,4.0},{4.0,5.0,6.0},};
Zmat A; A = new Zmat(d);
Eig e = new Eig(A);
System.out.println("V =");
Print.o(e.X,3,5);
System.out.println("D =");
Print.o(e.D,3,5);
}
}
JAMAを使用した固有値問題のプログラムは以下のとおりである。
// Eig_JAMA.java
import java.util.*;
import Jama.*;
public class Eig_JAMA{
public static void main(String[] args){
double[][] d = {{{3.0,4.0,5.0},{2.0,3.0,4.0},{4.0,5.0,6.0},};
Matrix A;
EigenvalueDecomposition e;
A = new Matrix(d);
e = A.eig();
System.out.println("V =");
e.getV().print(8,5);
System.out.println("D =");
e.getD().print(8,5);
}
}
そして、Octaveで使用したプログラムは以下のとおりである。
A = [3 4 5;2 3 4;4 5 6];
octave:2> [V,D] = eig(A)
以上3つの出力を以下に示す。
Jampack: ----------------------------
V = 1 2 3
1 5.66134e-01 4.08248e-01 -5.74599e-02
2 4.27432e-01 -8.16497e-01 -7.61056e-01
3 7.04836e-01 4.08248e-01 6.46136e-01
D = 1 2 3
1.22450e+01 + 0.00000e+00i 2.60293e-16 + 0.00000e+00i -2.44998e-01 + 0.00000e+00i
---------------------------- JAMA: ----------------------------
V = 0.56613 0.41427 -0.11379
0.42743 -0.82854 -1.50718
0.70484 0.41427 1.27960
D = 12.24500 0.00000 0.00000 0.00000 -0.00000 0.00000 0.00000 0.00000 -0.24500
---------------------------- Octave ----------------------------
V = -0.566134 -0.408248 -0.057460
-0.427432 0.816497 -0.761056
-0.704836 -0.408248 0.646136
D = 12.24500 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 -0.24500
----------------------------
これらを見ると、Jampackの出力が全く異なることが分かる。 (親切にも?) 行列のインデックス値が付加されている。 それから、Jampackの出力クラス(Print)では浮動小数点方式の表示形式しか 用意されていないようである。そのため、他の二つのような固定小数点方式の表示をするには 一工夫必要になるだろう。 また、固有値に、虚数部分(もちろん0であるが)も出力されているのも特徴的である。 それからJAMAのVの値が他の2つと比べてずいぶん誤差が生じている。 特に第3列は全く異なった値になってしまっている。しかし固有値Dは問題なく求められている のが、疑問である。