算法名称:求矩阵行列式的值(基于LU分解法)
算法描述:
对矩阵进行LU分解,显然,分解后的矩阵对角线上元素的乘积即为原始矩阵行列式的值,
注:由于在进行LU分解时可能会进行行交换的情况,而每次行交换都会带来行列式的符号变化,所以我们要记录行交换次数的奇偶性,奇数则符号改变,偶数则符号不变,请密切注意下面程序中出现的用来标记变换次数奇偶性的变量parity。
大矩阵情况的应对策略:
对实际出现的大矩阵,很可能出现行列式值上溢或下溢,超出了计算机所能表示的浮点数的范围。在这种情况下,可以修改下述程序中的循环部分,例如除以以十的幂次并单独保存该比例因子,或求出各乘数值的对数和,并单独保存其符号。
运行示例:
Origin matrix:
| 0.0 2.0 0.0 1.0 |
| 2.0 2.0 3.0 2.0 |
| 4.0 -3.0 0.0 1.0 |
| 6.0 1.0 -6.0 -5.0 |
-----------------------------------------------
After LU decomposition:
| 6.0 1.0 -6.0 -5.0 |
| 0.0 2.0 0.0 1.0 |
| 0.3333333333333333 0.8333333333333334 5.0 2.833333333333333 |
| 0.6666666666666666 -1.8333333333333333 0.8 3.8999999999999995 |
-----------------------------------------------
Its determinate value:-233.99999999999997
示例程序:
package com.nc4nr.chapter02.det;

public class Det ...{

double[][] a = ...{
...{0.0, 2.0, 0.0, 1.0},
...{2.0, 2.0, 3.0, 2.0},
...{4.0, -3.0, 0.0, 1.0},
...{6.0, 1.0, -6.0, -5.0}
};
int anrow = 4;
double[] vv = new double[anrow];
double parity = 1.0; // 记录做过行交换次数的奇偶性,正表示偶数次。用于行列式计算决定符号。

private void lucmp() ...{
int n = anrow, imax = 0;
for (int i = 0; i < n; i++) ...{
double big = 0.0;
for (int j = 0; j < n; j++) ...{
double temp = Math.abs(a[i][j]);
if (temp > big) big = temp;
}
vv[i] = 1.0/big;
}
for (int j = 0; j < n; j++) ...{
for (int i = 0; i < j; i++) ...{
double sum = a[i][j];
for (int k = 0; k < i; k++) sum -= a[i][k]*a[k][j];
a[i][j] = sum;
}
double big = 0.0;
for (int i = j; i < n; i++) ...{
double sum = a[i][j];
for (int k = 0; k < j; k++) sum -= a[i][k]*a[k][j];
a[i][j] = sum;
double dum = vv[i] * Math.abs(sum);
if (dum >= big) ...{
big = dum;
imax = i;
}
}
if (j != imax) ...{
for (int k = 0; k < n; k++) ...{
double mid = a[imax][k];
a[imax][k] = a[j][k];
a[j][k] = mid;
}
double mid = vv[imax];
vv[imax] = vv[j];
vv[j] = mid;
parity = -parity;
}
if (j != n - 1) ...{
double dum = 1.0/a[j][j];
for (int i = j+1; i < n; i++) a[i][j] *= dum;
}
}
}

private void det() ...{
double r = 1.0;
int n = anrow;
for (int i = 0; i < n; i++) r *= a[i][i];
System.out.println("Its determinate value:" + r * parity);
}

private void output(double a[][], int anrow) ...{
for (int i = 0; i < anrow; i++) ...{
System.out.println(" | " + a[i][0] + " " +
a[i][1] + " " +
a[i][2] + " " +
a[i][3] + " | ");
}
System.out.println("-----------------------------------------------");
}

public Det() ...{
System.out.println("Origin matrix:");
output(a,4);
lucmp();
System.out.println("After LU decomposition:");
output(a,4);
det();
}

public static void main(String[] args) ...{
new Det();
}
}
本文介绍了一种通过LU分解来求解矩阵行列式的算法。通过示例程序详细阐述了这一过程,适用于理解和实现矩阵运算。
4962

被折叠的 条评论
为什么被折叠?



