Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (51,7 ko)

1
load("/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageMatrixOperations.sage")
2
#load(str('/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageMatrixOperations.sage'))
3
sys.stderr.write("sagePolynomialOperations loading...\n")
4

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

    
92
def spo_float_poly_of_float_to_rat_poly_of_rat(polyOfFloat):
93
    """
94
    Create a polynomial over the rationals from a polynomial over
95
    a RealField.
96
    Important warning: default Sage behavior is to convert coefficients
97
    using continued fractions instead of making a simple conversion
98
    with a powers of two at denominators (and possible simplification).
99
    Hence conversion is not exact but with a relative error around 10^(-521).
100
    """
101
    ratPolynomialRing = QQ[str(polyOfFloat.variables()[0])]
102
    return(ratPolynomialRing(polyOfFloat))
103
# End spo_float_poly_of_float_to_rat_poly_of_rat.
104

    
105
def spo_float_poly_of_float_to_rat_poly_of_rat_pow_two(polyOfFloat):
106
    """
107
    Create a polynomial over the rationals from a polynomial over
108
    a RealField where all denominators are
109
    powers of two.
110
    Allows for exact conversions (and lcm computation of the coefficients
111
    denominator).
112
    """
113
    polyVariable = polyOfFloat.variables()[0] 
114
    RPR = QQ[str(polyVariable)]
115
    polyCoeffs      = polyOfFloat.coefficients()
116
    #print polyCoeffs
117
    polyExponents   = polyOfFloat.exponents()
118
    #print polyExponents
119
    polyDenomPtwoCoeffs = []
120
    for coeff in polyCoeffs:
121
        polyDenomPtwoCoeffs.append(sno_float_to_rat_pow_of_two_denom(coeff))
122
        #print "Converted coefficient:", sno_float_to_rat_pow_of_two_denom(coeff),
123
        #print type(sno_float_to_rat_pow_of_two_denom(coeff))
124
    ratPoly = RPR(0)
125
    #print type(ratPoly)
126
    ## !!! CAUTION !!! Do not use the RPR(coeff * polyVariagle^exponent)
127
    #  construction.
128
    #  The coefficient becomes plainly wrong when exponent == 0.
129
    #  No clue as to why.
130
    for coeff, exponent in zip(polyDenomPtwoCoeffs, polyExponents):
131
        ratPoly += coeff * RPR(polyVariable^exponent)
132
    return ratPoly
133
# End slz_float_poly_of_float_to_rat_poly_of_rat.
134

    
135

    
136
def spo_get_coefficient_for_monomial(monomialsList, coefficientsList, monomial):
137
    """
138
    Get, for a polynomial, the coefficient for a given monomial.
139
    The polynomial is given as two lists (monomials and coefficients as
140
    return by the respective methods ; indexes of the two lists must match).
141
    If the monomial is not found, 0 is returned.
142
    """
143
    monomialIndex = 0
144
    for mono in monomialsList:
145
        if mono == monomial:
146
            return coefficientsList[monomialIndex]
147
        monomialIndex += 1
148
    return 0
149
# End spo_get_coefficient_for_monomial.
150
    
151

    
152
def spo_expression_as_string(powI, boundI, powT, boundT, powP, powN):
153
    """
154
    Computes a string version of the i^k + t^l + p^m + N^n expression for
155
    output.
156
    """
157
    expressionAsString =""
158
    if powI != 0:
159
        expressionAsString += str(iBound^powI) + " i^" + str(powI)
160
    if powT != 0:
161
        if len(expressionAsString) != 0:
162
            expressionAsString += " * "
163
        expressionAsString += str(tBound^powT) + " t^" + str(powT)
164
    if powP != 0:
165
        if len(expressionAsString) != 0:
166
            expressionAsString += " * "
167
        expressionAsString += "p^" + str(powP)
168
    if (powN) != 0 :
169
        if len(expressionAsString) != 0:
170
            expressionAsString += " * "
171
        expressionAsString += "N^" + str(powN)
172
    return(expressionAsString)
173
# End spo_expression_as_string.
174

    
175
def spo_norm(poly, p=2):
176
    """
177
    Behaves more or less (no infinity defined) as the norm for the
178
    univariate polynomials.
179
    Quoting Sage documentation:
180
    "Definition: For integer p, the p-norm of a polynomial is the pth root of 
181
    the sum of the pth powers of the absolute values of the coefficients of 
182
    the polynomial."
183
    
184
    """
185
    # TODO: check the arguments (for p see below)..
186
    norm = 0
