Statistiques
| Révision :

root / pobysoPythonSage / src / sageSLZ / runSLZ-01.sage @ 190

Historique | Voir | Annoter | Télécharger (12,75 ko)

1
#! /opt/sage/sage
2
from scipy.constants.codata import precision
3
def initialize_env():
4
    #Load all necessary modules.
5
    if not 'mpfi' in sage.misc.cython.standard_libs:
6
        sage.misc.cython.standard_libs.append('mpfi')
7
    load("/home/storres/recherche/arithmetique/pobysoPythonSage/src/sollya_lib.sage")
8
    load("/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageMpfr.spyx")
9
    load("/home/storres/recherche/arithmetique/pobysoPythonSage/src/pobyso.py")
10
    load("/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageSLZ.sage")
11
    load("/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageNumericalOperations.sage")
12
    load("/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageRationalOperations.sage")
13
    # Matrix operations are loaded by polynomial operations.
14
    load("/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sagePolynomialOperations.sage")
15

    
16

    
17
def run_SLZ(inputFunction,
18
            inputLowerBound,
19
            inputUpperBound,
20
            alpha,
21
            degree,
22
            precision,
23
            emin,
24
            emax,
25
            targetHardnessToRound,
26
            debug = False):
27

    
28
    if debug:
29
        print "Function                :", inputFunction
30
        print "Lower bound             :", inputLowerBound
31
        print "Upper bounds            :", inputUpperBound
32
        print "Alpha                   :", alpha
33
        print "Degree                  :", degree
34
        print "Precision               :", precision
35
        print "Emin                    :", emin
36
        print "Emax                    :", emax
37
        print "Target hardness-to-round:", targetHardnessToRound
38
        print
39
    ## Structures.
40
    RRR         = RealField(precision)
41
    RRIF        = RealIntervalField(precision)
42
    ## Converting input bound into the "right" field.
43
    lowerBound = RRR(inputLowerBound)
44
    upperBound = RRR(inputUpperBound)
45
    ## Before going any further, check domain and image binade conditions.
46
    print inputFunction(1).n()
47
    (lb,ub) = slz_fix_bounds_for_binades(lowerBound, upperBound, inputFunction)
48
    if lb != lowerBound or ub != upperBound:
49
        print "lb:", lb, " - ub:", ub
50
        print "Invalid domain/image binades. Domain:",\
51
        lowerBound, upperBound, "Images:", \
52
        inputFunction(lowerBound), inputFunction(upperBound)
53
        raise Exception("Invalid domain/image binades.")
54
    #
55
    ## Progam initialization
56
    ### Approximation polynomial accuracy and hardness to round.
57
    polyApproxAccur           = 2^(-(targetHardnessToRound + 1))
58
    polyTargetHardnessToRound = targetHardnessToRound + 1
59
    ### Significand to integer conversion ratio.
60
    toIntegerFactor           = 2^(precision-1)
61
    print "Polynomial approximation required accuracy:", polyApproxAccur.n()
62
    ### Variables and rings for polynomials and root searching.
63
    i=var('i')
64
    t=var('t')
65
    inputFunctionVariable = inputFunction.variables()[0]
66
    function = inputFunction.subs({inputFunctionVariable:i})
67
    #  Polynomial Rings over the integers, for root finding.
68
    Zi = ZZ[i]
69
    Zt = ZZ[t]
70
    Zit = ZZ[i,t]
71
    ## Number of iterations limit.
72
    maxIter = 100000
73
    #
74
    ## Compute the scaled function and the degree, in their Sollya version 
75
    #  once for all.
76
    (scaledf, sdlb, sdub, silb, siub) = \
77
        slz_compute_scaled_function(function, lowerBound, upperBound, precision)
78
    print "Scaled function:", scaledf._assume_str().replace('_SAGE_VAR_', '')
79
    scaledfSo = sollya_lib_parse_string(scaledf._assume_str().replace('_SAGE_VAR_', ''))
80
    degreeSo  = pobyso_constant_from_int_sa_so(degree)
81
    #
82
    ## Compute the scaling. boundsIntervalRifSa defined out of the loops.
83
    domainBoundsInterval   = RRIF(lowerBound, upperBound)
84
    (unscalingFunction, scalingFunction) = \
85
        slz_interval_scaling_expression(domainBoundsInterval, i)
86
    #print scalingFunction, unscalingFunction
87
    ## Set the Sollya internal precision (with an arbitrary minimum of 192).
88
    internalSollyaPrec = ceil((RR('1.5') * targetHardnessToRound) / 64) * 64
89
    if internalSollyaPrec < 192:
90
        internalSollyaPrec = 192
91
    pobyso_set_prec_sa_so(internalSollyaPrec)
