void unipoly::normal_base(INT p, matrix& F, matrix& N, INT verbose_level) // compare Lueneburg~\cite{Lueneburg87a} p. 106. { INT f_v = (verbose_level >= 1); domain d(p); with ww(&d); INT i, f; Vector v, V; unipoly x, mue; f = degree(); F.Frobenius(*this, p, FALSE); if (f_v) { cout << "unipoly::normal_base(): Frobenius:\n" << F << endl; } F.KX_cyclic_module_generator(v, mue, verbose_level - 1); V.m_l(f); V[0] = v; x.x(); if (f_v) { cout << "unipoly::normal_base(): V[0]=" << v << endl; } for (i = 1; i < f; i++) { F.KX_module_apply(x, v); V[i] = v; if (f_v) { cout << "unipoly::normal_base(): V["<<i<<"]=" << v << endl; } } N.from_vector_of_columns(V); if (f_v) { cout << "unipoly::normal_base(): N=\n" << N << endl; } #if 0 matrix T, P, Pv, Q, Qv; integer a1; Vector v, vv, b, bb; T = F; T.elements_to_unipoly(); T.minus_X_times_id(); if (f_v) { cout << "F - x * Id=\n" << T << endl; } T.smith_normal_form(P, Pv, Q, Qv, f_vv, FALSE); if (f_v) { cout << "Q=\n" << Q << endl; } a1.m_i_i(1); Q.evaluate_at(a1); if (f_v) { cout << "Q(1)=\n" << Q << endl; cout << "F=\n" << F << endl; } Q.to_vector_of_columns(v); b = v.s_i(d - 1); vv.m_l(d); vv[1] = b; if (f_v) { cout << "N[0]=" << b << endl; } for (i = 1; i < d; i++) { bb.mult(F, b); b = bb; vv[i] = b; if (f_v) { cout << "N[" << i << "]=" << b << endl; } } N.from_vector_of_columns(vv); if (f_v) { cout << "N=" << N << endl; } #endif }