Exemplo n.º 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();
            }
        }