示例#1
0
        public static float Determinant(MatrixFixed M, bool balance)
        {
            int n = M.Rows;

            //assert(M.Columns() == n);

            switch (n)
            {
            case 1: return(M[0, 0]);

            case 2: return(Determinant(M[0], M[1]));

            case 3: return(Determinant(M[0], M[1], M[2]));

            case 4: return(Determinant(M[0], M[1], M[2], M[3]));

            default:
                if (balance)
                {
                    MatrixFixed tmp      = new MatrixFixed(M);
                    float       scalings = 1;
                    for (int t = 0; t < 5; ++t)
                    {
                        float rn;
                        // normalize rows.
                        for (uint i = 0; i < n; ++i)
                        {
                            rn = tmp.GetRow((int)i).RMS();
                            if (rn > 0)
                            {
                                scalings *= rn;
                                tmp.ScaleRow((int)i, 1.0f / rn);
                            }
                        }
                        // normalize columns.
                        for (uint i = 0; i < n; ++i)
                        {
                            rn = tmp.GetColumn((int)i).RMS();
                            if (rn > 0)
                            {
                                scalings *= rn;
                                tmp.ScaleColumn((int)i, 1.0f / rn);
                            }
                        }

                        /*
                         #if 0
                         *      // pivot
                         *      for (int k=0; k<n-1; ++k) {
                         *        // find largest element after (k, k):
                         *        int i0 = k, j0 = k;
                         *        abs_t v0(0);
                         *        for (int i=k; i<n; ++i) {
                         *          for (int j=k; j<n; ++j) {
                         *            abs_t v = std::abs(tmp[i][j]);
                         *            if (v > v0) {
                         *              i0 = i;
                         *              j0 = j;
                         *              v0 = v;
                         *            }
                         *          }
                         *        }
                         *        // largest element is in position (i0, j0).
                         *        if (i0 != k) {
                         *          for (int j=0; j<n; ++j)
                         *            std::swap(tmp[k][j], tmp[i0][j]);
                         *          scalings = -scalings;
                         *        }
                         *        if (j0 != k) {
                         *          for (int i=0; i<n; ++i)
                         *            std::swap(tmp[i][k], tmp[i][j0]);
                         *          scalings = -scalings;
                         *        }
                         *      }
                         #endif
                         */
                    }
                    float balanced_det = (new QR(tmp)).Determinant();
                    //std::clog << __FILE__ ": scalings, balanced_det = " << scalings << ", " << balanced_det << std::endl;
                    return((float)(scalings) * balanced_det);
                }
                else
                {
                    return((new QR(M)).Determinant());
                }
            }
        }