Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (27,69 ko)

1 74 storres
load "/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageMatrixOperations.sage"
2 87 storres
print "sagePolynomialOperations loading..."
3 106 storres
def spo_add_polynomial_coeffs_to_matrix_row(poly,
4 83 storres
                                            knownMonomials,
5 83 storres
                                            protoMatrixRows,
6 83 storres
                                            columnsWidth=0):
7 80 storres
    """
8 106 storres
    For a given polynomial ,
9 80 storres
    add the coefficients of the protoMatrix (a list of proto matrix rows).
10 80 storres
    Coefficients are added to the protoMatrix row in the order imposed by the
11 80 storres
    monomials discovery list (the knownMonomials list) built as construction
12 80 storres
    goes on.
13 83 storres
    As a bonus, data can be printed out for a visual check.
14 106 storres
    poly           : the polynomial; in argument;
15 106 storres
    knownMonomials : the list of the already known monomials; will determine
16 106 storres
                     the order of the coefficients appending to a row; in-out
17 106 storres
                     argument (new monomials may be discovered and then
18 106 storres
                     appended the the knowMonomials list);
19 80 storres
    protoMatrixRows: a list of lists, each one holding the coefficients of the
20 106 storres
                     monomials of a polynomial; in-out argument: a new row is
21 106 storres
                     added at each call;
22 80 storres
    columnWith     : the width, in characters, of the displayed column ; if 0,
23 106 storres
                     do not display anything; in argument.
24 80 storres
    """
25 106 storres
    pMonomials   = poly.monomials()
26 106 storres
    pCoefficients = poly.coefficients()
27 80 storres
    # We have started with the smaller degrees in the first variable.
28 80 storres
    pMonomials.reverse()
29 80 storres
    pCoefficients.reverse()
30 80 storres
    # New empty proto matrix row.
31 80 storres
    protoMatrixRowCoefficients = []
32 80 storres
    # We work according to the order of the already known monomials
33 80 storres
    # No known monomials yet: add the pMonomials to knownMonomials
34 80 storres
    # and add the coefficients to the proto matrix row.
35 80 storres
    if len(knownMonomials) == 0:
36 80 storres
        for pmIdx in xrange(0, len(pMonomials)):
37 80 storres
            knownMonomials.append(pMonomials[pmIdx])
38 80 storres
            protoMatrixRowCoefficients.append(pCoefficients[pmIdx])
39 80 storres
            if columnsWidth != 0:
40 80 storres
                monomialAsString = str(pCoefficients[pmIdx]) + " " + \
41 80 storres
                                   str(pMonomials[pmIdx])
42 80 storres
                print monomialAsString, " " * \
43 80 storres
                      (columnsWidth - len(monomialAsString)),
44 80 storres
    # There are some known monomials. We search for them in pMonomials and
45 80 storres
    # add their coefficients to the proto matrix row.
46 80 storres
    else:
47 80 storres
        for knownMonomialIndex in xrange(0,len(knownMonomials)):
48 80 storres
            # We lazily use an exception here since pMonomials.index() function
49 80 storres
            # may fail throwing the ValueError exception.
50 80 storres
            try:
51 80 storres
                indexInPmonomials = \
52 80 storres
                    pMonomials.index(knownMonomials[knownMonomialIndex])
53 80 storres
                if columnsWidth != 0:
54 80 storres
                    monomialAsString = str(pCoefficients[indexInPmonomials]) + \
55 80 storres
                        " " + str(knownMonomials[knownMonomialIndex])
56 80 storres
                    print monomialAsString, " " * \
57 80 storres
                        (columnsWidth - len(monomialAsString)),
58 80 storres
                # Add the coefficient to the proto matrix row and delete the \
59 80 storres
                # known monomial from the current pMonomial list
60 80 storres
                #(and the corresponding coefficient as well).
61 80 storres
                protoMatrixRowCoefficients.append(pCoefficients[indexInPmonomials])
62 80 storres
                del pMonomials[indexInPmonomials]
63 80 storres
                del pCoefficients[indexInPmonomials]
64 80 storres
            # The knownMonomials element is not in pMonomials
65 80 storres
            except ValueError:
66 80 storres
                protoMatrixRowCoefficients.append(0)
67 80 storres
                if columnsWidth != 0:
68 80 storres
                    monomialAsString = "0" + " "+ \
69 80 storres
                        str(knownMonomials[knownMonomialIndex])
70 80 storres
                    print monomialAsString, " " * \
71 80 storres
                        (columnsWidth - len(monomialAsString)),
72 80 storres
        # End for knownMonomialKey loop.
73 80 storres
        # We now append the remaining monomials of pMonomials to knownMonomials
74 80 storres
        # and the corresponding coefficients to proto matrix row.
75 80 storres
        for pmIdx in xrange(0, len(pMonomials)):
76 80 storres
            knownMonomials.append(pMonomials[pmIdx])
77 80 storres
            protoMatrixRowCoefficients.append(pCoefficients[pmIdx])
78 80 storres
            if columnsWidth != 0:
79 80 storres
                monomialAsString = str(pCoefficients[pmIdx]) + " " \
80 80 storres
                    + str(pMonomials[pmIdx])
81 80 storres
                print monomialAsString, " " * \
82 80 storres
                    (columnsWidth - len(monomialAsString)),
83 80 storres
        # End for pmIdx loop.
84 80 storres
    # Add the new list row elements to the proto matrix.
85 80 storres
    protoMatrixRows.append(protoMatrixRowCoefficients)
86 80 storres
    if columnsWidth != 0:
87 80 storres
        print
88 83 storres
# End spo_add_polynomial_coeffs_to_matrix_row
89 80 storres
90 105 storres
def spo_expression_as_string(powI, powT, powP, powN):
91 80 storres
    """
92 80 storres
    Computes a string version of the i^k + t^l + p^m + N^n expression for
93 80 storres
    output.
94 80 storres
    """
95 80 storres
    expressionAsString =""
96 80 storres
    if powI != 0:
97 80 storres
        expressionAsString += "i^" + str(powI)
98 80 storres
    if powT != 0:
99 80 storres
        if len(expressionAsString) != 0:
100 80 storres
            expressionAsString += " * "
101 80 storres
        expressionAsString += "t^" + str(powT)
102 80 storres
    if powP != 0:
103 80 storres
        if len(expressionAsString) != 0:
104 80 storres
            expressionAsString += " * "
105 80 storres
        expressionAsString += "p^" + str(powP)
106 105 storres
    if (powN) != 0 :
107 80 storres
        if len(expressionAsString) != 0:
108 80 storres
            expressionAsString += " * "
109 105 storres
        expressionAsString += "N^" + str(powN)
110 80 storres
    return(expressionAsString)
111 80 storres
# End spo_expression_as_string.
112 80 storres
113 87 storres
def spo_norm(poly, p=2):
114 81 storres
    """
115 81 storres
    Behaves more or less (no infinity defined) as the norm for the
116 81 storres
    univariate polynomials.
117 81 storres
    Quoting the Sage documentation:
118 81 storres
    Definition: For integer p, the p-norm of a polynomial is the pth root of
119 81 storres
    the sum of the pth powers of the absolute values of the coefficients of
120 81 storres
    the polynomial.
121 87 storres
122 81 storres
    """
123 87 storres
    # TODO: check the arguments (for p see below)..
124 81 storres
    norm = 0
125 87 storres
    # For infinity norm.
126 87 storres
    if p == Infinity:
127 87 storres
        for coefficient in poly.coefficients():
128 87 storres
            coefficientAbs = coefficient.abs()
129 87 storres
            if coefficientAbs > norm:
130 87 storres
                norm = coefficientAbs
131 87 storres
        return norm
132 87 storres
    # TODO: check here the value of p
133 94 storres
    # p must be an integer.
134 94 storres
    if int(p) != p:
135 94 storres
        return None
136 94 storres
    # p must be >= 1.
137 94 storres
    if p < 1:
138 94 storres
        return None
139 87 storres
    # For 1 norm.
140 87 storres
    if p == 1:
141 87 storres
        for coefficient in poly.coefficients():
142 87 storres
            norm +=  coefficient.abs()
143 87 storres
        return norm
144 87 storres
    # For other norms
