Révision 125

pobysoPythonSage/src/sageSLZ/sageSLZ.sage (revision 125)
97 97
    NOTE::
98 98
        When number >= 2^(emax+1), we return the "fake" binade 
99 99
        [2^(emax+1), +infinity]. Ditto for number <= -2^(emax+1)
100
        with interval [-infinity, -2^(emax+1)].
100
        with interval [-infinity, -2^(emax+1)]. We want to distinguish
101
        this case from that of "really" invalid arguments.
101 102
        
102 103
    """
103 104
    # Check the parameters.
104
    # RealNumbers only.
105
    # RealNumbers or RealNumber offspring only.
106
    # The execption construction is necessary since not all objects have
107
    # the mro() method. sage.rings.real_mpfr.RealNumber do.
105 108
    try:
106 109
        classTree = [number.__class__] + number.mro()
107 110
        if not sage.rings.real_mpfr.RealNumber in classTree:
......
116 119
        return None
117 120
    precision = number.precision()
118 121
    RF  = RealField(precision)
122
    if number == 0:
123
        return (RF(0),RF(2^(emin)) - RF(2^(emin-precision)))
119 124
    # A more precise RealField is needed to avoid unwanted rounding effects
120 125
    # when computing number.log2().
121 126
    RRF = RealField(max(2048, 2 * precision))
122 127
    # number = 0 special case, the binade bounds are 
123 128
    # [0, 2^emin - 2^(emin-precision)]
124
    if number == 0:
125
        return (RF(0),RF(2^(emin)) - RF(2^(emin-precision)))
126 129
    # Begin general case
127 130
    l2 = RRF(number).abs().log2()
128 131
    # Another special one: beyond largest representable -> "Fake" binade.
129 132
    if l2 >= emax + 1:
130 133
        if number > 0:
131
            return (RF(2^(emax+1)), RRR(+infinity) )
134
            return (RF(2^(emax+1)), RF(+infinity) )
132 135
        else:
133 136
            return (RF(-infinity), -RF(2^(emax+1)))
134 137
    offset = int(l2)
......
196 199
    A list of bivariate integer polynomial obtained using the Coppersmith
197 200
    algorithm. The polynomials correspond to the rows of the LLL-reduce
198 201
    reduced base that comply with the Coppersmith condition.
199
    
200
    TODO::
201
    Full rewrite, this is barely a draft.
202 202
    """
203 203
    # Arguments check.
204 204
    if iBound == 0 or tBound == 0:
......
235 235
    reducedMatrix = matrixToReduce.LLL(fp='fp')
236 236
    isLLLReduced  = reducedMatrix.is_LLL_reduced()
237 237
    if not isLLLReduced:
238
        return ()
238
        return set()
239 239
    monomialsCount     = len(knownMonomials)
240 240
    monomialsCountSqrt = sqrt(monomialsCount)
241 241
    #print "Monomials count:", monomialsCount, monomialsCountSqrt.n()
......
247 247
        l2Norm = row.norm(2)
248 248
        if (l2Norm * monomialsCountSqrt) < nAtAlpha:
249 249
            #print (l2Norm * monomialsCountSqrt).n()
250
            print l2Norm.n()
250
            #print l2Norm.n()
251 251
            ccReducedPolynomial = \
