Search This Blog

Wednesday, May 8, 2013

n_smallest_primitive_root at first glance

Hi all,
I've done the first function for FLINT library, namely n_smallest_primitive_root :)
It assumes that on input we have $n$ equal to $2$ or $4$ or $p^k$ or $2\cdot p^k$ for any odd $p\in\mathbb{P}$ and for any $k\in\mathbb{N}$ and finds the least primitive root $\pmod{n}$.
So as I said in the previous post the function iterates a candidate $g$ for being a primitive root from $2$, but it doesn't check all candidates, it misses integers which are divisible by 4, 9 or 25:
if(g % 4 == 0 || g % 9 == 0 || g % 25 == 0) g++;

I'm not quite sure if the last condition (g % 25) is good for speed improve, because it's rare that function must iterates a candidate to such big values.
I will check it later.

At first function assumes it found a real primitive root:
ok = 1;

but then it checks two conditions. If at least one of them is true, value stored in ok changes to 0. The first condition is, if the $g$ value has a multiplicative order not divisible by $\varphi(n)$:
if(n_powmod(g, phi, n) != 1)

The second condition check assumes that $g$ has a multiplicative order divisible by $\varphi(n)$ and check if it can be lower:
for (i = fac.num-1; i >= 0; i--)
{
   exp = phi / fac.p[i];
   if(n_powmod(g, exp, n) == 1)
   {
      ok = 0;
      break;
   }

}

The break inside the for loop is used to speed up - if one finds that it's not a real primitive root, it's senseless to check other cases.

If the function never went inside the break clause, it reaches the next condition:
if(ok == 1)
   return g;

Now it's time for a test phase.

In $10^{8}$ iteration a test finds the following maximal value of minimal primitive root:
$g=151 \pmod{4419925309802}$

No comments:

Post a Comment