Révision 80

pobysoPythonSage/src/sageSLZ/sagePolynomialOperations.sage (revision 80)
1 1
load "/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageMatrixOperations.sage"
2 2

  
3
def spo_add_polynomial_coeffs_to_matrix(pMonomials, 
4
                                        pCoefficients, 
5
                                        knownMonomials, 
6
                                        protoMatrixRows, 
7
                                        columnsWidth=0):
8
    """
9
    For a given polynomial (under the form of monomials and coefficents lists),
10
    add the coefficients of the protoMatrix (a list of proto matrix rows).
11
    Coefficients are added to the protoMatrix row in the order imposed by the 
12
    monomials discovery list (the knownMonomials list) built as construction
13
    goes on. 
14
    As a bonus data can be printed out for a visual check.
15
    pMonomials     : the list of the monomials coming form some polynomial;
16
    pCoefficients  : the list of the corresponding coefficients to add to
17
                     the protoMatrix in the exact same order as the monomials;
18
    knownMonomials : the list of the already knonw monomials;
19
    protoMatrixRows: a list of lists, each one holding the coefficients of the 
20
                     monomials
21
    columnWith     : the width, in characters, of the displayed column ; if 0, 
22
                     do not display anything.
23
    """
24
    # We have started with the smaller degrees in the first variable.
25
    pMonomials.reverse()
26
    pCoefficients.reverse()
27
    # New empty proto matrix row.
28
    protoMatrixRowCoefficients = []
29
    # We work according to the order of the already known monomials
30
    # No known monomials yet: add the pMonomials to knownMonomials 
31
    # and add the coefficients to the proto matrix row.
32
    if len(knownMonomials) == 0: 
33
        for pmIdx in xrange(0, len(pMonomials)):
34
            knownMonomials.append(pMonomials[pmIdx])
35
            protoMatrixRowCoefficients.append(pCoefficients[pmIdx])
36
            if columnsWidth != 0:
37
                monomialAsString = str(pCoefficients[pmIdx]) + " " + \
38
                                   str(pMonomials[pmIdx])
39
                print monomialAsString, " " * \
40
                      (columnsWidth - len(monomialAsString)),
41
    # There are some known monomials. We search for them in pMonomials and 
42
    # add their coefficients to the proto matrix row.
43
    else: 
44
        for knownMonomialIndex in xrange(0,len(knownMonomials)):
45
            # We lazily use an exception here since pMonomials.index() function
46
            # may fail throwing the ValueError exception.
47
            try:
48
                indexInPmonomials = \
49
                    pMonomials.index(knownMonomials[knownMonomialIndex])
50
                if columnsWidth != 0:
51
                    monomialAsString = str(pCoefficients[indexInPmonomials]) + \
52
                        " " + str(knownMonomials[knownMonomialIndex])
53
                    print monomialAsString, " " * \
54
                        (columnsWidth - len(monomialAsString)),
55
                # Add the coefficient to the proto matrix row and delete the \
56
                # known monomial from the current pMonomial list 
57
                #(and the corresponding coefficient as well).
58
                protoMatrixRowCoefficients.append(pCoefficients[indexInPmonomials])
59
                del pMonomials[indexInPmonomials]
60
                del pCoefficients[indexInPmonomials]
61
            # The knownMonomials element is not in pMonomials
62
            except ValueError:   
63
                protoMatrixRowCoefficients.append(0)
64
                if columnsWidth != 0:
65
                    monomialAsString = "0" + " "+ \
66
                        str(knownMonomials[knownMonomialIndex])
67
                    print monomialAsString, " " * \
68
                        (columnsWidth - len(monomialAsString)),
69
        # End for knownMonomialKey loop. 
70
        # We now append the remaining monomials of pMonomials to knownMonomials 
71
        # and the corresponding coefficients to proto matrix row.
72
        for pmIdx in xrange(0, len(pMonomials)):
73
            knownMonomials.append(pMonomials[pmIdx])
74
            protoMatrixRowCoefficients.append(pCoefficients[pmIdx])
75
            if columnsWidth != 0:
76
                monomialAsString = str(pCoefficients[pmIdx]) + " " \
77
                    + str(pMonomials[pmIdx])