252 252
                slz_compute_reduced_polynomial(row,
253 253
                                               knownMonomials,
......
258 258
            if not ccReducedPolynomial is None:
259 259
                ccReducedPolynomialsList.append(ccReducedPolynomial)
260 260
        else:
261
            print l2Norm.n() , ">", nAtAlpha
261
            #print l2Norm.n() , ">", nAtAlpha
262 262
            pass
263 263
    if len(ccReducedPolynomialsList) < 2:
264
        print "***Less than 2 Coppersmith condition compliant vectors.***"
264
        print "Less than 2 Coppersmith condition compliant vectors."
265 265
        return ()
266
    
267
    #print ccReducedPolynomialsList
266 268
    return ccReducedPolynomialsList
267 269
# End slz_compute_coppersmith_reduced_polynomials
268 270

  
......
286 288
    # Whatever the 2 variables are actually called, we call them
287 289
    # 'i' and 't' in all the variable names.
288 290
    (iVariable, tVariable) = inputPolynomial.variables()[:2]
289
    #print polyVars[0], type(polyVars[0])
290
    initialPolynomial = inputPolynomial.subs({iVariable:iVariable * iBound,
291
                                              tVariable:tVariable * tBound})
292
    polynomialsList = \
293
        spo_polynomial_to_polynomials_list_5(initialPolynomial,
294
                                             alpha,
295
                                             N,
296
                                             iBound,
297
                                             tBound,
298
                                             0)
299
    #print "Polynomials list:", polynomialsList
300
    ## Building the proto matrix.
301
    knownMonomials = []
302
    protoMatrix    = []
303
    for poly in polynomialsList:
304
        spo_add_polynomial_coeffs_to_matrix_row(poly,
305
                                                knownMonomials,
306
                                                protoMatrix,
307
                                                0)
308
    matrixToReduce = spo_proto_to_row_matrix(protoMatrix)
309
    #print matrixToReduce
310
    ## Reduction and checking.
311
    reducedMatrix = matrixToReduce.LLL(fp='fp')
312
    isLLLReduced  = reducedMatrix.is_LLL_reduced()
313
    if not isLLLReduced:
314
        return set()
315
    monomialsCount     = len(knownMonomials)
316
    monomialsCountSqrt = sqrt(monomialsCount)
317
    #print "Monomials count:", monomialsCount, monomialsCountSqrt.n()
318
    #print reducedMatrix
319
    ## Check the Coppersmith condition for each row and build the reduced 
320
    #  polynomials.
321
    ccReducedPolynomialsList = []
322
    for row in reducedMatrix.rows():
323
        l2Norm = row.norm(2)
324
        if (l2Norm * monomialsCountSqrt) < nAtAlpha:
325
            #print (l2Norm * monomialsCountSqrt).n()
326
            #print l2Norm.n()
327
            ccReducedPolynomial = \
328
                slz_compute_reduced_polynomial(row,
329
                                               knownMonomials,
330
                                               iVariable,
331
                                               iBound,
332
                                               tVariable,
333
                                               tBound)
334
            if not ccReducedPolynomial is None:
335
                ccReducedPolynomialsList.append(ccReducedPolynomial)
336
        else:
337
            #print l2Norm.n() , ">", nAtAlpha
338
            pass
339
    if len(ccReducedPolynomialsList) < 2:
340
        print "Less than 2 Coppersmith condition compliant vectors."
341
        return set()
342
    #print ccReducedPolynomialsList
291
    ccReducedPolynomialsList = \
292
        slz_compute_coppersmith_reduced_polynomials (inputPolynomial,
293
                                                     alpha,
294
                                                     N,
295
                                                     iBound,
296
                                                     tBound)
297
    if len(ccReducedPolynomialsList) == 0:
298
        return set()   
343 299
    ## Create the valid (poly1 and poly2 are algebraically independent) 
344 300
    # resultant tuples (poly1, poly2, resultant(poly1, poly2)).
345 301
    # Try to mix and match all the polynomial pairs built from the 
......
390 346
    return polynomialRootsSet
391 347
# End slz_compute_integer_polynomial_modular_roots.
392 348
#
349
def slz_compute_integer_polynomial_modular_roots_2(inputPolynomial,
350
                                                 alpha,
351
                                                 N,
352
                                                 iBound,
353
                                                 tBound):
354
    """
355
    For a given set of arguments (see below), compute the polynomial modular 
356
    roots, if any.
357
    This version differs in the way resultants are computed.   
358
    """
359
    # Arguments check.
360
    if iBound == 0 or tBound == 0:
361
        return set()
362
    # End arguments check.
363
    nAtAlpha = N^alpha
364
    ## Building polynomials for matrix.
365
    polyRing   = inputPolynomial.parent()
366
    # Whatever the 2 variables are actually called, we call them
367
    # 'i' and 't' in all the variable names.
368
    (iVariable, tVariable) = inputPolynomial.variables()[:2]
369
    #print polyVars[0], type(polyVars[0])
370
    ccReducedPolynomialsList = \
371
        slz_compute_coppersmith_reduced_polynomials (inputPolynomial,
372
                                                     alpha,
373
                                                     N,
374
                                                     iBound,
375
                                                     tBound)
376
    if len(ccReducedPolynomialsList) == 0:
377
        return set()   
378
    ## Create the valid (poly1 and poly2 are algebraically independent) 
379
    # resultant tuples (poly1, poly2, resultant(poly1, poly2)).
380
    # Try to mix and match all the polynomial pairs built from the 
381
    # ccReducedPolynomialsList to obtain non zero resultants.
382
    resultantsInTTuplesList = []
383
    for polyOuterIndex in xrange(0, len(ccReducedPolynomialsList)-1):
384
        for polyInnerIndex in xrange(polyOuterIndex+1, 
385
                                     len(ccReducedPolynomialsList)):
386
            # Compute the resultant in resultants in the
387
            # first variable (is it the optimal choice?).
388
            resultantInT = \
389
               ccReducedPolynomialsList[polyOuterIndex].resultant(ccReducedPolynomialsList[polyInnerIndex],
390
                                                                  ccReducedPolynomialsList[0].parent(str(tVariable)))
391
            #print "Resultant", resultantInT
392
            # Test algebraic independence.
393
            if not resultantInT.is_zero():
394
                resultantsInTTuplesList.append((ccReducedPolynomialsList[polyOuterIndex],
395
                                                 ccReducedPolynomialsList[polyInnerIndex],
396
                                                 resultantInT))
397
    # If no non zero resultant was found: we can't get no algebraically 
398
    # independent polynomials pair. Give up!
399
    if len(resultantsInTTuplesList) == 0:
400
        return set()
401
    #print resultantsInITuplesList
402
    # Compute the roots.
403
    Zi = ZZ[str(iVariable)]
404
    Zt = ZZ[str(tVariable)]
405
    polynomialRootsSet = set()
406
    # First, solve in the second variable since resultants are in the first
407
    # variable.
408
    for resultantInTTuple in resultantsInTTuplesList:
409
        iRootsList = Zi(resultantInTTuple[2]).roots()
410
        # For each iRoot, compute the corresponding tRoots and check 
411
        # them in the input polynomial.
412
        for iRoot in iRootsList:
413
            #print "iRoot:", iRoot
414
            # Roots returned by root() are (value, multiplicity) tuples.
415
            tRootsList = \
416
                Zt(resultantInTTuple[0].subs({resultantInTTuple[0].variables()[0]:iRoot[0]})).roots()
417
            print tRootsList
418
            # The tRootsList can be empty, hence the test.
419
            if len(tRootsList) != 0:
420
                for tRoot in tRootsList:
421
                    polyEvalModN = inputPolynomial(iRoot[0],tRoot[0]) / N
422
                    # polyEvalModN must be an integer.
423
                    if polyEvalModN == int(polyEvalModN):
424
                        polynomialRootsSet.add((iRoot[0],tRoot[0]))
425
    return polynomialRootsSet
426
# End slz_compute_integer_polynomial_modular_roots_2.
427
#
393 428
def slz_compute_polynomial_and_interval(functionSo, degreeSo, lowerBoundSa, 
394 429
                                        upperBoundSa, approxPrecSa, 
395 430
                                        sollyaPrecSa=None):
......
482 517
                                    var2,
483 518
                                    var2Bound):
484 519
    """
485
    Compute a polynomial from a reduced matrix row.
520
    Compute a polynomial from a single reduced matrix row.
486 521
    This function was introduced in order to avoid the computation of the
487
    polynomials (even those built from rows that do no verify the Coppersmith
488
    condition.
522
    all the polynomials  from the full matrix (even those built from rows 
523
    that do no verify the Coppersmith condition) as this may involves 
524
    expensive operations over (large) integer.
489 525
    """
490 526
    ## Check arguments.
491 527
    if len(knownMonomials) == 0:

Formats disponibles : Unified diff