LU分解(是/否部分主元法)+ 施密特(Schmidt)QR分解 + 吉文斯(Givens)QR分解 + Household QR分解 代码详解,可直接运行版本复测试用例(java8版)

1)2)LU分解(是/否部分主元法)+

3)施密特(Schmidt)QR分解 +

4)吉文斯(Givens)QR分解 +

5)Household QR分解 代码详解

可直接运行版本复测试用例(java8版)

更改测试用例:更改主方法内数组数据,或直接重写I/O流

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Fractorization {

    public static void main(String args[]){
        run(LUFractorization(new double[][]{
                {2.0, 2.0, 2.0},
                {4.0, 7.0, 7.0},
                {6.0, 18.0, 22.0},
        }, 0));
        run(LUFractorization(new double[][]{
                {1.0, 2.0, -3.0, 4.0},
                {4.0, 8.0, 12.0, -8.0},
                {2.0, 3.0, 2.0, 1.0},
                {-3.0, -1.0, 1.0, -4.0}
        }, 1));
        run(SchmidtQR(new double[][]{
                {1, 0, -1},
                {1, 2, 1},
                {1, 1, -3},
                {0, 1, 1}
        }));
        run(GivensQR(new double[][]{
                {0, -20, -14},
                {3, 27, -4},
                {4, 11, -2}
        }));
        run(HouseholdQR(new double[][]{
                {1, 19, -34},
                {-2, -5, 20},
                {2, 8, 37}
        }));
    }

    public static void run(List<double[][]> list){
        if(list.size() == 3){
            System.out.println("The matrix L of A is");
            print(list.get(0));
            System.out.println("The matrix U of A is");
            print(list.get(1));
            System.out.println("The matrix P of A is");
            print(list.get(2));
            System.out.println();
        }
        else{
            System.out.println("The matrix Q of A is");
            print(list.get(0));
            System.out.println("The matrix R of A is");
            print(list.get(1));
            System.out.println();
        }
    }

    public static List<double[][]> LUFractorization(double[][] matrix, int model){
        List<double[][]> list = new ArrayList<>();
        int length = matrix.length;
        double[][] L = new double[length][length];
        double[][] U = new double[length][length];
        double[][] P = new double[length][length];
        int[] indexP = new int[length];

        for(int i = 0; i < length; i++)
            indexP[i] = i;
        for(int i = 0; i < length; i++){
            if(model == 1)
                exchange(matrix, L, indexP, i, findExchange(matrix, i));
            for(int j = i+1; j < length; j++)
                L[j][i] = eliminate(matrix, i, j);
        }
        for(int i = 0; i < length; i++) {
            for(int j = length-1; j >= i; j--)
                U[i][j] = matrix[i][j];
            if(model == 1)
                P[i][indexP[i]] = 1;
            else
                P[i][i] = 1;
            L[i][i] = 1;
        }
        list.add(L);
        list.add(U);
        list.add(P);
        return list;
    }

    public static List<double[][]> SchmidtQR(double[][] matrix){
        int m = matrix.length;
        int n = matrix[0].length;
        double[][] R = new double[n][n];
        List<double[][]> outList = new LinkedList<>();
        for(int i = 0; i < n; i++){
            double[][] u = new double[m][1];
            for(int j = 0; j < m; j++)
                u[j][0] = matrix[j][i];
            for(int j = 0; j < i; j++) {
                double[][] q = new double[m][1];
                for(int k = 0; k < m; k++)
                    q[k][0] = matrix[k][j];
                double r = matrixProduct(T(q), u)[0][0];
                u = matrixPlus(u, matrixNumProduct(r, q), false);
                R[j][i] = r;
            }
            double mode = 0;
            for(int j = 0; j < m; j++)
                mode += u[j][0]*u[j][0];
            double r = Math.pow(mode, 0.5);
            R[i][i] = r;
            u = matrixNumProduct(1/r, u);
            for(int j = 0; j < m; j++)
                matrix[j][i] = u[j][0];
        }
        outList.add(matrix);
        outList.add(R);
        return outList;
    }

    public static List<double[][]> GivensQR(double[][] matrix){
        int maxRow = matrix.length;
        int maxCol = matrix[0].length;
        int m = matrix.length;
        int n = matrix[0].length;
        List<double[][]> QList = new LinkedList<>();
        List<double[][]> RList = new LinkedList<>();
        List<double[][]> outList = new LinkedList<>();
        while(maxRow > 1 && maxCol > 1){
            int row = matrix.length;
            double[][] u = new double[row][1];
            for(int i = 0; i < row; i++)
                u[i][0] = matrix[i][0];
            List<double[][]> TList = new LinkedList<>();
            for(int i = 1; i < row; i++){
                if(Double.doubleToLongBits(u[i][0]) == Double.doubleToLongBits(0.00))
                    continue;
                double c = u[0][0] / Math.pow((u[0][0]*u[0][0])+(u[i][0]*u[i][0]), 0.5);
                double s = u[i][0] / Math.pow((u[0][0]*u[0][0])+(u[i][0]*u[i][0]), 0.5);
                double[][] T = eye(row);
                T[0][0] = T[i][i] = c;
                T[0][i] = s;
                T[i][0] = -s;
                u = matrixProduct(T, u);
                TList.add(T);
            }
            double[][] T = ((LinkedList<double[][]>)TList).poll();
            while(!TList.isEmpty()){
                double[][] temp = ((LinkedList<double[][]>)TList).poll();
                T = matrixProduct(temp, T);
            }
            QList.add(T);
            RList.add(matrixProduct(T, matrix));
            matrix = nextStep(matrixProduct(T, matrix));
            maxCol --;
            maxRow --;
        }
        outList.add(T(repairQList(QList, m, n)));
        outList.add(repairRList(RList, m, n));
        return outList;
    }

    public static List<double[][]> HouseholdQR(double[][] matrix){
        int maxRow = matrix.length;
        int maxCol = matrix[0].length;
        int m = matrix.length;
        int n = matrix[0].length;
        List<double[][]> QList = new LinkedList<>();
        List<double[][]> RList = new LinkedList<>();
        List<double[][]> outList = new LinkedList<>();
        while(maxRow > 1 && maxCol > 1){
            int row = matrix.length;
            double[][] u = new double[row][1];
            for(int i = 0; i < row; i++)
                u[i][0] = matrix[i][0];
            double mode = 0;
            for(int i = 0; i < row; i++)
                mode += u[i][0]*u[i][0];
            mode = Math.pow(mode, 0.5);
            u[0][0] -= mode;
            double coff = 2 / matrixProduct(T(u),u)[0][0];
            double[][] R = matrixPlus(eye(row), matrixNumProduct(coff, matrixProduct(u, T(u))), false);
            double[][] mid = matrixProduct(R, matrix);
            QList.add(R);
            RList.add(mid);
            matrix = nextStep(mid);
            maxCol --;
            maxRow --;
        }
        outList.add(T(repairQList(QList, m, n)));
        outList.add(repairRList(RList, m, n));
        return outList;
    }

    private static double[][] matrixProduct(double[][] A, double[][] B){
        int y = A.length;
        int x = B[0].length;
        double C[][] = new double[y][x];
        for (int i = 0; i < y; i++)
            for (int j = 0; j < x; j++)
                for (int k = 0; k < B.length; k++)
                    C[i][j] += A[i][k] * B[k][j];
        return C;
    }

    private static double[][] matrixPlus(double[][] A, double[][] B, boolean positive){
        int row = A.length;
        int col = A[0].length;
        double[][] C = new double[row][col];
        for(int i = 0; i < row; i++){
            for(int j = 0; j < col; j++){
                if(positive)
                    C[i][j] = A[i][j] + B[i][j];
                else
                    C[i][j] = A[i][j] - B[i][j];
            }
        }
        return C;
    }

    private static double[][] matrixNumProduct(double b, double[][] A){
        int row = A.length;
        int col = A[0].length;
        double[][] C = new double[row][col];
        for(int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                    C[i][j] = b * A[i][j];
            }
        }
        return C;
    }

    private static double[][] repairQList(List<double[][]> QList, int m, int n){
        double[][] Q = ((LinkedList<double[][]>)QList).poll();
        while(!QList.isEmpty()){
            double[][] temp = ((LinkedList<double[][]>)QList).poll();
            int row = temp.length;
            int col = temp[0].length;
            double[][] productor = new double[m][n];
            for(int i = 0; i < row; i++)
                for (int j = 0; j < col; j++)
                    productor[m-row+i][n-col+j] = temp[i][j];
            for(int i = 0; i < m-row; i++)
                productor[i][i] = 1;
            Q = matrixProduct(productor, Q);
        }
        return Q;
    }

    private static double[][] repairRList(List<double[][]> RList, int m, int n){
        double[][] R = ((LinkedList<double[][]>)RList).poll();
        while(!RList.isEmpty()){
            double[][] temp = ((LinkedList<double[][]>)RList).poll();
            int row = temp.length;
            int col = temp[0].length;
            for(int i = 0; i < row; i++)
                for (int j = 0; j < col; j++)
                    R[m-row+i][n-col+j] = temp[i][j];
        }
        return R;
    }

    private static double[][] T(double[][] A){
        int row = A.length;
        int col = A[0].length;
        double[][] C = new double[col][row];
        for(int i = 0; i < col; i++) {
            for (int j = 0; j < row; j++) {
                C[i][j] = A[j][i];
            }
        }
        return C;
    }

    private static double[][] eye(int x){
        double[][] I = new double[x][x];
        for(int i = 0; i < x; i++)
            I[i][i] = 1;
        return I;
    }

    private static double[][] nextStep(double[][] A){
        int row = A.length;
        int col = A[0].length;
        double[][] C = new double[row-1][col-1];
        for(int i = 0; i < col-1; i++)
            for (int j = 0; j < row-1; j++)
                C[i][j] = A[i+1][j+1];
        return C;
    }

    private static int findExchange(double[][] matrix, int pivot){
        int length = matrix.length;
        double max = matrix[pivot][pivot];
        int out = pivot;
        for(int i = pivot; i < length; i++){
            if(absoluteValue(matrix[i][pivot]) > absoluteValue(max)){
                max = matrix[i][pivot];
                out = i;
            }
        }
        return out;
    }

    private static void exchange(double[][] matrix, double[][] L, int[]indexP, int i, int exchange){
        double[] temp = matrix[i];
        matrix[i] = matrix[exchange];
        matrix[exchange] = temp;
        double[] LTemp = L[i];
        L[i] = L[exchange];
        L[exchange] = LTemp;
        int tempIndex = indexP[i];
        indexP[i] = indexP[exchange];
        indexP[exchange] = tempIndex;
    }

    private static double eliminate(double[][] matrix, int i, int j){
        int length = matrix.length;
        double coefficient = matrix[j][i]/matrix[i][i];
        matrix[j][i] = 0;
        for(int k = i+1; k < length; k++)
            matrix[j][k] -= coefficient*matrix[i][k];
        return coefficient;
    }

    private static double absoluteValue(double x){
        return x >= 0 ? x : -x;
    }

    private static double[][] copy(double[][] matrix){
        int length = matrix.length;
        double[][] out = new double[length][length];
        for(int i = 0; i < length; i++)
            for(int j = 0; j < length; j++)
                out[i][j] = matrix[i][j];
        return out;
    }


    private static void print(double[][] matrix){
        int row = matrix.length;
        int col = matrix[0].length;
        for(int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                BigDecimal bigDecimal = new BigDecimal(matrix[i][j]);
                String out = String.valueOf(bigDecimal.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue());
                int add = 8 - out.length();
                for(int k = 0; k < add; k++)
                    out += " ";
                System.out.print(out);
            }
            System.out.println();
        }
    }
}

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值