92
    print "Sollya internal precision:", internalSollyaPrec
93
    ## Some variables.
94
    ### General variables
95
    lb                  = sdlb
96
    ub                  = sdub
97
    nbw                 = 0
98
    intervalUlp         = ub.ulp()
99
    #### Will be set by slz_interval_and_polynomila_to_sage.
100
    ic                  = 0 
101
    icAsInt             = 0    # Set from ic.
102
    solutionsSet        = set()
103
    tsErrorWidth        = []
104
    csErrorVectors      = []
105
    csVectorsResultants = []
106
    floatP              = 0  # Taylor polynomial.
107
    floatPcv            = 0  # Ditto with variable change.
108
    intvl               = "" # Taylor interval
109
    terr                = 0  # Taylor error.
110
    iterCount = 0
111
    htrnSet = set()
112
    ### Timers and counters.
113
    wallTimeStart                   = 0
114
    cpuTimeStart                    = 0
115
    taylCondFailedCount             = 0
116
    coppCondFailedCount             = 0
117
    resultCondFailedCount           = 0
118
    coppCondFailed                  = False
119
    resultCondFailed                = False
120
    globalResultsList               = []
121
    basisConstructionsCount         = 0
122
    basisConstructionsFullTime      = 0
123
    basisConstructionTime           = 0
124
    reductionsCount                 = 0
125
    reductionsFullTime              = 0
126
    reductionTime                   = 0
127
    resultantsComputationsCount     = 0
128
    resultantsComputationsFullTime  = 0
129
    resultantsComputationTime       = 0
130
    rootsComputationsCount          = 0
131
    rootsComputationsFullTime       = 0
132
    rootsComputationTime            = 0
133
    print
134
    ## Global times are started here.
135
    wallTimeStart                   = walltime()
136
    cpuTimeStart                    = cputime()
137
    ## Main loop.
138
    while True:
139
        if lb >= sdub:
140
            print "Lower bound reached upper bound."
141
            break
142
        if iterCount == maxIter:
143
            print "Reached maxIter. Aborting"
144
            break
145
        iterCount += 1
146
        print "[", lb, ",", ub, "]", ((ub - lb) / intervalUlp).log2().n(), \
147
            "log2(numbers)." 
148
        ### Compute a Sollya polynomial that will honor the Taylor condition.
149
        prceSo = slz_compute_polynomial_and_interval(scaledfSo,
150
                                                     degreeSo,
151
                                                     lb,
152
                                                     ub,
153
                                                     polyApproxAccur)
154
        ### Convert back the data into Sage space.                         
155
        (floatP, floatPcv, intvl, ic, terr) = \
156
            slz_interval_and_polynomial_to_sage((prceSo[0], prceSo[0],
157
                                                 prceSo[1], prceSo[2], 
158
                                                 prceSo[3]))
159
        intvl = RRIF(intvl)
160
        ## Clean-up Sollya stuff.
161
        for elem in prceSo:
162
            sollya_lib_clear_obj(elem)
163
        #print  floatP, floatPcv, intvl, ic, terr
164
        #print floatP
165
        #print intvl.endpoints()[0].n(), \
166
        #      ic.n(),
167
        #intvl.endpoints()[1].n()
168
        ### Check returned data.
169
        #### Is approximation error OK?
170
        if terr > polyApproxAccur:
171
            exceptionErrorMess  = \
172
                "Approximation failed - computed error:" + \
173
                str(terr) + " - target error: "
174
            exceptionErrorMess += \
175
                str(polyApproxAccur) + ". Aborting!"
176
            raise Exception(exceptionErrorMess)
177
        #### Is lower bound OK?
178
        if lb != intvl.endpoints()[0]:
179
            exceptionErrorMess =  "Wrong lower bound:" + \
180
                               str(lb) + ". Aborting!"
181
            raise Exception(exceptionErrorMess)
182
        #### Set upper bound.
183
        if ub > intvl.endpoints()[1]:
184
            ub = intvl.endpoints()[1]
185
            print "[", lb, ",", ub, "]", ((ub - lb) / intervalUlp).log2().n(), \
186
            "log2(numbers)." 
187
            taylCondFailedCount += 1
188
        #### Is interval not degenerate?
189
        if lb >= ub:
190
            exceptionErrorMess = "Degenerate interval: " + \
191
                                "lowerBound(" + str(lb) +\
192
                                ")>= upperBound(" + str(ub) + \
193
                                "). Aborting!"
194
            raise Exception(exceptionErrorMess)
195
        #### Is interval center ok?
196
        if ic <= lb or ic >= ub:
197
            exceptionErrorMess =  "Invalid interval center for " + \