145 81 storres
    for coefficient in poly.coefficients():
146 103 storres
        norm +=  coefficient.abs()^p
147 87 storres
    return pow(norm, 1/p)
148 81 storres
# end spo_norm
149 81 storres
150 100 storres
def spo_polynomial_to_proto_matrix(p, alpha, N, columnsWidth=0):
151 74 storres
    """
152 83 storres
    From a (bivariate) polynomial and some other parameters build a proto
153 87 storres
    matrix (an array of "rows") to be converted into a "true" matrix and
154 83 storres
    eventually by reduced by fpLLL.
155 102 storres
    The matrix is such as those found in Boneh-Durphee and Stehlé.
156 74 storres
157 83 storres
    Parameters
158 83 storres
    ----------
159 87 storres
    p: the (bivariate) polynomial;
160 87 storres
    pRing: the ring over which p is defined;
161 74 storres
    alpha:
162 74 storres
    N:
163 83 storres
    columsWidth: if == 0, no information is displayed, otherwise data is
164 83 storres
                 printed in colums of columnsWitdth width.
165 74 storres
    """
166 100 storres
    pRing = p.parent()
167 77 storres
    knownMonomials = []
168 77 storres
    protoMatrixRows = []
169 92 storres
    polynomialsList = []
170 74 storres
    pVariables = p.variables()
171 74 storres
    iVariable = pVariables[0]
172 76 storres
    tVariable = pVariables[1]
173 87 storres
    polynomialAtPower = pRing(1)
174 87 storres
    currentPolynomial = pRing(1)
175 74 storres
    pIdegree = p.degree(pVariables[0])
176 74 storres
    pTdegree = p.degree(pVariables[1])
177 87 storres
    currentIdegree = currentPolynomial.degree(iVariable)
178 105 storres
    nAtAlpha = N^alpha
179 105 storres
    nAtPower = nAtAlpha
180 92 storres
    polExpStr = ""
181 74 storres
    # We work from p^0 * N^alpha to p^alpha * N^0
182 74 storres
    for pPower in xrange(0, alpha + 1):
183 76 storres
        # pPower == 0 is a special case. We introduce all the monomials but one
184 78 storres
        # in i and those in t necessary to be able to introduce
185 76 storres
        # p. We arbitrary choose to introduce the highest degree monomial in i
186 76 storres
        # with p. We also introduce all the mixed i^k * t^l monomials with
187 77 storres
        # k < p.degree(i) and l <= p.degree(t).
188 78 storres
        # Mixed terms introduction is necessary here before we start "i shifts"
189 78 storres
        # in the next iteration.
190 74 storres
        if pPower == 0:
191 78 storres
            # Notice that i^pIdegree is excluded as the bound of the xrange is
192 78 storres
            # pIdegree
193 74 storres
            for iPower in xrange(0, pIdegree):
194 74 storres
                for tPower in xrange(0, pTdegree + 1):
195 77 storres
                    if columnsWidth != 0:
196 92 storres
                        polExpStr = spo_expression_as_string(iPower,
197 76 storres
                                                             tPower,
198 76 storres
                                                             pPower,
199 105 storres
                                                             alpha-pPower)
200 92 storres
                        print "->", polExpStr
201 74 storres
                    currentExpression = iVariable^iPower * \
202 91 storres
                                        tVariable^tPower * nAtAlpha
203 78 storres
                    # polynomialAtPower == 1 here. Next line should be commented
204 78 storres
                    # out but it does not work! Some conversion problem?
205 91 storres
                    currentPolynomial = pRing(currentExpression)
206 106 storres
                    polynomialsList.append(currentPolynomial)
207 74 storres
                    pMonomials = currentPolynomial.monomials()
208 74 storres
                    pCoefficients = currentPolynomial.coefficients()
209 83 storres
                    spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
210 83 storres
                                                            pCoefficients,
211 83 storres
                                                            knownMonomials,
212 83 storres
                                                            protoMatrixRows,
213 83 storres
                                                            columnsWidth)
214 78 storres
                # End tPower.
215 78 storres
            # End for iPower.
216 77 storres
        else: # pPower > 0: (p^1..p^alpha)
