Révision 219 pobysoPythonSage/src/sageSLZ/sageSLZ.sage

sageSLZ.sage (revision 219)
336 336
    return ccReducedPolynomialsList
337 337
# End slz_compute_coppersmith_reduced_polynomials_with_lattice volume
338 338

  
339
def slz_compute_initial_lattice_matrix(inputPolynomial,
340
                                       alpha,
341
                                       N,
342
                                       iBound,
343
                                       tBound):
344
    """
345
    For a given set of arguments (see below), compute the initial lattice
346
    that could be reduced. 
347
    INPUT:
348
    
349
    - "inputPolynomial" -- (no default) a bivariate integer polynomial;
350
    - "alpha" -- the alpha parameter of the Coppersmith algorithm;
351
    - "N" -- the modulus;
352
    - "iBound" -- the bound on the first variable;
353
    - "tBound" -- the bound on the second variable.
354
    
355
    OUTPUT:
356
    
357
    A list of bivariate integer polynomial obtained using the Coppersmith
358
    algorithm. The polynomials correspond to the rows of the LLL-reduce
359
    reduced base that comply with the Coppersmith condition.
360
    """
361
    # Arguments check.
362
    if iBound == 0 or tBound == 0:
363
        return None
364
    # End arguments check.
365
    nAtAlpha = N^alpha
366
    ## Building polynomials for matrix.
367
    polyRing   = inputPolynomial.parent()
368
    # Whatever the 2 variables are actually called, we call them
369
    # 'i' and 't' in all the variable names.
370
    (iVariable, tVariable) = inputPolynomial.variables()[:2]
371
    #print polyVars[0], type(polyVars[0])
372
    initialPolynomial = inputPolynomial.subs({iVariable:iVariable * iBound,
373
                                              tVariable:tVariable * tBound})
374
    polynomialsList = \
375
        spo_polynomial_to_polynomials_list_8(initialPolynomial,
376
                                             alpha,
377
                                             N,
378
                                             iBound,
379
                                             tBound,
380
                                             0)
381
    #print "Polynomials list:", polynomialsList
382
    ## Building the proto matrix.
383
    knownMonomials = []
384
    protoMatrix    = []
385
    for poly in polynomialsList:
386
        spo_add_polynomial_coeffs_to_matrix_row(poly,
387
                                                knownMonomials,
388
                                                protoMatrix,
389
                                                0)
390
    matrixToReduce = spo_proto_to_row_matrix(protoMatrix)
391
    return matrixToReduce
392
# End slz_compute_initial_lattice_matrix.
393

  
339 394
def slz_compute_integer_polynomial_modular_roots(inputPolynomial,
340 395
                                                 alpha,
341 396
                                                 N,
......
610 665

  
611 666
def slz_compute_polynomial_and_interval_01(functionSo, degreeSo, lowerBoundSa, 
612 667
                                        upperBoundSa, approxAccurSa, 
668
                                        sollyaPrecSa=None, debug=False):
669
    """
670
    Under the assumptions listed for slz_get_intervals_and_polynomials, compute
671
    a polynomial that approximates the function on a an interval starting
672
    at lowerBoundSa and finishing at a value that guarantees that the polynomial
673
    approximates with the expected precision.
674
    The interval upper bound is lowered until the expected approximation 
675
    precision is reached.
676
    The polynomial, the bounds, the center of the interval and the error
677
    are returned.
678
    OUTPUT:
679
    A tuple made of 4 Sollya objects:
680
    - a polynomial;
681
    - an range (an interval, not in the sense of number given as an interval);
682
    - the center of the interval;
683
    - the maximum error in the approximation of the input functionSo by the
684
      output polynomial ; this error <= approxAccurSaS.
685
    
686
    """
687
    #print"In slz_compute_polynomial_and_interval..."
688
    ## Superficial argument check.
689
    if lowerBoundSa > upperBoundSa:
690
        return None
691
    ## Change Sollya precision, if requested.
692
    if not sollyaPrecSa is None:
693
        sollyaPrecSo = pobyso_get_prec_so()
694
        pobyso_set_prec_sa_so(sollyaPrecSa)
695
    else:
696
        sollyaPrecSa = pobyso_get_prec_so_sa()
697
        sollyaPrecSo = None
698
    RRR = lowerBoundSa.parent()
699
    intervalShrinkConstFactorSa = RRR('0.9')
700
    absoluteErrorTypeSo = pobyso_absolute_so_so()
701
    currentRangeSo = pobyso_bounds_to_range_sa_so(lowerBoundSa, upperBoundSa)
702
    currentUpperBoundSa = upperBoundSa
703
    currentLowerBoundSa = lowerBoundSa
704
    # What we want here is the polynomial without the variable change, 
705
    # since our actual variable will be x-intervalCenter defined over the 
706
    # domain [lowerBound-intervalCenter , upperBound-intervalCenter]. 
707
    (polySo, intervalCenterSo, maxErrorSo) = \
708
        pobyso_taylor_expansion_no_change_var_so_so(functionSo, degreeSo, 
709
                                                    currentRangeSo, 
710
                                                    absoluteErrorTypeSo)
711
    maxErrorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo)
