Skip to content

Commit

Permalink
- Added the Number is_imprimitive_carmichael(n).
Browse files Browse the repository at this point in the history
Returns true if `n` is an imprimitive Carmichael numbers, as defined by OEIS: A328935.

Example:

	say 325533792014488126487416882038879701391121.is_imprimitive_carmichael   # true

The method efficiently tries to factorize large Carmichael numbers, using the `miller_factor(n)` method.
  • Loading branch information
trizen committed Aug 26, 2020
1 parent cd9d3ce commit d435c38
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
55 changes: 55 additions & 0 deletions lib/Sidef/Types/Number/Number.pm
Original file line number Diff line number Diff line change
Expand Up @@ -14494,6 +14494,61 @@ package Sidef::Types::Number::Number {
: Sidef::Types::Bool::Bool::FALSE;
}

sub is_imprimitive_carmichael { # OEIS: A328935
my ($n) = @_;

__is_int__($$n) || return Sidef::Types::Bool::Bool::FALSE;
$n = _any2mpz($$n) // return Sidef::Types::Bool::Bool::FALSE;
Math::GMPz::Rmpz_cmp_ui($n, 294409) >= 0 or return Sidef::Types::Bool::Bool::FALSE;

if ($HAS_PRIME_UTIL && Math::GMPz::Rmpz_fits_ulong_p($n)) {

$n = Math::GMPz::Rmpz_get_ui($n);
Math::Prime::Util::is_carmichael($n) || return Sidef::Types::Bool::Bool::FALSE;
my @factors = map { $_ - 1 } Math::Prime::Util::factor($n);

my $gcd = Math::Prime::Util::gcd(@factors);
my $lcm = Math::Prime::Util::lcm(@factors);

return (
(($gcd * $gcd) > $lcm)
? Sidef::Types::Bool::Bool::TRUE
: Sidef::Types::Bool::Bool::FALSE
);
}

Math::Prime::Util::GMP::is_carmichael($n) || return Sidef::Types::Bool::Bool::FALSE;

my @factors = map { $$_ } @{(bless \$n)->miller_factor};
my @primes;

foreach my $k (@factors) {
if (Math::Prime::Util::GMP::is_prob_prime($k)) {
push @primes, $k;
}
else {
push @primes, Math::Prime::Util::GMP::factor($k);
}
}

@factors = map { Math::Prime::Util::GMP::subint($_, 1) } @primes;

my $gcd = Math::Prime::Util::GMP::gcd(@factors);
my $lcm = Math::Prime::Util::GMP::lcm(@factors);

state $x = Math::GMPz::Rmpz_init_nobless();
state $y = Math::GMPz::Rmpz_init_nobless();

Math::GMPz::Rmpz_set_str($x, $gcd, 10);
Math::GMPz::Rmpz_set_str($y, $lcm, 10);

Math::GMPz::Rmpz_mul($x, $x, $x);

(Math::GMPz::Rmpz_cmp($x, $y) > 0)
? Sidef::Types::Bool::Bool::TRUE
: Sidef::Types::Bool::Bool::FALSE;
}

sub is_lucas_carmichael { # OEIS: A006972
my ($n) = @_;

Expand Down
18 changes: 18 additions & 0 deletions lib/Sidef/Types/Number/Number.pod
Original file line number Diff line number Diff line change
Expand Up @@ -2406,6 +2406,14 @@ Return the

=cut

=head2 is_imprimitive_carmichael

Number.is_imprimitive_carmichael() -> I<Obj>

Return the

=cut

=head2 is_inf

Number.is_inf() -> I<Obj>
Expand Down Expand Up @@ -3250,6 +3258,16 @@ Aliases: I<mfactorial>, I<multi_factorial>

=cut

=head2 miller_factor

Number.miller_factor() -> I<Obj>

Return the

Aliases: I<miller_rabin_factor>

=cut

=head2 miller_rabin_random

Number.miller_rabin_random() -> I<Obj>
Expand Down

0 comments on commit d435c38

Please sign in to comment.