217 78 storres
            # This where we introduce the p^pPower * N^(alpha-pPower)
218 77 storres
            # polynomial.
219 77 storres
            # This step could technically be fused as the first iteration
220 77 storres
            # of the next loop (with iPower starting at 0).
221 77 storres
            # We set it apart for clarity.
222 77 storres
            if columnsWidth != 0:
223 105 storres
                polExpStr = spo_expression_as_string(0, 0, pPower, alpha-pPower)
224 92 storres
                print "->", polExpStr
225 77 storres
            currentPolynomial = polynomialAtPower * nAtPower
226 106 storres
            polynomialsList.append(currentPolynomial)
227 77 storres
            pMonomials = currentPolynomial.monomials()
228 77 storres
            pCoefficients = currentPolynomial.coefficients()
229 83 storres
            spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
230 83 storres
                                                    pCoefficients,
231 83 storres
                                                    knownMonomials,
232 83 storres
                                                    protoMatrixRows,
233 83 storres
                                                    columnsWidth)
234 77 storres
235 77 storres
            # The i^iPower * p^pPower polynomials: they add i^k monomials to
236 77 storres
            # p^pPower up to k < pIdegree * pPower. This only introduces i^k
237 77 storres
            # monomials since mixed terms (that were introduced at a previous
238 77 storres
            # stage) are only shifted to already existing
239 77 storres
            # ones. p^pPower is "shifted" to higher degrees in i as far as
240 77 storres
            # possible, one step short of the degree in i of p^(pPower+1) .
241 77 storres
            # These "pure" i^k monomials can only show up with i multiplications.
242 77 storres
            for iPower in xrange(1, pIdegree):
243 87 storres
                if columnsWidth != 0:
244 92 storres
                    polExpStr = spo_expression_as_string(iPower, \
245 87 storres
                                                         0,      \
246 87 storres
                                                         pPower, \
247 87 storres
                                                         alpha)
248 92 storres
                    print "->", polExpStr
249 77 storres
                currentExpression = i^iPower * nAtPower
250 87 storres
                currentPolynomial = pRing(currentExpression) * polynomialAtPower
251 106 storres
                polynomialsList.append(currentPolynomial)
252 77 storres
                pMonomials = currentPolynomial.monomials()
253 77 storres
                pCoefficients = currentPolynomial.coefficients()
254 87 storres
                spo_add_polynomial_coeffs_to_matrix_row(pMonomials,      \
255 87 storres
                                                        pCoefficients,   \
256 87 storres
                                                        knownMonomials,  \
257 87 storres
                                                        protoMatrixRows, \
258 83 storres
                                                        columnsWidth)
259 77 storres
            # End for iPower
260 77 storres
            # We want now to introduce a t * p^pPower polynomial. But before
261 77 storres
            # that we must introduce some mixed monomials.
262 77 storres
            # This loop is no triggered before pPower == 2.
263 78 storres
            # It introduces a first set of high i degree mixed monomials.
264 77 storres
            for iPower in xrange(1, pPower):
265 77 storres
                tPower = pPower - iPower + 1
266 77 storres
                if columnsWidth != 0:
267 92 storres
                    polExpStr = spo_expression_as_string(iPower * pIdegree,
268 77 storres
                                                         tPower,
269 77 storres
                                                         0,
270 77 storres
                                                         alpha)
271 92 storres
                    print "->", polExpStr
272 91 storres
                currentExpression = i^(iPower * pIdegree) * t^tPower * nAtAlpha
273 87 storres
                currentPolynomial = pRing(currentExpression)
274 106 storres
                polynomialsList.append(currentPolynomial)
275 77 storres
                pMonomials = currentPolynomial.monomials()
276 77 storres
                pCoefficients = currentPolynomial.coefficients()
277 83 storres
                spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
278 83 storres
                                                        pCoefficients,
279 83 storres
                                                        knownMonomials,
280 83 storres
                                                        protoMatrixRows,
281 83 storres
                                                        columnsWidth)
282 77 storres
            # End for iPower
283 78 storres
            #
284 78 storres
            # This is the mixed monomials main loop. It introduces:
285 77 storres
            # - the missing mixed monomials needed before the
