Révision 219

pobysoPythonSage/src/pobyso.py (revision 219)
1128 1128
                                                           itpSo,
1129 1129
                                                           ftpSo,
1130 1130
                                                           maxPrecSo,
1131
                                                           maxErrSo):
1132
    print "Input arguments:"
1133
    #pobyso_autoprint(polySo)
1134
    #pobyso_autoprint(funcSo)
1135
    #pobyso_autoprint(icSo)
1136
    #pobyso_autoprint(intervalSo)
1137
    #pobyso_autoprint(itpSo)
1138
    #pobyso_autoprint(ftpSo)
1139
    #pobyso_autoprint(maxPrecSo)
1140
    #pobyso_autoprint(maxErrSo)
1141
    #print "________________"
1131
                                                           maxErrSo,
1132
                                                           debug=False):
1133
    if debug:
1134
        print "Input arguments:"
1135
        pobyso_autoprint(polySo)
1136
        pobyso_autoprint(funcSo)
1137
        pobyso_autoprint(icSo)
1138
        pobyso_autoprint(intervalSo)
1139
        pobyso_autoprint(itpSo)
1140
        pobyso_autoprint(ftpSo)
1141
        pobyso_autoprint(maxPrecSo)
1142
        pobyso_autoprint(maxErrSo)
1143
        print "________________"
1142 1144
    
1143 1145
    ## Higher order function see: 
1144 1146
    #  http://effbot.org/pyfaq/how-do-you-make-a-higher-order-function-in-python.htm
......
1155 1157
    
1156 1158
    #
1157 1159
    degreeSa        = pobyso_polynomial_degree_so_sa(polySo)
1158
    print "degreeSa:", degreeSa
1159 1160
    ratio           = precision_decay_ratio_function(degreeSa)
1160
    print "ratio:", ratio
1161 1161
    itpSa           = pobyso_constant_from_int_so_sa(itpSo)
1162
    print "itpsSa:", itpSa
1163 1162
    ftpSa           = pobyso_constant_from_int_so_sa(ftpSo)
1164
    print "ftpSa:", ftpSa
1165 1163
    maxPrecSa       = pobyso_constant_from_int_so_sa(maxPrecSo)
1166
    print "maxPrecSa:", maxPrecSa
1167 1164
    maxErrSa        = pobyso_get_constant_as_rn_so_sa(maxErrSo)
1168
    print "maxErrSa:", maxErrSa
1165
    if debug:
1166
        print "degreeSa:", degreeSa
1167
        print "ratio:", ratio
1168
        print "itpsSa:", itpSa
1169
        print "ftpSa:", ftpSa
1170
        print "maxPrecSa:", maxPrecSa
1171
        print "maxErrSa:", maxErrSa
1169 1172
    lastResPolySo   = None
1170 1173
    lastInfNormSo   = None
1171
    print "About to enter the while loop..."
1174
    #print "About to enter the while loop..."
1172 1175
    while True: 
1173 1176
        resPolySo   = pobyso_constant_0_sa_so()
1174 1177
        pDeltaSa    = ftpSa - itpSa
......
1179 1182
            #print ratio(indexSa)
1180 1183
            ctpSa = floor(ftpSa - (pDeltaSa * ratio(indexSa)))
1181 1184
            ctpSo = pobyso_constant_from_int_sa_so(ctpSa)
1182
            print "Index:", indexSa, " - Target precision:", 
1183
            pobyso_autoprint(ctpSo)
1185
            if debug:
1186
                print "Index:", indexSa, " - Target precision:", 
1187
                pobyso_autoprint(ctpSo)
1184 1188
            cmonSo  = \