78
                print monomialAsString, " " * \
79
                    (columnsWidth - len(monomialAsString)),
80
        # End for pmIdx loop.
81
    # Add the new list row elements to the proto matrix.
82
    protoMatrixRows.append(protoMatrixRowCoefficients)
83
    if columnsWidth != 0:
84
        print    
85
# End spo_add_polynomial_coeffs_to_matrix
86

  
87
def spo_expression_as_string(powI, powT, powP, alpha):
88
    """
89
    Computes a string version of the i^k + t^l + p^m + N^n expression for
90
    output.
91
    """
92
    expressionAsString =""
93
    if powI != 0:
94
        expressionAsString += "i^" + str(powI)
95
    if powT != 0:
96
        if len(expressionAsString) != 0:
97
            expressionAsString += " * "
98
        expressionAsString += "t^" + str(powT)
99
    if powP != 0:
100
        if len(expressionAsString) != 0:
101
            expressionAsString += " * "
102
        expressionAsString += "p^" + str(powP)
103
    if (alpha - powP) != 0 :
104
        if len(expressionAsString) != 0:
105
            expressionAsString += " * "
106
        expressionAsString += "N^" + str(alpha - powP)
107
    return(expressionAsString)
108
# End spo_expression_as_string.
109

  
3 110
def spo_polynomial_to_matrix(p, pRing, alpha, N, columnsWidth=0):
4 111
    """
5 112
    From a (bivariate) polynomial and some other parameters build a matrix
6 113
    to be reduced by fpLLL.
7
    The matrix is such as those found in Boneh-Durphy and Stehlé.
114
    The matrix is such as those found in Boneh-Durphee and Stehl?.
8 115
    
9 116
    p: the (bivariate) polynomial
10 117
    alpha:
......
209 316
    # End for pPower loop
210 317
    return protoMatrixRows
211 318
# End spo_polynomial_to_matrix
212

  
213
def spo_add_polynomial_coeffs_to_matrix(pMonomials, 
214
                                        pCoefficients, 
215
                                        knownMonomials, 
216
                                        protoMatrixRows, 
217
                                        columnsWidth=0):
218
    """
219
    For a given polynomial (under the form of monomials and coefficents lists),
220
    add the coefficients of the protoMatrix (a list of proto rows).
221
    Coefficients are added to the protoMatrix row in the order imposed by the 
222
    monomials discovery list (the knownMonomials list) built as construction
223
    goes on. 
224
    As a bonus data can be printed out for a visual check.
225
    pMonomials     : the list of the monomials coming form some polynomial;
226
    pCoefficients  : the list of the corresponding coefficients to add to
227
                     the protoMatrix in the exact same order as the monomials;
228
    knownMonomials : the list of the already knonw monomials;
229
    protoMatrixRows: a list of lists, each one holding the coefficients of the 
230
                     monomials
231
    columnWith     : the width, in characters, of the displayed column ; if 0, 
232
                     do not display anything.