187
    # For infinity norm.
188
    if p == Infinity:
189
        for coefficient in poly.coefficients():
190
            coefficientAbs = coefficient.abs()
191
            if coefficientAbs > norm:
192
                norm = coefficientAbs
193
        return norm
194
    # TODO: check here the value of p
195
    # p must be a positive integer >= 1.
196
    if p < 1 or (not p in ZZ):
197
        return None
198
    # For 1 norm.
199
    if p == 1:
200
        for coefficient in poly.coefficients():
201
            norm +=  coefficient.abs()
202
        return norm
203
    # For other norms
204
    for coefficient in poly.coefficients():
205
        norm +=  coefficient.abs()^p
206
    return pow(norm, 1/p)
207
# end spo_norm
208

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

    
446
def spo_polynomial_to_polynomials_list_2(p, alpha, N, iBound, tBound,
447
                                         columnsWidth=0):
448
    """
449
    Badly out of sync code: check with versions 3 or 4.
450
    
451
    From p, alpha, N build a list of polynomials...
452
    TODO: clean up the comments below!
453
    
454
    From a (bivariate) polynomial and some other parameters build a proto 
455
    matrix (an array of "rows") to be converted into a "true" matrix and 
456
    eventually by reduced by fpLLL.
457
    The matrix is based on a list of polynomials that are built in a way
458
    that one and only monomial is added at each new polynomial. Among the many
459
    possible ways to build this list we pick one strongly dependent on the 
460
    structure of the polynomial and of the problem.
461
    We consider here the polynomials of the form: 
462
    a_k*i^k + a_(k-1)*i^(k-1) + ... + a_1*i + a_0 - t 
463
    The values of i and t are bounded and we eventually look for (i_0,t_0) 
464
    pairs such that:
465
    a_k*i_0^k + a_(k-1)*i_0^(k-1) + ... + a_1*i_0 + a_0 = t_0
466
    Hence, departing from the procedure in described in Boneh-Durfee, we will 
467
    not use "t-shifts" but only "i-shifts".
468
        
469
    Parameters
470
    ----------
471
    p: the (bivariate) polynomial;
472
    pRing: the ring over which p is defined;
473
    alpha:
474
    N:
475
    columsWidth: if == 0, no information is displayed, otherwise data is 
476
                 printed in colums of columnsWitdth width.
477
    """
478
    pRing = p.parent()
479
    polynomialsList = []
480
    pVariables = p.variables()
481
    iVariable = pVariables[0]
482
    tVariable = pVariables[1]
483
    polynomialAtPower = pRing(1)
484
    currentPolynomial = pRing(1)
485
    pIdegree = p.degree(iVariable)
486
    pTdegree = p.degree(tVariable)
487
    currentIdegree = currentPolynomial.degree(iVariable)
488
    nAtAlpha = N^alpha
489
    nAtPower = nAtAlpha
490
    polExpStr = ""
491
    # We work from p^0 * N^alpha to p^alpha * N^0
492
    for pPower in xrange(0, alpha + 1):
493
        # pPower == 0 is a special case. We introduce all the monomials in i 
494
        # up to i^pIdegree.
495
        if pPower == 0:
496
            # Notice who iPower runs up to i^pIdegree.
497
            for iPower in xrange(0, pIdegree + 1): 
498
                # No t power is taken into account as we limit our selves to
499
                # degree 1 in t and make no "t-shifts".
500
                if columnsWidth != 0:
501
                    polExpStr = spo_expression_as_string(iPower,
502
                                                         iBound, 
503
                                                         0, 
504
                                                         tBound,
505
                                                         0, 
506
                                                         alpha)
507
                    print "->", polExpStr
508
                currentExpression = iVariable^iPower * nAtAlpha * iBound^iPower
509
                # polynomialAtPower == 1 here. Next line should be commented
510
                # out but it does not work! Some conversion problem?
511
                currentPolynomial = pRing(currentExpression)
512
                polynomialsList.append(currentPolynomial) 
513
            # End for iPower.
514
        else: # pPower > 0: (p^1..p^alpha)
515
            # This where we introduce the p^pPower * N^(alpha-pPower)
516
            # polynomial. This is also where the t^pPower monomials shows up for
517
            # the first time.
518
            if columnsWidth != 0:
519
                polExpStr = spo_expression_as_string(0, iBound, 0, tBound, \
520
                                                     pPower, alpha-pPower)
521
                print "->", polExpStr
522
            currentPolynomial = polynomialAtPower * nAtPower
523
            polynomialsList.append(currentPolynomial) 
