void L::initNiederreiter
(GeneratorMatrixGen<typename A::type> &gm, A a, int d,
 const typename PolynomialRing<A>::type &irred)
{
    typedef typename A::type T;
    typedef PolynomialRing<A> PolyRing;
    typedef typename PolyRing::type Poly;

    const int degree = irred.degree ();

    const int vSize
        = std::max (gm.getM() + degree - 1,   // these elements are copied to gm
                    (gm.getPrec() + degree + 1));  // used in the loop

    Array<T> v (vSize);
    PolyRing poly (a);

    // cout << "Using " << irred << " for d=" << d << endl;

    Poly newPoly = poly.one();

    int u = 0;

    for (int j = 0; j < gm.getPrec(); j++)
    {
        // cout << "  j=" << j << endl;
        // Do we need a new v?

        if (u == 0)
        {
            Poly oldPoly = newPoly;
            int oldDegree = oldPoly.degree ();

            // calculate polyK+1 from polyK

            poly.mulBy (newPoly, irred);
            int newDegree = newPoly.degree ();
            // cout << "    newPolynomial: " << newPoly << endl;

            // kj can be set to any value between 0 <= kj < newDegree

            const int kj = oldDegree   // proposed by BFN
                           // newDegree - 1    // standard, bad???
                           // 0
                           // (newDegree > 3) ? 3 : oldDegree
                           ;

            std::fill (&v[0], &v[kj], T());  // Set leading v's to 0

            v[kj] = a.one();                     // the next one is 1

            if (kj < oldDegree)
            {
                T term = oldPoly [kj];

                for (int r = kj + 1; r < oldDegree; ++r)
                {
                    v [r] = a.one (); // 1 is arbitrary. Could be 0, too

                    a.addTo (term, a.mul (oldPoly [r], v [r]));
                }

                // set v[] not equal to -term

                v [oldDegree] = a.sub (a.one(), term);

                for (int r = oldDegree + 1; r < newDegree; ++r) v [r] = a.one(); //or 0
            }
            else
            {
                for (int r = kj + 1; r < newDegree; ++r) v [r] = a.one(); // or 0..
            }

            // All other elements are calculated by a recursion parameterized
            // by polyK

            for (int r = 0; r < vSize - newDegree; ++r)
            {
                T term = T();

                for (int i = 0; i < newDegree; ++i)
                {
                    a.addTo (term, a.mul (newPoly [i], v [r+i]));
                }
                v [newDegree + r] = a.neg (term);
            }
        }

        // Set data in ci

        for (int r = 0; r < gm.getM(); ++r)  gm.setd (d,r,j, v[r+u]);

        if (++u == degree) u = 0;
    }
}