Statistiques
| Révision :

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

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

    
90
def spo_get_coefficient_for_monomial(monomialsList, coefficientsList, monomial):
91
    """
92
    Get, for a polynomial, the coefficient for a given monomial.
93
    The polynomial is given as two lists (monomials and coefficients as
94
    return by the respective methods ; indexes of the two lists must match).
95
    If the monomial is not found, 0 is returned.
96
    """
97
    monomialIndex = 0
98
    for mono in monomialsList:
99
        if mono == monomial:
100
            return coefficientsList[monomialIndex]
101
        monomialIndex += 1
102
    return 0
103
# End spo_get_coefficient_for_monomial.
104
    
105

    
106
def spo_expression_as_string(powI, powT, powP, powN):
107
    """
108
    Computes a string version of the i^k + t^l + p^m + N^n expression for
109
    output.
110
    """
111
    expressionAsString =""
112
    if powI != 0:
113
        expressionAsString += "i^" + str(powI)
114
    if powT != 0:
115
        if len(expressionAsString) != 0:
116
            expressionAsString += " * "
117
        expressionAsString += "t^" + str(powT)
118
    if powP != 0:
119
        if len(expressionAsString) != 0:
120
            expressionAsString += " * "
121
        expressionAsString += "p^" + str(powP)
122
    if (powN) != 0 :
123
        if len(expressionAsString) != 0:
124
            expressionAsString += " * "
125
        expressionAsString += "N^" + str(powN)
126
    return(expressionAsString)
127
# End spo_expression_as_string.
128

    
129
def spo_norm(poly, p=2):
130
    """
131
    Behaves more or less (no infinity defined) as the norm for the
132
    univariate polynomials.
133
    Quoting Sage documentation:
134
    "Definition: For integer p, the p-norm of a polynomial is the pth root of 
135
    the sum of the pth powers of the absolute values of the coefficients of 
136
    the polynomial."
137
    
138
    """
139
    # TODO: check the arguments (for p see below)..
140
    norm = 0
141
    # For infinity norm.
142
    if p == Infinity:
143
        for coefficient in poly.coefficients():
144
            coefficientAbs = coefficient.abs()
145
            if coefficientAbs > norm:
146
                norm = coefficientAbs
147
        return norm
148
    # TODO: check here the value of p
149
    # p must be a positive integer >= 1.
150
    if p < 1 or (not p in ZZ):
151
        return None
152
    # For 1 norm.
153
    if p == 1:
154
        for coefficient in poly.coefficients():
155
            norm +=  coefficient.abs()
156
        return norm
157
    # For other norms
158
    for coefficient in poly.coefficients():
159
        norm +=  coefficient.abs()^p
160
    return pow(norm, 1/p)
161
# end spo_norm
162

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

    
399
def spo_polynomial_to_polynomials_list_2(p, alpha, N, columnsWidth=0):
400
    """
401
    From p, alpha, N build a list of polynomials...
402
    TODO: clean up the comments below!
403
    
404
    From a (bivariate) polynomial and some other parameters build a proto 
405
    matrix (an array of "rows") to be converted into a "true" matrix and 
406
    eventually by reduced by fpLLL.
407
    The matrix is based on a list of polynomials that are built in a way
408
    that one and only monomial is added at each new polynomial. Among the many
409
    possible ways to build this list we pick one strongly dependent on the 
410
    structure of the polynomial and of the problem.
411
    We consider here the polynomials of the form: 
412
    a_k*i^k + a_(k-1)*i^(k-1) + ... + a_1*i + a_0 - t 
413
    The values of i and t are bounded and we eventually look for (i_0,t_0) 
414
    pairs such that:
415
    a_k*i_0^k + a_(k-1)*i_0^(k-1) + ... + a_1*i_0 + a_0 = t_0
416
    Hence, departing from the procedure in described in Boneh-Durfee, we will 
417
    not use "t-shifts" but only "i-shifts".
418
        
419
    Parameters
420
    ----------
421
    p: the (bivariate) polynomial;
422
    pRing: the ring over which p is defined;
423
    alpha:
424
    N:
425
    columsWidth: if == 0, no information is displayed, otherwise data is 
426
                 printed in colums of columnsWitdth width.
427
    """
428
    pRing = p.parent()