524
            # Exit when pPower == alpha
525
            if pPower == alpha:
526
                return polynomialsList
527
            # This is where the "i-shifts" take place. Mixed terms, i^k * t^l
528
            # (that were introduced at a previous
529
            # stage or are introduced now) are only shifted to already existing 
530
            # ones with the notable exception of i^iPower * t^pPower, which
531
            # must be manually introduced.
532
            # p^pPower is "shifted" to higher degrees in i as far as 
533
            # possible, up to of the degree in i of p^(pPower+1).
534
            # These "pure" i^k monomials can only show up with i multiplications.
535
            for iPower in xrange(1, pIdegree + 1):
536
                # The i^iPower * t^pPower monomial. Notice the alpha exponent
537
                # for N.
538
                internalIpower = iPower
539
                for tPower in xrange(pPower,0,-1):
540
                    if columnsWidth != 0:
541
                        polExpStr = spo_expression_as_string(internalIpower, 
542
                                                             iBound,
543
                                                             tPower,
544
                                                             tBound,
545
                                                             0,
546
                                                             alpha)
547
                        print "->", polExpStr
548
                    currentExpression = i^internalIpower * t^tPower * \
549
                                        nAtAlpha * iBound^internalIpower * \
550
                                        tBound^tPower
551
                    
552
                    currentPolynomial = pRing(currentExpression)
553
                    polynomialsList.append(currentPolynomial) 
554
                    internalIpower += pIdegree
555
                # End for tPower
556
                # The i^iPower * p^pPower * N^(alpha-pPower) i-shift.
557
                if columnsWidth != 0:
558
                    polExpStr = spo_expression_as_string(iPower, 
559
                                                         iBound,
560
                                                         0,      
561
                                                         tBound,
562
                                                         pPower, 
563
                                                         alpha-pPower)
564
                    print "->", polExpStr
565
                currentExpression = i^iPower * nAtPower * iBound^iPower
566
                currentPolynomial = pRing(currentExpression) * polynomialAtPower
567
                polynomialsList.append(currentPolynomial) 
568
            # End for iPower
569
        polynomialAtPower *= p  
570
        nAtPower /= N
571
    # End for pPower loop
572
    return polynomialsList
573
# End spo_polynomial_to_proto_matrix_2
574

    
575
def spo_polynomial_to_polynomials_list_3(p, alpha, N, iBound, tBound,
576
                                         columnsWidth=0):
577
    """
578
    From p, alpha, N build a list of polynomials...
579
    TODO: more in depth rationale...
580
    
581
    Our goal is to introduce each monomial with the smallest coefficient.
582
     
583
    
584
        
585
    Parameters
586
    ----------
587
    p: the (bivariate) polynomial;
588
    pRing: the ring over which p is defined;
589
    alpha:
590
    N:
591
    columsWidth: if == 0, no information is displayed, otherwise data is 
592
                 printed in colums of columnsWitdth width.
593
    """
594
    pRing = p.parent()
595
    polynomialsList = []
596
    pVariables = p.variables()
597
    iVariable = pVariables[0]
598
    tVariable = pVariables[1]
599
    polynomialAtPower = pRing(1)
600
    currentPolynomial = pRing(1)
601
    pIdegree = p.degree(iVariable)
602
    pTdegree = p.degree(tVariable)
603
    currentIdegree = currentPolynomial.degree(iVariable)
604
    nAtAlpha = N^alpha
605
    nAtPower = nAtAlpha
606
    polExpStr = ""
607
    # We work from p^0 * N^alpha to p^alpha * N^0
608
    for pPower in xrange(0, alpha + 1):
609
        # pPower == 0 is a special case. We introduce all the monomials in i 
610
        # up to i^pIdegree.
611
        if pPower == 0:
612
            # Notice who iPower runs up to i^pIdegree.
613
            for iPower in xrange(0, pIdegree + 1): 
614
                # No t power is taken into account as we limit our selves to
615
                # degree 1 in t and make no "t-shifts".
616
                if columnsWidth != 0:
617
                    polExpStr = spo_expression_as_string(iPower, 
618
                                                         iBound,
619
                                                         0, 
620
                                                         tBound,
621
                                                         0, 
622
                                                         alpha)
623
                    print "->", polExpStr
624
                currentExpression = iVariable^iPower * nAtAlpha * iBound^iPower
625
                # polynomialAtPower == 1 here. Next line should be commented
626
                # out but it does not work! Some conversion problem?
627
                currentPolynomial = pRing(currentExpression)