1185 1189
                sollya_lib_build_function_mul(sollya_lib_coeff(polySo, indexSo),
1186 1190
                                      sollya_lib_build_function_pow( \
......
1201 1205
                                                  resPolyCvSo)
1202 1206
        infNormSo = sollya_lib_dirtyinfnorm(errFuncSo, intervalSo)
1203 1207
        cerrSa    = pobyso_get_constant_as_rn_so_sa(infNormSo)
1204
        print "Infnorm (Sollya):", pobyso_autoprint(infNormSo)
1208
        if debug:
1209
            print "Infnorm (Sollya):", 
1210
            pobyso_autoprint(infNormSo)
1205 1211
        sollya_lib_clear_obj(errFuncSo)
1206 1212
        #print "Infnorm  (Sage):", cerrSa
1207 1213
        if (cerrSa > maxErrSa):
1208
            print "Error is too large."
1214
            if debug:
1215
                print "Error is too large."
1209 1216
            if lastResPolySo is None:
1210
                print "Enlarging prec."
1217
                if debug:
1218
                    print "Enlarging prec."
1211 1219
                ntpSa = floor(ftpSa + ftpSa/50)
1212 1220
                ## Can't enlarge (numerical)
1213 1221
                if ntpSa == ftpSa:
......
1221 1229
                continue
1222 1230
            ## One enlargement took place.
1223 1231
            else:
1224
                print "Exit with the last before last polynomial."
1232
                if debug:
1233
                    print "Exit with the last before last polynomial."
1225 1234
                sollya_lib_clear_obj(resPolySo)
1226 1235
                sollya_lib_clear_obj(infNormSo)
1227 1236
                return (lastResPolySo, lastInfNormSo)
1228 1237
        # cerrSa <= maxErrSa: scrap more bits, possibly.
1229 1238
        else:
1230
            print "Error is too small"
1231
            if cerrSa <= (maxErrSa/2): 
1232
                print "Shrinking prec."
1239
            if debug:
1240
                print "Error is too small"
1241
            if cerrSa <= (maxErrSa/2):
1242
                if debug: 
1243
                    print "Shrinking prec."
1233 1244
                ntpSa = floor(ftpSa - ftpSa/50)
1234 1245
                ## Can't shrink (numerical)
1235 1246
                if ntpSa == ftpSa:
pobysoPythonSage/src/sageSLZ/sageRunSLZ.sage (revision 219)
1950 1950
    Changes from V3:
1951 1951
        Root search is changed again:
1952 1952
            - only resultants in i are computed;
1953
            - root are searched for;
1953
            - roots in i are searched for;
1954 1954
            - if any, they are tested for hardness-to-round.
1955 1955
    Changes from V2:
1956 1956
        Root search is changed:
......
2396 2396
    ## Output counters
2397 2397
# End srs_runSLZ-v04
2398 2398

  
2399
def srs_run_SLZ_v05(inputFunction,
2400
                    inputLowerBound,
2401
                    inputUpperBound,
2402
                    alpha,
2403
                    degree,
2404
                    precision,
2405
                    emin,
2406
                    emax,
2407
                    targetHardnessToRound,
2408
                    debug = False):
2409
    """
2410
    Changes from V4:
2411
        Approximation polynomial has coefficients rounded.
2412
    Changes from V3:
2413
        Root search is changed again:
2414
            - only resultants in i are computed;
2415
            - roots in i are searched for;
2416
            - if any, they are tested for hardness-to-round.
2417
    Changes from V2:
2418
        Root search is changed:
2419
            - we compute the resultants in i and in t;
2420
            - we compute the roots set of each of these resultants;
2421
            - we combine all the possible pairs between the two sets;
2422
            - we check these pairs in polynomials for correctness.
2423
    Changes from V1: 
2424
        1- check for roots as soon as a resultant is computed;
2425
        2- once a non null resultant is found, check for roots;
2426
        3- constant resultant == no root.
2427
    """
2428

  
2429
    if debug:
2430
        print "Function                :", inputFunction
2431
        print "Lower bound             :", inputLowerBound
2432
        print "Upper bounds            :", inputUpperBound
2433
        print "Alpha                   :", alpha
2434
        print "Degree                  :", degree
2435
        print "Precision               :", precision
2436
        print "Emin                    :", emin
2437
        print "Emax                    :", emax
2438
        print "Target hardness-to-round:", targetHardnessToRound
2439
        print
2440
    ## Important constants.
2441
    ### Stretch the interval if no error happens.
2442
    noErrorIntervalStretch = 1 + 2^(-5)
2443
    ### If no vector validates the Coppersmith condition, shrink the interval
2444
    #   by the following factor.
2445
    noCoppersmithIntervalShrink = 1/2
2446
    ### If only (or at least) one vector validates the Coppersmith condition, 
2447
    #   shrink the interval by the following factor.
2448
    oneCoppersmithIntervalShrink = 3/4
2449
    #### If only null resultants are found, shrink the interval by the 
2450
    #    following factor.
2451
    onlyNullResultantsShrink     = 3/4
2452
    ## Structures.
2453
    RRR         = RealField(precision)
2454
    RRIF        = RealIntervalField(precision)
2455
    ## Converting input bound into the "right" field.
2456
    lowerBound = RRR(inputLowerBound)
2457
    upperBound = RRR(inputUpperBound)
2458
    ## Before going any further, check domain and image binade conditions.
2459
    print inputFunction(1).n()
2460
    output = slz_fix_bounds_for_binades(lowerBound, upperBound, inputFunction)
2461
    if output is None:
2462
        print "Invalid domain/image binades. Domain:",\
2463
        lowerBound, upperBound, "Images:", \
2464
        inputFunction(lowerBound), inputFunction(upperBound)
2465
        raise Exception("Invalid domain/image binades.")
2466
    lb = output[0] ; ub = output[1]
2467
    if lb != lowerBound or ub != upperBound:
2468
        print "lb:", lb, " - ub:", ub
2469
        print "Invalid domain/image binades. Domain:",\
2470
        lowerBound, upperBound, "Images:", \
2471
        inputFunction(lowerBound), inputFunction(upperBound)
2472
        raise Exception("Invalid domain/image binades.")
2473
    #
2474
    ## Progam initialization
2475
    ### Approximation polynomial accuracy and hardness to round.
2476
    polyApproxAccur           = 2^(-(targetHardnessToRound + 1))
2477
    polyTargetHardnessToRound = targetHardnessToRound + 1
2478
    ### Significand to integer conversion ratio.
2479
    toIntegerFactor           = 2^(precision-1)
2480
    print "Polynomial approximation required accuracy:", polyApproxAccur.n()
2481
    ### Variables and rings for polynomials and root searching.
2482
    i=var('i')
2483
    t=var('t')
2484
    inputFunctionVariable = inputFunction.variables()[0]
2485
    function = inputFunction.subs({inputFunctionVariable:i})
2486
    #  Polynomial Rings over the integers, for root finding.
2487
    Zi = ZZ[i]
2488
    Zt = ZZ[t]
2489
    Zit = ZZ[i,t]
2490
    ## Number of iterations limit.
2491
    maxIter = 100000
2492
    #
2493
    ## Compute the scaled function and the degree, in their Sollya version 
2494
    #  once for all.
2495
    (scaledf, sdlb, sdub, silb, siub) = \
2496
        slz_compute_scaled_function(function, lowerBound, upperBound, precision)
2497
    print "Scaled function:", scaledf._assume_str().replace('_SAGE_VAR_', '')
2498
    scaledfSo = sollya_lib_parse_string(scaledf._assume_str().replace('_SAGE_VAR_', ''))
2499
    degreeSo  = pobyso_constant_from_int_sa_so(degree)
2500
    #
2501
    ## Compute the scaling. boundsIntervalRifSa defined out of the loops.
2502
    domainBoundsInterval   = RRIF(lowerBound, upperBound)
2503
    (unscalingFunction, scalingFunction) = \
2504
        slz_interval_scaling_expression(domainBoundsInterval, i)
2505
    #print scalingFunction, unscalingFunction
2506
    ## Set the Sollya internal precision (with an arbitrary minimum of 192).
2507
    internalSollyaPrec = ceil((RR('1.5') * targetHardnessToRound) / 64) * 64
2508
    if internalSollyaPrec < 192:
2509
        internalSollyaPrec = 192
2510
    pobyso_set_prec_sa_so(internalSollyaPrec)
2511
    print "Sollya internal precision:", internalSollyaPrec
2512
    ## Some variables.
2513
    ### General variables
2514
    lb                  = sdlb
2515
    ub                  = sdub
2516
    nbw                 = 0
2517
    intervalUlp         = ub.ulp()
2518
    #### Will be set by slz_interval_and_polynomila_to_sage.
2519
    ic                  = 0 
2520
    icAsInt             = 0    # Set from ic.
2521
    solutionsSet        = set()
2522
    tsErrorWidth        = []
2523
    csErrorVectors      = []
2524
    csVectorsResultants = []
2525
    floatP              = 0  # Taylor polynomial.
2526
    floatPcv            = 0  # Ditto with variable change.
2527
    intvl               = "" # Taylor interval
2528
    terr                = 0  # Taylor error.
2529
    iterCount = 0
2530
    htrnSet = set()
2531
    ### Timers and counters.
2532
    wallTimeStart                   = 0
2533
    cpuTimeStart                    = 0
2534
    taylCondFailedCount             = 0
2535
    coppCondFailedCount             = 0
2536
    resultCondFailedCount           = 0
2537
    coppCondFailed                  = False
2538
    resultCondFailed                = False
2539
    globalResultsList               = []
2540
    basisConstructionsCount         = 0
2541
    basisConstructionsFullTime      = 0
2542
    basisConstructionTime           = 0
2543
    reductionsCount                 = 0
2544
    reductionsFullTime              = 0
2545
    reductionTime                   = 0
2546
    resultantsComputationsCount     = 0
2547
    resultantsComputationsFullTime  = 0
2548
    resultantsComputationTime       = 0
2549
    rootsComputationsCount          = 0
2550
    rootsComputationsFullTime       = 0
2551
    rootsComputationTime            = 0
2552
    print
2553
    ## Global times are started here.
2554
    wallTimeStart                   = walltime()
2555
    cpuTimeStart                    = cputime()
2556
    ## Main loop.
2557
    while True:
2558
        if lb >= sdub:
2559
            print "Lower bound reached upper bound."
2560
            break
2561
        if iterCount == maxIter:
2562
            print "Reached maxIter. Aborting"
2563
            break
2564
        iterCount += 1
2565
        print "[", lb, ",", ub, "]", ((ub - lb) / intervalUlp).log2().n(), \
2566
            "log2(numbers)." 
2567
        ### Compute a Sollya polynomial that will honor the Taylor condition.
2568
        prceSo = slz_compute_polynomial_and_interval_01(scaledfSo,
2569
                                                        degreeSo,
2570
                                                        lb,
2571
                                                        ub,
2572
                                                        polyApproxAccur)
2573
        ### Convert back the data into Sage space.                         
2574
        (floatP, floatPcv, intvl, ic, terr) = \
2575
            slz_interval_and_polynomial_to_sage((prceSo[0], prceSo[0],
2576
                                                 prceSo[1], prceSo[2], 
2577
                                                 prceSo[3]))
2578
        intvl = RRIF(intvl)
2579
        ## Clean-up Sollya stuff.
2580
        for elem in prceSo:
2581
            sollya_lib_clear_obj(elem)
2582
        #print  floatP, floatPcv, intvl, ic, terr
2583
        #print floatP
2584
        #print intvl.endpoints()[0].n(), \
2585
        #      ic.n(),
2586
        #intvl.endpoints()[1].n()
2587
        ### Check returned data.
2588
        #### Is approximation error OK?
2589
        if terr > polyApproxAccur:
2590
            exceptionErrorMess  = \
2591
                "Approximation failed - computed error:" + \
2592
                str(terr) + " - target error: "
2593
            exceptionErrorMess += \
2594
                str(polyApproxAccur) + ". Aborting!"
2595
            raise Exception(exceptionErrorMess)
2596
        #### Is lower bound OK?
2597
        if lb != intvl.endpoints()[0]:
2598
            exceptionErrorMess =  "Wrong lower bound:" + \
2599
                               str(lb) + ". Aborting!"
2600
            raise Exception(exceptionErrorMess)
2601
        #### Set upper bound.
2602
        if ub > intvl.endpoints()[1]:
2603
            ub = intvl.endpoints()[1]
2604
            print "[", lb, ",", ub, "]", ((ub - lb) / intervalUlp).log2().n(), \
2605
            "log2(numbers)." 
2606
            taylCondFailedCount += 1
2607
        #### Is interval not degenerate?
2608
        if lb >= ub:
2609
            exceptionErrorMess = "Degenerate interval: " + \
2610
                                "lowerBound(" + str(lb) +\
2611
                                ")>= upperBound(" + str(ub) + \
2612
                                "). Aborting!"
2613
            raise Exception(exceptionErrorMess)
2614
        #### Is interval center ok?
2615
        if ic <= lb or ic >= ub:
2616
            exceptionErrorMess =  "Invalid interval center for " + \
2617
                                str(lb) + ',' + str(ic) + ',' +  \
2618
                                str(ub) + ". Aborting!"
2619
            raise Exception(exceptionErrorMess)
2620
        ##### Current interval width and reset future interval width.
2621
        bw = ub - lb
2622
        nbw = 0
2623
        icAsInt = int(ic * toIntegerFactor)
2624
        #### The following ratio is always >= 1. In case we may want to
2625
        #    enlarge the interval
2626
        curTaylErrRat = polyApproxAccur / terr
2627
        ### Make the  integral transformations.
2628
        #### Bounds and interval center.
2629
        intIc = int(ic * toIntegerFactor)
2630
        intLb = int(lb * toIntegerFactor) - intIc
2631
        intUb = int(ub * toIntegerFactor) - intIc
2632
        #
2633
        #### Polynomials
2634
        basisConstructionTime         = cputime()
2635
        ##### To a polynomial with rational coefficients with rational arguments
2636
        ratRatP = slz_float_poly_of_float_to_rat_poly_of_rat_pow_two(floatP)
2637
        ##### To a polynomial with rational coefficients with integer arguments
2638
        ratIntP = \
2639
            slz_rat_poly_of_rat_to_rat_poly_of_int(ratRatP, precision)
2640
        #####  Ultimately a multivariate polynomial with integer coefficients  
2641
        #      with integer arguments.
2642
        coppersmithTuple = \
2643
            slz_rat_poly_of_int_to_poly_for_coppersmith(ratIntP, 
2644
                                                        precision, 
2645
                                                        targetHardnessToRound, 
2646
                                                        i, t)
2647
        #### Recover Coppersmith information.
2648
        intIntP = coppersmithTuple[0]
2649
        N = coppersmithTuple[1]
2650
        nAtAlpha = N^alpha
2651
        tBound = coppersmithTuple[2]
2652
        leastCommonMultiple = coppersmithTuple[3]
2653
        iBound = max(abs(intLb),abs(intUb))
2654
        basisConstructionsFullTime        += cputime(basisConstructionTime)
2655
        basisConstructionsCount           += 1
2656
        """
2657
        #### Compute the matrix to reduce.
2658
        matrixToReduce = slz_compute_initial_lattice_matrix(intIntP,
2659
                                                            alpha,
2660
                                                            N,
2661
                                                            iBound,
2662
                                                            tBound)
2663
        matrixFile = file('/tmp/matrixToReduce.txt', 'w')
2664
        for row in matrixToReduce.rows():
2665
            matrixFile.write(str(row) + "\n")
2666
        matrixFile.close()
2667
        raise Exception("Deliberate stop here.")
2668
        """
2669
        reductionTime                     = cputime()
2670
        #### Compute the reduced polynomials.
2671
        ccReducedPolynomialsList =  \
2672
                slz_compute_coppersmith_reduced_polynomials(intIntP, 
2673
                                                            alpha, 
2674
                                                            N, 
2675
                                                            iBound, 
2676
                                                            tBound)
2677
        if ccReducedPolynomialsList is None:
2678
            raise Exception("Reduction failed.")
2679
        reductionsFullTime    += cputime(reductionTime)
2680
        reductionsCount       += 1
2681
        if len(ccReducedPolynomialsList) < 2:
2682
            print "Nothing to form resultants with."
2683
            print
2684
            coppCondFailedCount += 1
2685
            coppCondFailed = True
2686
            ##### Apply a different shrink factor according to 
2687
            #  the number of compliant polynomials.
2688
            if len(ccReducedPolynomialsList) == 0:
2689
                ub = lb + bw * noCoppersmithIntervalShrink
2690
            else: # At least one compliant polynomial.
2691
                ub = lb + bw * oneCoppersmithIntervalShrink
2692
            if ub > sdub:
2693
                ub = sdub
2694
            if lb == ub:
2695
                raise Exception("Cant shrink interval \
2696
                anymore to get Coppersmith condition.")
2697
            nbw = 0
2698
            continue
2699
        #### We have at least two polynomials.
2700
        #    Let us try to compute resultants.
2701
        #    For each resultant computed, go for the solutions.
2702
        ##### Build the pairs list.
2703
        polyPairsList           = []
2704
        for polyOuterIndex in xrange(0, len(ccReducedPolynomialsList) - 1):
2705
            for polyInnerIndex in xrange(polyOuterIndex+1, 
2706
                                         len(ccReducedPolynomialsList)):
2707
                polyPairsList.append((ccReducedPolynomialsList[polyOuterIndex],
2708
                                      ccReducedPolynomialsList[polyInnerIndex]))
2709
        #### Actual root search.
2710
        iRootsSet           = set()
2711
        hasNonNullResultant = False
2712
        for polyPair in polyPairsList:
2713
            resultantsComputationTime   = cputime()
2714
            currentResultantI = \
2715
                slz_resultant(polyPair[0],
2716
                              polyPair[1],
2717
                              t)
2718
            resultantsComputationsCount    += 1
2719
            resultantsComputationsFullTime +=  \
2720
                cputime(resultantsComputationTime)
2721
            #### Function slz_resultant returns None both for None and O
2722
            #    resultants.
2723
            if currentResultantI is None:
2724
                print "Nul resultant"
2725
                continue # Next polyPair.
2726
            ## We deleted the currentResultantI computation.
2727
            #### We have a non null resultant. From now on, whatever this
2728
            #    root search yields, no extra root search is necessary.
2729
            hasNonNullResultant = True
2730
            #### A constant resultant leads to no root. Root search is done.
2731
            if currentResultantI.degree() < 1:
2732
                print "Resultant is constant:", currentResultantI
2733
                break # There is no root.
2734
            #### Actual iroots computation.
2735
            rootsComputationTime        = cputime()
2736
            iRootsList = Zi(currentResultantI).roots()
2737
            rootsComputationsCount      +=  1
2738
            rootsComputationsFullTime   =   cputime(rootsComputationTime)
2739
            if len(iRootsList) == 0:
2740
                print "No roots in \"i\"."
2741
                break # No roots in i.
2742
            else:
2743
                for iRoot in iRootsList:
2744
                    # A root is given as a (value, multiplicity) tuple.
2745
                    iRootsSet.add(iRoot[0])
2746
        # End loop for polyPair in polyParsList. We only loop again if a 
2747
        # None or zero resultant is found.
2748
        #### Prepare for results for the current interval..
2749
        intervalResultsList = []
2750
        intervalResultsList.append((lb, ub))
2751
        #### Check roots.
2752
        rootsResultsList = []
2753
        for iRoot in iRootsSet:
2754
            specificRootResultsList = []
2755
            failingBounds           = []
2756
            # Root qualifies for modular equation, test it for hardness to round.
2757
            hardToRoundCaseAsFloat = RRR((icAsInt + iRoot) / toIntegerFactor)
2758
            #print "Before unscaling:", hardToRoundCaseAsFloat.n(prec=precision)
2759
            #print scalingFunction
2760
            scaledHardToRoundCaseAsFloat = \
2761
                scalingFunction(hardToRoundCaseAsFloat) 
2762
            print "Candidate HTRNc at x =", \
2763
                scaledHardToRoundCaseAsFloat.n().str(base=2),
2764
            if slz_is_htrn(scaledHardToRoundCaseAsFloat,
2765
                           function,
2766
                           2^-(targetHardnessToRound),
2767
                           RRR):
2768
                print hardToRoundCaseAsFloat, "is HTRN case."
2769
                specificRootResultsList.append(hardToRoundCaseAsFloat.n().str(base=2))
2770
                if lb <= hardToRoundCaseAsFloat and hardToRoundCaseAsFloat <= ub:
2771
                    print "Found in interval."
2772
                else:
2773
                    print "Found out of interval."
2774
                # Check the i root is within the i bound.
2775
                if abs(iRoot) > iBound:
2776
                    print "IRoot", iRoot, "is out of bounds for modular equation."
2777
                    print "i bound:", iBound
2778
                    failingBounds.append('i')
2779
                    failingBounds.append(iRoot)
2780
                    failingBounds.append(iBound)
2781
                if len(failingBounds) > 0:
2782
                    specificRootResultsList.append(failingBounds)
2783
            else: # From slz_is_htrn...
2784
                print "is not an HTRN case."
2785
            if len(specificRootResultsList) > 0:
2786
                rootsResultsList.append(specificRootResultsList)
2787
        if len(rootsResultsList) > 0:
2788
            intervalResultsList.append(rootsResultsList)
2789
        ### Check if a non null resultant was found. If not shrink the interval.
2790
        if not hasNonNullResultant:
2791
            print "Only null resultants for this reduction, shrinking interval."
2792
            resultCondFailed      =  True
2793
            resultCondFailedCount += 1
2794
            ### Shrink interval for next iteration.
2795
            ub = lb + bw * onlyNullResultantsShrink
2796
            if ub > sdub:
2797
                ub = sdub
2798
            nbw = 0
2799
            continue
2800
        #### An intervalResultsList has at least the bounds.
2801
        globalResultsList.append(intervalResultsList)   
2802
        #### Compute an incremented width for next upper bound, only
2803
        #    if not Coppersmith condition nor resultant condition
2804
        #    failed at the previous run. 
2805
        if not coppCondFailed and not resultCondFailed:
2806
            nbw = noErrorIntervalStretch * bw
2807
        else:
2808
            nbw = bw
2809
        ##### Reset the failure flags. They will be raised
2810
        #     again if needed.
2811
        coppCondFailed   = False
2812
        resultCondFailed = False
2813
        #### For next iteration (at end of loop)
2814
        #print "nbw:", nbw
2815
        lb  = ub
2816
        ub += nbw     
2817
        if ub > sdub:
2818
            ub = sdub
2819
        print
2820
    # End while True
2821
    ## Main loop just ended.
2822
    globalWallTime = walltime(wallTimeStart)
2823
    globalCpuTime  = cputime(cpuTimeStart)
2824
    ## Output results
2825
    print ; print "Intervals and HTRNs" ; print
2826
    for intervalResultsList in globalResultsList:
2827
        print "[", intervalResultsList[0][0], ",",intervalResultsList[0][1], "]",
2828
        if len(intervalResultsList) > 1:
2829
            rootsResultsList = intervalResultsList[1]
2830
            for specificRootResultsList in rootsResultsList:
2831
                print "\t", specificRootResultsList[0],
2832
                if len(specificRootResultsList) > 1:
2833
                    print specificRootResultsList[1],
2834
        print ; print
2835
    #print globalResultsList
2836
    #
2837
    print "Timers and counters"
2838
    print
2839
    print "Number of iterations:", iterCount
2840
    print "Taylor condition failures:", taylCondFailedCount
2841
    print "Coppersmith condition failures:", coppCondFailedCount
2842
    print "Resultant condition failures:", resultCondFailedCount
2843
    print "Iterations count: ", iterCount
2844
    print "Number of intervals:", len(globalResultsList)
2845
    print "Number of basis constructions:", basisConstructionsCount 
2846
    print "Total CPU time spent in basis constructions:", \
2847
        basisConstructionsFullTime
2848
    if basisConstructionsCount != 0:
2849
        print "Average basis construction CPU time:", \
2850
            basisConstructionsFullTime/basisConstructionsCount
2851
    print "Number of reductions:", reductionsCount
2852
    print "Total CPU time spent in reductions:", reductionsFullTime
2853
    if reductionsCount != 0:
2854
        print "Average reduction CPU time:", \
2855
            reductionsFullTime/reductionsCount
2856
    print "Number of resultants computation rounds:", \
2857
        resultantsComputationsCount
2858
    print "Total CPU time spent in resultants computation rounds:", \
2859
        resultantsComputationsFullTime
2860
    if resultantsComputationsCount != 0:
2861
        print "Average resultants computation round CPU time:", \
2862
            resultantsComputationsFullTime/resultantsComputationsCount
2863
    print "Number of root finding rounds:", rootsComputationsCount
2864
    print "Total CPU time spent in roots finding rounds:", \
2865
        rootsComputationsFullTime
2866
    if rootsComputationsCount != 0:
2867
        print "Average roots finding round CPU time:", \
2868
            rootsComputationsFullTime/rootsComputationsCount
2869
    print "Global Wall time:", globalWallTime
2870
    print "Global CPU time:", globalCpuTime
2871
    ## Output counters
2872
# End srs_runSLZ-v05
pobysoPythonSage/src/sageSLZ/runSLZ-04.sage (revision 219)
22 22
initialize_env()
23 23
x = var('x')
24 24
func(x) = exp(x)
25
precision = 53
25
precision = 113
26 26
RRR = RealField(precision)
27
intervalCenter      = RRR("1.9E9CBBFD6080B",16)  * 2^-31
27
intervalCenter      = RRR(3/8)
28 28
icUlp               = intervalCenter.ulp()
29
intervalRadiusInUlp = 2^49 + 2^45          
29
intervalRadiusInUlp = 2^49 + 2^45
30
intervalRadius      = RRR(2^(-35))          
30 31
srs_run_SLZ_v04(inputFunction=func, 
31
                inputLowerBound = RRR(1) * 2^-31, 
32
                inputUpperBound = RRR(1) * 2^-30 - icUlp, 
33
                alpha           = 2, 
34
                degree          = 2, 
35
                precision       = 53, 
36
                emin            = -1022, 
37
                emax            = 1023, 
38
                targetHardnessToRound =  precision+50, 
39
                debug           = True)
32
                inputLowerBound         = intervalCenter - intervalRadius, 
33
                inputUpperBound         = intervalCenter + intervalRadius, 
34
                alpha                   = 6, 
35
                degree                  = 18, 
36
                precision               = precision, 
37
                emin                    = -16382, 
38
                emax                    = 16383, 
39
                targetHardnessToRound   = precision * 6, 
40
                debug                   = True)
40 41
#
41 42
"""
42 43
srs_run_SLZ_v01(inputFunction=func, 
pobysoPythonSage/src/sageSLZ/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