2013-03-29

NetBeans IDE で JAMA を試す

JAMA(JAva MAtrix package) a. は Java で基本的な線形代数計算を行うためのパブリックドメインのライブラリです。

JLAPACK の時と同じサンプル、100000 組の xy が対になっているデータ fdata01.zip (fdata01.txt) を使って、JLAPACK の時と同じように b.、次の 4 次の多項式でフィッティングするために、その係数 c0,  c1,  c2,  c3,  c4 を最小二乗法で求めてみました。

y = c0 + c1x + c2x2 + c3x3 + c4x4

使用環境

  • OS : Fedora 18 (Linux)
  • JDK : jdk-1.7.0_17-fcs.x86_64
  • IDE : NetBeans IDE 7.3

以下が JAMA を利用した場合のサンプルプログラムと実行例です。なお、使用した JAMA は Version 1.0.3 (November 9, 2012) です。

package jamatest;

import Jama.Matrix;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class JamaTest {

    public static void main(String[] args) {
        int m = 100000, n = 5;
        double xMat[][], yVec[];
        xMat = new double[m][n];
        yVec = new double[m];

        File file = new File("/home/bitwalk/work/ex101_01/fdata01.txt");

        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String str;
            int i = 0;
            while ((str = br.readLine()) != null) {
                double xValue = Double.parseDouble(str.substring(0, 6));
                yVec[i] = Double.parseDouble(str.substring(6, 20));
                for (int j = 0; j < n; j++) {
                    xMat[i][j] = Math.pow(xValue, (double) j);
                }
                i++;
            }
            br.close();
        } catch (FileNotFoundException e) {
            System.out.println(e);
        } catch (IOException e) {
            System.out.println(e);
        }

        // xMat -> X
        Matrix X = new Matrix(xMat, m, n);
        // yVec -> y
        Matrix y = new Matrix(yVec, m);
        // solution for y = Xc
        Matrix c = X.solve(y);
        // Result
        System.out.println("# of DATA\t" + m);
        System.out.println("Coefficients");
        for (int j = 0; j < n; j++) {
            System.out.println("C(" + j + ") =  " + c.get(j, 0));
        }
    }
}
run:
# of DATA 100000
Coefficients
C(0) =  37.76585776133068
C(1) =  0.04968384703746971
C(2) =  6.988983959987343E-6
C(3) =  -4.2174249160063376E-7
C(4) =  2.686562674530643E-10
ビルド成功(合計時間: 0秒)

この程度の次数の行列計算では、JLAPACK との差を感じませんが、このサンプルの n の値を大きくすると差が顕著に判るようになります。つまり JAMA の方が遅いのですが、Java での扱いやすさは、JLAPACK に勝っていると思います。

参考サイト

  1. JAMA: Java Matrix Package
  2. NetBeans IDE で JLAPACK を試す (2)
  3. bitWalk's workshop - JAMA

2013-03-24

NetBeans IDE で JLAPACK を試す (2)

JLAPACK ライブラリが NetBeans IDE 上で利用できるようになったので、以前、gfortran + LAPACK で試したサンプルを、Java + JLAPACK でも試してみました。参考サイト a. で、LAPACK の最小二乗問題を扱う倍精度用の手続き副プログラム DGELS b. を利用した QR 分解のサンプルを紹介していますので、これを Java 用に書き換えました。

サンプルは、100000 組の x と y が対になっているデータ fdata01.zip (fdata01.txt) を読み込んで、下記の4次の多項式に最小二乗法でフィッティングしたときの係数 c1c5 を求めるというプログラムです。

y = c0 + c1x + c2x2 + c3x3 + c4x4

上記 gfortran のサンプルプログラム ex101_01.f を Java に書き直した DgelsTest.java を以下に示します。

package dgelstest;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.netlib.lapack.Dgels;
import org.netlib.util.intW;

public class DgelsTest {
    public static void main(String[] args) {
        intW info = new intW(2);
        int m = 100000, n = 5;
        int nrhs = 1, lda = m, ldb = m, lwork = 2 * n;

        double a[], b[], work[];
        a = new double[m * n];
        b = new double[m];
        work = new double[lwork];

        File file = new File("/home/bitwalk/work/ex101_01/fdata01.txt");

        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            String str;
            int i = 0;
            while ((str = br.readLine()) != null) {
                double x = Double.parseDouble(str.substring(0, 6));
                b[i] = Double.parseDouble(str.substring(6, 20));
                for (int j = 0; j < n; j++) {
                    a[i + m * j] = Math.pow(x, (double) j);
                }
                i++;
            }
            br.close();
        } catch (FileNotFoundException e) {
            System.out.println(e);
        } catch (IOException e) {
            System.out.println(e);
        }

        Dgels.dgels("N", m, n, nrhs, a, 0, lda, b, 0, ldb, work, 0, lwork, info);

        if (info.val == 0) {
            System.out.println("# of DATA\t" + m);
            System.out.println("Coefficients");
            for (int j = 0; j < n; j++) {
                System.out.println("C(" + j + ") =  " + b[j]);
            }
        } else {
            System.out.println("Error!");
            System.out.println("info = " + info.val);
        }
    }
}

実行結果は以下のようになりました。

run:
# of DATA 100000
Coefficients
C(0) =  37.76585776132993
C(1) =  0.04968384703750248
C(2) =  6.988983959858456E-6
C(3) =  -4.2174249160048426E-7
C(4) =  2.686562674530099E-10
ビルド成功(合計時間: 0秒)