628
                polynomialsList.append(currentPolynomial) 
629
            # End for iPower.
630
        else: # pPower > 0: (p^1..p^alpha)
631
            # This where we introduce the p^pPower * N^(alpha-pPower)
632
            # polynomial. This is also where the t^pPower monomials shows up for
633
            # the first time. It app
634
            if columnsWidth != 0:
635
                polExpStr = spo_expression_as_string(0, iBound, 
636
                                                     0, tBound,
637
                                                     pPower, alpha-pPower)
638
                print "->", polExpStr
639
            currentPolynomial = polynomialAtPower * nAtPower
640
            polynomialsList.append(currentPolynomial) 
641
            # Exit when pPower == alpha
642
            if pPower == alpha:
643
                return polynomialsList
644
            # This is where the "i-shifts" take place. Mixed terms, i^k * t^l
645
            # (that were introduced at a previous
646
            # stage or are introduced now) are only shifted to already existing 
647
            # ones with the notable exception of i^iPower * t^pPower, which
648
            # must be manually introduced.
649
            # p^pPower is "shifted" to higher degrees in i as far as 
650
            # possible, up to of the degree in i of p^(pPower+1).
651
            # These "pure" i^k monomials can only show up with i multiplications.
652
            for iPower in xrange(1, pIdegree + 1):
653
                # The i^iPower * t^pPower monomial. Notice the alpha exponent
654
                # for N.
655
                internalIpower = iPower
656
                for tPower in xrange(pPower,0,-1):
657
                    if columnsWidth != 0:
658
                        polExpStr = spo_expression_as_string(internalIpower,
659
                                                             iBound, 
660
                                                             tPower,  
661
                                                             tBound,
662
                                                             0,
663
                                                             alpha)
664
                        print "->", polExpStr
665
                    currentExpression = i^internalIpower * t^tPower * nAtAlpha * \
666
                                        iBound^internalIpower * tBound^tPower
667
                    currentPolynomial = pRing(currentExpression)
668
                    polynomialsList.append(currentPolynomial) 
669
                    internalIpower += pIdegree
670
                # End for tPower
671
                # Here we have to choose between a 
672
                # i^iPower * p^pPower * N^(alpha-pPower) i-shift and
673
                # i^iPower * i^(d_i(p) * pPower) * N^alpha, depending on which 
674
                # coefficient is smallest.
675
                IcurrentExponent = iPower + \
676
                                (pPower * polynomialAtPower.degree(iVariable))
677
                currentMonomial = pRing(iVariable^IcurrentExponent)
678
                currentPolynomial = pRing(iVariable^iPower * nAtPower * \
679
                                          iBound^iPower) * \
680
                                          polynomialAtPower
681
                currMonomials = currentPolynomial.monomials()
682
                currCoefficients = currentPolynomial.coefficients()
683
                currentCoefficient = spo_get_coefficient_for_monomial( \
684
                                                    currMonomials, 
685
                                                    currCoefficients, 
686
                                                    currentMonomial)
687
                print "Current coefficient:", currentCoefficient
688
                alterCoefficient = iBound^IcurrentExponent * nAtAlpha 
689
                print "N^alpha * ibound^", IcurrentExponent, ":", \
690
                         alterCoefficient
691
                if currentCoefficient > alterCoefficient :
692
                    if columnsWidth != 0:
693
                        polExpStr = spo_expression_as_string(IcurrentExponent,
694
                                                             iBound,
695
                                                             0,
696
                                                             tBound,
697
                                                             0,
698
                                                             alpha)
699
                        print "->", polExpStr
700
                    polynomialsList.append(currentMonomial * \
701
                                           alterCoefficient)
702
                else:
703
                    if columnsWidth != 0:
704
                        polExpStr = spo_expression_as_string(iPower, iBound,
705
                                                             0, tBound,
706
                                                             pPower, 
707
                                                             alpha-pPower)
708
                        print "->", polExpStr
709
                    polynomialsList.append(currentPolynomial) 
710
            # End for iPower
711
        polynomialAtPower *= p  
712
        nAtPower /= N
713
    # End for pPower loop
714
    return polynomialsList 
715
# End spo_polynomial_to_proto_matrix_3
716

    
717
def spo_polynomial_to_polynomials_list_4(p, alpha, N, iBound, tBound,
718
                                         columnsWidth=0):