286 78 storres
            #   t^l * p^pPower * N^(alpha-pPower) polynomial;
287 78 storres
            # - the t^l * p^pPower * N^(alpha-pPower) itself;
288 78 storres
            # - for each of i^k * t^l * p^pPower * N^(alpha-pPower) polynomials:
289 78 storres
            #   - the the missing mixed monomials needed  polynomials,
290 78 storres
            #   - the i^k * t^l * p^pPower * N^(alpha-pPower) itself.
291 78 storres
            # The t^l * p^pPower * N^(alpha-pPower) is introduced when
292 78 storres
            #
293 77 storres
            for iShift in xrange(0, pIdegree):
294 77 storres
                # When pTdegree == 1, the following loop only introduces
295 77 storres
                # a single new monomial.
296 77 storres
                #print "++++++++++"
297 77 storres
                for outerTpower in xrange(1, pTdegree + 1):
298 77 storres
                    # First one high i degree mixed monomial.
299 77 storres
                    iPower = iShift + pPower * pIdegree
300 77 storres
                    if columnsWidth != 0:
301 92 storres
                        polExpStr = spo_expression_as_string(iPower,
302 77 storres
                                                             outerTpower,
303 77 storres
                                                             0,
304 77 storres
                                                             alpha)
305 92 storres
                        print "->", polExpStr
306 91 storres
                    currentExpression = i^iPower * t^outerTpower * nAtAlpha
307 87 storres
                    currentPolynomial = pRing(currentExpression)
308 106 storres
                    polynomialsList.append(currentPolynomial)
309 77 storres
                    pMonomials = currentPolynomial.monomials()
310 77 storres
                    pCoefficients = currentPolynomial.coefficients()
311 83 storres
                    spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
312 83 storres
                                                            pCoefficients,
313 83 storres
                                                            knownMonomials,
314 83 storres
                                                            protoMatrixRows,
315 83 storres
                                                            columnsWidth)
316 77 storres
                    #print "+++++"
317 78 storres
                    # At iShift == 0, the following innerTpower loop adds
318 78 storres
                    # duplicate monomials, since no extra i^l * t^k is needed
319 78 storres
                    # before introducing the
320 77 storres
                    # i^iShift * t^outerPpower * p^pPower * N^(alpha-pPower)
321 77 storres
                    # polynomial.
322 77 storres
                    # It introduces smaller i degree monomials than the
323 77 storres
                    # one(s) added previously (no pPower multiplication).
324 77 storres
                    # Here the exponent of t decreases as that of i increases.
325 78 storres
                    # This conditional is not entered before pPower == 1.
326 78 storres
                    # The innerTpower loop does not produce anything before
327 78 storres
                    # pPower == 2. We keep it anyway for other configuration of
328 78 storres
                    # p.
329 77 storres
                    if iShift > 0:
330 77 storres
                        iPower = pIdegree + iShift
331 77 storres
                        for innerTpower in xrange(pPower, 1, -1):
332 77 storres
                            if columnsWidth != 0:
333 92 storres
                                polExpStr = spo_expression_as_string(iPower,
334 77 storres
                                                                     innerTpower,
335 77 storres
                                                                     0,
336 77 storres
                                                                     alpha)
337 77 storres
                            currentExpression = \
338 91 storres
                                    i^(iPower) * t^(innerTpower) * nAtAlpha
339 87 storres
                            currentPolynomial = pRing(currentExpression)
340 106 storres
                            polynomialsList.append(currentPolynomial)
341 77 storres
                            pMonomials = currentPolynomial.monomials()
342 77 storres
                            pCoefficients = currentPolynomial.coefficients()
343 83 storres
                            spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
344 77 storres
                                                                pCoefficients,
345 77 storres
                                                                knownMonomials,
346 77 storres
                                                                protoMatrixRows,
347 77 storres
                                                                columnsWidth)
348 77 storres
                            iPower += pIdegree
349 77 storres
                        # End for innerTpower
350 77 storres
                    # End of if iShift > 0
351 78 storres
                    # When iShift == 0, just after each of the
352 78 storres
                    # p^pPower * N^(alpha-pPower) polynomials has
