Skip to content

Commit

Permalink
admit an optional third argument in OrderMod (PR #4105)
Browse files Browse the repository at this point in the history
* admit an optional third argument in `OrderMod` ...

... that is a multiple of the order one wants to compute.
Note that the current function computes `Lambda( m )` as the
"default multiple",
and then divides this number by its prime divisors until the
order is found.
If one knows a reasonable multiple in advance then the perhaps
expensive computation of `Lambda( m )` can be skipped.

* mention what happens in case of a wrong bound
  • Loading branch information
ThomasBreuer authored Aug 31, 2020
1 parent 532a88d commit 9b8f5b7
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
14 changes: 11 additions & 3 deletions lib/numtheor.gd
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,11 @@ DeclareOperation( "Lambda", [ IsObject ] );

#############################################################################
##
#F OrderMod( <n>, <m> ) . . . . . . . . multiplicative order of an integer
#F OrderMod( <n>, <m>[, <bound>] ) . . . multiplicative order of an integer
##
## <#GAPDoc Label="OrderMod">
## <ManSection>
## <Func Name="OrderMod" Arg='n, m'/>
## <Func Name="OrderMod" Arg='n, m[, bound]'/>
##
## <Description>
## <Index>multiplicative order of an integer</Index>
Expand All @@ -181,13 +181,21 @@ DeclareOperation( "Lambda", [ IsObject ] );
## each element of maximal order is called a primitive root modulo <A>m</A>
## (see&nbsp;<Ref Func="IsPrimitiveRootMod"/>).
## <P/>
## If no a priori known multiple <A>bound</A> of the desired order is given,
## <Ref Func="OrderMod"/> usually spends most of its time factoring <A>m</A>
## and <M>\phi(<A>m</A>)</M> (see&nbsp;<Ref Func="FactorsInt"/>).
## for computing <M>\lambda(<A>m</A>)</M> (see <Ref Oper="Lambda"/>) as the
## default for <A>bound</A>, and then factoring <A>bound</A>
## (see&nbsp;<Ref Func="FactorsInt"/>).
## <P/>
## If an incorrect <A>bound</A> is given then the result will be wrong.
## <Example><![CDATA[
## gap> OrderMod( 2, 7 );
## 3
## gap> OrderMod( 3, 7 ); # 3 is a primitive root modulo 7
## 6
## gap> m:= (5^166-1) / 167;; # about 10^113
## gap> OrderMod( 5, m, 166 ); # needs minutes without third argument
## 166
## ]]></Example>
## </Description>
## </ManSection>
Expand Down
12 changes: 9 additions & 3 deletions lib/numtheor.gi
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,11 @@ InstallMethod( Lambda,

#############################################################################
##
#F OrderMod( <n>, <m> ) . . . . . . . . multiplicative order of an integer
#F OrderMod( <n>, <m>[, <bound>] ) . . . multiplicative order of an integer
##
#N 23-Apr-91 martin improve 'OrderMod' similar to 'IsPrimitiveRootMod'
##
InstallGlobalFunction( OrderMod, function ( n, m )
InstallGlobalFunction( OrderMod, function ( n, m, bound... )
local x, o, d;

# check the arguments and reduce $n$ into the range $0..m-1$
Expand All @@ -138,7 +138,13 @@ InstallGlobalFunction( OrderMod, function ( n, m )

# otherwise try the divisors of $\lambda(m)$ and their divisors, etc.
else
o := Lambda( m );
if Length( bound ) = 1 then
# We know a multiple of the desired order.
o := bound[1];
else
# The default a priori known multiple is 'Lambda( m )'.
o := Lambda( m );
fi;
for d in PrimeDivisors( o ) do
while o mod d = 0 and PowerModInt(n,o/d,m) = 1 do
o := o / d;
Expand Down

0 comments on commit 9b8f5b7

Please sign in to comment.