719
    """
720
    From p, alpha, N build a list of polynomials...
721
    TODO: more in depth rationale...
722
    
723
    Our goal is to introduce each monomial with the smallest coefficient.
724
     
725
    
726
        
727
    Parameters
728
    ----------
729
    p: the (bivariate) polynomial;
730
    pRing: the ring over which p is defined;
731
    alpha:
732
    N:
733
    columsWidth: if == 0, no information is displayed, otherwise data is 
734
                 printed in colums of columnsWitdth width.
735
    """
736
    pRing = p.parent()
737
    polynomialsList = []
738
    pVariables = p.variables()
739
    iVariable = pVariables[0]
740
    tVariable = pVariables[1]
741
    polynomialAtPower = copy(p)
742
    currentPolynomial = pRing(1)
743
    pIdegree = p.degree(iVariable)
744
    pTdegree = p.degree(tVariable)
745
    maxIdegree = pIdegree * alpha
746
    currentIdegree = currentPolynomial.degree(iVariable)
747
    nAtAlpha = N^alpha
748
    nAtPower = nAtAlpha
749
    polExpStr = ""
750
    # We first introduce all the monomials in i alone multiplied by N^alpha.
751
    for iPower in xrange(0, maxIdegree + 1):
752
        if columnsWidth !=0:
753
            polExpStr = spo_expression_as_string(iPower, iBound,
754
                                                 0, tBound, 
755
                                                 0, alpha)
756
            print "->", polExpStr
757
        currentExpression = iVariable^iPower * nAtAlpha * iBound^iPower
758
        currentPolynomial = pRing(currentExpression)
759
        polynomialsList.append(currentPolynomial)
760
    # End for iPower
761
    # We work from p^1 * N^alpha-1 to p^alpha * N^0
762
    for pPower in xrange(1, alpha + 1):
763
        # First of all the p^pPower * N^(alpha-pPower) polynomial.
764
        nAtPower /= N
765
        if columnsWidth !=0:
766
            polExpStr = spo_expression_as_string(0, iBound,
767
                                                 0, tBound,
768
                                                 pPower, alpha-pPower)
769
            print "->", polExpStr
770
        currentPolynomial = polynomialAtPower * nAtPower
771
        polynomialsList.append(currentPolynomial)
772
        # Exit when pPower == alpha
773
        if pPower == alpha:
774
            return polynomialsList
775
        # We now introduce the mixed i^k * t^l monomials by i^m * p^n * N^(alpha-n)
776
        for iPower in xrange(1, pIdegree + 1): 
777
            if columnsWidth != 0:
778
                polExpStr = spo_expression_as_string(iPower, iBound,
779
                                                     0, tBound, 
780
                                                     pPower, alpha-pPower)
781
                print "->", polExpStr
782
            currentExpression = i^iPower * iBound^iPower * nAtPower
783
            currentPolynomial = pRing(currentExpression) * polynomialAtPower
784
            polynomialsList.append(currentPolynomial) 
785
        # End for iPower
786
        polynomialAtPower *= p  
787
    # End for pPower loop
788
    return polynomialsList 
789
# End spo_polynomial_to_proto_matrix_4
790

    
791
def spo_polynomial_to_polynomials_list_5(p, alpha, N, iBound, tBound,
792
                                         columnsWidth=0):
793
    """
794
    From p, alpha, N build a list of polynomials use to create a base
795
    that will eventually be reduced with LLL.
796
    
797
    The bounds are computed for the coefficients that will be used to
798
    form the base.
799
    
800
    We try to introduce only one new monomial at a time, to obtain a
801
    triangular matrix (it is easy to compute the volume of the underlining
802
    latice if the matrix is triangular).
803

    
804
    There are many possibilities to introduce the monomials: our goal is also 
805
    to introduce each of them on the diagonal with the smallest coefficient.
806

    
807
    The method depends on the structure of the polynomial. Here it is adapted
808
    to the a_n*i^n + ... + a_1 * i - t + b form.     
809
        
810
    Parameters
811
    ----------
812
    p: the (bivariate) polynomial;
813
    alpha:
814
    N:
815
    iBound:
816
    tBound:
817
    columsWidth: if == 0, no information is displayed, otherwise data is 
818
                 printed in colums of columnsWitdth width.
819
    """
820
    pRing = p.parent()
821
    polynomialsList = []
822
    pVariables = p.variables()
823
    iVariable = pVariables[0]
824
    tVariable = pVariables[1]
825
    polynomialAtPower = copy(p)
826
    currentPolynomial = pRing(1)
827
    pIdegree = p.degree(iVariable)
828
    pTdegree = p.degree(tVariable)
829
    maxIdegree = pIdegree * alpha
