Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (27,65 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_expression_as_string(powI, powT, powP, powN):
91
    """
92
    Computes a string version of the i^k + t^l + p^m + N^n expression for
93
    output.
94
    """
95
    expressionAsString =""
96
    if powI != 0:
97
        expressionAsString += "i^" + str(powI)
98
    if powT != 0:
99
        if len(expressionAsString) != 0:
100
            expressionAsString += " * "
101
        expressionAsString += "t^" + str(powT)
102
    if powP != 0:
103
        if len(expressionAsString) != 0:
104
            expressionAsString += " * "
105
        expressionAsString += "p^" + str(powP)
106
    if (powN) != 0 :
107
        if len(expressionAsString) != 0:
108
            expressionAsString += " * "
109
        expressionAsString += "N^" + str(powN)
110
    return(expressionAsString)
111
# End spo_expression_as_string.
112

    
113
def spo_norm(poly, p=2):
114
    """
115
    Behaves more or less (no infinity defined) as the norm for the
116
    univariate polynomials.
117
    Quoting Sage documentation:
118
    "Definition: For integer p, the p-norm of a polynomial is the pth root of 
119
    the sum of the pth powers of the absolute values of the coefficients of 
120
    the polynomial."
121
    
122
    """
123
    # TODO: check the arguments (for p see below)..
124
    norm = 0
125
    # For infinity norm.
126
    if p == Infinity:
127
        for coefficient in poly.coefficients():
128
            coefficientAbs = coefficient.abs()
129
            if coefficientAbs > norm:
130
                norm = coefficientAbs
131
        return norm
132
    # TODO: check here the value of p
133
    # p must be a positive integer >= 1.
134
    if p < 1 or (not p in ZZ):
135
        return None
136
    # For 1 norm.
137
    if p == 1:
138
        for coefficient in poly.coefficients():
139
            norm +=  coefficient.abs()
140
        return norm
141
    # For other norms
142
    for coefficient in poly.coefficients():
143
        norm +=  coefficient.abs()^p
144
    return pow(norm, 1/p)
145
# end spo_norm
146

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

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

    
500
def spo_proto_to_column_matrix(protoMatrixColumns, \
501
                               knownMonomialsList, \
502
                               boundVar1, \
503
                               boundVar2):
504
    """
505
    Create a column (each row holds the coefficients of one monomial) matrix.
506
    
507
    Parameters
508
    ----------
509
    protoMatrixColumns: a list of coefficient lists.
510
    """
511
    numColumns = len(protoMatrixColumns)
512
    if numColumns == 0:
513
        return None
514
    # The last column holds has the maximum length. 
515
    numRows = len(protoMatrixColumns[numColumns-1])
516
    if numColumns == 0:
517
        return None
518
    baseMatrix = matrix(ZZ, numRows, numColumns)
519
    for colIndex in xrange(0, numColumns):
520
        for rowIndex in xrange(0, len(protoMatrixColumns[colIndex])):
521
            if protoMatrixColumns[colIndex][rowIndex] != 0:
522
                baseMatrix[rowIndex, colIndex] = \
523
                    protoMatrixColumns[colIndex][rowIndex] * \
524
                    knownMonomialsList[rowIndex](boundVar1, boundVar2)
525
    return baseMatrix
526
# End spo_proto_to_column_matrix.
527
#
528
def spo_proto_to_row_matrix(protoMatrixRows, \
529
                            knownMonomialsList, \
530
                            boundVar1, \
531
                            boundVar2):
532
    """
533
    Create a row (each column holds the evaluation one monomial at boundVar1 and
534
    boundVar2 values) matrix.
535
    
536
    Parameters
537
    ----------
538
    protoMatrixRows: a list of coefficient lists.
539
    """
540
    numRows = len(protoMatrixRows)
541
    if numRows == 0:
542
        return None
543
    # The last row is the longest one.
544
    numColumns = len(protoMatrixRows[numRows-1])
545
    if numColumns == 0:
546
        return None
547
    baseMatrix = matrix(ZZ, numRows, numColumns)
548
    for rowIndex in xrange(0, numRows):
549
        for colIndex in xrange(0, len(protoMatrixRows[rowIndex])):
550
            if protoMatrixRows[rowIndex][colIndex] !=  0:
551
                baseMatrix[rowIndex, colIndex] = \
552
                    protoMatrixRows[rowIndex][colIndex] * \
553
                    knownMonomialsList[colIndex](boundVar1,boundVar2)
554
            #print rowIndex, colIndex,
555
            #print protoMatrixRows[rowIndex][colIndex],
556
            #print knownMonomialsList[colIndex](boundVar1,boundVar2)
557
    return baseMatrix
558
# End spo_proto_to_row_matrix.
559
#
560
print "\t...sagePolynomialOperations loaded"