Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (21,83 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^p).abs()
144
    return pow(norm, 1/p)
145
# end spo_norm
146

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

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