233
    """
234
    # We have started with the smaller degrees in the first variable.
235
    pMonomials.reverse()
236
    pCoefficients.reverse()
237
    # New empty proto matrix row.
238
    protoMatrixRowCoefficients = []
239
    # We work according to the order of the already known monomials
240
    # No known monomials yet: add the pMonomials to knownMonomials 
241
    # and add the coefficients to the proto matrix row.
242
    if len(knownMonomials) == 0: 
243
        for pmIdx in xrange(0, len(pMonomials)):
244
            knownMonomials.append(pMonomials[pmIdx])
245
            protoMatrixRowCoefficients.append(pCoefficients[pmIdx])
246
            if columnsWidth != 0:
247
                monomialAsString = str(pCoefficients[pmIdx]) + " " + \
248
                                   str(pMonomials[pmIdx])
249
                print monomialAsString, " " * \
250
                      (columnsWidth - len(monomialAsString)),
251
    # There are some known monomials. We search for them in pMonomials and 
252
    # add their coefficients to the proto matrix row.
253
    else: 
254
        for knownMonomialIndex in xrange(0,len(knownMonomials)):
255
            # We lazily use an exception here since pMonomials.index() function
256
            # may fail throwing the ValueError exception.
257
            try:
258
                indexInPmonomials = \
259
                    pMonomials.index(knownMonomials[knownMonomialIndex])
260
                if columnsWidth != 0:
261
                    monomialAsString = str(pCoefficients[indexInPmonomials]) + \
262
                        " " + str(knownMonomials[knownMonomialIndex])
263
                    print monomialAsString, " " * \
264
                        (columnsWidth - len(monomialAsString)),
265
                # Add the coefficient to the proto matrix row and delete the \
266
                # known monomial from the current pMonomial list 
267
                #(and the corresponding coefficient as well).
268
                protoMatrixRowCoefficients.append(pCoefficients[indexInPmonomials])
269
                del pMonomials[indexInPmonomials]
270
                del pCoefficients[indexInPmonomials]
271
            # The knownMonomials element is not in pMonomials
272
            except ValueError:   
273
                protoMatrixRowCoefficients.append(0)
274
                if columnsWidth != 0:
275
                    monomialAsString = "0" + " "+ \
276
                        str(knownMonomials[knownMonomialIndex])
277
                    print monomialAsString, " " * \
278
                        (columnsWidth - len(monomialAsString)),
279
        # End for knownMonomialKey loop. 
280
        # We now append the remaining monomials of pMonomials to knownMonomials 
281
        # and the corresponding coefficients to proto matrix row.
282
        for pmIdx in xrange(0, len(pMonomials)):
283
            knownMonomials.append(pMonomials[pmIdx])
284
            protoMatrixRowCoefficients.append(pCoefficients[pmIdx])
285
            if columnsWidth != 0:
286
                monomialAsString = str(pCoefficients[pmIdx]) + " " \
287
                    + str(pMonomials[pmIdx])
288
                print monomialAsString, " " * \
289
                    (columnsWidth - len(monomialAsString)),
290
        # End for pmIdx loop.
291
    # Add the new list row elements to the proto matrix.
292
    protoMatrixRows.append(protoMatrixRowCoefficients)
293
    if columnsWidth != 0:
294
        print    
295
# End spo_add_polynomial_coeffs_to_matrix
296

  
297
def spo_expression_as_string(powI, powT, powP, alpha):
298
    """
299
    Computes a string version of the i^k + t^l + p^m + N^n expression for
300
    output.
301
    """
302
    expressionAsString =""
303
    if powI != 0:
304
        expressionAsString += "i^" + str(powI)
305
    if powT != 0:
306
        if len(expressionAsString) != 0:
307
            expressionAsString += " * "
308
        expressionAsString += "t^" + str(powT)
309
    if powP != 0:
310
        if len(expressionAsString) != 0:
311
            expressionAsString += " * "
312
        expressionAsString += "p^" + str(powP)
313
    if (alpha - powP) != 0 :
314
        if len(expressionAsString) != 0:
315
            expressionAsString += " * "
316
        expressionAsString += "N^" + str(alpha - powP)
317
    return(expressionAsString)
318
# End spo_expression_as_string.
pobysoPythonSage/src/sageSLZ/sageSLZ.sage (revision 80)
58 58
    # End slz_compute_polynomial_and_interval
59 59

  
60 60
def slz_compute_scaled_function(functionSa, \
61
                                      variableNameSa, \
62 61
                                      lowerBoundSa, \
63 62
                                      upperBoundSa, \
64 63
                                      floatingPointPrecSa):
......
72 71
    [3]: the scaled image lower bound
73 72
    [4]: the scaled image upper bound
74 73
    """
75
    x = var(variableNameSa)
74
    x = functionSa.variables()[0]
75
    # Reassert f as a function (an not a mere expression).
76
    
76 77
    # Scalling the domain -> [1,2[.
77 78
    boundsIntervalRifSa = RealIntervalField(floatingPointPrecSa)
78 79
    domainBoundsIntervalSa = boundsIntervalRifSa(lowerBoundSa, upperBoundSa)
79 80
    (domainScalingExpressionSa, invDomainScalingExpressionSa) = \
80
        slz_interval_scaling_expression(domainBoundsIntervalSa, variableNameSa)
81
        slz_interval_scaling_expression(domainBoundsIntervalSa, x)
