Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Trac #20464: cleanup of ecm interface
Browse files Browse the repository at this point in the history
there is a random doctest in this file, let us sort the output

see http://patchbot.sagemath.org/log/19190/Ubuntu/14.04/x86_64/3.13.0-77
-generic/poseidon/2016-04-13%2015:04:45?short

for an example of failure.

Let us also clean the whitespaces and make the file pep8.

URL: http://trac.sagemath.org/20464
Reported by: chapoton
Ticket author(s): Frédéric Chapoton
Reviewer(s): Travis Scrimshaw
  • Loading branch information
Release Manager authored and vbraun committed Apr 27, 2016
2 parents 62be89a + 039e772 commit 655da7a
Showing 1 changed file with 30 additions and 35 deletions.
65 changes: 30 additions & 35 deletions src/sage/interfaces/ecm.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ def _make_cmd(self, B1, B2, kwds):
def _run_ecm(self, cmd, n):
"""
Run ECM and return output as string.
INPUT:
- ``cmd`` -- list of strings. The command.
- ``n`` -- integer suitable for ECM. No argument checking is
Expand All @@ -213,15 +213,15 @@ def _run_ecm(self, cmd, n):
if err != '':
raise ValueError(err)
return out

def __call__(self, n):
"""
Call syntax.
INPUT:
- ``n`` -- integer.
OUTPUT:
String. The ECM output.
Expand Down Expand Up @@ -249,7 +249,7 @@ def interact(self):
print "Press control-C to exit."
os.system(self._cmd)

# Recommended settings from
# Recommended settings from
# http://www.mersennewiki.org/index.php/Elliptic_Curve_Method
_recommended_B1_list = {15: 2000,
20: 11000,
Expand All @@ -262,7 +262,7 @@ def interact(self):
55: 110000000,
60: 260000000,
65: 850000000,
70: 2900000000,}
70: 2900000000}

