Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (19,58 ko)

1
load "/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageMatrixOperations.sage"
2

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

    
341
def spo_proto_to_column_matrix(protoMatrixRows):
342
    """
343
    Create a row (each column holds the coefficients of one polynomial) matrix.
344
    protoMatrixRows.
345
    
346
    Parameters
347
    ----------
348
    protoMatrixRows: a list of coefficient lists.
349
    """
350
    numRows = len(protoMatrixRows)
351
    if numRows == 0:
352
        return None
353
    numColumns = len(protoMatrixRows[numRows-1])
354
    if numColumns == 0:
355
        return None
356
    baseMatrix = matrix(ZZ, numRows, numColumns)
357
    for rowIndex in xrange(0, numRows):
358
        if monomialLengthChars != 0:
359
            print protoMatrixRows[rowIndex]
360
        for colIndex in xrange(0, len(protoMatrixRows[rowIndex])):
361
            baseMatrix[colIndex, rowIndex] = protoMatrixRows[rowIndex][colIndex]
362
    return baseMatrix
363
# End spo_proto_to_column_matrix.
364
#
365
def spo_proto_to_row_matrix(protoMatrixRows):
366
    """
367
    Create a row (each row holds the coefficients of one polynomial) matrix.
368
    protoMatrixRows.
369
    
370
    Parameters
371
    ----------
372
    protoMatrixRows: a list of coefficient lists.
373
    """
374
    numRows = len(protoMatrixRows)
375
    if numRows == 0:
376
        return None
377
    numColumns = len(protoMatrixRows[numRows-1])
378
    if numColumns == 0:
379
        return None
380
    baseMatrix = matrix(ZZ, numRows, numColumns)
381
    for rowIndex in xrange(0, numRows):
382
        if monomialLengthChars != 0:
383
            print protoMatrixRows[rowIndex]
384
        for colIndex in xrange(0, len(protoMatrixRows[rowIndex])):
385
            baseMatrix[rowIndex, colIndex] = protoMatrixRows[rowIndex][colIndex]
386
    return baseMatrix
387
# End spo_proto_to_row_matrix.
388
#
389
print "sagePolynomialOperations loaded..."