The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Math::NumSeq::Totient -- Euler's totient function, count of coprimes

SYNOPSIS

 use Math::NumSeq::Totient;
 my $seq = Math::NumSeq::Totient->new;
 my ($i, $value) = $seq->next;

DESCRIPTION

Euler's totient function, being the count of integers coprime to i,

    1, 1, 2, 2, 4, 2, 6, 4, etc          (A000010)
    starting i=1

For example i=6 has no common factor with 1 or 5, so the totient is 2.

The totient can be calculated from the prime factorization by changing one copy of each distinct prime p to p-1.

    totient(n) =        product          (p-1) * p^(e-1)
                  prime factors p^e in n

FUNCTIONS

See "FUNCTIONS" in Math::NumSeq for behaviour common to all sequence classes.

$seq = Math::NumSeq::Totient->new ()

Create and return a new sequence object.

Random Access

$value = $seq->ith($i)

Return totient(i).

This calculation requires factorizing $i and in the current code after small factors a hard limit of 2**32 is enforced in the interests of not going into a near-infinite loop. Above that the return is undef.

$bool = $seq->pred($value)

Return true if $value occurs in the sequence, ie. $value is the totient of something.

FORMULAS

Predicate

Totient(n) > 1 is always even because the factors factor p-1 for odd prime p is even, or if no odd primes in n then totient(2^k)=2^(k-1) is even. So odd numbers > 1 don't occur as totients.

The strategy is to look at the divisors of the given value to find the p-1, q-1 etc parts arising as totient(n=p*q) etc.

    initial maxdivisor unlimited
    try divisors of value, with divisor < maxdivisor
      if p=divisor+1 is prime then
        remainder = value/divisor
        loop
          if recurse pred(remainder, maxdivisor=divisor) then yes
          if remainder divisible by p then remainder/=p
          else next divisor of value

The divisors tried include 1 and the value itself. 1 becomes p=2 casting out possible factors of 2. For value itself if p=value+1 prime then simply totient(value+1)=value means it is a totient.

Care must be taken not to repeat a prime p, since value=(p-1)*(p-1) is not a totient form. One way to do this is to demand only smaller divisors when recursing, hence the "maxdivisor".

Any divisors > 1 will have to be even to give p=divisor+1 odd to be a prime. Effectively each p-1, q-1, etc part of the target takes at least one factor of 2 out of the value. It might be possible to handle the 2^k part of the target value specially, for instance noting that on reaching the last factor of 2 there can be no further recursion, only value=p^a*(p-1) can be a totient.

This search implicitly produces an n=p^a*q^b*etc with totient(n)=value but for the pred() method that n is not required, only the fact it exists.

SEE ALSO

Math::NumSeq, Math::NumSeq::TotientCumulative, Math::NumSeq::TotientPerfect, Math::NumSeq::TotientSteps

"euler_phi" in Math::Prime::Util

HOME PAGE

http://user42.tuxfamily.org/math-numseq/index.html

LICENSE

Copyright 2011, 2012, 2013, 2014, 2016, 2019, 2020, 2021 Kevin Ryde

Math-NumSeq is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

Math-NumSeq is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Math-NumSeq. If not, see <http://www.gnu.org/licenses/>.