Statistiques
| Révision :

root / pobysoPythonSage / src / sageSLZ / sagePolynomialOperations.sage @ 81

Historique | Voir | Annoter | Télécharger (17,63 ko)

1
load "/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageMatrixOperations.sage"
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

    
110
def spo_norm(poly, degree):
111
    """
112
    Behaves more or less (no infinity defined) as the norm for the
113
    univariate polynomials.
114
    Quoting the Sage documentation:
115
    Definition: For integer p, the p-norm of a polynomial is the pth root of 
116
    the sum of the pth powers of the absolute values of the coefficients of 
117
    the polynomial.
118
    """
119
    # TODO: check the arguments.
120
    norm = 0
121
    for coefficient in poly.coefficients():
122
        norm +=  (coefficient^degree).abs()
123
    return pow(norm, 1/degree)
124
# end spo_norm
125

    
126
def spo_polynomial_to_matrix(p, pRing, alpha, N, columnsWidth=0):
127
    """
128
    From a (bivariate) polynomial and some other parameters build a matrix
129
    to be reduced by fpLLL.
130
    The matrix is such as those found in Boneh-Durphee and Stehl?.
131
    
132
    p: the (bivariate) polynomial
133
    alpha:
134
    N:
135
    
136
    """
137
    knownMonomials = []
138
    protoMatrixRows = []
139
    pVariables = p.variables()
140
    iVariable = pVariables[0]
141
    tVariable = pVariables[1]
142
    polynomialAtPower = P(1)
143
    currentPolynomial = P(1)
144
    pIdegree = p.degree(pVariables[0])
145
    pTdegree = p.degree(pVariables[1])
146
    currentIdegree = currentPolynomial.degree(i)
147
    nAtPower = N^alpha
148
    # We work from p^0 * N^alpha to p^alpha * N^0
149
    for pPower in xrange(0, alpha + 1):
150
        # pPower == 0 is a special case. We introduce all the monomials but one
151
        # in i and those in t necessary to be able to introduce
152
        # p. We arbitrary choose to introduce the highest degree monomial in i
153
        # with p. We also introduce all the mixed i^k * t^l monomials with
154
        # k < p.degree(i) and l <= p.degree(t).
155
        # Mixed terms introduction is necessary here before we start "i shifts"
156
        # in the next iteration.
157
        if pPower == 0:
158
            # Notice that i^pIdegree is excluded as the bound of the xrange is
159
            # pIdegree
160
            for iPower in xrange(0, pIdegree): 
161
                for tPower in xrange(0, pTdegree + 1):
162
                    if columnsWidth != 0:
163
                        print "->", spo_expression_as_string(iPower, 
164
                                                             tPower, 
165
                                                             pPower, 
166
                                                             alpha)
167
                    currentExpression = iVariable^iPower * \
168
                                        tVariable^tPower * nAtPower
169
                    # polynomialAtPower == 1 here. Next line should be commented
170
                    # out but it does not work! Some conversion problem?
171
                    currentPolynomial = pRing(currentExpression) * \
172
                                        polynomialAtPower 
173
                    pMonomials = currentPolynomial.monomials()
174
                    pCoefficients = currentPolynomial.coefficients()
175
                    spo_add_polynomial_coeffs_to_matrix(pMonomials, 
176
                                                        pCoefficients, 
177
                                                        knownMonomials, 
178
                                                        protoMatrixRows, 
179
                                                        columnsWidth)
180
                # End tPower.
181
            # End for iPower.
182
        else: # pPower > 0: (p^1..p^alpha)
183
            # This where we introduce the p^pPower * N^(alpha-pPower)
184
            # polynomial.
185
            # This step could technically be fused as the first iteration
186
            # of the next loop (with iPower starting at 0).
187
            # We set it apart for clarity.
188
            if columnsWidth != 0:
189
                print "->", spo_expression_as_string(0, 0, pPower, alpha)
190
            currentPolynomial = polynomialAtPower * nAtPower
191
            pMonomials = currentPolynomial.monomials()
192
            pCoefficients = currentPolynomial.coefficients()
193
            spo_add_polynomial_coeffs_to_matrix(pMonomials, 
194
                                                pCoefficients, 
195
                                                knownMonomials, 
196
                                                protoMatrixRows, 
197
                                                columnsWidth)
198
            
199
            # The i^iPower * p^pPower polynomials: they add i^k monomials to  
200
            # p^pPower up to k < pIdegree * pPower. This only introduces i^k 
201
            # monomials since mixed terms (that were introduced at a previous
202
            # stage) are only shifted to already existing 
203
            # ones. p^pPower is "shifted" to higher degrees in i as far as 
204
            # possible, one step short of the degree in i of p^(pPower+1) .
205
            # These "pure" i^k monomials can only show up with i multiplications.
206
            for iPower in xrange(1, pIdegree):
207
                print "->", spo_expression_as_string(iPower, 0, pPower, alpha)
208
                currentExpression = i^iPower * nAtPower
209
                currentPolynomial = P(currentExpression) * polynomialAtPower
210
                pMonomials = currentPolynomial.monomials()
211
                pCoefficients = currentPolynomial.coefficients()
212
                spo_add_polynomial_coeffs_to_matrix(pMonomials, 
213
                                                    pCoefficients, 
214
                                                    knownMonomials, 
215
                                                    protoMatrixRows, 
216
                                                    columnsWidth)
217
            # End for iPower
218
            # We want now to introduce a t * p^pPower polynomial. But before
219
            # that we must introduce some mixed monomials.
220
            # This loop is no triggered before pPower == 2.
221
            # It introduces a first set of high i degree mixed monomials.