353 78 storres
                    # been introduced (followed by a string of
354 78 storres
                    # i^k * p^pPower * N^(alpha-pPower) polynomials) a
355 78 storres
                    # t^l *  p^pPower * N^(alpha-pPower) is introduced here.
356 78 storres
                    #
357 77 storres
                    # Eventually, the following section introduces the
358 105 storres
                    # i^iShift * t^outerTpower * p^iPower * N^(alpha-pPower)
359 77 storres
                    # polynomials.
360 77 storres
                    if columnsWidth != 0:
361 92 storres
                        polExpStr = spo_expression_as_string(iShift,
362 77 storres
                                                             outerTpower,
363 77 storres
                                                             pPower,
364 105 storres
                                                             alpha-pPower)
365 92 storres
                        print "->", polExpStr
366 77 storres
                    currentExpression = i^iShift * t^outerTpower * nAtPower
367 105 storres
                    currentPolynomial = pRing(currentExpression) * \
368 105 storres
                                            polynomialAtPower
369 106 storres
                    polynomialsList.append(currentPolynomial)
370 77 storres
                    pMonomials = currentPolynomial.monomials()
371 77 storres
                    pCoefficients = currentPolynomial.coefficients()
372 83 storres
                    spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
373 83 storres
                                                            pCoefficients,
374 83 storres
                                                            knownMonomials,
375 83 storres
                                                            protoMatrixRows,
376 83 storres
                                                            columnsWidth)
377 77 storres
                # End for outerTpower
378 77 storres
                #print "++++++++++"
379 77 storres
            # End for iShift
380 77 storres
        polynomialAtPower *= p
381 77 storres
        nAtPower /= N
382 77 storres
    # End for pPower loop
383 92 storres
    return ((protoMatrixRows, knownMonomials, polynomialsList))
384 83 storres
# End spo_polynomial_to_proto_matrix
385 81 storres
386 106 storres
def spo_polynomial_to_polynomials_list_2(p, alpha, N, columnsWidth=0):
387 105 storres
    """
388 106 storres
    From p, alpha, N build a list of polynomials...
389 106 storres
    TODO: clean up the comments below!
390 106 storres
391 105 storres
    From a (bivariate) polynomial and some other parameters build a proto
392 105 storres
    matrix (an array of "rows") to be converted into a "true" matrix and
393 105 storres
    eventually by reduced by fpLLL.
394 105 storres
    The matrix is based on a list of polynomials that are built in a way
395 105 storres
    that one and only monomial is added at each new polynomial. Among the many
396 105 storres
    possible ways to build this list we pick one strongly dependent on the
397 105 storres
    structure of the polynomial and of the problem.
398 105 storres
    We consider here the polynomials of the form:
399 105 storres
    a_k*i^k + a_(k-1)*i^(k-1) + ... + a_1*i + a_0 - t
400 105 storres
    The values of i and t are bounded and we eventually look for (i_0,t_0)
401 105 storres
    pairs such that:
402 105 storres
    a_k*i_0^k + a_(k-1)*i_0^(k-1) + ... + a_1*i_0 + a_0 = t_0
403 105 storres
    Hence, departing from the procedure in described in Boneh-Durfee, we will
404 105 storres
    not use "t-shifts" but only "i-shifts".
405 105 storres
406 105 storres
    Parameters
407 105 storres
    ----------
408 105 storres
    p: the (bivariate) polynomial;
409 105 storres
    pRing: the ring over which p is defined;
410 105 storres
    alpha:
411 105 storres
    N:
412 105 storres
    columsWidth: if == 0, no information is displayed, otherwise data is
413 105 storres
                 printed in colums of columnsWitdth width.
414 105 storres
    """
415 105 storres
    pRing = p.parent()
416 105 storres
    knownMonomials = []
417 105 storres
    polynomialsList = []
418 105 storres
    pVariables = p.variables()
419 105 storres
    iVariable = pVariables[0]
420 105 storres
    tVariable = pVariables[1]
421 105 storres
    polynomialAtPower = pRing(1)
422 105 storres
    currentPolynomial = pRing(1)
423 105 storres
    pIdegree = p.degree(iVariable)
