@@ -3876,8 +3876,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
3876
3876
sig_off()
3877
3877
return x
3878
3878
3879
- def factor (self , algorithm = ' pari ' , proof = None , limit = None , int_ = False ,
3880
- verbose = 0 ):
3879
+ def factor (self , algorithm = None , proof = None , limit = None , int_ = False ,
3880
+ verbose = 0 , flint_bits = None ):
3881
3881
"""
3882
3882
Return the prime factorization of this integer as a
3883
3883
formal Factorization object.
@@ -3896,7 +3896,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
3896
3896
- ``'magma'`` -- use the MAGMA computer algebra system (requires
3897
3897
an installation of MAGMA)
3898
3898
3899
- - ``'qsieve'`` -- use Bill Hart's quadratic sieve code ;
3899
+ - ``'qsieve'`` -- use ``qsieve_factor`` in the FLINT library ;
3900
3900
WARNING: this may not work as expected, see qsieve? for
3901
3901
more information
3902
3902
@@ -3910,6 +3910,10 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
3910
3910
given it must fit in a ``signed int``, and the factorization is done
3911
3911
using trial division and primes up to limit
3912
3912
3913
+ - ``flint_bits`` -- integer or ``None`` (default: ``None``); if specified,
3914
+ perform only a partial factorization, primes at most ``2^flint_bits``
3915
+ have a high probability of being detected
3916
+
3913
3917
OUTPUT: a Factorization object containing the prime factors and
3914
3918
their multiplicities
3915
3919
@@ -3958,6 +3962,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
3958
3962
sage: n.factor(algorithm='flint') # needs sage.libs.flint
3959
3963
2 * 3 * 11 * 13 * 41 * 73 * 22650083 * 1424602265462161
3960
3964
3965
+ Example with ``flint_bits``. The small prime factor is found since it is
3966
+ much smaller than `2^{50}`, but not the large ones::
3967
+
3968
+ sage: n = next_prime(2^256) * next_prime(2^257) * next_prime(2^40)
3969
+ sage: n.factor(algorithm='flint', flint_bits=50) # needs sage.libs.flint
3970
+ 1099511627791 * 2681...6291
3971
+
3961
3972
We factor using a quadratic sieve algorithm::
3962
3973
3963
3974
sage: # needs sage.libs.pari
@@ -3985,14 +3996,11 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
3985
3996
sage: n.factor(algorithm='foobar')
3986
3997
Traceback (most recent call last):
3987
3998
...
3988
- ValueError: Algorithm is not known
3999
+ ValueError: algorithm is not known
3989
4000
"""
3990
4001
from sage.structure.factorization import Factorization
3991
4002
from sage.structure.factorization_integer import IntegerFactorization
3992
4003
3993
- if algorithm not in [' pari' , ' flint' , ' kash' , ' magma' , ' qsieve' , ' ecm' ]:
3994
- raise ValueError (" Algorithm is not known" )
3995
-
3996
4004
cdef Integer n, p, unit
3997
4005
3998
4006
if mpz_sgn(self .value) == 0 :
@@ -4003,18 +4011,27 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
4003
4011
unit = one
4004
4012
else :
4005
4013
n = PY_NEW(Integer)
4006
- unit = PY_NEW(Integer)
4007
4014
mpz_neg(n.value, self .value)
4008
- mpz_set_si(unit.value, - 1 )
4009
-
4010
- if mpz_cmpabs_ui(n.value, 1 ) == 0 :
4011
- return IntegerFactorization([], unit = unit, unsafe = True ,
4012
- sort = False , simplify = False )
4015
+ unit = smallInteger(- 1 )
4013
4016
4014
4017
if limit is not None :
4018
+ if algorithm is not None :
4019
+ raise ValueError (' trial division will always be used when when limit is provided' )
4015
4020
from sage.rings.factorint import factor_trial_division
4016
4021
return factor_trial_division(self , limit)
4017
4022
4023
+ if algorithm is None :
4024
+ algorithm = ' pari'
4025
+ elif algorithm not in [' pari' , ' flint' , ' kash' , ' magma' , ' qsieve' , ' ecm' ]:
4026
+ raise ValueError (" algorithm is not known" )
4027
+
4028
+ if algorithm != ' flint' and flint_bits is not None :
4029
+ raise ValueError (" cannot specify flint_bits when algorithm is not flint" )
4030
+
4031
+ if n.is_one():
4032
+ return IntegerFactorization([], unit = unit, unsafe = True ,
4033
+ sort = False , simplify = False )
4034
+
4018
4035
if mpz_fits_slong_p(n.value):
4019
4036
global n_factor_to_list
4020
4037
if n_factor_to_list is None :
@@ -4044,7 +4061,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
4044
4061
sort = False , simplify = False )
4045
4062
elif algorithm == ' flint' :
4046
4063
from sage.rings.factorint_flint import factor_using_flint
4047
- F = factor_using_flint(n)
4064
+ if flint_bits is not None and flint_bits <= 0 :
4065
+ raise ValueError (' flint_bits must be positive or None' )
4066
+ F = factor_using_flint(n, flint_bits or 0 )
4048
4067
F.sort()
4049
4068
return IntegerFactorization(F, unit = unit, unsafe = True ,
4050
4069
sort = False , simplify = False )
@@ -6662,13 +6681,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
6662
6681
if not mpz_sgn(n.value):
6663
6682
mpz_set_ui(t.value, 0 )
6664
6683
mpz_abs(g.value, self .value)
6665
- mpz_set_si(s.value, 1 if mpz_sgn(self .value) >= 0 else - 1 )
6684
+ s = smallInteger( 1 if mpz_sgn(self .value) >= 0 else - 1 )
6666
6685
return g, s, t
6667
6686
6668
6687
if not mpz_sgn(self .value):
6669
6688
mpz_set_ui(s.value, 0 )
6670
6689
mpz_abs(g.value, n.value)
6671
- mpz_set_si(t.value, 1 if mpz_sgn(n.value) >= 0 else - 1 )
6690
+ t = smallInteger( 1 if mpz_sgn(n.value) >= 0 else - 1 )
6672
6691
return g, s, t
6673
6692
6674
6693
# both n and self are nonzero, so we need to do a division and
0 commit comments