712
    while maxErrorSa > approxAccurSa:
713
        print "++Approximation error:", maxErrorSa.n()
714
        sollya_lib_clear_obj(polySo)
715
        sollya_lib_clear_obj(intervalCenterSo)
716
        sollya_lib_clear_obj(maxErrorSo)
717
        # Very empirical shrinking factor.
718
        shrinkFactorSa = 1 /  (maxErrorSa/approxAccurSa).log2().abs()
719
        print "Shrink factor:", \
720
              shrinkFactorSa.n(), \
721
              intervalShrinkConstFactorSa
722
        print
723
        #errorRatioSa = approxAccurSa/maxErrorSa
724
        #print "Error ratio: ", errorRatioSa
725
        # Make sure interval shrinks.
726
        if shrinkFactorSa > intervalShrinkConstFactorSa:
727
            actualShrinkFactorSa = intervalShrinkConstFactorSa
728
            #print "Fixed"
729
        else:
730
            actualShrinkFactorSa = shrinkFactorSa
731
            #print "Computed",shrinkFactorSa,maxErrorSa
732
            #print shrinkFactorSa, maxErrorSa
733
        #print "Shrink factor", actualShrinkFactorSa
734
        currentUpperBoundSa = currentLowerBoundSa + \
735
                                (currentUpperBoundSa - currentLowerBoundSa) * \
736
                                actualShrinkFactorSa
737
        #print "Current upper bound:", currentUpperBoundSa
738
        sollya_lib_clear_obj(currentRangeSo)
739
        # Check what is left with the bounds.
740
        if currentUpperBoundSa <= currentLowerBoundSa or \
741
              currentUpperBoundSa == currentLowerBoundSa.nextabove():
742
            sollya_lib_clear_obj(absoluteErrorTypeSo)
743
            print "Can't find an interval."
744
            print "Use either or both a higher polynomial degree or a higher",
745
            print "internal precision."
746
            print "Aborting!"
747
            if not sollyaPrecSo is None:
748
                pobyso_set_prec_so_so(sollyaPrecSo)
749
                sollya_lib_clear_obj(sollyaPrecSo)
750
            return None
751
        currentRangeSo = pobyso_bounds_to_range_sa_so(currentLowerBoundSa, 
752
                                                      currentUpperBoundSa)
753
        # print "New interval:",
754
        # pobyso_autoprint(currentRangeSo)
755
        #print "Second Taylor expansion call."
756
        (polySo, intervalCenterSo, maxErrorSo) = \
757
            pobyso_taylor_expansion_no_change_var_so_so(functionSo, degreeSo, 
758
                                                        currentRangeSo, 
759
                                                        absoluteErrorTypeSo)