424 105 storres
    pTdegree = p.degree(tVariable)
425 105 storres
    currentIdegree = currentPolynomial.degree(iVariable)
426 105 storres
    nAtAlpha = N^alpha
427 105 storres
    nAtPower = nAtAlpha
428 105 storres
    polExpStr = ""
429 105 storres
    # We work from p^0 * N^alpha to p^alpha * N^0
430 105 storres
    for pPower in xrange(0, alpha + 1):
431 105 storres
        # pPower == 0 is a special case. We introduce all the monomials in i
432 105 storres
        # up to i^pIdegree.
433 105 storres
        if pPower == 0:
434 105 storres
            # Notice who iPower runs up to i^pIdegree.
435 105 storres
            for iPower in xrange(0, pIdegree + 1):
436 105 storres
                # No t power is taken into account as we limit our selves to
437 105 storres
                # degree 1 in t and make no "t-shifts".
438 105 storres
                if columnsWidth != 0:
439 105 storres
                    polExpStr = spo_expression_as_string(iPower,
440 105 storres
                                                         0,
441 105 storres
                                                         0,
442 105 storres
                                                         alpha)
443 105 storres
                    print "->", polExpStr
444 105 storres
                currentExpression = iVariable^iPower * nAtAlpha
445 105 storres
                # polynomialAtPower == 1 here. Next line should be commented
446 105 storres
                # out but it does not work! Some conversion problem?
447 105 storres
                currentPolynomial = pRing(currentExpression)
448 105 storres
                polynomialsList.append(currentPolynomial)
449 105 storres
            # End for iPower.
450 105 storres
        else: # pPower > 0: (p^1..p^alpha)
451 105 storres
            # This where we introduce the p^pPower * N^(alpha-pPower)
452 105 storres
            # polynomial. This is also where the t^pPower monomials shows up for
453 105 storres
            # the first time.
454 105 storres
            if columnsWidth != 0:
455 105 storres
                polExpStr = spo_expression_as_string(0, 0, pPower, alpha-pPower)
456 105 storres
                print "->", polExpStr
457 105 storres
            currentPolynomial = polynomialAtPower * nAtPower
458 105 storres
            polynomialsList.append(currentPolynomial)
459 106 storres
            # Exit when pPower == alpha
460 106 storres
            if pPower == alpha:
461 106 storres
                return((knownMonomials, polynomialsList))
462 105 storres
            # This is where the "i-shifts" take place. Mixed terms, i^k * t^l
463 105 storres
            # (that were introduced at a previous
464 105 storres
            # stage or are introduced now) are only shifted to already existing
465 105 storres
            # ones with the notable exception of i^iPower * t^pPower, which
466 105 storres
            # must be manually introduced.
467 105 storres
            # p^pPower is "shifted" to higher degrees in i as far as
468 105 storres
            # possible, up to of the degree in i of p^(pPower+1).
469 105 storres
            # These "pure" i^k monomials can only show up with i multiplications.
470 105 storres
            for iPower in xrange(1, pIdegree + 1):
471 105 storres
                # The i^iPower * t^pPower monomial. Notice the alpha exponent
472 105 storres
                # for N.
473 105 storres
                internalIpower = iPower
474 105 storres
                for tPower in xrange(pPower,0,-1):
475 105 storres
                    if columnsWidth != 0:
476 105 storres
                        polExpStr = spo_expression_as_string(internalIpower, \
477 105 storres
                                                             tPower,  \
478 105 storres
                                                             0, \
479 105 storres
                                                             alpha)
480 105 storres
                        print "->", polExpStr
481 105 storres
                    currentExpression = i^internalIpower * t^tPower * nAtAlpha
482 105 storres
                    currentPolynomial = pRing(currentExpression)
483 105 storres
                    polynomialsList.append(currentPolynomial)
484 105 storres
                    internalIpower += pIdegree
485 105 storres
                # End for tPower
486 105 storres
                # The i^iPower * p^pPower * N^(alpha-pPower) i-shift.
487 105 storres
                if columnsWidth != 0:
488 105 storres
                    polExpStr = spo_expression_as_string(iPower, \
489 105 storres
                                                         0,      \
490 105 storres
                                                         pPower, \
491 105 storres
                                                         alpha-pPower)
