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