830
    currentIdegree = currentPolynomial.degree(iVariable)
831
    nAtAlpha = N^alpha
832
    nAtPower = nAtAlpha
833
    polExpStr = ""
834
    # We first introduce all the monomials in i alone multiplied by N^alpha.
835
    for iPower in xrange(0, maxIdegree + 1):
836
        if columnsWidth !=0:
837
            polExpStr = spo_expression_as_string(iPower, iBound,
838
                                                 0, tBound, 
839
                                                 0, alpha)
840
            print "->", polExpStr
841
        currentExpression = iVariable^iPower * nAtAlpha * iBound^iPower
842
        currentPolynomial = pRing(currentExpression)
843
        polynomialsList.append(currentPolynomial)
844
    # End for iPower
845
    # We work from p^1 * N^alpha-1 to p^alpha * N^0
846
    for pPower in xrange(1, alpha + 1):
847
        # First of all the p^pPower * N^(alpha-pPower) polynomial.
848
        nAtPower /= N
849
        if columnsWidth !=0:
850
            polExpStr = spo_expression_as_string(0, iBound,
851
                                                 0, tBound,
852
                                                 pPower, alpha-pPower)
853
            print "->", polExpStr
854
        currentPolynomial = polynomialAtPower * nAtPower
855
        polynomialsList.append(currentPolynomial)
856
        # Exit when pPower == alpha
857
        if pPower == alpha:
858
            return polynomialsList
859
        for iPower in xrange(1, pIdegree + 1):
860
            iCurrentPower = pIdegree + iPower
861
            for tPower in xrange(pPower-1, 0, -1):
862
                #print "tPower:", tPower
863
                if columnsWidth != 0:
864
                    polExpStr = spo_expression_as_string(iCurrentPower, iBound,
865
                                                         tPower, tBound, 
866
                                                         0, alpha)
867
                    print "->", polExpStr
868
                currentExpression = i^iCurrentPower * iBound^iCurrentPower * t^tPower * tBound^tPower *nAtAlpha 
869
                currentPolynomial = pRing(currentExpression)
870
                polynomialsList.append(currentPolynomial)
871
                iCurrentPower += pIdegree 
872
            # End for tPower 
873
        # We now introduce the mixed i^k * t^l monomials by i^m * p^n * N^(alpha-n)
874
            if columnsWidth != 0:
875
                polExpStr = spo_expression_as_string(iPower, iBound,
876
                                                     0, tBound, 
877
                                                     pPower, alpha-pPower)
878
                print "->", polExpStr
879
            currentExpression = i^iPower * iBound^iPower * nAtPower
880
            currentPolynomial = pRing(currentExpression) * polynomialAtPower
881
            polynomialsList.append(currentPolynomial) 
882
        # End for iPower
883
        polynomialAtPower *= p  
884
    # End for pPower loop
885
    return polynomialsList 
886
# End spo_polynomial_to_proto_matrix_5
887

    
888
def spo_polynomial_to_polynomials_list_6(p, alpha, N, iBound, tBound,
889
                                         columnsWidth=0):
890
    """
891
    From p, alpha, N build a list of polynomials use to create a base
892
    that will eventually be reduced with LLL.
893
    
894
    The bounds are computed for the coefficients that will be used to
895
    form the base.
896
    
897
    We try to introduce only one new monomial at a time, whithout trying to
898
    obtain a triangular matrix.
899

    
900
    There are many possibilities to introduce the monomials: our goal is also 
901
    to introduce each of them on the diagonal with the smallest coefficient.
902

    
903
    The method depends on the structure of the polynomial. Here it is adapted
904
    to the a_n*i^n + ... + a_1 * i - t + b form.     
905
        
906
    Parameters
907
    ----------
908
    p: the (bivariate) polynomial;
909
    alpha:
910
    N:
911
    iBound:
912
    tBound:
913
    columsWidth: if == 0, no information is displayed, otherwise data is 
914
                 printed in colums of columnsWitdth width.
915
    """
916
    pRing = p.parent()
917
    polynomialsList = []
918
    pVariables = p.variables()
919
    iVariable = pVariables[0]
920
    tVariable = pVariables[1]
921
    polynomialAtPower = copy(p)
922
    currentPolynomial = pRing(1)     # Constant term.
923
    pIdegree = p.degree(iVariable)
924
    pTdegree = p.degree(tVariable)
925
    maxIdegree = pIdegree * alpha
926
    currentIdegree = currentPolynomial.degree(iVariable)
927
    nAtAlpha = N^alpha
928
    nAtPower = nAtAlpha