222
            for iPower in xrange(1, pPower):
223
                tPower = pPower - iPower + 1
224
                if columnsWidth != 0:
225
                    print "->", spo_expression_as_string(iPower * pIdegree, 
226
                                                         tPower, 
227
                                                         0,  
228
                                                         alpha)
229
                currentExpression = i^(iPower * pIdegree) * t^tPower * nAtPower
230
                currentPolynomial = P(currentExpression)
231
                pMonomials = currentPolynomial.monomials()
232
                pCoefficients = currentPolynomial.coefficients()
233
                spo_add_polynomial_coeffs_to_matrix(pMonomials, 
234
                                                    pCoefficients, 
235
                                                    knownMonomials, 
236
                                                    protoMatrixRows, 
237
                                                    columnsWidth)
238
            # End for iPower
239
            #
240
            # This is the mixed monomials main loop. It introduces:
241
            # - the missing mixed monomials needed before the 
242
            #   t^l * p^pPower * N^(alpha-pPower) polynomial;
243
            # - the t^l * p^pPower * N^(alpha-pPower) itself;
244
            # - for each of i^k * t^l * p^pPower * N^(alpha-pPower) polynomials:
245
            #   - the the missing mixed monomials needed  polynomials,
246
            #   - the i^k * t^l * p^pPower * N^(alpha-pPower) itself.
247
            # The t^l * p^pPower * N^(alpha-pPower) is introduced when
248
            # 
249
            for iShift in xrange(0, pIdegree):
250
                # When pTdegree == 1, the following loop only introduces 
251
                # a single new monomial.
252
                #print "++++++++++"
253
                for outerTpower in xrange(1, pTdegree + 1):
254
                    # First one high i degree mixed monomial.
255
                    iPower = iShift + pPower * pIdegree
256
                    if columnsWidth != 0:
257
                        print "->", spo_expression_as_string(iPower, 
258
                                                             outerTpower,
259
                                                             0,
260
                                                             alpha)
261
                    currentExpression = i^iPower * t^outerTpower * nAtPower
262
                    currentPolynomial = P(currentExpression)
263
                    pMonomials = currentPolynomial.monomials()
264
                    pCoefficients = currentPolynomial.coefficients()
265
                    spo_add_polynomial_coeffs_to_matrix(pMonomials, 
266
                                                        pCoefficients, 
267
                                                        knownMonomials, 
268
                                                        protoMatrixRows, 
269
                                                        columnsWidth)
270
                    #print "+++++"
271
                    # At iShift == 0, the following innerTpower loop adds  
272
                    # duplicate monomials, since no extra i^l * t^k is needed 
273
                    # before introducing the  
274
                    # i^iShift * t^outerPpower * p^pPower * N^(alpha-pPower) 
275
                    # polynomial.
276
                    # It introduces smaller i degree monomials than the
277
                    # one(s) added previously (no pPower multiplication).
278
                    # Here the exponent of t decreases as that of i increases.
279
                    # This conditional is not entered before pPower == 1.
280
                    # The innerTpower loop does not produce anything before
281
                    # pPower == 2. We keep it anyway for other configuration of
282
                    # p.
283
                    if iShift > 0:
284
                        iPower = pIdegree + iShift
285
                        for innerTpower in xrange(pPower, 1, -1):
286
                            if columnsWidth != 0:
287
                                print "->", spo_expression_as_string(iPower, 
288
                                                                     innerTpower,
289
                                                                     0,
290
                                                                     alpha) 
291
                            currentExpression = \
292
                                    i^(iPower) * t^(innerTpower) * nAtPower
293
                            currentPolynomial = P(currentExpression)
294
                            pMonomials = currentPolynomial.monomials()
295
                            pCoefficients = currentPolynomial.coefficients()
296
                            spo_add_polynomial_coeffs_to_matrix(pMonomials, 
297
                                                                pCoefficients, 
298
                                                                knownMonomials, 
299
                                                                protoMatrixRows, 
300
                                                                columnsWidth)
301
                            iPower += pIdegree
302
                        # End for innerTpower
303
                    # End of if iShift > 0
304
                    # When iShift == 0, just after each of the  
305
                    # p^pPower * N^(alpha-pPower) polynomials has 
306
                    # been introduced (followed by a string of 
307
                    # i^k * p^pPower * N^(alpha-pPower) polynomials) a
308
                    # t^l *  p^pPower * N^(alpha-pPower) is introduced here.
309
                    # 
310
                    # Eventually, the following section introduces the 
311
                    # i^iShift * t^outerTpower * p^iPower * N^(alpha-iPower) 
312
                    # polynomials.
313
                    if columnsWidth != 0:
314
                        print "->", spo_expression_as_string(iShift, 
315
                                                             outerTpower,
316
                                                             pPower,
317
                                                             alpha)
318
                    currentExpression = i^iShift * t^outerTpower * nAtPower
319
                    currentPolynomial = P(currentExpression) * polynomialAtPower
320
                    pMonomials = currentPolynomial.monomials()
321
                    pCoefficients = currentPolynomial.coefficients()
322
                    spo_add_polynomial_coeffs_to_matrix(pMonomials, 
323
                                                        pCoefficients, 
324
                                                        knownMonomials, 
325
                                                        protoMatrixRows, 
326
                                                        columnsWidth)
327
                # End for outerTpower 
328
                #print "++++++++++"
329
            # End for iShift
330
        polynomialAtPower *= p  
331
        nAtPower /= N
332
    # End for pPower loop
333
    return protoMatrixRows
334
# End spo_polynomial_to_matrix
335

    
336
print "sagePolynomialOperations loaded..."