高斯乔丹消除算法Java



我的高斯乔丹消除方法遇到了一些问题。它看起来有点过于简单,但在纸面上它应该可以工作。它将枢轴设置为 1,考虑到在 0 的情况下它必须执行交换。然后,它将该行减去具有相同数据透视列索引号的剩余行的值 conindex。

我在最终算法中使用这些方法。

行乘法:

public static double[] rowMul(double[] row, double scalar) {
    BigDecimal[] temp = new BigDecimal[row.length];
    BigDecimal s = new BigDecimal(scalar);
    double[] newrow = new double[row.length];
    for (int i = 0; i < row.length; i++) {
        temp[i] = new BigDecimal(row[i]).multiply(s);
        newrow[i] = temp[i].doubleValue();
    }
    return newrow;
}

划分行:

public static double[] rowDiv(double[] row, double divisor) {
    BigDecimal[] temp = new BigDecimal[row.length];
    BigDecimal s = new BigDecimal(divisor);
    double[] newrow = new double[row.length];
    for (int i = 0; i < row.length; i++) {
        temp[i] = new BigDecimal(row[i]).divide(s);
        newrow[i] = temp[i].doubleValue();
    }
    return newrow;
}

行减法:

public static double[] subtractRow(double[] mat1, double[] mat2) {
    double[] c = new double[mat1.length];
    for (int i = 0; i < mat1.length; i++) {
        c[i] = mat1[i] - mat2[i];
    }
    return c;
}

数据透视检查和行交换:

public static boolean checkPivot(double[][] mat, int row) {
    if (mat[row][row] == 0) {
        return true;
    } else {
        return false;
    }
}
// Keeps track of the number of swaps performed to secure a finite solution.
private static int swapcount = 0;
// Mind giving the index value. So row starting from 0 up instead of 1!
public static double[][] swapRow(double[][] mat, int row) {
    swapcount++;
    if (swapcount >= mat.length - row) {
        System.out.println("no possible combinations.");
        swapcount = 0;
        return mat;
    }
    double[] temp = mat[row];
    for (int i = row; i < mat.length - 1; i++) {
        mat[i] = mat[i + 1];
    }
    mat[mat.length - 1] = temp;
    if (checkPivot(mat, row) == true) {
        mat = swapRow(mat, row);
    }
    swapcount = 0;
    return mat;
}

然后是我最后的高斯乔丹算法:

public static double[][] gaussJordan(double[][] matrix) {
    double[][] mat = matrix;
    int m = mat.length;
    for (int i = 0; i < m; i++) {
        if (checkPivot(mat, i) == true) {
            mat = swapRow(mat, i);
        }
        mat[i] = rowDiv(mat[i], mat[i][i]);
        for (int j = 0; j < m; j++) {
            if (j == i) {
                j++;
            } else {
                mat[j] = subtractRow(mat[j], rowMul(mat[i], mat[j][i]));
            }
        }
    }
    return mat;
}

如果我给它这个矩阵来计算。

private static double[][] elim = {
    {-20,-10,10,-10},
    {  0, 10,-5, 10},
    {-10, 10,15, 20}
};

它以某种方式跳过左侧方形 3 x 3 矩阵的中间列并返回。

1.0 0.375 0.0 0.625 
0.0 1.75  0.0 2.25 
0.0 1.5   1.0 2.5 

预期结果是:

1.0 0.0 0.0 0.14286
0.0 1.0 0.0 1.28571
0.0 0.0 1.0 0.57143

有人可以帮助我找到我一定忽略的东西吗?我只是希望它没有什么明显的!我感谢你的麻烦。

mat[j] = subtractRow(mat[j], rowMul(mat[i], mat[j][i]));

似乎不对。有了它,mat[j][i] 的新值是 mat[j][i] - (mat[i][i] * mat[j][i](,即 != 0。

我认为应该是

mat[j] = subtractRow(mat[j], rowMul(mat[i], mat[j][i] / mat[i][i]));

mat[j][i] 的新值是 mat[j][i] - (mat[i][i] * mat[j][i]/mat[i]

[i](,它实际上是 0。

也:

if (mat[row][row] == 0) {

这对双打来说是有风险的。我会建议像 Math.abs(mat[row][row]( <1e-9

我希望这有所帮助。

最新更新