随机矩阵的行列式几乎总是为零

时间:2017-01-01 10:45:52

标签: java matrix random

你好,新年快乐。

我实现了一个矩阵类,一个静态方法是创建一个随机矩阵。

这很简单,似乎有用

public static Matrix random(int m, int n)
{
    Random r = new Random();
    Matrix rndMatrix = new Matrix(m, n);
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < n; j++)
        {
            rndMatrix.setEntry(Math.random(), i, j);
        }
    }
    return rndMatrix;
}

矩阵对象的成员是各种方法,2个表示行数和列数的整数,以及表示数据的double [] []。

我还实现了一种计算给定矩阵的行列式的方法。

它相当复杂,但这是代码

public double determinant() throws RuntimeException // Via Gauss elimination. O(n^3)
{
    int m, n;
    double det = 1;
    m = this.getDimensions()[0];
    n = this.getDimensions()[1];

    if(m != n) // not a square matrix
    {
        System.out.println("determinant given non square matrix");
        RuntimeException e = new RuntimeException();
        throw e;
    }

    Matrix copy = new Matrix(this); // work on a copy, don't change original

    for(int i = 0; i < m-1; i++) // pivot row (and column) is i
    {
        double maxPivot = Math.abs(copy.getEntry(i, i));
        int maxPivotRow = i;
        for(int j = 1; j < m; j++) // perform partial pivoting for numerical stability
        {
            double potentialPivot = copy.getEntry(j, i);
            if(Math.abs(potentialPivot) > maxPivot)
            {
                maxPivot = potentialPivot;
                maxPivotRow = j;
            }
        } //now our pivot is at copy[maxPivotRow][i]

        if(maxPivotRow != i) //need to swap rows
        {
            det *= -1; //each row swap changes sign of determinant

            for(int j = 0; j < m; j++) //change row i and row maxPivotRow. j runs on columns
            {
                double temp = copy.getEntry(i, j);
                copy.setEntry(copy.getEntry(maxPivotRow, j), i, j);
                copy.setEntry(temp, maxPivotRow, j);
            } // now our pivot is at copy[i][i]
        }

        if(copy.getEntry(i, i) == 0) //Pivot is 0, meaning determinant is 0
            return det;

        for(int j = i + 1; j < m; j++) // rank!
        {
            double coefficient = copy.getEntry(j, i) / copy.getEntry(i, i);
            for(int k = i; k < m; k++)
            {
                double currentElement = copy.getEntry(j, k);
                copy.setEntry(currentElement - coefficient * copy.getEntry(i, k), j, k);
            }
        } 
    }// copy is now row reduced, upper triangular. determinant is product of diagonal

    for(int i = 0; i < m; i++)
    {
        det *= copy.getEntry(i, i);
    }

    return det;
}

计算通过高斯消除(部分旋转)然后乘以对角线上的元素来完成。我已经多次测试了它似乎有效。

问题在于它不适用于随机矩阵,或者说,我遇到了意想不到的行为。

10次中有9次我将创建一个随机矩阵并计算其行列式,它将打印0.0或-0.0。

这看起来很奇怪。 “大多数”矩阵是可逆的。那么为什么会这样呢?有bug吗?我不懂数学吗?

编辑:一些示例(底部的数字是决定因素

0.9563941736946711 0.39448005321813573 0.5470486104302432 0.5261160742874216 0.3951820646725023 
0.7346088704461295 0.7599880918925735 0.8497744950194082 0.8867153096935724 0.3682481741589534 
0.9263551689754832 0.2317726305104606 0.18178575740374336 0.07986150434799666 0.7819470135579004 
0.1745757641530633 0.25563633619467996 0.2829688806860611 0.5118728924839205 0.03297040489736147 
0.25186307283907405 0.9562803829692509 0.483921593496489 0.8755617387463226 0.31088898779219853 
0.0

0.00891316485803817 0.713796166860513 0.13287589794651955 0.4064378440682588 0.4978814476005716 
0.12055412802144772 0.972471867370921 0.53095134849769 0.22189312703335484 0.8817515464656179 
0.9315367039854036 0.6438575977028148 0.43392574349285307 0.08726203670701893 0.6130528522290233 
0.9643660752404595 0.3691976358204304 0.340490090444587 0.5684232640065617 0.0628244760775013 
0.15365612075823543 0.3168819918400785 0.6665980934501206 0.02089370959057013 0.6078409694254645 
-0.0

0.9621768497790205 0.8676421360459282 0.4465279858313177 0.48320978463573283 0.5439303840591143 
0.09762305323682163 0.42529504824730524 0.7969529998650778 0.5061554064144165 0.4140523901347064 
0.003060974877453826 0.5969505627805348 0.5322677244514962 0.5667640313747856 0.9861085023353954 
0.3615427851315477 0.6472381774117999 0.9852641653717541 0.2397370854247155 0.7528175137110793 
0.5143296881839451 0.020615097451925468 0.24636629586280845 0.39986298958960864 0.7414827709198659 
6.393441112567584E-18

然而,当我创建一个随机3乘3矩阵时:

0.6791409154789895 0.9015085022510533 0.9674292726638446 
0.9059154025420992 0.26610950783426457 0.08492267434013878 
0.6974770770379765 0.4474657891394087 0.12363906335455344 
0.16156349092473768

0.1048566480579386 0.5949449637931188 0.28220872314980017 
0.6303444427050728 0.17136149490672603 0.7630494228097563 
0.010042979011053998 0.4443731402226164 0.44005633657936627 
-0.10955506568102251

0.7080008734798865 0.7058454701623011 0.6520827337491946 
0.10322829578835746 0.7757507432730788 0.3650950541868936 
0.2742422959683706 0.9949312192553693 0.05039578697883251 
-0.23425225979344966

0 个答案:

没有答案