我正在尝试用Java计算逆矩阵。
我遵循伴随方法(首先计算伴随矩阵,然后转置这个矩阵,最后乘以行列式的值的倒数)。
当矩阵不是太大时,它就会起作用。我已经检查过,对于大小不超过12x12的矩阵,很快就能提供结果。但是,当矩阵大于12x12时,完成计算所需的时间呈指数增长。
我需要求逆的矩阵是19x19,这需要太多的时间。时间消耗较多的方法是用于行列式计算的方法。
我使用的代码是:
public static double determinant(double[][] input) {
int rows = nRows(input); //number of rows in the matrix
int columns = nColumns(input); //number of columns in the matrix
double determinant = 0;
if ((rows== 1) && (columns == 1)) return input[0][0];
int sign = 1;
for (int column = 0; column < columns; column++) {
double[][] submatrix = getSubmatrix(input, rows, columns,column);
determinant = determinant + sign*input[0][column]*determinant(submatrix);
sign*=-1;
}
return determinant;
} 有人知道如何更有效地计算大型矩阵的行列式吗?如果没有,有谁知道如何使用其他算法计算大型矩阵的求逆?
谢谢
发布于 2010-01-03 03:59:06
成倍增长?不,我相信矩阵求逆是O(N^3)。
我推荐使用LU decomposition来求解矩阵方程。当你使用行列式时,你不需要求解行列式。
更好的是,查看一个包来帮助你。JAMA出现在我的脑海中。
12x12或19x19不是大矩阵。解决具有数万或数十万个自由度的问题是很常见的。
这里有一个如何使用JAMA的工作示例。在编译和运行时,必须在CLASSPATH中包含JAMA JAR:
package linearalgebra;
import Jama.LUDecomposition;
import Jama.Matrix;
public class JamaDemo
{
public static void main(String[] args)
{
double [][] values = {{1, 1, 2}, {2, 4, -3}, {3, 6, -5}}; // each array is a row in the matrix
double [] rhs = { 9, 1, 0 }; // rhs vector
double [] answer = { 1, 2, 3 }; // this is the answer that you should get.
Matrix a = new Matrix(values);
a.print(10, 2);
LUDecomposition luDecomposition = new LUDecomposition(a);
luDecomposition.getL().print(10, 2); // lower matrix
luDecomposition.getU().print(10, 2); // upper matrix
Matrix b = new Matrix(rhs, rhs.length);
Matrix x = luDecomposition.solve(b); // solve Ax = b for the unknown vector x
x.print(10, 2); // print the solution
Matrix residual = a.times(x).minus(b); // calculate the residual error
double rnorm = residual.normInf(); // get the max error (yes, it's very small)
System.out.println("residual: " + rnorm);
}
}根据quant_dev的建议,下面是使用Apache Commons Math解决的相同问题:
package linearalgebra;
import org.apache.commons.math.linear.Array2DRowRealMatrix;
import org.apache.commons.math.linear.ArrayRealVector;
import org.apache.commons.math.linear.DecompositionSolver;
import org.apache.commons.math.linear.LUDecompositionImpl;
import org.apache.commons.math.linear.RealMatrix;
import org.apache.commons.math.linear.RealVector;
public class LinearAlgebraDemo
{
public static void main(String[] args)
{
double [][] values = {{1, 1, 2}, {2, 4, -3}, {3, 6, -5}};
double [] rhs = { 9, 1, 0 };
RealMatrix a = new Array2DRowRealMatrix(values);
System.out.println("a matrix: " + a);
DecompositionSolver solver = new LUDecompositionImpl(a).getSolver();
RealVector b = new ArrayRealVector(rhs);
RealVector x = solver.solve(b);
System.out.println("solution x: " + x);;
RealVector residual = a.operate(x).subtract(b);
double rnorm = residual.getLInfNorm();
System.out.println("residual: " + rnorm);
}
}根据您的情况调整这些策略。
发布于 2010-01-03 04:26:54
为此,我建议使用Apache Commons Math 2.0。JAMA是一个已死的项目。ACM 2.0实际上取自JAMA的线性代数,并进一步发展了它。
发布于 2013-03-12 14:45:38
la4j (线性代数for Java)库支持矩阵求逆。下面是一个简单的例子:
Matrix a = new Basic2DMatrix(new double[][]{
{ 1.0, 2.0, 3.0 },
{ 4.0, 5.0, 6.0 },
{ 7.0, 8.0. 9.0 }
});
Matrix b = a.invert(Matrices.DEFAULT_INVERTOR); // uses Gaussian Eliminationhttps://stackoverflow.com/questions/1992638
复制相似问题