'Compute matrix determinant using Bareiss\' fraction-free
algorithm which is an extension of the well known Gaussian
elimination method. This approach is best suited for dense
symbolic matrices and will result in a determinant with
minimal number of fractions. It means that less term
rewriting is needed on resulting formulae.
TODO: Implement algorithm for sparse matrices (SFF),
http://www.eecis.udel.edu/~saunders/papers/sffge/it5.ps.'

def _eval_det_bareiss(self):

    def _find_pivot(l):
        for (pos, val) in enumerate(l):
            if val:
                return (pos, val, None, None)
        return (None, None, None, None)
    def bareiss(mat, cumm=1):
        if (mat.rows == 0):
            return S.One
        elif (mat.rows == 1):
            return mat[(0, 0)]
        (pivot_pos, pivot_val, _, _) = _find_pivot(mat[:, 0])
        if (pivot_pos == None):
            return S.Zero
        sign = ((-1) ** (pivot_pos % 2))
        rows = list((i for i in range(mat.rows) if (i != pivot_pos)))
        cols = list(range(mat.cols))
        tmp_mat = mat.extract(rows, cols)
        def entry(i, j):
            ret = (((pivot_val * tmp_mat[(i, (j + 1))]) - (mat[(pivot_pos, (j + 1))] * tmp_mat[(i, 0)])) / cumm)
            if (not ret.is_Atom):
                cancel(ret)
            return ret
        return (sign * bareiss(self._new((mat.rows - 1), (mat.cols - 1), entry), pivot_val))
    return cancel(bareiss(self))