81 82
    print "domainScalingExpression for argument :", domainScalingExpressionSa
82 83
    print "f: ", f
83 84
    ff = f.subs({x : domainScalingExpressionSa})
84 85
    #ff = f.subs_expr(x==domainScalingExpressionSa)
85
    scaledLowerBoundSa = invDomainScalingExpressionSa(lowerBoundSa).n()
86
    scaledUpperBoundSa = invDomainScalingExpressionSa(upperBoundSa).n()
86
    domainScalingFunction(x) = invDomainScalingExpressionSa
87
    scaledLowerBoundSa = domainScalingFunction(lowerBoundSa).n()
88
    scaledUpperBoundSa = domainScalingFunction(upperBoundSa).n()
87 89
    print 'ff:', ff, "- Domain:", scaledLowerBoundSa, scaledUpperBoundSa
88 90
    #
89 91
    # Scalling the image -> [1,2[.
......
96 98
    print 'ff:', ff, '- Image:', flbSa, fubSa, imageBinadeBottomSa
97 99
    imageBoundsIntervalSa = boundsIntervalRifSa(flbSa, fubSa)
98 100
    (imageScalingExpressionSa, invImageScalingExpressionSa) = \
99
        slz_interval_scaling_expression(imageBoundsIntervalSa, variableNameSa)
101
        slz_interval_scaling_expression(imageBoundsIntervalSa, x)
100 102
    iis = invImageScalingExpressionSa.function(x)
101 103
    fff = iis.subs({x:ff})
102 104
    print "fff:", fff,
......
110 112
    return(polynomialRing(polyOfFloat))
111 113
# End slz_float_poly_of_float_to_rat_poly_of_rat
112 114
     