760
        #maxErrorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo, RRR)
761
        #print "Max errorSo:",
762
        #pobyso_autoprint(maxErrorSo)
763
        maxErrorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo)
764
        #print "Max errorSa:", maxErrorSa
765
        #print "Sollya prec:",
766
        #pobyso_autoprint(sollya_lib_get_prec(None))
767
    # End while
768
    sollya_lib_clear_obj(absoluteErrorTypeSo)
769
    itpSo           = pobyso_constant_from_int_sa_so(floor(sollyaPrecSa/3))
770
    ftpSo           = pobyso_constant_from_int_sa_so(floor(2*sollyaPrecSa/3))
771
    maxPrecSo       = pobyso_constant_from_int_sa_so(sollyaPrecSa)
772
    approxAccurSo   = pobyso_constant_sa_so(RR(approxAccurSa))
773
    if debug:
774
        print "About to call polynomial rounding with:"
775
        print "polySo: ",           ; pobyso_autoprint(polySo)
776
        print "functionSo: ",       ; pobyso_autoprint(functionSo)
777
        print "intervalCenterSo: ", ; pobyso_autoprint(intervalCenterSo)
778
        print "currentRangeSo: ",   ; pobyso_autoprint(currentRangeSo)
779
        print "itpSo: ",            ; pobyso_autoprint(itpSo)
780
        print "ftpSo: ",            ; pobyso_autoprint(ftpSo)
781
        print "maxPrecSo: ",        ; pobyso_autoprint(maxPrecSo)
782
        print "approxAccurSo: ",    ; pobyso_autoprint(approxAccurSo)
783
    (roundedPolySo, roundedPolyMaxErrSo) = \
784
    pobyso_polynomial_coefficients_progressive_round_so_so(polySo,
785
                                                           functionSo,
786
                                                           intervalCenterSo,
787
                                                           currentRangeSo,
788
                                                           itpSo,
789
                                                           ftpSo,
790
                                                           maxPrecSo,
791
                                                           approxAccurSo)
792
    
793
    sollya_lib_clear_obj(polySo)
794
    sollya_lib_clear_obj(maxErrorSo)
795
    sollya_lib_clear_obj(itpSo)
796
    sollya_lib_clear_obj(ftpSo)
797
    sollya_lib_clear_obj(approxAccurSo)
798
    if not sollyaPrecSo is None:
799
        pobyso_set_prec_so_so(sollyaPrecSo)
800
        sollya_lib_clear_obj(sollyaPrecSo)
801
    if debug:
802
        print "1: ", ; pobyso_autoprint(roundedPolySo)
803
        print "2: ", ; pobyso_autoprint(currentRangeSo)
804
        print "3: ", ; pobyso_autoprint(intervalCenterSo)
805
        print "4: ", ; pobyso_autoprint(roundedPolyMaxErrSo)
806
    return (roundedPolySo, currentRangeSo, intervalCenterSo, roundedPolyMaxErrSo)
807
# End slz_compute_polynomial_and_interval_01
808

  
809
def slz_compute_polynomial_and_interval_02(functionSo, degreeSo, lowerBoundSa, 
810
                                        upperBoundSa, approxAccurSa, 
613 811
                                        sollyaPrecSa=None):
614 812
    """
615 813
    Under the assumptions listed for slz_get_intervals_and_polynomials, compute
......
747 945
    print "3: ", ; pobyso_autoprint(intervalCenterSo)
748 946
    print "4: ", ; pobyso_autoprint(roundedPolyMaxErrSo)
749 947
    return (roundedPolySo, currentRangeSo, intervalCenterSo, roundedPolyMaxErrSo)
750
# End slz_compute_polynomial_and_interval_01
948
# End slz_compute_polynomial_and_interval_02
751 949

  
752 950
def slz_compute_reduced_polynomial(matrixRow,
753 951
                                    knownMonomials,

Formats disponibles : Unified diff