429
    polynomialsList = []
430
    pVariables = p.variables()
431
    iVariable = pVariables[0]
432
    tVariable = pVariables[1]
433
    polynomialAtPower = pRing(1)
434
    currentPolynomial = pRing(1)
435
    pIdegree = p.degree(iVariable)
436
    pTdegree = p.degree(tVariable)
437
    currentIdegree = currentPolynomial.degree(iVariable)
438
    nAtAlpha = N^alpha
439
    nAtPower = nAtAlpha
440
    polExpStr = ""
441
    # We work from p^0 * N^alpha to p^alpha * N^0
442
    for pPower in xrange(0, alpha + 1):
443
        # pPower == 0 is a special case. We introduce all the monomials in i 
444
        # up to i^pIdegree.
445
        if pPower == 0:
446
            # Notice who iPower runs up to i^pIdegree.
447
            for iPower in xrange(0, pIdegree + 1): 
448
                # No t power is taken into account as we limit our selves to
449
                # degree 1 in t and make no "t-shifts".
450
                if columnsWidth != 0:
451
                    polExpStr = spo_expression_as_string(iPower, 
452
                                                         0, 
453
                                                         0, 
454
                                                         alpha)
455
                    print "->", polExpStr
456
                currentExpression = iVariable^iPower * nAtAlpha
457
                # polynomialAtPower == 1 here. Next line should be commented
458
                # out but it does not work! Some conversion problem?
459
                currentPolynomial = pRing(currentExpression)
460
                polynomialsList.append(currentPolynomial) 
461
            # End for iPower.
462
        else: # pPower > 0: (p^1..p^alpha)
463
            # This where we introduce the p^pPower * N^(alpha-pPower)
464
            # polynomial. This is also where the t^pPower monomials shows up for
465
            # the first time.
466
            if columnsWidth != 0:
467
                polExpStr = spo_expression_as_string(0, 0, pPower, alpha-pPower)
468
                print "->", polExpStr
469
            currentPolynomial = polynomialAtPower * nAtPower
470
            polynomialsList.append(currentPolynomial) 
471
            # Exit when pPower == alpha
472
            if pPower == alpha:
473
                return((knownMonomials, polynomialsList))
474
            # This is where the "i-shifts" take place. Mixed terms, i^k * t^l
475
            # (that were introduced at a previous
476
            # stage or are introduced now) are only shifted to already existing 
477
            # ones with the notable exception of i^iPower * t^pPower, which
478
            # must be manually introduced.
479
            # p^pPower is "shifted" to higher degrees in i as far as 
480
            # possible, up to of the degree in i of p^(pPower+1).
481
            # These "pure" i^k monomials can only show up with i multiplications.
482
            for iPower in xrange(1, pIdegree + 1):
483
                # The i^iPower * t^pPower monomial. Notice the alpha exponent
484
                # for N.
485
                internalIpower = iPower
486
                for tPower in xrange(pPower,0,-1):
487
                    if columnsWidth != 0:
488
                        polExpStr = spo_expression_as_string(internalIpower, \
489
                                                             tPower,  \
490
                                                             0, \
491
                                                             alpha)
492
                        print "->", polExpStr
493
                    currentExpression = i^internalIpower * t^tPower * nAtAlpha
494
                    currentPolynomial = pRing(currentExpression)
495
                    polynomialsList.append(currentPolynomial) 
496
                    internalIpower += pIdegree
497
                # End for tPower
498
                # The i^iPower * p^pPower * N^(alpha-pPower) i-shift.
499
                if columnsWidth != 0:
500
                    polExpStr = spo_expression_as_string(iPower, \
501
                                                         0,      \
502
                                                         pPower, \
503
                                                         alpha-pPower)
504
                    print "->", polExpStr
505
                currentExpression = i^iPower * nAtPower
506
                currentPolynomial = pRing(currentExpression) * polynomialAtPower
507
                polynomialsList.append(currentPolynomial) 
508
            # End for iPower
509
        polynomialAtPower *= p  
510
        nAtPower /= N
511
    # End for pPower loop
512
    return polynomialsList
513
# End spo_polynomial_to_proto_matrix_2
514

    
515
def spo_polynomial_to_polynomials_list_3(p, alpha, N, iBound, tBound, \
516
                                         columnsWidth=0):
