【问题标题】:Compute Null Space Basis of Matrix in Java在 Java 中计算矩阵的空空间基
【发布时间】:2018-05-20 12:25:13
【问题描述】:

我正在尝试在 Java 中获取 Matrix 3x3 的空空间(内核)。我尝试过使用Efficient Java Matrix Library(不一定非要这样,这只是一个例子。我已经尝试过使用 apache 之类的其他工具并获得了相同的结果)。

这是我的代码:

public static void main(String[] args) {
    double[][] data = new double[][] {
        {1,2,3},
        {1,2,3},
        {1,2,3}
    };
    SimpleMatrix m = new SimpleMatrix(data);
    SimpleSVD svd = m.svd();
    SimpleMatrix nullSpace = svd.nullSpace();
    nullSpace.print();
}

问题是我得到了正交,我想要它的基础

 0,964  0,000 
-0,148 -0,832 
-0,222  0,555 

这里使用Matlab得到的基:null(M,'r')

-2    -3
 1     0
 0     1

【问题讨论】:

  • 你应该在应用函数之前打印矩阵,以确保你知道你在输入什么。

标签: java matrix


【解决方案1】:

所以我自己找到了答案。我注意到可以编辑 MATLAB 脚本并打开我想要的脚本,然后用 Java 实现相同的脚本。我会在此处将它发布给可能需要它的每个人,但请注意,此脚本不是原始 .m 的副本。

我使用 Apache 矩阵库,如前所述,另外还有两件事。

  1. 我使用this class that I found navigating into apache test files
  2. 我使用它this function that a guy made in another java question(只是 rref 函数,但对它进行了一些更改,所以我将在此处添加它以及我的内核函数)

现在是代码(我将大部分代码放在 MatrixFunctions.java 中,主要是为了节省空间):

MatrixFunctions.java

//...Some other stuff
    public static double[][] rref(double[][] matrix, List<Integer> pivot) {
        double[][] rref = new double[matrix.length][];
        for (int i = 0; i < matrix.length; i++)
            rref[i] = Arrays.copyOf(matrix[i], matrix[i].length);

        int r = 0;
        for (int c = 0; c < rref[0].length && r < rref.length; c++) {
            int j = r;
            for (int i = r + 1; i < rref.length; i++)
                if (Math.abs(rref[i][c]) > Math.abs(rref[j][c]))
                    j = i;
            if (Math.abs(rref[j][c]) < 0.00001)
                continue;

            //Remember where we pivoted
            pivot.add(j);

            double[] temp = rref[j];
            rref[j] = rref[r];
            rref[r] = temp;

            double s = 1.0 / rref[r][c];
            for (j = 0; j < rref[0].length; j++)
                rref[r][j] *= s;
            for (int i = 0; i < rref.length; i++) {
                if (i != r) {
                    double t = rref[i][c];
                    for (j = 0; j < rref[0].length; j++)
                        rref[i][j] -= t * rref[r][j];
                }
            }
            r++;
        }

        return rref;
    }

    public static RealMatrix kernel(RealMatrix A) {
        int m = A.getRowDimension(), n = A.getColumnDimension();
        List<Integer> pivot = new ArrayList<>();
        RealMatrix R = MatrixUtils.createRealMatrix(MatrixFunctions.rref(A.getData(), pivot));
        int r = pivot.size();
        HashMap<Integer, Integer> nopiv = new HashMap<>();
        for (int i = 0; i < n; i++) {
            nopiv.put(i, i+1);
        }
        for (Integer e : pivot) {
            if (nopiv.containsValue(e+1))
                nopiv.remove(e, e+1);
        }
        //Remove ones contained inside pivot from nopiv
        for (int j = 0; j < r; j++) {
            int index = pivot.get(j);
            if (nopiv.containsValue(index))
                nopiv.remove(index);
        }

        double[][] Z = new double[n][n-r];    

        //Add 1(s) in the main diagonal
        if (n > r) {
            double[][] eye = new double[n-r][n-r];
            for (int i = 0; i < eye.length; i++) {
                for (int j = 0; j < eye[i].length; j++) {
                    if (j==i)
                        eye[i][j] = 1;
                    else
                        eye[i][j] = 0;
                }
            }
            //Add eye in Z
            Integer[] loc = nopiv.values().toArray(new Integer[nopiv.size()]);
            for (int i = 0; i < loc.length; i++) {
                int index = loc[i];
                for (int j = 0; j < Z[0].length; j++) {
                    Z[index-1][j] = eye[i][j];
                }
            }

            if (r > 0) {
                for (int i = 0; i < r; i++) {
                    int indexi = pivot.get(i);
                    for (int j = 0; j < loc.length; j++) {
                        int indexd = loc[j]-1;
                        Z[indexi][j] = -R.getEntry(i, indexd);
                    }
                }
            }
        }

        return MatrixUtils.createRealMatrix(Z);
    }
//...NnanananananaBATMAN!!

最后一个主要测试它:

    public static void main(String[] args) {
        double[][] matrix = new double[][] {
            {1,2,3},
            {1,2,3},
            {1,2,3}
        };
        //Calculate
        RealMatrix A = MatrixFunctions.kernel(MatrixUtils.createRealMatrix(matrix));
        System.out.println(A); // displays C formatted appropriately
    }

还有输出:

Array2DRowRealMatrix{
 {-2.0,-3.0},
 {1.0,0.0},
 {0.0,1.0}
}

哪款适合我需要的....

我用更多元素测试了这个函数,以确保它运行良好。但我不能确保它一直都能正常工作,而且肯定不是最有效的方法。

【讨论】:

    猜你喜欢
    • 2011-02-28
    • 2018-02-25
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    • 2021-12-28
    • 1970-01-01
    相关资源
    最近更新 更多