BitMatrix<dim> subquotientMap
(const Subquotient<dim>& source,
 const Subquotient<dim>& dest,
 const BitMatrix<dim>& m)
{
    assert(m.numColumns()==source.rank());
    assert(m.numRows()==dest.rank());

    BitMatrix<dim> result(dest.dimension(),0);

    // restrict m to source.space()
    for (RankFlags::iterator it=source.support().begin(); it(); ++it)
    {
        SmallBitVector v = m*source.space().basis(*it);
        assert(v.size()==dest.rank());

        /*
        // go to canonical representative modulo destination subspace
        dest.denominator().mod_reduce(v);
        assert(v.size()==dest.rank());

        // get coordinates in canonical basis
        v.slice(dest.space().support());  // express |v| in basis of |d_space|
        assert(v.size()==dest.space().dimension());

        v.slice(dest.support());
        */

        v=dest.toBasis(v);
        assert(v.size()==dest.dimension()); // dimension of the subquotient

        result.addColumn(v);
    }
    return result;
}
void Subspace<dim>::apply(const BitMatrix<dim>& r)
{
    assert(r.numColumns()==d_rank);

    BitVectorList<dim> b;
    b.reserve(dimension());

    for (size_t j = 0; j<dimension(); ++j)
    {
        b.push_back(r*d_basis[j]);
        assert(b.back().size()==r.numRows());
    }

    Subspace<dim> ns(b,r.numRows()); // construct (and normalize) new subspace
    swap(ns); // and install it in our place
}