198
                                str(lb) + ',' + str(ic) + ',' +  \
199
                                str(ub) + ". Aborting!"
200
            raise Exception(exceptionErrorMess)
201
        ##### Current interval width and reset future interval width.
202
        bw = ub - lb
203
        nbw = 0
204
        icAsInt = int(ic * toIntegerFactor)
205
        #### The following ratio is always >= 1. In case we may want to
206
        #  enlarge the interval
207
        curTaylErrRat = polyApproxAccur / terr
208
        ## Make the  integral transformations.
209
        ### First for interval center and bounds.
210
        intIc = int(ic * toIntegerFactor)
211
        intLb = int(lb * toIntegerFactor) - intIc
212
        intUb = int(ub * toIntegerFactor) - intIc
213
        #
214
        #### Loop flesh
215
        #### End loop flesh.
216
        #### Compute an incremented width for next upper bound, only
217
        #    if not Coppersmith condition nor resultant condition
218
        #    failed at the previous run. 
219
        if not coppCondFailed and not resultCondFailed:
220
            nbw = (1 + 2^(-5)) * bw
221
            ##### Reset the failure flags. They will be raised
222
            #     again if needed.
223
        else:
224
            nbw = bw
225
        rootsComputationsFullTime       =   cputime(rootsComputationTime)
226
        rootsComputationsCount          +=  1
227
        coppCondFailed   = False
228
        resultCondFailed = False
229
        #### For next iteration (at end of loop)
230
        #print "nbw:", nbw
231
        lb  = ub
232
        ub += nbw     
233
        if ub > sdub:
234
            ub = sdub
235
        print
236
    # End while True
237
    ## Main loop just ended.
238
    globalWallTime = walltime(wallTimeStart)
239
    globalCpuTime  = cputime(cpuTimeStart)
240
    ## Output results
241
    print ; print "Intervals and HTRNs"
242
    for intervalResultsList in globalResultsList:
243
        print "[", intervalResultsList[0][0], ",",intervalResultsList[0][1], "]",
244
        if len(intervalResultsList) > 1:
245
            rootsResultsList = intervalResultsList[1]
246
            for specificRootResultsList in rootsResultsList:
247
                print "\t", specificRootResultsList[0],
248
                if len(specificRootResultsList) > 1:
249
                    print specificRootResultsList[1],
250
        print ; print
251
    #print globalResultsList
252
    #
253
    print "Timers and counters"
254
    print
255
    print "Number of iterations:", iterCount
256
    print "Taylor condition failures:", taylCondFailedCount
257
    print "Coppersmith condition failures:", coppCondFailedCount
258
    print "Resultant condition failures:", resultCondFailedCount
259
    print "Iterations count: ", iterCount
260
    print "Number of intervals:", len(globalResultsList)
261
    print "Number of basis constructions:", basisConstructionsCount 
262
    print "Total CPU time spent in basis constructions:", \
263
        basisConstructionsFullTime
264
    if basisConstructionsCount != 0:
265
        print "Average basis construction CPU time:", \
266
            basisConstructionsFullTime/basisConstructionsCount
267
    print "Number of reductions:", reductionsCount
268
    print "Total CPU time spent in reductions:", reductionsFullTime
269
    if reductionsCount != 0:
270
        print "Average reduction CPU time:", \
271
            reductionsFullTime/reductionsCount
272
    print "Number of resultants computation rounds:", \
273
        resultantsComputationsCount
274
    print "Total CPU time spent in resultants computation rounds:", \
275
        resultantsComputationsFullTime
276
    if resultantsComputationsCount != 0:
277
        print "Average resultants computation round CPU time:", \
278
            resultantsComputationsFullTime/resultantsComputationsCount
279
    print "Number of root finding rounds:", rootsComputationsCount
280
    print "Total CPU time spent in roots finding rounds:", \
281
        rootsComputationsFullTime
282
    if rootsComputationsCount != 0:
283
        print "Average roots finding round CPU time:", \
284
            rootsComputationsFullTime/rootsComputationsCount
285
    print "Global Wall time:", globalWallTime
286
    print "Global CPU time:", globalCpuTime
287
    ## Output counters
288

    
289
print "Running SLZ..."
290
initialize_env()
291
x = var('x')
292
func(x) = exp(x)
293
precision = 53
294
RRR = RealField(precision)
295
run_SLZ(inputFunction=func, 
296
        inputLowerBound = 1/4, 
297
        inputUpperBound = RRR(1/2) - RRR(1/4).ulp(), 
298
        alpha = 2, 
299
        degree = 10, 
300
        precision = 53, 
301
        emin = -1022, 
302
        emax = 1023, 
303
        targetHardnessToRound =  precision+50, 
304
        debug = True)