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(); } }