Java优化的Cramers规则函数
最近学习了precalculus中的Cramers规则,并决定用Java制作一个算法来帮助我更好地理解它 下面的代码100%正确地工作,但是它没有使用任何类型的for循环来以更简单的方式完成它所做的事情 问:Java中是否有更优雅的Cramers规则实现 我想做一个基本的行列式方法,然后在需要取Dx,Dy和Dz的行列式时做一些列交换。(对于Dx,将第4列与原始矩阵的第1列交换,然后取行列式并除以原始行列式。) 这听起来不错吧Java优化的Cramers规则函数,java,algorithm,math,matrix,linear-algebra,Java,Algorithm,Math,Matrix,Linear Algebra,最近学习了precalculus中的Cramers规则,并决定用Java制作一个算法来帮助我更好地理解它 下面的代码100%正确地工作,但是它没有使用任何类型的for循环来以更简单的方式完成它所做的事情 问:Java中是否有更优雅的Cramers规则实现 我想做一个基本的行列式方法,然后在需要取Dx,Dy和Dz的行列式时做一些列交换。(对于Dx,将第4列与原始矩阵的第1列交换,然后取行列式并除以原始行列式。) 这听起来不错吧 public static void main(String[
public static void main(String[] args) {
int[][] matrix = new int[3][3];
matrix[0] = new int[] { 3, 5, -1, -2 };
matrix[1] = new int[] { 1, -4, 2, 13 };
matrix[2] = new int[] { 2, 4, 3, 1 };
int[] r = crame(matrix);
info("x: " + r[0] + ", y: " + r[1] + ", z: " + r[2]);
for(int i = 0; i < matrix.length; i++) {
int[] base = matrix[i];
if(check(base, r, base[3])) {
info("System " + (i+1) + " checks!");
} else {
info("System " + (i+1) + " fails check!");
}
}
}
public static int[] crame(int[][] m) {
int[] result;
if (m.length == 2) {
result = new int[2];
int D = (m[0][0] * m[1][1]) - (m[1][0] * m[0][1]);
int Dx = (m[0][2] * m[1][1]) - (m[1][2] * m[0][1]);
int Dy = (m[0][0] * m[1][2]) - (m[1][0] * m[0][2]);
result[0] = (int) (Dx / D);
result[1] = (int) (Dy / D);
} else if (m.length == 3) {
result = new int[3];
int D = (((m[0][2] * m[1][1] * m[0][2]) + (m[2][1] * m[1][2] * m[0][0]) + (m[2][2]
* m[1][0] * m[0][2])) - ((m[0][0] * m[1][1] * m[2][2])
+ (m[0][1] * m[1][2] * m[0][2]) + (m[0][2] * m[1][0] * m[2][1])));
int Dx = (((m[2][3] * m[1][1] * m[0][2]) + (m[2][1] * m[1][2] * m[0][3]) + (m[2][2]
* m[1][3] * m[0][1])) - ((m[0][3] * m[1][1] * m[2][2])
+ (m[0][1] * m[1][2] * m[2][3]) + (m[0][2] * m[1][3] * m[2][1])));
int Dy = (((m[2][0] * m[1][3] * m[0][2]) + (m[2][3] * m[1][2] * m[0][3]) + (m[2][2]
* m[1][0] * m[0][3])) - ((m[0][0] * m[1][3] * m[2][2])
+ (m[0][3] * m[1][2] * m[2][0]) + (m[0][2] * m[1][0] * m[2][3])));
int Dz = (((m[2][0] * m[1][1] * m[0][3]) + (m[2][1] * m[1][3] * m[0][0]) + (m[2][3]
* m[1][0] * m[0][1])) - ((m[0][0] * m[1][1] * m[2][3])
+ (m[0][1] * m[1][3] * m[2][0]) + (m[0][3] * m[1][0] * m[2][1])));
result[0] = (int) (Dx / D);
result[1] = (int) (Dy / D);
result[2] = (int) (Dz / D);
} else {
return new int[] {};
}
return result;
}
public static int product(int[] a, int[] b) {
int p = 0;
int[] fin = new int[(a.length -1)];
for(int x = 0; x < fin.length; x++) {
fin[x] = a[x] * b[x];
}
for (int f : fin) {
p += f;
}
return p;
}
public static boolean check(int[] a, int[] b, int z) {
return product(a, b) == z;
}
public static void info(String log) {
System.out.println(log);
}
publicstaticvoidmain(字符串[]args){
int[][]矩阵=新int[3][3];
矩阵[0]=newint[]{3,5,-1,-2};
矩阵[1]=newint[]{1,-4,2,13};
矩阵[2]=newint[]{2,4,3,1};
int[]r=crame(矩阵);
信息(“x:+r[0]+”,y:+r[1]+”,z:+r[2]);
对于(int i=0;i
我的问题是关于一种特定的算法,它只适用于用Cramers规则求解方程组,有没有更优雅的算法?该函数仅针对平方矩阵设计
这不是一个家庭作业,在HS之后,我将学习CS,并且我一直致力于开发算法作为初步实践
感谢您查看此信息您的方法至少对我来说不错;然而,我可能不知道有什么更有效的方法。不有趣的部分可能是找出如何最好地实现行列式计算方法,因为它显然是
但一旦你知道这是可行的,剩下的对我来说就没问题了。缓存原始矩阵的行列式,在列中替换等。首先,Cramers规则有一种完美的方式:它将线性系统的代数解作为其系数中的有理函数给出 然而,实际上,它有其局限性。虽然对于2x2系统来说,这是最完美的公式,对于3x3系统来说仍然很好,但如果以简单的方式实施,其性能会随着每个附加维度而恶化 用Leverrier-Faddeev算法几乎可以实现Cramers规则的字面实现。它只需要计算矩阵积和矩阵迹,以及处理矩阵对角线。它不仅计算矩阵A的行列式(以及特征多项式的其他系数),而且在其迭代矩阵中还包含or因子矩阵A#。关于这个矩阵有趣的事实是,它允许将A*x=b的解写成(A#*b)/det(A),也就是说,A#*b的条目已经是Cramers规则所要求的其他行列式 Leverrier Faddeev需要n4+O(n3)操作。同样的结果也可以通过更复杂的Samuelson算法得到,该算法的复杂度只有该算法的三分之一,即n4/3+O(n3)
如果系统(A | b)首先转换为三角形形式,那么Cramers规则中所需行列式的计算就变得非常简单。这可以通过Gauß消元法、aka-LU分解(通过旋转实现数值稳定性)或QR分解(最容易调试的应该是带有Givens旋转的变体)来实现。然后,在三角形系统中,有效地应用Cramers规则是向后代换。准确地找到了如何有效地做到这一点 提供了一种无缝行列式的方法,并提到了矩阵分解。我还没有学会这一点,因为它不是一个HS级别的概念,但我用它做了一些问题,这是一个可靠的方法 最终代码:
public static void main(String[] args) {
int[][] matrix = new int[3][3];
matrix[0] = new int[] { 3, 5, -1, -2 };
matrix[1] = new int[] { 1, -4, 2, 13 };
matrix[2] = new int[] { 2, 4, 3, 1 };
int[] r = crame(matrix);
info("x: " + r[0] + ", y: " + r[1] + ", z: " + r[2]);
for (int i = 0; i < matrix.length; i++) {
int[] base = matrix[i];
if (check(base, r, base[3])) {
info("System " + (i + 1) + " checks!");
} else {
info("System " + (i + 1) + " fails check!");
}
}
}
public static int getDet(int[][] a) {
int n = a.length - 1;
if (n < 0)
return 0;
int M[][][] = new int[n + 1][][];
M[n] = a; // init first, largest, M to a
// create working arrays
for (int i = 0; i < n; i++)
M[i] = new int[i + 1][i + 1];
return getDet(M, n);
} // end method getDecDet double [][] parameter
public static int getDet(int[][][] M, int m) {
if (m == 0)
return M[0][0][0];
int e = 1;
// init subarray to upper left mxm submatrix
for (int i = 0; i < m; i++)
for (int j = 0; j < m; j++)
M[m - 1][i][j] = M[m][i][j];
int sum = M[m][m][m] * getDet(M, m - 1);
// walk through rest of rows of M
for (int i = m - 1; i >= 0; i--) {
for (int j = 0; j < m; j++)
M[m - 1][i][j] = M[m][i + 1][j];
e = -e;
sum += e * M[m][i][m] * getDet(M, m - 1);
} // end for each row of matrix
return sum;
} // end getDecDet double [][][], int
public static int[] crame(int[][] m) {
int[] result;
if (m.length == 2) {
result = new int[m.length];
int D = getDet(m);
for (int i = 0; i < m.length; i++) {
result[i] = getDet(slide(m, i, m.length)) / D;
}
} else if (m.length == 3) {
result = new int[m.length];
int D = getDet(m);
for (int i = 0; i < m.length; i++) {
result[i] = (getDet(slide(m, i, m.length)) / D);
}
} else {
return new int[] {};
}
return result;
}
public static int[][] slide(int[][] base, int col, int fin) {
int[][] copy = new int[base.length][];
for (int i = 0; i < base.length; i++) {
int[] aMatrix = base[i];
int aLength = aMatrix.length;
copy[i] = new int[aLength];
System.arraycopy(aMatrix, 0, copy[i], 0, aLength);
}
for (int i = 0; i < base.length; i++) {
copy[i][col] = base[i][fin];
}
return copy;
}
public static int product(int[] a, int[] b) {
int p = 0;
int[] fin = new int[(a.length - 1)];
for (int x = 0; x < fin.length; x++) {
fin[x] = a[x] * b[x];
}
for (int f : fin) {
p += f;
}
return p;
}
public static boolean check(int[] a, int[] b, int z) {
return product(a, b) == z;
}
public static void info(String log) {
System.out.println(log);
}
publicstaticvoidmai