929
    polExpStr = ""
930
    #
931
    """
932
    ## Bound for iPower + pIdegree*tPower <= alpha*pIdegree
933
    print "degree in i:", pIdegree
934
    powersRangeUpperBound = alpha * pIdegree + 1 # +1 for the range.
935
    for iPower in xrange(0, powersRangeUpperBound):
936
        tPower = 0
937
        while (iPower + tPower * pIdegree) < powersRangeUpperBound:
938
                print "iPower:", iPower, " tPower:", tPower
939
                q = pRing(iVariable * iBound)^iPower * ((p * N)^tPower)
940
                print "q monomials:", q.monomials()
941
                polynomialsList.append(q)
942
                tPower += 1
943
    """
944
    """
945
    Start from iExp = 0 since starting from 1 does not allow for 
946
    resultants != 0.
947
    """
948
    for iExp in xrange(0, alpha+1):
949
        tExp = 0
950
        while iExp + tExp <= alpha:
951
            q = pRing(iVariable * iBound)^iExp * ((p * N)^tExp)
952
            sys.stdout.write("q " + str(iExp) + "," + str(tExp) + ": ")
953
            print q
954
            polynomialsList.append(q)
955
            tExp += 1
956
    return polynomialsList
957
                
958
    """
959
    # We first introduce all the monomials in i alone multiplied by N^alpha.
960
    for iPower in xrange(0, maxIdegree + 1):
961
        if columnsWidth !=0:
962
            polExpStr = spo_expression_as_string(iPower, iBound,
963
                                                 0, tBound, 
964
                                                 0, alpha)
965
            print "->", polExpStr
966
        currentExpression = iVariable^iPower * nAtAlpha * iBound^iPower
967
        currentPolynomial = pRing(currentExpression)
968
        polynomialsList.append(currentPolynomial)
969
    # End for iPower
970
    # We work from p^1 * N^alpha-1 to p^alpha * N^0
971
    for pPower in xrange(1, alpha + 1):
972
        # First of all the p^pPower * N^(alpha-pPower) polynomial.
973
        nAtPower /= N
974
        if columnsWidth !=0:
975
            polExpStr = spo_expression_as_string(0, iBound,
976
                                                 0, tBound,
977
                                                 pPower, alpha-pPower)
978
            print "->", polExpStr
979
        currentPolynomial = polynomialAtPower * nAtPower
980
        polynomialsList.append(currentPolynomial)
981
        # Exit when pPower == alpha
982
        if pPower == alpha:
983
            return polynomialsList
984
        for iPower in xrange(1, pIdegree + 1):
985
            iCurrentPower = pIdegree + iPower
986
            for tPower in xrange(pPower-1, 0, -1):
987
                #print "tPower:", tPower
988
                if columnsWidth != 0:
989
                    polExpStr = spo_expression_as_string(iCurrentPower, iBound,
990
                                                         tPower, tBound, 
991
                                                         0, alpha)
992
                    print "->", polExpStr
993
                currentExpression = i^iCurrentPower * iBound^iCurrentPower * t^tPower * tBound^tPower *nAtAlpha 
994
                currentPolynomial = pRing(currentExpression)
995
                polynomialsList.append(currentPolynomial)
996
                iCurrentPower += pIdegree 
997
            # End for tPower 
998
        # We now introduce the mixed i^k * t^l monomials by i^m * p^n * N^(alpha-n)
999
            if columnsWidth != 0:
1000
                polExpStr = spo_expression_as_string(iPower, iBound,
1001
                                                     0, tBound, 
1002
                                                     pPower, alpha-pPower)
1003
                print "->", polExpStr
1004
            currentExpression = i^iPower * iBound^iPower * nAtPower
1005
            currentPolynomial = pRing(currentExpression) * polynomialAtPower
1006
            polynomialsList.append(currentPolynomial) 
1007
        # End for iPower
1008
        polynomialAtPower *= p  
1009
    # End for pPower loop
1010
    """
1011
    return polynomialsList 
1012
# End spo_polynomial_to_proto_matrix_6
1013

    
1014
def spo_polynomial_to_polynomials_list_7(p, alpha, N, iBound, tBound,
1015
                                         columnsWidth=0):
1016
    """
1017
    As per Random Bits... direct loops nesting.
1018
    """
1019
    pRing = p.parent()
1020
    polynomialsList = []
1021
    pVariables = p.variables()
1022
    iVariable = pVariables[0]
1023
    tVariable = pVariables[1]
1024
    polynomialAtPower = copy(p)
