From window, to wind

趣味のゲームとJavaプログラムなどについて 適当に書き綴るブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Javaで最小二乗法

Javaで最小二乗法を行うためのメソッドを用意したクラスです。
最小二乗法の結果は連立方程式を解くことで得られるので、
連立方程式を解くために行列の掃き出し法を用います。
そこで行列を扱うMatrixクラスと掃き出し法を行うための連立方程式を作り掃き出し法を実行するMinR2クラスを作製しました。
使用例
X,YのデータはArrayListで渡します。メソッドで渡すint型の引数は2なら一次関数の直線、3なら二次関数の曲線といった多項式の次数となっています。メソッドで得られた結果はArrayListで帰ってきます。一番最初にx^0の係数、二番目にx^1の係数といった具合に係数が帰ってきます。

package program;

import java.util.ArrayList;

public class MainRun {

   
    public static void main(String[] args) {
        ArrayList<Double> XMatrix = new ArrayList<Double>();
        ArrayList<Double> YMatrix = new ArrayList<Double>();
       
        XMatrix.add(1.0);
        YMatrix.add(2.0);
        XMatrix.add(2.0);
        YMatrix.add(4.0);
        XMatrix.add(3.0);
        YMatrix.add(1.0);
        XMatrix.add(4.0);
        YMatrix.add(7.0);
        XMatrix.add(6.0);
        YMatrix.add(5.0);
        XMatrix.add(8.0);
        YMatrix.add(9.0);
        XMatrix.add(10.0);
        YMatrix.add(3.0);
       
        ArrayList<Double> AMatrix1 = MinR2.gettest(XMatrix, YMatrix, 2);
        System.out.println(AMatrix1);
        ArrayList<Double> AMatrix2 = MinR2.gettest(XMatrix, YMatrix, 3);
        System.out.println(AMatrix2);
    }

}


ソースコード
Matrixクラス

package program;

public class Matrix{

    private int i, j;
    private double[][] matrix;
    Matrix(int n, int m){
        matrix = new double[n][m];
        for(i=0;i<m;i++){
            for(j=0;j<n;j++){
                matrix[j][i]=0.0;
            }
        }
    }
   
    public void set(double value, int x, int y){
        matrix[x][y]=value;
    }
   
    public double get(int x, int y){
        return(matrix[x][y]);
    }
}


MinR2クラス

package program;

import java.util.ArrayList;

public final class MinR2 {

    private static ArrayList<Double> ZMatrix;
    private static int i, j, length, rank, t;
    private static Matrix CMatrix;
    static ArrayList<Double> gettest(ArrayList<Double> x,ArrayList<Double> y, int number){
        if(x.size()>y.size()){
            length=y.size();
        }else{
            length=x.size();
        }
        CMatrix = new Matrix(number,number);
        ZMatrix = new ArrayList<Double>();
        for(i=0;i<number;i++){
            for(j=0;j<number;j++){
                CMatrix.set(sum(x,i+j), j, i);
            }
            ZMatrix.add(sum(x,y,i,1));
        }
        //掃き出し法
        SweepOutMethod(number);
       
        return(ZMatrix);
    }
   
    private static void SweepOutMethod(int number){
        for(rank=0;rank<number;rank++){
            if(CMatrix.get(rank,rank)==0)changeRow(number);
            //対角係数を1となるようにrank行を割る。
            double dummy =CMatrix.get(rank, rank);
            for(t=0;t<number;t++){
                CMatrix.set(CMatrix.get(t, rank)/dummy,t, rank);
            }
            ZMatrix.set(rank, ZMatrix.get(rank)/dummy);
            //他の行に数倍にしたもので引きrank列を0にする。
            for(i=0;i<number;i++){
                if(rank!=i){
                    dummy =CMatrix.get(rank, i);
                    for(j=rank;j<number;j++){
                        CMatrix.set(CMatrix.get(j, i)-CMatrix.get(j, rank)*dummy, j, i);
                    }
                    ZMatrix.set(i, ZMatrix.get(i)-ZMatrix.get(rank)*dummy);
                }
            }
        }
    }
   
    //0とならない行と交換
    private static boolean changeRow(int number){
        int count =rank;
        while(CMatrix.get(rank, count)==0){
            if(count==number)break;
            count++;
        }
        for(int chx=rank;chx<number;chx++){
            double dummy = CMatrix.get(chx,rank);
            CMatrix.set(CMatrix.get(chx, count), chx, rank);
            CMatrix.set(dummy, chx, count);
        }
        double dummy = ZMatrix.get(rank);
        ZMatrix.set(rank, ZMatrix.get(count));
        ZMatrix.set(count, dummy);
        if(CMatrix.get(rank, count)==0){
            System.out.println("解くこと不可");
            return(false);
        }else{
            return(true);
        }
    }
   
    private static double sum(ArrayList<Double> element, int m){
        double sum1=0;
        for(int sumi=0;sumi<length;sumi++){
            sum1+=Math.pow(element.get(sumi), m);
        }
        return(sum1);
    }
   
    private static double sum(ArrayList<Double> element1, ArrayList<Double> element2, int m1, int m2){
        double sum2=0;
        for(int sumi=0;sumi<length;sumi++){
            sum2+=Math.pow(element1.get(sumi), m1)*Math.pow(element2.get(sumi), m2);
        }
        return(sum2);
    }
}

スポンサーサイト

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://kagenyan.blog69.fc2.com/tb.php/28-e9ba6c45
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。