def _B1_table_value(self, factor_digits, min=15, max=70):
"""
Expand All @@ -283,12 +283,12 @@ def _B1_table_value(self, factor_digits, min=15, max=70):
sage: ecm._B1_table_value(33)
35
"""
if factor_digits < min:
if factor_digits < min:
factor_digits = min
if factor_digits > max:
if factor_digits > max:
raise ValueError('too many digits')
step = 5
return ((factor_digits+step-1) // step) * step
return ((factor_digits + step - 1) // step) * step

def recommended_B1(self, factor_digits):
r"""
Expand Down Expand Up @@ -330,7 +330,7 @@ def _parse_output(self, n, out):
- ``n`` -- integer. The ECM input number.
- ``out`` -- string. The stdout from the ECM invocation.
OUTPUT:
List of pairs ``(integer, bool)`` consisting of factors of the
Expand Down Expand Up @@ -370,7 +370,7 @@ def _parse_output(self, n, out):
sage: from sage.interfaces.ecm import TEST_ECM_OUTPUT_3, TEST_ECM_OUTPUT_4
sage: n3 = 66955751844124594814248420514215108438425124740949701470891
sage: ecm._parse_output(n3, TEST_ECM_OUTPUT_3)
[(197002597249, True),
[(197002597249, True),
(339872432034468861533158743041639097889948066859, False)]
sage: ecm._parse_output(n3, TEST_ECM_OUTPUT_4)
[(265748496095531068869578877937, False),
Expand All @@ -385,8 +385,8 @@ def _parse_output(self, n, out):
m = self._parse_status_re.match(line)
if m is not None:
group = m.groups()
self._last_params = {'B1' : group[0], 'B2' : group[1],
'poly' : group[2], 'sigma' : group[3]}
self._last_params = {'B1': group[0], 'B2': group[1],
'poly': group[2], 'sigma': group[3]}
continue
m = self._found_input_re.match(line)
if m is not None:
Expand All @@ -404,7 +404,7 @@ def _parse_output(self, n, out):
primality = m.group('primality')
assert primality in ['Probable prime', 'Composite']
result += [(ZZ(cofactor), primality == 'Probable prime')]
#assert len(result) == 2
# assert len(result) == 2
return result
raise ValueError('failed to parse ECM output')

Expand All @@ -417,7 +417,7 @@ def one_curve(self, n, factor_digits=None, B1=2000, algorithm="ECM", **kwds):
curves to factor `n`.
INPUT:
- ``n`` -- a positive integer
- ``factor_digits`` -- integer. Decimal digits estimate of the
Expand Down Expand Up @@ -490,8 +490,8 @@ def _find_factor(self, n, factor_digits, B1, **kwds):
sage: f = ECM()
sage: n = 508021860739623467191080372196682785441177798407961
sage: f._find_factor(n, None, 2000)
[(79792266297612017, True),
sage: sorted(f._find_factor(n, None, 2000))
[(79792266297612017, True),
(6366805760909027985741435139224233, True)]
"""
n = self._validate(n)
Expand All @@ -513,8 +513,8 @@ def find_factor(self, n, factor_digits=None, B1=2000, **kwds):
`n`.
INPUT:
- ``n`` -- a positive integer,
- ``n`` -- a positive integer,
- ``factor_digits`` -- integer or ``None`` (default). Decimal
digits estimate of the wanted factor.
Expand All @@ -530,7 +530,7 @@ def find_factor(self, n, factor_digits=None, B1=2000, **kwds):
the factor, this is the best algorithm to find a
factor.
.. NOTE:
.. NOTE::
ECM is not a good primality test. Not finding a
factorization is only weak evidence for `n` being
Expand All @@ -544,7 +544,7 @@ def find_factor(self, n, factor_digits=None, B1=2000, **kwds):
sage: f.find_factor(n)
[79792266297612017, 6366805760909027985741435139224233]
Note that the input number can't have more than 4095 digits::
Note that the input number cannot have more than 4095 digits::
sage: f=2^2^14+1
sage: ecm.find_factor(f)
Expand All @@ -562,7 +562,7 @@ def factor(self, n, factor_digits=None, B1=2000, proof=False, **kwds):
Combines GMP-ECM with a primality test, see
:meth:`~sage.rings.integer.Integer.is_prime`. The primality
test is provable or probabilistic depending on the `proof`
flag.
flag.
Moreover, for small `n` PARI is used directly.
Expand All @@ -582,7 +582,7 @@ def factor(self, n, factor_digits=None, B1=2000, proof=False, **kwds):
- ``B1`` -- initial lower bound, defaults to 2000 (15 digit
factors). Used if ``factor_digits`` is not specified.
- ``proof`` -- boolean (default: ``False``). Whether to prove
that the factors are prime.
Expand All @@ -596,7 +596,7 @@ def factor(self, n, factor_digits=None, B1=2000, proof=False, **kwds):
.. NOTE::
Trial division should typically be performed, but this is
not implemented (yet) in this method.
not implemented (yet) in this method.
If you suspect that n is the product of two
similarly-sized primes, other methods (such as a quadratic
Expand All @@ -621,18 +621,18 @@ def factor(self, n, factor_digits=None, B1=2000, proof=False, **kwds):
probable_prime_factors = [] # output prime factors
while len(factors) > 0:
n = factors.pop()

# Step 0: Primality test
if n.is_prime(proof=proof):
probable_prime_factors.append(n)
continue

# Step 1: Use PARI directly for small primes
if n.ndigits() < 15:
for p,e in n.factor(algorithm='pari'):
probable_prime_factors.extend([p]*e)
for p, e in n.factor(algorithm='pari'):
probable_prime_factors.extend([p] * e)
continue

# Step 2: Deal with small factors efficiently
# Step 2+1/3: Determine if N is a perfect power
if n.is_perfect_power():
Expand Down Expand Up @@ -661,7 +661,7 @@ def get_last_params(self):
will return the parameters that yielded the factorization.
OUTPUT:
A dictionary containing the parameters for the most recent
factorization.
Expand All @@ -679,7 +679,7 @@ def time(self, n, factor_digits, verbose=False):
Print a runtime estimate.
BUGS:
This method should really return something and not just print
stuff on the screen.
Expand Down Expand Up @@ -876,8 +876,3 @@ def _validate(self, n):
Found composite factor of 30 digits: 265748496095531068869578877937
Probable prime cofactor 251951573867253012259144010843 has 30 digits
"""





0 comments on commit 655da7a

Please sign in to comment.