Skip to content

Commit

Permalink
- Enable optimizations in modular lucas sequences for native integers.
Browse files Browse the repository at this point in the history
This improves the performance of `lucasUmod(P, Q, n, m)` and `lucasVmod(P, Q, n, m)` when `P` and `Q` are small (half the size of ULONG_MAX) and `n` and `m` fit inside a native integer.
  • Loading branch information
trizen committed Feb 9, 2021
1 parent 775e7cb commit fcb63fe
Showing 1 changed file with 9 additions and 12 deletions.
21 changes: 9 additions & 12 deletions lib/Sidef/Types/Number/Number.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8474,7 +8474,7 @@ package Sidef::Types::Number::Number {
if ( Math::GMPz::Rmpz_cmpabs_ui($P, $LUCAS_PQ_LIMIT) < 0
and Math::GMPz::Rmpz_cmpabs_ui($Q, $LUCAS_PQ_LIMIT) < 0) {
my ($U, $V);
if (0 and HAS_PRIME_UTIL and Math::GMPz::Rmpz_fits_ulong_p($m) and Math::GMPz::Rmpz_fits_ulong_p($n)) {
if (HAS_PRIME_UTIL and Math::GMPz::Rmpz_fits_ulong_p($m) and Math::GMPz::Rmpz_fits_ulong_p($n)) {
eval {
($U, $V) =
Math::Prime::Util::lucas_sequence(Math::GMPz::Rmpz_get_ui($m), Math::GMPz::Rmpz_get_si($P),
Expand Down Expand Up @@ -8511,10 +8511,9 @@ package Sidef::Types::Number::Number {
my ($P, $Q, $n, $m) = @_;

if ( Math::GMPz::Rmpz_cmpabs_ui($P, $LUCAS_PQ_LIMIT) < 0
and Math::GMPz::Rmpz_cmpabs_ui($Q, $LUCAS_PQ_LIMIT) < 0
and $P * $P - $Q * 4 != 0) {
and Math::GMPz::Rmpz_cmpabs_ui($Q, $LUCAS_PQ_LIMIT) < 0) {
my ($U, $V);
if (0 and HAS_PRIME_UTIL and Math::GMPz::Rmpz_fits_ulong_p($m) and Math::GMPz::Rmpz_fits_ulong_p($n)) {
if (HAS_PRIME_UTIL and Math::GMPz::Rmpz_fits_ulong_p($m) and Math::GMPz::Rmpz_fits_ulong_p($n)) {
eval {
($U, $V) =
Math::Prime::Util::lucas_sequence(Math::GMPz::Rmpz_get_ui($m), Math::GMPz::Rmpz_get_si($P),
Expand Down Expand Up @@ -8551,10 +8550,9 @@ package Sidef::Types::Number::Number {
my ($P, $Q, $n, $m) = @_;

if ( Math::GMPz::Rmpz_cmpabs_ui($P, $LUCAS_PQ_LIMIT) < 0
and Math::GMPz::Rmpz_cmpabs_ui($Q, $LUCAS_PQ_LIMIT) < 0
and $P * $P - $Q * 4 != 0) {
and Math::GMPz::Rmpz_cmpabs_ui($Q, $LUCAS_PQ_LIMIT) < 0) {
my ($U, $V);
if (0 and HAS_PRIME_UTIL and Math::GMPz::Rmpz_fits_ulong_p($m) and Math::GMPz::Rmpz_fits_ulong_p($n)) {
if (HAS_PRIME_UTIL and Math::GMPz::Rmpz_fits_ulong_p($m) and Math::GMPz::Rmpz_fits_ulong_p($n)) {
eval {
($U, $V) =
Math::Prime::Util::lucas_sequence(Math::GMPz::Rmpz_get_ui($m), Math::GMPz::Rmpz_get_si($P),
Expand Down Expand Up @@ -9707,7 +9705,7 @@ package Sidef::Types::Number::Number {
my $n = _any2mpz($$from) // return ZERO;

Math::GMPz::Rmpz_sgn($n) > 0
or return ZERO;
or return ZERO;

# Optimization for native integers
if (Math::GMPz::Rmpz_fits_ulong_p($n)) {
Expand Down Expand Up @@ -9771,12 +9769,11 @@ package Sidef::Types::Number::Number {
# Implementation for large values of n
my $c = Math::GMPz::Rmpz_init_set_ui(0);
my $t = Math::GMPz::Rmpz_init();
my $s = Math::GMPz::Rmpz_init();

Math::GMPz::Rmpz_sqrt($s, $n);
Math::GMPz::Rmpz_fits_ulong_p($s) || goto &nan; # too large
Math::GMPz::Rmpz_sqrt($t, $n);
Math::GMPz::Rmpz_fits_ulong_p($t) || goto &nan; # too large

$s = Math::GMPz::Rmpz_get_ui($s);
my $s = Math::GMPz::Rmpz_get_ui($t);

if (HAS_PRIME_UTIL) {
Math::Prime::Util::forsquarefree(
Expand Down

0 comments on commit fcb63fe

Please sign in to comment.