517
    """
518
    From p, alpha, N build a list of polynomials...
519
    TODO: more in depth rationale...
520
    
521
    Our goal is to introduce each monomial with the smallest coefficient.
522
     
523
    
524
        
525
    Parameters
526
    ----------
527
    p: the (bivariate) polynomial;
528
    pRing: the ring over which p is defined;
529
    alpha:
530
    N:
531
    columsWidth: if == 0, no information is displayed, otherwise data is 
532
                 printed in colums of columnsWitdth width.
533
    """
534
    pRing = p.parent()
535
    knownMonomials = []
536
    polynomialsList = []
537
    pVariables = p.variables()
538
    iVariable = pVariables[0]
539
    tVariable = pVariables[1]
540
    polynomialAtPower = pRing(1)
541
    currentPolynomial = pRing(1)
542
    pIdegree = p.degree(iVariable)
543
    pTdegree = p.degree(tVariable)
544
    currentIdegree = currentPolynomial.degree(iVariable)
545
    nAtAlpha = N^alpha
546
    nAtPower = nAtAlpha
547
    polExpStr = ""
548
    # We work from p^0 * N^alpha to p^alpha * N^0
549
    for pPower in xrange(0, alpha + 1):
550
        # pPower == 0 is a special case. We introduce all the monomials in i 
551
        # up to i^pIdegree.
552
        if pPower == 0:
553
            # Notice who iPower runs up to i^pIdegree.
554
            for iPower in xrange(0, pIdegree + 1): 
555
                # No t power is taken into account as we limit our selves to
556
                # degree 1 in t and make no "t-shifts".
557
                if columnsWidth != 0:
558
                    polExpStr = spo_expression_as_string(iPower, 
559
                                                         0, 
560
                                                         0, 
561
                                                         alpha)
562
                    print "->", polExpStr
563
                currentExpression = iVariable^iPower * nAtAlpha
564
                # polynomialAtPower == 1 here. Next line should be commented
565
                # out but it does not work! Some conversion problem?
566
                currentPolynomial = pRing(currentExpression)
567
                polynomialsList.append(currentPolynomial) 
568
            # End for iPower.
569
        else: # pPower > 0: (p^1..p^alpha)
570
            # This where we introduce the p^pPower * N^(alpha-pPower)
571
            # polynomial. This is also where the t^pPower monomials shows up for
572
            # the first time. It app
573
            if columnsWidth != 0:
574
                polExpStr = spo_expression_as_string(0, 0, pPower, alpha-pPower)
575
                print "->", polExpStr
576
            currentPolynomial = polynomialAtPower * nAtPower
577
            polynomialsList.append(currentPolynomial) 
578
            # Exit when pPower == alpha
579
            if pPower == alpha:
580
                return((knownMonomials, polynomialsList))
581
            # This is where the "i-shifts" take place. Mixed terms, i^k * t^l
582
            # (that were introduced at a previous
583
            # stage or are introduced now) are only shifted to already existing 
584
            # ones with the notable exception of i^iPower * t^pPower, which
585
            # must be manually introduced.
586
            # p^pPower is "shifted" to higher degrees in i as far as 
587
            # possible, up to of the degree in i of p^(pPower+1).
588
            # These "pure" i^k monomials can only show up with i multiplications.
589
            for iPower in xrange(1, pIdegree + 1):
590
                # The i^iPower * t^pPower monomial. Notice the alpha exponent
591
                # for N.
592
                internalIpower = iPower
593
                for tPower in xrange(pPower,0,-1):
594
                    if columnsWidth != 0:
595
                        polExpStr = spo_expression_as_string(internalIpower, \
596
                                                             tPower,  \
597
                                                             0, \
598
                                                             alpha)
599
                        print "->", polExpStr
600
                    currentExpression = i^internalIpower * t^tPower * nAtAlpha
601
                    currentPolynomial = pRing(currentExpression)
602
                    polynomialsList.append(currentPolynomial) 
603
                    internalIpower += pIdegree
604
                # End for tPower
605
                # Here we have to choose between a 
606
                # i^iPower * p^pPower * N^(alpha-pPower) i-shift and
607
                # i^iPower * i^(d_i(p) * pPower) * N^alpha, depend on which 
