Function: znsubgroupgenerators
Section: number_theoretical
C-Name: znsubgroupgenerators
Prototype: GD0,L,
Help: znsubgroupgenerators(H, {flag=0}): find generators of the subgroup H
 of (Z/fZ)^*; H is given by a vector of 1/0 values: the a-th component is 1
 if and only if a belongs to H.
Doc: Finds a minimal set of generators for the subgroup of $(\Z/f\Z)^*$
 given by a vector (or vectorsmall) $H$ of length $f$:
 for $1\leq a\leq f$, \kbd{H[a]} is 1 or 0 according as $a\in H_F$
 or $a\not\in H_F$. In most PARI functions, subgroups of an abelian group
 are given as HNF left-divisors of a diagonal matrix, representing the
 discrete logarithms of the subgroup generators in terms of a fixed
 generators for the group cyclic components. The present function
 allows to convert an enumeration of the subgroup elements to this
 representation as follows:
 \bprog
 ? G = znstar(f, 1);
 ? v = znsubgroupgenerators(H);
 ? subHNF(G, v) = mathnfmodid(Mat([znlog(h, G) | h<-v]), G.cyc);
 @eprog\noindent The function \kbd{subHNF} can be applied to any
 elements of $(\Z/f\Z)^*$, yielding the subgroup they generate, but using
 \kbd{znsubgroupgenerators} first allows to reduce the number of discrete
 logarithms to be computed.

 For example, if $H=\{\,1,4,11,14\,\}\subset(\Z/15\Z)^{\times}$,
 then we have
 \bprog
 ? f = 15; H = vector(f); H[1]=H[4]=H[11]=H[14] = 1;
 ? v = znsubgroupgenerators(H)
 %2 = [4, 11]
 ? G = znstar(f, 1); G.cyc
 %3 = [4, 2]
 ? subHNF(G, v)
 %4 =
 [2 0]

 [0 1]
 ? subHNF(G, [1,4,11,14])
 %5 =
 [2 0]

 [0 1]
 @eprog\noindent This function is mostly useful when $f$ is large
 and $H$ has small index: if $H$ has few elements, one may just use
 \kbd{subHNF} directly on the elements of $H$. For instance, let
 $K = \Q(\zeta_p, \sqrt{m}) \subset L = \Q(\zeta_f)$, where $p$ is
 a prime, $\sqrt{m}$ is a quadratic number and $f$ is the conductor of the
 abelian extension $K/\Q$. The following GP script creates $H$ as the Galois
 group of $L/K$, as a subgroub of $(\Z/fZ)^*$:
 \bprog
 HK(m, p, flag = 0)=
 { my(d = quaddisc(m), f = lcm(d, p), H);
   H = vectorsmall(f, a, a % p == 1 && kronecker(d,a) > 0);
   [f, znsubgroupgenerators(H,flag)];
 }
 ? [f, v] = HK(36322, 5)
 time = 193 ms.
 %1 = [726440, [41, 61, 111, 131]]
 ? G = znstar(f,1); G.cyc;
 %2 = [1260, 12, 2, 2, 2, 2]
 ? A = subHNF(G, v)
 %3 =
 [2 0 1 1 0 1]

 [0 4 0 0 0 2]

 [0 0 1 0 0 0]

 [0 0 0 1 0 0]

 [0 0 0 0 1 0]

 [0 0 0 0 0 1]
 \\ Double check
 ? p = 5; d = quaddisc(36322);
 ? w = select(a->a % p == 1 && kronecker(d,a) > 0, [1..f]); #w
 time = 133 ms.
 %5 = 30240  \\ w enumerates the elements of H
 ? subHNF(G, w) == A \\ same result, about twice slower
 time = 242 ms.
 %6 = 1
 @eprog\noindent
 This shows that $K=\Q(\sqrt{36322},\zeta_5)$ is contained in
 $\Q(\zeta_{726440})$ and $H=\langle 41, 61, 111, 131 \rangle$.
 Note that $H=\langle 41\rangle\langle 61\rangle\langle 111 \rangle
 \langle 131\rangle$ is not a direct product. If $\fl=1$, then the function
 finds generators which decompose $H$ to direct factors:
 \bprog
 ? HK(36322, 5, 1)
 %3 = [726440, [41, 31261, 324611, 506221]]
 @eprog\noindent This time
 $H=\langle 41\rangle\times \langle 31261\rangle \times
 \langle 324611 \rangle \times \langle 506221 \rangle$.
