Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (21,85 ko)

1
load "/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageMatrixOperations.sage"
2
print "sagePolynomialOperations loading..."
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, p=2):
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
    """
120
    # TODO: check the arguments (for p see below)..
121
    norm = 0
122
    # For infinity norm.
123
    if p == Infinity:
124
        for coefficient in poly.coefficients():
125
            coefficientAbs = coefficient.abs()
126
            if coefficientAbs > norm:
127
                norm = coefficientAbs
128
        return norm
129
    # TODO: check here the value of p
130
    # p must be an integer.
131
    if int(p) != p:
132
        return None
133
    # p must be >= 1.
134
    if p < 1:
135
        return None
136
    # For 1 norm.
137
    if p == 1:
138
        for coefficient in poly.coefficients():
139
            norm +=  coefficient.abs()
140
        return norm
141
    # For other norms
142
    for coefficient in poly.coefficients():
143
        norm +=  coefficient.abs()^p
144
    return pow(norm, 1/p)
145
# end spo_norm
146

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

    
382
def spo_proto_to_column_matrix(protoMatrixColumns, \
383
                               knownMonomialsList, \
384
                               boundVar1, \
385
                               boundVar2):
386
    """
387
    Create a column (each row holds the coefficients of one monomial) matrix.
388
    
389
    Parameters
390
    ----------
391
    protoMatrixColumns: a list of coefficient lists.
392
    """
393
    numColumns = len(protoMatrixColumns)
394
    if numColumns == 0:
395
        return None
396
    # The last column holds has the maximum length. 
397
    numRows = len(protoMatrixColumns[numColumns-1])
398
    if numColumns == 0:
399
        return None
400
    baseMatrix = matrix(ZZ, numRows, numColumns)
401
    for colIndex in xrange(0, numColumns):
402
        for rowIndex in xrange(0, len(protoMatrixColumns[colIndex])):
403
            if protoMatrixColumns[colIndex][rowIndex] != 0:
404
                baseMatrix[rowIndex, colIndex] = \
405
                    protoMatrixColumns[colIndex][rowIndex] * \
406
                    knownMonomialsList[rowIndex](boundVar1, boundVar2)
407
    return baseMatrix
408
# End spo_proto_to_column_matrix.
409
#
410
def spo_proto_to_row_matrix(protoMatrixRows, \
411
                            knownMonomialsList, \
412
                            boundVar1, \
413
                            boundVar2):
414
    """
415
    Create a row (each column holds the evaluation one monomial at boundVar1 and
416
    boundVar2 values) matrix.
417
    
418
    Parameters
419
    ----------
420
    protoMatrixRows: a list of coefficient lists.
421
    """
422
    numRows = len(protoMatrixRows)
423
    if numRows == 0:
424
        return None
425
    # The last row is the longest one.
426
    numColumns = len(protoMatrixRows[numRows-1])
427
    if numColumns == 0:
428
        return None
429
    baseMatrix = matrix(ZZ, numRows, numColumns)
430
    for rowIndex in xrange(0, numRows):
431
        for colIndex in xrange(0, len(protoMatrixRows[rowIndex])):
432
            if protoMatrixRows[rowIndex][colIndex] !=  0:
433
                baseMatrix[rowIndex, colIndex] = \
434
                    protoMatrixRows[rowIndex][colIndex] * \
435
                    knownMonomialsList[colIndex](boundVar1,boundVar2)
436
            #print rowIndex, colIndex,
437
            #print protoMatrixRows[rowIndex][colIndex],
438
            #print knownMonomialsList[colIndex](boundVar1,boundVar2)
439
    return baseMatrix
440
# End spo_proto_to_row_matrix.
441
#
442
print "\t...sagePolynomialOperations loaded"