いまどきの PC(と言っても、自分の PC は結構古いのですが)だと、Java を使っても、 100000 x 5 の行列計算程度では、データの読み込み時間を含めて大した時間がかかりません。

Dgels クラスでは、行列の要素を一次元配列に配置するので、C や Java の二次元配列における行と列の関係が、Fortran では逆になることを意識しなければなりません。なお、JLAPACK では、行列を二次元配列で扱える、DGELS c. というクラスも用意されているはずなのですが、このクラスがなぜか認識されなかったので、試すことができませんでした。

参考サイト

  1. LAPACK の利用例 - Workshop Complex at bitWalk
  2. Dgels - The Innovative Computing Laboratory (ICL) のサイトに掲載されている JLAPACK の文書
  3. DGELS - 同上
  4. NetBeans IDE で JLAPACK を試す - NetBeans IDE 上でライブラリの使い方を説明
  5. bitWalk's workshop - JLAPACK

2013-03-20

NetBeans IDE で JLAPACK を試す

JLAPACK は、は f2j により変換された Java 版の LAPACK です。

LAPACK (Linear Algebra PACKage) とは、Fortran で記述された数値解析ソフトウェアライブラリ(BSD ライセンス)のことで、線型方程式や線型最小二乗問題、固有値問題、特異値問題等を数値的に解くために利用されています。これを f2j という、Fortran ソースから Java ソースおよびクラスファイルへ翻訳するツールを用いて生成されたものが JLAPACK です。

Java でアプリケーションを作るにあたって(十分に枯れていて)計算結果に信頼ができて、使いやすい数値計算ライブラリを探しています。まずは、Fortran や C で自分でも使用実績がある LAPACK の Java 版を評価してみることにしましたので、NetBeans IDE 上での使い方を備忘録としてまとめました。

使用環境

  • OS : Fedora 18 (Linux)
  • JDK : jdk-1.7.0_17-fcs.x86_64
  • IDE : NetBeans IDE 7.3

まず、JLAPACK をダウンロード a.して、適当な場所に展開します((jlapack-0.8.tgz)。

NetBeans IDE を起動して、メニューから ツール(T)Ant ライブラリ(L) を選ぶと、「Ant ライブラリ・マネージャ」のダイアログが表示されますので、新規ライブラリ(N)... ボタンをクリックして新しいライブラリ名を指定します。ここでは、追加するライブラリを JLAPACK としました。そして、JLAPACK の jar ファイルをライブラリのクラスパスに追加します。

動作確認用にプロジェクトを作成します。ここでは、jlapack-0.8.tgz を展開したディレクトリ jlapack-0.8 内の examples/DgesvdTest.java を使用しました。このプロジェクトで JLAPACK ライブラリを利用するため、プロジェクトの『ライブラリ』を右クリックして『ライブラリの追加...』を選択します。

『ライブラリの追加』ダイアログから、JLAPACK を選び、ライブラリの追加 ボタンをクリックしてプロジェクトのライブラリに追加します。

下記は実行した結果です。

機会があれば、具体的なサンプルを試した結果を紹介します。

参考サイト

  1. java/f2j - Netlib にける JLAPACK のダウンロードサイト
  2. LAPACK — Linear Algebra PACKage - Netlib の LAPACK のサイト
  3. LAPACK Routines - kusuhara's wiki - Fortran での説明ですが、構造解析で使いそうなルーチンの一覧がまとめられています。
  4. NetBeans IDE で JLAPACK を試す (2) - 最小二乗問題を扱うサンプルを紹介しています。

2013-03-08

「Java 7 Update 17」公開、既に悪用が確認されている脆弱性を修正

3 月 4 日に、Java 7 Update 17 が公開されていました。ちょっと油断しているといつの間にかアップデートされていて慌てます。今回は JavaFX の方はアップデートされていませんでした。ちなみに Java 6 update 43 もリリースされています。


2013-03-02

JavaFX Scene Builder を Linux で試す

Linux (Fedora) 上でも JavaFX Scene Builder を使えるようになったのはいつだったか…。多忙にかまけてずっと試していなかったのですが、遅ればせながら動作確認をしました。使用環境は、Fedora 18 (x86_64) / jdk-1.7.0_15-fcs.x86_64 / NetBeans IDE 7.3 です。

まず JavaFX Developer Preview から、Linux 64-bit (tar.gz) をダウンロードします。今日ダウンロードしたファイルは、javafx_scenebuilder-1_1-beta-b21-linux-x64-14_feb_2013.tar.gz でした。これを適当な場所に解凍すると JavaFXSceneBuilder1.1 というディレクトリー内に展開されます。

NetBeans IDE のメニューから、ツール(T) → オプション(O) で、オプション設定ウィンドウを開き、以下のように Scene Builder のディレクトリーを指定します。


Scene Builder を起動するには、FXML ファイルを右クリックするとメニューが表示されますので、そこから開くを選びます(あるいは左ダブルクリックでも Scene Builder は起動します)。


すると、JavaFX Scene Builder が起動されます。


ちなみに、バージョン情報は以下のようになっています。


これで、もっと JavaFX のアプリケーションが作成しやすくなります。なんとしても週末に仕事を家に持ち帰らないようにしないと、時間を確保できません。