113
def slz_get_intervals_and_polynomials(functionSa, variableNameSa, degreeSa, 
115
def slz_get_intervals_and_polynomials(functionSa, degreeSa, 
114 116
                                      lowerBoundSa, 
115 117
                                      upperBoundSa, floatingPointPrecSa, 
116 118
                                      internalSollyaPrecSa, approxPrecSa):
......
133 135
    - the center, x0, of the interval;
134 136
    - the corresponding approximation error.
135 137
    """
136
    x = var(variableNameSa)
137
    # Scalling the domain -> [1,2[.
138
    boundsIntervalRifSa = RealIntervalField(floatingPointPrecSa)
139
    domainBoundsIntervalSa = boundsIntervalRifSa(lowerBoundSa, upperBoundSa)
140
    (domainScalingExpressionSa, invDomainScalingExpressionSa) = \
141
        slz_interval_scaling_expression(domainBoundsIntervalSa, variableNameSa)
142
    print "domainScalingExpression for argument :", domainScalingExpressionSa
143
    print "f: ", f
144
    ff = f.subs({x : domainScalingExpressionSa})
145
    #ff = f.subs_expr(x==domainScalingExpressionSa)
146
    scaledLowerBoundSa = invDomainScalingExpressionSa(lowerBoundSa).n()
147
    scaledUpperBoundSa = invDomainScalingExpressionSa(upperBoundSa).n()
148
    print 'ff:', ff, "- Domain:", scaledLowerBoundSa, scaledUpperBoundSa
138
    x = functionSa.variables()[0] # Actual variable name can be anything.
139
    (fff, scaledLowerBoundSa, scaledUpperBoundSa, \
140
            scaledLowerBoundImageSa, scaledUpperBoundImageSa) = \
141
                slz_compute_scaled_function(functionSa, \
142
                                            lowerBoundSa, \
143
                                            upperBoundSa, \
144
                                            floatingPointPrecSa)
149 145
    #
150
    # Scalling the image -> [1,2[.
151
    flbSa = f(lowerBoundSa).n()
152
    fubSa = f(upperBoundSa).n()
153
    if flbSa <= fubSa: # Increasing
154
        imageBinadeBottomSa = floor(flbSa.log2())
155
    else: # Decreasing
156
        imageBinadeBottomSa = floor(fubSa.log2())
157
    print 'ff:', ff, '- Image:', flbSa, fubSa, imageBinadeBottomSa
158
    imageBoundsIntervalSa = boundsIntervalRifSa(flbSa, fubSa)
159
    (imageScalingExpressionSa, invImageScalingExpressionSa) = \
160
        slz_interval_scaling_expression(imageBoundsIntervalSa, variableNameSa)
161
    iis = invImageScalingExpressionSa.function(x)
162
    fff = iis.subs({x:ff})
163
    print "fff:", fff,
164
    print " - Image:", fff(scaledLowerBoundSa), fff(scaledUpperBoundSa)
165
    #
166 146
    resultArray = []
167 147
    #
168 148
    print "Approximation precision: ", RR(approxPrecSa)
......
208 188
    return(resultArray)
209 189
    # End slz_get_intervals_and_polynomials
210 190

  
211
def slz_interval_scaling_expression(boundsInterval, varName):
191
def slz_interval_scaling_expression(boundsInterval, expVar):
212 192
    """
213 193
    Compute the scaling expression to map an interval that span only
214 194
    a binade to [1, 2) and the inverse expression as well.
......
219 199
        if boundsInterval.endpoints()[0] >= 0:
220 200
            scalingCoeff = 2^floor(boundsInterval.endpoints()[0].log2())
221 201
            invScalingCoeff = 1/scalingCoeff
222
            return((scalingCoeff * eval(varName), 
223
                    invScalingCoeff * eval(varName)))
202
            return((scalingCoeff * expVar, 
203
                    invScalingCoeff * expVar))
224 204
        else:
225 205
            scalingCoeff = \
226 206
                2^(floor((-boundsInterval.endpoints()[0]).log2()) - 1)
227 207
            scalingOffset = -3 * scalingCoeff
228
            return((scalingCoeff * eval(varName) + scalingOffset,
229
                    1/scalingCoeff * eval(varName) + 3))
208
            return((scalingCoeff * expVar + scalingOffset,
209
                    1/scalingCoeff * expVar + 3))
230 210
    else: 
231 211
        if boundsInterval.endpoints()[0] >= 0:
232 212
            scalingCoeff = 2^floor(boundsInterval.endpoints()[0].log2())
233 213
            scalingOffset = 0
234
            return((scalingCoeff * eval(varName), 
235
                    1/scalingCoeff * eval(varName)))
214
            return((scalingCoeff * expVar, 
215
                    1/scalingCoeff * expVar))
236 216
        else:
237 217
            scalingCoeff = \
238 218
                2^(floor((-boundsInterval.endpoints()[1]).log2()))
239 219
            scalingOffset =  -3 * scalingCoeff
240 220
            #scalingOffset = 0
241
            return((scalingCoeff * eval(varName) + scalingOffset,
242
                    1/scalingCoeff * eval(varName) + 3))
221
            return((scalingCoeff * expVar + scalingOffset,
222
                    1/scalingCoeff * expVar + 3))
243 223

  
244 224
   
245 225
def slz_polynomial_and_interval_to_sage(polyRangeCenterErrorSo):
......
269 249
    return((polynomialSa, polynomialChangedVarSa, intervalSa, centerSa, errorSa))
270 250
    # End slz_polynomial_and_interval_to_sage
271 251

  
272
def slz_rat_poly_of_int_to_int_poly_of_int(ratPolyOfInt):
273
    pass
274
# End slz_ratPoly_of_int_to_int_poly_of_int
252
def slz_rat_poly_of_int_to_poly_for_coppersmith(ratPolyOfInt, 
253
                                                precision,
254
                                                targetHardnessToRound,
255
                                                variable1,
256
                                                variable2):
257
    """
258
    Creates a new polynomial with integer coefficients for use with the
259
    Coppersmith method.
260
    A the same time it computes :
261
    - 2^K (N);
262
    - 2^k
263
    - lcm
264
    """
265
    # Create a new integer polynomial ring.
266
    IP = PolynomialRing(ZZ, name=str(variable1) + "," + str(variable2))
267
    # Coefficients are issued in the increasing power order.
268
    ratPolyCoefficients = ratPolyOfInt.coefficients()
269
    # Build the list of number we compute the lcmm of.
270
    coefficientDenominators = sro_denominators(ratPolyCoefficients)
271
    coefficientDenominators.append(2^precision)
272
    coefficientDenominators.append(2^(targetHardnessToRound + 1))
273
    leastCommonMultiple = sro_lcmm(coefficientDenominators)
274
    # Compute the lcm
275
    leastCommonMultiple = sro_lcmm(coefficientDenominators)
276
    # Compute the expression corresponding to the new polynomial
277
    coefficientNumerators =  sro_numerators(ratPolyCoefficients)
278
    print coefficientNumerators
279
    polynomialExpression = 0
280
    power = 0
281
    # Iterate over two lists at the same time, stop when the shorter is
282
    # exhausted.
283
    for numerator, denominator in \
284
                            zip(coefficientNumerators, coefficientDenominators):
285
        multiplicator = leastCommonMultiple / denominator 
286
        newCoefficient = numerator * multiplicator
287
        polynomialExpression += newCoefficient * variable1^power
288
        power +=1
289
    polynomialExpression += - variable2
290
    return (IP(polynomialExpression),
291
            leastCommonMultiple / 2^precision, # 2^K or N.
292
            leastCommonMultiple / 2 ^(targetHardnessToRound + 1), # tBound
293
            leastCommonMultiple)
294
        
295
# End slz_ratPoly_of_int_to_poly_for_coppersmith
275 296

  
276 297
def slz_rat_poly_of_rat_to_rat_poly_of_int(ratPolyOfRat, 
277 298
                                          precision):
pobysoPythonSage/src/sageSLZ/sageRationalOperations.sage (revision 80)
6 6
- Serge Torres: first operations set (2013-04) 
7 7
"""
8 8

  
9
def denominators(rationalList = None):
9
def sro_denominators(rationalList = None):
10 10
    """
11 11
    Compute the list of the denominators of a rational numbers list.
12 12
    """
......
37 37
                    "has no \"denominator()\" member." 
38 38
            return([])
39 39
    return(denominatorsList)
40
# End sro_denominators
40 41

  
41
def lcmm(rationalList = None):
42
def sro_lcmm(rationalList = None):
42 43
    """ 
43 44
    Compute the lcm of an sequence (list, tuple) of rational numbers.
44 45
    """
......
62 63
    except Exception:
63 64
        print "Exception raised in lcmm!"
64 65
        return(0)
65
    
66
def numerators(rationalList = None):
66
# End sro_lcmm
67

  
68
def sro_numerators(rationalList = None):
67 69
    """
68 70
    Compute the list of the numerators of a rational numbers list.
69 71
    """
......
93 95
            print "numerators:", rationalList[i], \
94 96
                    "has no \"numerator()\" member." 
95 97
            return([])
96
    return(numeratorsList)
98
    return(numeratorsList)
99
# End sro_numerators
pobysoPythonSage/src/sageSLZ/sageSLZ-Notes.html (revision 80)
68 68
abbr           {font-family : helvetica, arial, sans-serif;
69 69
                font-style : normal;
70 70
                font-weight : bold}
71
/* Identique ? <abbr> */
71
/* Identique ? abbr */
72 72
acronym        {font-family : helvetica, arial, sans-serif;
73 73
                font-style : normal;
74 74
                font-weight : bold}
......
265 265
hr.twentypc    {margin-left: 40%;
266 266
                margin-right: 40%;}
267 267
/* Notes */
268
/* L'appel de note est r?alis? par un ?l?ment <a> de classe callNote */
268
/* L'appel de note est r?alis? par un ?l?ment "a" de classe callNote */
269 269
a.callNote     {}
270
/* Le retour de note est r?alis? par un ?l?ment </a><a> de classe retFromNote */
270
/* Le retour de note est r?alis? par un ?l?ment "a" de classe retFromNote */
271 271
a.retFromNote  {}
272 272
/* Liste des notes proprement dite */
273 273
ol.notes       {margin-left: 0%;
......
296 296
div.toc        {margin-left : 50pt}
297 297
ul.toc         {font-size : 14pt ; 
298 298
                font-family : Helvetica , Arial , sans-serif}
299
</a></abbr></style>
299
</style>
300 300
  <title>sageSLZ Notes</title>
301 301
</head>
302 302

  

Formats disponibles : Unified diff