我的高斯乔丹消除方法遇到了一些问题。它看起来有点过于简单,但在纸面上它应该可以工作。它将枢轴设置为 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]));
[i](,它实际上是 0。
也:
if (mat[row][row] == 0) {
这对双打来说是有风险的。我会建议像 Math.abs(mat[row][row]( <1e-9
我希望这有所帮助。