【发布时间】:2014-12-20 18:17:30
【问题描述】:
我的 Gauss Jordan 消除方法有些问题。它看起来有点过于简单,但在纸面上它应该可以工作。考虑到在 0 的情况下它必须执行交换,它将枢轴设置为 1。然后它减去该行乘以与数据透视列具有相同索引号的剩余行的值 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
有人可以帮我找出我必须忽略的东西吗?我只是希望它没有什么明显的!谢谢你的麻烦。
【问题讨论】:
-
请包括预期结果
-
我没有得到你的问题的答案,但你似乎以一种相当奇怪的方式混合了
double和BigDecimal。尝试使用这两种类型中的任何一种进行代数的问题在于,它们都不能准确地表示像 1/3 这样的简单分数,因此应该给你0的行操作实际上没有。我建议尝试找到有理数的实现。 -
好的,谢谢您的反应。我会调查的。
-
我必须承认这让我有些不安。而且我想我知道一种实现有理数的方法,特别是在除法中。然而,不知何故,感觉不像是导致这个特定问题的原因。尽管如此,我还是会把你的建议牢记在心。再次感谢您。
标签: java algorithm matrix linear-algebra