void SymmetricSolver::circulantMul(const BlockCMat& M, mvec& v, unsigned int nPhi) {
    assert(!(v.size()%nPhi));
    assert(M.nCols()*nPhi == v.size());
    
    // stuff vector into vector-of-vectors for circulant blocks
    VarVec<mvec> vv;
    for(unsigned int i=0; i<v.size()/nPhi; i++)
        vv.push_back(mvec(&v[i*nPhi], &v[i*nPhi]+nPhi));
    vv = M.lMultiply<mvec,mvec>(vv);
    
    // pull data back out
    v.getData().resize(M.nRows()*nPhi);
    for(unsigned int i=0; i<M.nRows(); i++)
        for(unsigned int j=0; j<nPhi; j++)
            v[i*nPhi+j] = vv[i][j];
}