492 105 storres
                    print "->", polExpStr
493 105 storres
                currentExpression = i^iPower * nAtPower
494 105 storres
                currentPolynomial = pRing(currentExpression) * polynomialAtPower
495 105 storres
                polynomialsList.append(currentPolynomial)
496 105 storres
            # End for iPower
497 105 storres
        polynomialAtPower *= p
498 105 storres
        nAtPower /= N
499 105 storres
    # End for pPower loop
500 106 storres
    return((knownMonomials, polynomialsList))
501 105 storres
# End spo_polynomial_to_proto_matrix_2
502 105 storres
503 90 storres
def spo_proto_to_column_matrix(protoMatrixColumns, \
504 90 storres
                               knownMonomialsList, \
505 90 storres
                               boundVar1, \
506 90 storres
                               boundVar2):
507 83 storres
    """
508 87 storres
    Create a column (each row holds the coefficients of one monomial) matrix.
509 83 storres
510 83 storres
    Parameters
511 83 storres
    ----------
512 87 storres
    protoMatrixColumns: a list of coefficient lists.
513 83 storres
    """
514 87 storres
    numColumns = len(protoMatrixColumns)
515 87 storres
    if numColumns == 0:
516 83 storres
        return None
517 87 storres
    # The last column holds has the maximum length.
518 87 storres
    numRows = len(protoMatrixColumns[numColumns-1])
519 83 storres
    if numColumns == 0:
520 83 storres
        return None
521 83 storres
    baseMatrix = matrix(ZZ, numRows, numColumns)
522 87 storres
    for colIndex in xrange(0, numColumns):
523 87 storres
        for rowIndex in xrange(0, len(protoMatrixColumns[colIndex])):
524 90 storres
            if protoMatrixColumns[colIndex][rowIndex] != 0:
525 90 storres
                baseMatrix[rowIndex, colIndex] = \
526 90 storres
                    protoMatrixColumns[colIndex][rowIndex] * \
527 90 storres
                    knownMonomialsList[rowIndex](boundVar1, boundVar2)
528 83 storres
    return baseMatrix
529 83 storres
# End spo_proto_to_column_matrix.
530 83 storres
#
531 88 storres
def spo_proto_to_row_matrix(protoMatrixRows, \
532 88 storres
                            knownMonomialsList, \
533 88 storres
                            boundVar1, \
534 88 storres
                            boundVar2):
535 83 storres
    """
536 90 storres
    Create a row (each column holds the evaluation one monomial at boundVar1 and
537 90 storres
    boundVar2 values) matrix.
538 83 storres
539 83 storres
    Parameters
540 83 storres
    ----------
541 83 storres
    protoMatrixRows: a list of coefficient lists.
542 83 storres
    """
543 83 storres
    numRows = len(protoMatrixRows)
544 83 storres
    if numRows == 0:
545 83 storres
        return None
546 91 storres
    # The last row is the longest one.
547 83 storres
    numColumns = len(protoMatrixRows[numRows-1])
548 83 storres
    if numColumns == 0:
549 83 storres
        return None
550 83 storres
    baseMatrix = matrix(ZZ, numRows, numColumns)
551 83 storres
    for rowIndex in xrange(0, numRows):
552 83 storres
        for colIndex in xrange(0, len(protoMatrixRows[rowIndex])):
553 89 storres
            if protoMatrixRows[rowIndex][colIndex] !=  0:
554 89 storres
                baseMatrix[rowIndex, colIndex] = \
555 89 storres
                    protoMatrixRows[rowIndex][colIndex] * \
556 89 storres
                    knownMonomialsList[colIndex](boundVar1,boundVar2)
557 89 storres
            #print rowIndex, colIndex,
558 89 storres
            #print protoMatrixRows[rowIndex][colIndex],
559 89 storres
            #print knownMonomialsList[colIndex](boundVar1,boundVar2)
560 83 storres
    return baseMatrix
561 83 storres
# End spo_proto_to_row_matrix.
562 83 storres
#
563 87 storres
print "\t...sagePolynomialOperations loaded"