1025
    currentPolynomial = pRing(1)     # Constant term.
1026

    
1027
    for iExp in xrange(0, alpha+1):
1028
        pExp = 0
1029
        while (iExp + pExp) <= alpha:
1030
            print "iExp:", iExp, \
1031
                "- pExp:", pExp, \
1032
                "- alpha-pExp:", alpha-pExp
1033
            q = pRing(iVariable * iBound)^iExp * p^pExp * N^(alpha-pExp)
1034
            print q.monomials()
1035
            polynomialsList.append(q)
1036
            pExp += 1
1037
    return polynomialsList
1038
# End spo_polynomial_to_polynomials_list_7
1039

    
1040
def spo_polynomial_to_polynomials_list_8(p, alpha, N, iBound, tBound,
1041
                                         columnsWidth=0):
1042
    """
1043
    As per Random Bits... (reversed loop nesting)
1044
    """
1045
    pRing = p.parent()
1046
    polynomialsList = []
1047
    pVariables = p.variables()
1048
    iVariable = pVariables[0]
1049
    tVariable = pVariables[1]
1050
    polynomialAtPower = copy(p)
1051
    currentPolynomial = pRing(1)     # Constant term.
1052
     
1053
    for pExp in xrange(0, alpha+1):
1054
        iExp = 0
1055
        while (iExp + pExp) <= alpha:
1056
            #print "iExp:", iExp, \
1057
            #    "- pExp:", pExp, \
1058
            #    "- alpha-pExp:", alpha-pExp
1059
            q = pRing(iVariable * iBound)^iExp * p^pExp * N^(alpha-pExp)
1060
            #print q.monomials()
1061
            if columnsWidth != 0:
1062
                print " " * columnsWidth, q, 
1063
            polynomialsList.append(q)
1064
            iExp += 1
1065
    return polynomialsList
1066
# End spo_polynomial_to_polynomials_list_8
1067

    
1068
def spo_proto_to_column_matrix(protoMatrixColumns):
1069
    """
1070
    Create a column (each row holds the coefficients for one monomial) matrix.
1071
    
1072
    Parameters
1073
    ----------
1074
    protoMatrixColumns: a list of coefficient lists.
1075
    """
1076
    numColumns = len(protoMatrixColumns)
1077
    if numColumns == 0:
1078
        return None
1079
    # The last column holds has the maximum length. 
1080
    numRows = len(protoMatrixColumns[numColumns-1])
1081
    if numColumns == 0:
1082
        return None
1083
    baseMatrix = matrix(ZZ, numRows, numColumns)
1084
    for colIndex in xrange(0, numColumns):
1085
        for rowIndex in xrange(0, len(protoMatrixColumns[colIndex])):
1086
            if protoMatrixColumns[colIndex][rowIndex] != 0:
1087
                baseMatrix[rowIndex, colIndex] = \
1088
                    protoMatrixColumns[colIndex][rowIndex]
1089
    return baseMatrix
1090
# End spo_proto_to_column_matrix.
1091
#
1092
def spo_proto_to_row_matrix(protoMatrixRows):
1093
    """
1094
    Create a row (each column holds the coefficients corresponding to one 
1095
    monomial) matrix from the protoMatrixRows list.
1096
    
1097
    Parameters
1098
    ----------
1099
    protoMatrixRows: a list of coefficient lists.
1100
    """
1101
    numRows = len(protoMatrixRows)
1102
    if numRows == 0:
1103
        return None
1104
    # Search for the longest row to get the number of columns.
1105
    numColumns = 0
1106
    for row in protoMatrixRows:
1107
        rowLength = len(row)
1108
        if numColumns < rowLength:
1109
            numColumns = rowLength
1110
    if numColumns == 0:
1111
        return None
1112
    baseMatrix = matrix(ZZ, numRows, numColumns)
1113
    for rowIndex in xrange(0, numRows):
1114
        for colIndex in xrange(0, len(protoMatrixRows[rowIndex])):
1115
            if protoMatrixRows[rowIndex][colIndex] !=  0:
1116
                baseMatrix[rowIndex, colIndex] = \
1117
                    protoMatrixRows[rowIndex][colIndex]
1118
            #print rowIndex, colIndex,
1119
            #print protoMatrixRows[rowIndex][colIndex],
1120
            #print knownMonomialsList[colIndex](boundVar1,boundVar2)
1121
    return baseMatrix
1122
# End spo_proto_to_row_matrix.
1123
#
1124
sys.stderr.write("\t...sagePolynomialOperations loaded.\n")