608
                # coefficient is smallest.
609
                IcurrentExponent = iPower + \
610
                                        (pPower * polynomialAtPower.degree(i))
611
                currentMonomial = pRing(i^(IcurrentExponent))
612
                currentPolynomial = pRing(i^iPower * nAtPower) * \
613
                                                            polynomialAtPower
614
                currMonomials = currentPolynomial.monomials()
615
                currCoefficients = currentPolynomial.coefficients()
616
                currentCoefficient = spo_get_coefficient_for_monomial( \
617
                                                    currMonomials, 
618
                                                    currCoefficients, 
619
                                                    currentMonomial)
620
                if currentCoefficient > nAtAlpha:
621
                    if columnsWidth != 0:
622
                        polExpStr = spo_expression_as_string(IcurrentCoefficient, \
623
                                                             0,      \
624
                                                             0, \
625
                                                             alpha)
626
                    print "->", polExpStr
627
                    polynomialsList.append(currentMonomial * nAtAlpha)
628
                else:
629
                    if columnsWidth != 0:
630
                        polExpStr = spo_expression_as_string(iPower, \
631
                                                             0,      \
632
                                                             pPower, \
633
                                                             alpha-pPower)
634
                    print "->", polExpStr
635
                    polynomialsList.append(currentPolynomial) 
636
            # End for iPower
637
        polynomialAtPower *= p  
638
        nAtPower /= N
639
    # End for pPower loop
640
    return polynomialsList 
641
# End spo_polynomial_to_proto_matrix_3
642

    
643
def spo_proto_to_column_matrix(protoMatrixColumns, \
644
                               knownMonomialsList, \
645
                               boundVar1, \
646
                               boundVar2):
647
    """
648
    Create a column (each row holds the coefficients of one monomial) matrix.
649
    
650
    Parameters
651
    ----------
652
    protoMatrixColumns: a list of coefficient lists.
653
    """
654
    numColumns = len(protoMatrixColumns)
655
    if numColumns == 0:
656
        return None
657
    # The last column holds has the maximum length. 
658
    numRows = len(protoMatrixColumns[numColumns-1])
659
    if numColumns == 0:
660
        return None
661
    baseMatrix = matrix(ZZ, numRows, numColumns)
662
    for colIndex in xrange(0, numColumns):
663
        for rowIndex in xrange(0, len(protoMatrixColumns[colIndex])):
664
            if protoMatrixColumns[colIndex][rowIndex] != 0:
665
                baseMatrix[rowIndex, colIndex] = \
666
                    protoMatrixColumns[colIndex][rowIndex] * \
667
                    knownMonomialsList[rowIndex](boundVar1, boundVar2)
668
    return baseMatrix
669
# End spo_proto_to_column_matrix.
670
#
671
def spo_proto_to_row_matrix(protoMatrixRows, \
672
                            knownMonomialsList, \
673
                            boundVar1, \
674
                            boundVar2):
675
    """
676
    Create a row (each column holds the evaluation one monomial at boundVar1 and
677
    boundVar2 values) matrix.
678
    
679
    Parameters
680
    ----------
681
    protoMatrixRows: a list of coefficient lists.
682
    """
683
    numRows = len(protoMatrixRows)
684
    if numRows == 0:
685
        return None
686
    # The last row is the longest one.
687
    numColumns = len(protoMatrixRows[numRows-1])
688
    if numColumns == 0:
689
        return None
690
    baseMatrix = matrix(ZZ, numRows, numColumns)
691
    for rowIndex in xrange(0, numRows):
692
        for colIndex in xrange(0, len(protoMatrixRows[rowIndex])):
693
            if protoMatrixRows[rowIndex][colIndex] !=  0:
694
                baseMatrix[rowIndex, colIndex] = \
695
                    protoMatrixRows[rowIndex][colIndex] * \
696
                    knownMonomialsList[colIndex](boundVar1,boundVar2)
697
            #print rowIndex, colIndex,
698
            #print protoMatrixRows[rowIndex][colIndex],
699
            #print knownMonomialsList[colIndex](boundVar1,boundVar2)
700
    return baseMatrix
701
# End spo_proto_to_row_matrix.
702
#
703
print "\t...sagePolynomialOperations loaded"