Java 大矩阵的行列式
我正在用Java做一个项目,我必须使用BigInteger类来实现一个加密方法 我有平方矩阵nxn,其中n可以是200,我需要计算行列式。我用子矩阵的行列式做了这个方法,但是它需要花费很长时间来计算Java 大矩阵的行列式,java,matrix,biginteger,determinants,non-recursive,Java,Matrix,Biginteger,Determinants,Non Recursive,我正在用Java做一个项目,我必须使用BigInteger类来实现一个加密方法 我有平方矩阵nxn,其中n可以是200,我需要计算行列式。我用子矩阵的行列式做了这个方法,但是它需要花费很长时间来计算 public BigInteger determinant(Matrix matrix){ if (matrix.getColumns()!=matrix.getRows()){ System.out.println("The matrix is not square");
public BigInteger determinant(Matrix matrix){
if (matrix.getColumns()!=matrix.getRows()){
System.out.println("The matrix is not square");
return BigInteger.valueOf(-1);
}
if (matrix.getColumns() == 1) {
return matrix.getMatrix()[0][0];
}
if (matrix.getRows()==2) {
return ((matrix.getValueAt(0, 0).multiply(matrix.getValueAt(1, 1)))).subtract(( matrix.getValueAt(0, 1).multiply(matrix.getValueAt(1, 0))));
}
BigInteger sum = BigInteger.valueOf(0);
for (int i=0; i<matrix.getColumns(); i++) {
sum = sum.add(this.changeSign(BigInteger.valueOf(i)).multiply(matrix.getValueAt(0, i)).multiply(determinant(createSubMatrix(matrix, 0, i))));// * determinant(createSubMatrix(matrix, 0, i));
}
return sum;
}
公共大整数行列式(矩阵){
if(matrix.getColumns()!=matrix.getRows()){
System.out.println(“矩阵不是正方形”);
返回BigInteger.valueOf(-1);
}
if(matrix.getColumns()==1){
return matrix.getMatrix()[0][0];
}
if(matrix.getRows()==2){
返回((matrix.getValueAt(0,0)。乘(matrix.getValueAt(1,1)))。减((matrix.getValueAt(0,1)。乘(matrix.getValueAt(1,0)));
}
BigInteger总和=BigInteger.valueOf(0);
对于(int i=0;i我已经将此作为一条评论发布,但我认为这实际上可以解决您的问题,所以我也将其作为一个答案发布。
您可以使用此软件包:计算大型矩阵判定的一种常见做法是使用LUP分解。在这种情况下,可以使用以下思想计算判定值:
{L, U, P} = LUP(A)
sign = -1 ^ 'number of permutations in P'
det(A) = diagonalProduct(U) * sign
这就是大型数学软件包的作用。您可能应该自己实现LU。我相信这正是您所需要的。使用此类,您可以计算任意维数的矩阵的行列式
这个类使用许多不同的方法来使矩阵变成三角形,然后计算其行列式。它可以用于高维矩阵,如500 x 500甚至更高。这个类的优点是,您可以在BigDecimal中得到结果,所以并没有无穷大,您将得到答案总是准确的。顺便说一句,使用多种方法并避免递归会使答案的速度更快,性能更高。希望能有所帮助
import java.math.BigDecimal;
public class DeterminantCalc {
private double[][] matrix;
private int sign = 1;
DeterminantCalc(double[][] matrix) {
this.matrix = matrix;
}
public int getSign() {
return sign;
}
public BigDecimal determinant() {
BigDecimal deter;
if (isUpperTriangular() || isLowerTriangular())
deter = multiplyDiameter().multiply(BigDecimal.valueOf(sign));
else {
makeTriangular();
deter = multiplyDiameter().multiply(BigDecimal.valueOf(sign));
}
return deter;
}
/* receives a matrix and makes it triangular using allowed operations
on columns and rows
*/
public void makeTriangular() {
for (int j = 0; j < matrix.length; j++) {
sortCol(j);
for (int i = matrix.length - 1; i > j; i--) {
if (matrix[i][j] == 0)
continue;
double x = matrix[i][j];
double y = matrix[i - 1][j];
multiplyRow(i, (-y / x));
addRow(i, i - 1);
multiplyRow(i, (-x / y));
}
}
}
public boolean isUpperTriangular() {
if (matrix.length < 2)
return false;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < i; j++) {
if (matrix[i][j] != 0)
return false;
}
}
return true;
}
public boolean isLowerTriangular() {
if (matrix.length < 2)
return false;
for (int j = 0; j < matrix.length; j++) {
for (int i = 0; j > i; i++) {
if (matrix[i][j] != 0)
return false;
}
}
return true;
}
public BigDecimal multiplyDiameter() {
BigDecimal result = BigDecimal.ONE;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
if (i == j)
result = result.multiply(BigDecimal.valueOf(matrix[i][j]));
}
}
return result;
}
// when matrix[i][j] = 0 it makes it's value non-zero
public void makeNonZero(int rowPos, int colPos) {
int len = matrix.length;
outer:
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
if (matrix[i][j] != 0) {
if (i == rowPos) { // found "!= 0" in it's own row, so cols must be added
addCol(colPos, j);
break outer;
}
if (j == colPos) { // found "!= 0" in it's own col, so rows must be added
addRow(rowPos, i);
break outer;
}
}
}
}
}
//add row1 to row2 and store in row1
public void addRow(int row1, int row2) {
for (int j = 0; j < matrix.length; j++)
matrix[row1][j] += matrix[row2][j];
}
//add col1 to col2 and store in col1
public void addCol(int col1, int col2) {
for (int i = 0; i < matrix.length; i++)
matrix[i][col1] += matrix[i][col2];
}
//multiply the whole row by num
public void multiplyRow(int row, double num) {
if (num < 0)
sign *= -1;
for (int j = 0; j < matrix.length; j++) {
matrix[row][j] *= num;
}
}
//multiply the whole column by num
public void multiplyCol(int col, double num) {
if (num < 0)
sign *= -1;
for (int i = 0; i < matrix.length; i++)
matrix[i][col] *= num;
}
// sort the cols from the biggest to the lowest value
public void sortCol(int col) {
for (int i = matrix.length - 1; i >= col; i--) {
for (int k = matrix.length - 1; k >= col; k--) {
double tmp1 = matrix[i][col];
double tmp2 = matrix[k][col];
if (Math.abs(tmp1) < Math.abs(tmp2))
replaceRow(i, k);
}
}
}
//replace row1 with row2
public void replaceRow(int row1, int row2) {
if (row1 != row2)
sign *= -1;
double[] tempRow = new double[matrix.length];
for (int j = 0; j < matrix.length; j++) {
tempRow[j] = matrix[row1][j];
matrix[row1][j] = matrix[row2][j];
matrix[row2][j] = tempRow[j];
}
}
//replace col1 with col2
public void replaceCol(int col1, int col2) {
if (col1 != col2)
sign *= -1;
System.out.printf("replace col%d with col%d, sign = %d%n", col1, col2, sign);
double[][] tempCol = new double[matrix.length][1];
for (int i = 0; i < matrix.length; i++) {
tempCol[i][0] = matrix[i][col1];
matrix[i][col1] = matrix[i][col2];
matrix[i][col2] = tempCol[i][0];
}
}
import java.math.BigDecimal;
公共类行列式计算{
私有双[]矩阵;
私有整数符号=1;
行列式计算(双[]矩阵){
这个矩阵=矩阵;
}
公共int getSign(){
返回标志;
}
公共双十进制行列式(){
大十进制决定;
if(isUpperTriangular()| | isLowerTriangular())
Dete=倍增直径().multiply(BigDecimal.valueOf(sign));
否则{
使三角形();
Dete=倍增直径().multiply(BigDecimal.valueOf(sign));
}
返回阻止;
}
/*接收一个矩阵,并使用允许的操作使其成为三角形
关于列和行
*/
公共空间(英文){
对于(int j=0;jj;i--){
if(矩阵[i][j]==0)
继续;
双x=矩阵[i][j];
双y=矩阵[i-1][j];
多晶硅(i,(-y/x));
addRow(i,i-1);
多路(i,(-x/y));
}
}
}
公共布尔值(){
如果(矩阵长度<2)
返回false;
对于(int i=0;ii;i++){
如果(矩阵[i][j]!=0)
返回false;
}
}
返回true;
}
公共双十进制多直径计(){
BigDecimal结果=BigDecimal.1;
对于(int i=0;i=col;i--){
对于(int k=matrix.length-1;k>=col;k--){
双tmp1=矩阵[i][col];
双tmp2=矩阵[k][col];
if(数学abs(tmp1)import java.math.BigDecimal;
import java.security.SecureRandom;
import java.text.NumberFormat;
import java.util.Scanner;
public class DeterminantTest {
public static void main(String[] args) {
String determinant;
//generating random numbers
int len = 500;
SecureRandom random = new SecureRandom();
double[][] matrix = new double[len][len];
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
matrix[i][j] = random.nextInt(500);
System.out.printf("%15.2f", matrix[i][j]);
}
}
System.out.println();
/*double[][] matrix = {
{1, 5, 2, -2, 3, 2, 5, 1, 0, 5},
{4, 6, 0, -2, -2, 0, 1, 1, -2, 1},
{0, 5, 1, 0, 1, -5, -9, 0, 4, 1},
{2, 3, 5, -1, 2, 2, 0, 4, 5, -1},
{1, 0, 3, -1, 5, 1, 0, 2, 0, 2},
{1, 1, 0, -2, 5, 1, 2, 1, 1, 6},
{1, 0, 1, -1, 1, 1, 0, 1, 1, 1},
{1, 5, 5, 0, 3, 5, 5, 0, 0, 6},
{1, -5, 2, -2, 3, 2, 5, 1, 1, 5},
{1, 5, -2, -2, 3, 1, 5, 0, 0, 1}
};
double[][] matrix = menu();*/
DeterminantCalc deter = new DeterminantCalc(matrix);
BigDecimal det = deter.determinant();
determinant = NumberFormat.getInstance().format(det);
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
System.out.printf("%15.2f", matrix[i][j]);
}
System.out.println();
}
System.out.println();
System.out.printf("%s%s%n", "Determinant: ", determinant);
System.out.printf("%s%d", "sign: ", deter.getSign());
}
public static double[][] menu() {
Scanner scanner = new Scanner(System.in);
System.out.print("Matrix Dimension: ");
int dim = scanner.nextInt();
double[][] inputMatrix = new double[dim][dim];
System.out.println("Set the Matrix: ");
for (int i = 0; i < dim; i++) {
System.out.printf("%5s%d%n", "row", i + 1);
for (int j = 0; j < dim; j++) {
System.out.printf("M[%d][%d] = ", i + 1, j + 1);
inputMatrix[i][j] = scanner.nextDouble();
}
System.out.println();
}
scanner.close();
return inputMatrix;
}