LoginSignup
0
0

More than 3 years have passed since last update.

前進,後進消去過程,pivot選択諸々のコード

Last updated at Posted at 2018-03-07

概要:

Ax=bを解く際の

1 Gauss(1+2)
2 前進消去過程(Forward_sub)
3 後進消去過程(Backward_sub)
4 Pivot(最大成分)を選ぶやつ(Pivot)
5 Pivotがm行目にあるとして,今いるk行目と行ごと交換するやつ,ベクトルb版(swapVec)
6 Pivotがm行目にあるとして,今いるk行目と行ごと交換するやつ,行列A版(swapMat)
7 PivotGauss

※Eclipseで自作したものをそのまま貼り付けました.mainの中にGaussが放り込んであります.間違ってるかも知れません.
※詳しい理論は載っていません.ググるか文献を参照してください.よろしくお願いします.

コード全部 ↓↓↓↓↓↓↓

    public static void main(String[] args) {
        // Gauss消去(前進+後進)
            int N = c.length;
            //コピーする
            double [][]A = new double[N][N];
            double []b = new double[N];
            A = copyMat(a);
            b= copyVec(c);
            double [] d = Forward_sub(A,b);
            double[] x = Backward_sub(A,d);
            return x;
        }

        //前進消去過程
        public static double[] Forward_sub(double A[][] ,double b[]){
            int N = A.length;
            double alpha = 0.0;
            for(int k=0 ; k<N-1;k++){
                for(int i= k+1; i<N; i++){
                    alpha = A[i][k] / A[k][k];
                    for(int j=k+1;j<N;j++){
                        A[i][j] = A[i][j] - alpha * A[k][j];
                        A[i][k] = 0.0;
                    }
                    b[i] = b[i] - alpha * b[k];
                }
            }
            return b;
        }

        //後退代入過程
        public static double[] Backward_sub(double A[][],double y[]){
        int N = A.length;
        for(int k=N-1; k>=0;k--){
            for(int p=k+1; p<N; p++){
                y[k] =y[k] - A[k][p] * y[p];
            }
        y[k] = y[k] / A[k][k];
        }
        return y;
        }

        //k列目に対して絶対値最大値をpivotに選ぶ
        public static int Pivot(int k , double[][]A){
            int n = A.length;
            double [] a = new double[n];//空の配列
            double max =0.0;
            int pivot = k;
            for(int i=0;i<n;i++){//i行k列目の要素を配列に入れる([0][3],[1][3],[2][3],…)
                a[i]= A[i][k];
            }
            for(int j=k;j<n;j++){//配列の要素を順に見て最大値を見つける
                if(Math.abs(a[j])>Math.abs(max)){
                    max=a[j];
                    pivot=j;
                }
            }
            return pivot;
        }

        //ベクトルbのk行目とm行目を入れ替える
        public static double[] swapVec(double[] b0,int m,int k){
            double[]b = new double[b0.length];
            b = copyVec(b0);
            double temp = b[k];
            b[k] = b[m];
            b[m] = temp;
            return b;
        }

        //行列Aのk行目とm行目を入れ替える
        public static double[][] swapMat(double[][] A0,int m,int k){
            double[][]A = new double[A0.length][A0[0].length];
            A = copyMat(A0);
            double []temp = new double[A.length];
            for(int i=0;i<A.length;i++){
                temp[i] = A[k][i];
                A[k][i] = A[m][i];
                A[m][i] = temp[i];
            }
            return A;
        }

        //ピボット選択付きGauss消去
        public static double[] pivotGauss(double J[][] ,double[]f){
            int n = J.length;//ベクトル要素数
            double [][] J2 = new double[n][n];//pivot後のヤコビ行列
            double [] f2 = new double[n];//pivot後の右辺項
            double [] del = new double[n];
            for(int k=0;k<n-1;k++){
            int m =Calc.Pivot(k, J);//k列目に対して絶対値最大値をmに選ぶ
            J2 = Calc.swapMat(J,m,k);
            f2 = Calc.swapVec(f, m, k);
            del = Calc.Gauss(J2, f2);
            }
            return del;
        }

感想:
数値解析って有限要素法がメジャーなのか未だ踏み込めておらずいつか理解できるようにしたいです.
また、掃き出し法は時間がかかるため,別の解法も試さなければとも思いました.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0