Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (34,39 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 109 storres
def spo_get_coefficient_for_monomial(monomialsList, coefficientsList, monomial):
91 109 storres
    """
92 109 storres
    Get, for a polynomial, the coefficient for a given monomial.
93 109 storres
    The polynomial is given as two lists (monomials and coefficients as
94 109 storres
    return by the respective methods ; indexes of the two lists must match).
95 109 storres
    If the monomial is not found, 0 is returned.
96 109 storres
    """
97 109 storres
    monomialIndex = 0
98 109 storres
    for mono in monomialsList:
99 109 storres
        if mono == monomial:
100 109 storres
            return coefficientsList[monomialIndex]
101 109 storres
        monomialIndex += 1
102 109 storres
    return 0
103 109 storres
# End spo_get_coefficient_for_monomial.
104 109 storres
105 109 storres
106 105 storres
def spo_expression_as_string(powI, powT, powP, powN):
107 80 storres
    """
108 80 storres
    Computes a string version of the i^k + t^l + p^m + N^n expression for
109 80 storres
    output.
110 80 storres
    """
111 80 storres
    expressionAsString =""
112 80 storres
    if powI != 0:
113 80 storres
        expressionAsString += "i^" + str(powI)
114 80 storres
    if powT != 0:
115 80 storres
        if len(expressionAsString) != 0:
116 80 storres
            expressionAsString += " * "
117 80 storres
        expressionAsString += "t^" + str(powT)
118 80 storres
    if powP != 0:
119 80 storres
        if len(expressionAsString) != 0:
120 80 storres
            expressionAsString += " * "
121 80 storres
        expressionAsString += "p^" + str(powP)
122 105 storres
    if (powN) != 0 :
123 80 storres
        if len(expressionAsString) != 0:
124 80 storres
            expressionAsString += " * "
125 105 storres
        expressionAsString += "N^" + str(powN)
126 80 storres
    return(expressionAsString)
127 80 storres
# End spo_expression_as_string.
128 80 storres
129 87 storres
def spo_norm(poly, p=2):
130 81 storres
    """
131 81 storres
    Behaves more or less (no infinity defined) as the norm for the
132 81 storres
    univariate polynomials.
133 107 storres
    Quoting Sage documentation:
134 107 storres
    "Definition: For integer p, the p-norm of a polynomial is the pth root of
135 81 storres
    the sum of the pth powers of the absolute values of the coefficients of
136 107 storres
    the polynomial."
137 87 storres
138 81 storres
    """
139 87 storres
    # TODO: check the arguments (for p see below)..
140 81 storres
    norm = 0
141 87 storres
    # For infinity norm.
142 87 storres
    if p == Infinity:
143 87 storres
        for coefficient in poly.coefficients():
144 87 storres
            coefficientAbs = coefficient.abs()
145 87 storres
            if coefficientAbs > norm:
146 87 storres
                norm = coefficientAbs
147 87 storres
        return norm
148 87 storres
    # TODO: check here the value of p
149 107 storres
    # p must be a positive integer >= 1.
150 107 storres
    if p < 1 or (not p in ZZ):
151 94 storres
        return None
152 87 storres
    # For 1 norm.
153 87 storres
    if p == 1:
154 87 storres
        for coefficient in poly.coefficients():
155 87 storres
            norm +=  coefficient.abs()
156 87 storres
        return norm
157 87 storres
    # For other norms
158 81 storres
    for coefficient in poly.coefficients():
159 103 storres
        norm +=  coefficient.abs()^p
160 87 storres
    return pow(norm, 1/p)
161 81 storres
# end spo_norm
162 81 storres
163 100 storres
def spo_polynomial_to_proto_matrix(p, alpha, N, columnsWidth=0):
164 74 storres
    """
165 83 storres
    From a (bivariate) polynomial and some other parameters build a proto
166 87 storres
    matrix (an array of "rows") to be converted into a "true" matrix and
167 83 storres
    eventually by reduced by fpLLL.
168 102 storres
    The matrix is such as those found in Boneh-Durphee and Stehlé.
169 74 storres
170 83 storres
    Parameters
171 83 storres
    ----------
172 87 storres
    p: the (bivariate) polynomial;
173 87 storres
    pRing: the ring over which p is defined;
174 74 storres
    alpha:
175 74 storres
    N:
176 83 storres
    columsWidth: if == 0, no information is displayed, otherwise data is
177 83 storres
                 printed in colums of columnsWitdth width.
178 74 storres
    """
179 100 storres
    pRing = p.parent()
180 77 storres
    knownMonomials = []
181 77 storres
    protoMatrixRows = []
182 92 storres
    polynomialsList = []
183 74 storres
    pVariables = p.variables()
184 74 storres
    iVariable = pVariables[0]
185 76 storres
    tVariable = pVariables[1]
186 87 storres
    polynomialAtPower = pRing(1)
187 87 storres
    currentPolynomial = pRing(1)
188 74 storres
    pIdegree = p.degree(pVariables[0])
189 74 storres
    pTdegree = p.degree(pVariables[1])
190 87 storres
    currentIdegree = currentPolynomial.degree(iVariable)
191 105 storres
    nAtAlpha = N^alpha
192 105 storres
    nAtPower = nAtAlpha
193 92 storres
    polExpStr = ""
194 74 storres
    # We work from p^0 * N^alpha to p^alpha * N^0
195 74 storres
    for pPower in xrange(0, alpha + 1):
196 76 storres
        # pPower == 0 is a special case. We introduce all the monomials but one
197 78 storres
        # in i and those in t necessary to be able to introduce
198 76 storres
        # p. We arbitrary choose to introduce the highest degree monomial in i
199 76 storres
        # with p. We also introduce all the mixed i^k * t^l monomials with
200 77 storres
        # k < p.degree(i) and l <= p.degree(t).
201 78 storres
        # Mixed terms introduction is necessary here before we start "i shifts"
202 78 storres
        # in the next iteration.
203 74 storres
        if pPower == 0:
204 78 storres
            # Notice that i^pIdegree is excluded as the bound of the xrange is
205 78 storres
            # pIdegree
206 74 storres
            for iPower in xrange(0, pIdegree):
207 74 storres
                for tPower in xrange(0, pTdegree + 1):
208 77 storres
                    if columnsWidth != 0:
209 92 storres
                        polExpStr = spo_expression_as_string(iPower,
210 76 storres
                                                             tPower,
211 76 storres
                                                             pPower,
212 105 storres
                                                             alpha-pPower)
213 92 storres
                        print "->", polExpStr
214 74 storres
                    currentExpression = iVariable^iPower * \
215 91 storres
                                        tVariable^tPower * nAtAlpha
216 78 storres
                    # polynomialAtPower == 1 here. Next line should be commented
217 78 storres
                    # out but it does not work! Some conversion problem?
218 91 storres
                    currentPolynomial = pRing(currentExpression)
219 106 storres
                    polynomialsList.append(currentPolynomial)
220 74 storres
                    pMonomials = currentPolynomial.monomials()
221 74 storres
                    pCoefficients = currentPolynomial.coefficients()
222 83 storres
                    spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
223 83 storres
                                                            pCoefficients,
224 83 storres
                                                            knownMonomials,
225 83 storres
                                                            protoMatrixRows,
226 83 storres
                                                            columnsWidth)
227 78 storres
                # End tPower.
228 78 storres
            # End for iPower.
229 77 storres
        else: # pPower > 0: (p^1..p^alpha)
230 78 storres
            # This where we introduce the p^pPower * N^(alpha-pPower)
231 77 storres
            # polynomial.
232 77 storres
            # This step could technically be fused as the first iteration
233 77 storres
            # of the next loop (with iPower starting at 0).
234 77 storres
            # We set it apart for clarity.
235 77 storres
            if columnsWidth != 0:
236 105 storres
                polExpStr = spo_expression_as_string(0, 0, pPower, alpha-pPower)
237 92 storres
                print "->", polExpStr
238 77 storres
            currentPolynomial = polynomialAtPower * nAtPower
239 106 storres
            polynomialsList.append(currentPolynomial)
240 77 storres
            pMonomials = currentPolynomial.monomials()
241 77 storres
            pCoefficients = currentPolynomial.coefficients()
242 83 storres
            spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
243 83 storres
                                                    pCoefficients,
244 83 storres
                                                    knownMonomials,
245 83 storres
                                                    protoMatrixRows,
246 83 storres
                                                    columnsWidth)
247 77 storres
248 77 storres
            # The i^iPower * p^pPower polynomials: they add i^k monomials to
249 77 storres
            # p^pPower up to k < pIdegree * pPower. This only introduces i^k
250 77 storres
            # monomials since mixed terms (that were introduced at a previous
251 77 storres
            # stage) are only shifted to already existing
252 77 storres
            # ones. p^pPower is "shifted" to higher degrees in i as far as
253 77 storres
            # possible, one step short of the degree in i of p^(pPower+1) .
254 77 storres
            # These "pure" i^k monomials can only show up with i multiplications.
255 77 storres
            for iPower in xrange(1, pIdegree):
256 87 storres
                if columnsWidth != 0:
257 92 storres
                    polExpStr = spo_expression_as_string(iPower, \
258 87 storres
                                                         0,      \
259 87 storres
                                                         pPower, \
260 87 storres
                                                         alpha)
261 92 storres
                    print "->", polExpStr
262 77 storres
                currentExpression = i^iPower * nAtPower
263 87 storres
                currentPolynomial = pRing(currentExpression) * polynomialAtPower
264 106 storres
                polynomialsList.append(currentPolynomial)
265 77 storres
                pMonomials = currentPolynomial.monomials()
266 77 storres
                pCoefficients = currentPolynomial.coefficients()
267 87 storres
                spo_add_polynomial_coeffs_to_matrix_row(pMonomials,      \
268 87 storres
                                                        pCoefficients,   \
269 87 storres
                                                        knownMonomials,  \
270 87 storres
                                                        protoMatrixRows, \
271 83 storres
                                                        columnsWidth)
272 77 storres
            # End for iPower
273 77 storres
            # We want now to introduce a t * p^pPower polynomial. But before
274 77 storres
            # that we must introduce some mixed monomials.
275 77 storres
            # This loop is no triggered before pPower == 2.
276 78 storres
            # It introduces a first set of high i degree mixed monomials.
277 77 storres
            for iPower in xrange(1, pPower):
278 77 storres
                tPower = pPower - iPower + 1
279 77 storres
                if columnsWidth != 0:
280 92 storres
                    polExpStr = spo_expression_as_string(iPower * pIdegree,
281 77 storres
                                                         tPower,
282 77 storres
                                                         0,
283 77 storres
                                                         alpha)
284 92 storres
                    print "->", polExpStr
285 91 storres
                currentExpression = i^(iPower * pIdegree) * t^tPower * nAtAlpha
286 87 storres
                currentPolynomial = pRing(currentExpression)
287 106 storres
                polynomialsList.append(currentPolynomial)
288 77 storres
                pMonomials = currentPolynomial.monomials()
289 77 storres
                pCoefficients = currentPolynomial.coefficients()
290 83 storres
                spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
291 83 storres
                                                        pCoefficients,
292 83 storres
                                                        knownMonomials,
293 83 storres
                                                        protoMatrixRows,
294 83 storres
                                                        columnsWidth)
295 77 storres
            # End for iPower
296 78 storres
            #
297 78 storres
            # This is the mixed monomials main loop. It introduces:
298 77 storres
            # - the missing mixed monomials needed before the
299 78 storres
            #   t^l * p^pPower * N^(alpha-pPower) polynomial;
300 78 storres
            # - the t^l * p^pPower * N^(alpha-pPower) itself;
301 78 storres
            # - for each of i^k * t^l * p^pPower * N^(alpha-pPower) polynomials:
302 78 storres
            #   - the the missing mixed monomials needed  polynomials,
303 78 storres
            #   - the i^k * t^l * p^pPower * N^(alpha-pPower) itself.
304 78 storres
            # The t^l * p^pPower * N^(alpha-pPower) is introduced when
305 78 storres
            #
306 77 storres
            for iShift in xrange(0, pIdegree):
307 77 storres
                # When pTdegree == 1, the following loop only introduces
308 77 storres
                # a single new monomial.
309 77 storres
                #print "++++++++++"
310 77 storres
                for outerTpower in xrange(1, pTdegree + 1):
311 77 storres
                    # First one high i degree mixed monomial.
312 77 storres
                    iPower = iShift + pPower * pIdegree
313 77 storres
                    if columnsWidth != 0:
314 92 storres
                        polExpStr = spo_expression_as_string(iPower,
315 77 storres
                                                             outerTpower,
316 77 storres
                                                             0,
317 77 storres
                                                             alpha)
318 92 storres
                        print "->", polExpStr
319 91 storres
                    currentExpression = i^iPower * t^outerTpower * nAtAlpha
320 87 storres
                    currentPolynomial = pRing(currentExpression)
321 106 storres
                    polynomialsList.append(currentPolynomial)
322 77 storres
                    pMonomials = currentPolynomial.monomials()
323 77 storres
                    pCoefficients = currentPolynomial.coefficients()
324 83 storres
                    spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
325 83 storres
                                                            pCoefficients,
326 83 storres
                                                            knownMonomials,
327 83 storres
                                                            protoMatrixRows,
328 83 storres
                                                            columnsWidth)
329 77 storres
                    #print "+++++"
330 78 storres
                    # At iShift == 0, the following innerTpower loop adds
331 78 storres
                    # duplicate monomials, since no extra i^l * t^k is needed
332 78 storres
                    # before introducing the
333 77 storres
                    # i^iShift * t^outerPpower * p^pPower * N^(alpha-pPower)
334 77 storres
                    # polynomial.
335 77 storres
                    # It introduces smaller i degree monomials than the
336 77 storres
                    # one(s) added previously (no pPower multiplication).
337 77 storres
                    # Here the exponent of t decreases as that of i increases.
338 78 storres
                    # This conditional is not entered before pPower == 1.
339 78 storres
                    # The innerTpower loop does not produce anything before
340 78 storres
                    # pPower == 2. We keep it anyway for other configuration of
341 78 storres
                    # p.
342 77 storres
                    if iShift > 0:
343 77 storres
                        iPower = pIdegree + iShift
344 77 storres
                        for innerTpower in xrange(pPower, 1, -1):
345 77 storres
                            if columnsWidth != 0:
346 92 storres
                                polExpStr = spo_expression_as_string(iPower,
347 77 storres
                                                                     innerTpower,
348 77 storres
                                                                     0,
349 77 storres
                                                                     alpha)
350 77 storres
                            currentExpression = \
351 91 storres
                                    i^(iPower) * t^(innerTpower) * nAtAlpha
352 87 storres
                            currentPolynomial = pRing(currentExpression)
353 106 storres
                            polynomialsList.append(currentPolynomial)
354 77 storres
                            pMonomials = currentPolynomial.monomials()
355 77 storres
                            pCoefficients = currentPolynomial.coefficients()
356 83 storres
                            spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
357 77 storres
                                                                pCoefficients,
358 77 storres
                                                                knownMonomials,
359 77 storres
                                                                protoMatrixRows,
360 77 storres
                                                                columnsWidth)
361 77 storres
                            iPower += pIdegree
362 77 storres
                        # End for innerTpower
363 77 storres
                    # End of if iShift > 0
364 78 storres
                    # When iShift == 0, just after each of the
365 78 storres
                    # p^pPower * N^(alpha-pPower) polynomials has
366 78 storres
                    # been introduced (followed by a string of
367 78 storres
                    # i^k * p^pPower * N^(alpha-pPower) polynomials) a
368 78 storres
                    # t^l *  p^pPower * N^(alpha-pPower) is introduced here.
369 78 storres
                    #
370 77 storres
                    # Eventually, the following section introduces the
371 105 storres
                    # i^iShift * t^outerTpower * p^iPower * N^(alpha-pPower)
372 77 storres
                    # polynomials.
373 77 storres
                    if columnsWidth != 0:
374 92 storres
                        polExpStr = spo_expression_as_string(iShift,
375 77 storres
                                                             outerTpower,
376 77 storres
                                                             pPower,
377 105 storres
                                                             alpha-pPower)
378 92 storres
                        print "->", polExpStr
379 77 storres
                    currentExpression = i^iShift * t^outerTpower * nAtPower
380 105 storres
                    currentPolynomial = pRing(currentExpression) * \
381 105 storres
                                            polynomialAtPower
382 106 storres
                    polynomialsList.append(currentPolynomial)
383 77 storres
                    pMonomials = currentPolynomial.monomials()
384 77 storres
                    pCoefficients = currentPolynomial.coefficients()
385 83 storres
                    spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
386 83 storres
                                                            pCoefficients,
387 83 storres
                                                            knownMonomials,
388 83 storres
                                                            protoMatrixRows,
389 83 storres
                                                            columnsWidth)
390 77 storres
                # End for outerTpower
391 77 storres
                #print "++++++++++"
392 77 storres
            # End for iShift
393 77 storres
        polynomialAtPower *= p
394 77 storres
        nAtPower /= N
395 77 storres
    # End for pPower loop
396 92 storres
    return ((protoMatrixRows, knownMonomials, polynomialsList))
397 83 storres
# End spo_polynomial_to_proto_matrix
398 81 storres
399 106 storres
def spo_polynomial_to_polynomials_list_2(p, alpha, N, columnsWidth=0):
400 105 storres
    """
401 106 storres
    From p, alpha, N build a list of polynomials...
402 106 storres
    TODO: clean up the comments below!
403 106 storres
404 105 storres
    From a (bivariate) polynomial and some other parameters build a proto
405 105 storres
    matrix (an array of "rows") to be converted into a "true" matrix and
406 105 storres
    eventually by reduced by fpLLL.
407 105 storres
    The matrix is based on a list of polynomials that are built in a way
408 105 storres
    that one and only monomial is added at each new polynomial. Among the many
409 105 storres
    possible ways to build this list we pick one strongly dependent on the
410 105 storres
    structure of the polynomial and of the problem.
411 105 storres
    We consider here the polynomials of the form:
412 105 storres
    a_k*i^k + a_(k-1)*i^(k-1) + ... + a_1*i + a_0 - t
413 105 storres
    The values of i and t are bounded and we eventually look for (i_0,t_0)
414 105 storres
    pairs such that:
415 105 storres
    a_k*i_0^k + a_(k-1)*i_0^(k-1) + ... + a_1*i_0 + a_0 = t_0
416 105 storres
    Hence, departing from the procedure in described in Boneh-Durfee, we will
417 105 storres
    not use "t-shifts" but only "i-shifts".
418 105 storres
419 105 storres
    Parameters
420 105 storres
    ----------
421 105 storres
    p: the (bivariate) polynomial;
422 105 storres
    pRing: the ring over which p is defined;
423 105 storres
    alpha:
424 105 storres
    N:
425 105 storres
    columsWidth: if == 0, no information is displayed, otherwise data is
426 105 storres
                 printed in colums of columnsWitdth width.
427 105 storres
    """
428 105 storres
    pRing = p.parent()
429 105 storres
    polynomialsList = []
430 105 storres
    pVariables = p.variables()
431 105 storres
    iVariable = pVariables[0]
432 105 storres
    tVariable = pVariables[1]
433 105 storres
    polynomialAtPower = pRing(1)
434 105 storres
    currentPolynomial = pRing(1)
435 105 storres
    pIdegree = p.degree(iVariable)
436 105 storres
    pTdegree = p.degree(tVariable)
437 105 storres
    currentIdegree = currentPolynomial.degree(iVariable)
438 105 storres
    nAtAlpha = N^alpha
439 105 storres
    nAtPower = nAtAlpha
440 105 storres
    polExpStr = ""
441 105 storres
    # We work from p^0 * N^alpha to p^alpha * N^0
442 105 storres
    for pPower in xrange(0, alpha + 1):
443 105 storres
        # pPower == 0 is a special case. We introduce all the monomials in i
444 105 storres
        # up to i^pIdegree.
445 105 storres
        if pPower == 0:
446 105 storres
            # Notice who iPower runs up to i^pIdegree.
447 105 storres
            for iPower in xrange(0, pIdegree + 1):
448 105 storres
                # No t power is taken into account as we limit our selves to
449 105 storres
                # degree 1 in t and make no "t-shifts".
450 105 storres
                if columnsWidth != 0:
451 105 storres
                    polExpStr = spo_expression_as_string(iPower,
452 105 storres
                                                         0,
453 105 storres
                                                         0,
454 105 storres
                                                         alpha)
455 105 storres
                    print "->", polExpStr
456 105 storres
                currentExpression = iVariable^iPower * nAtAlpha
457 105 storres
                # polynomialAtPower == 1 here. Next line should be commented
458 105 storres
                # out but it does not work! Some conversion problem?
459 105 storres
                currentPolynomial = pRing(currentExpression)
460 105 storres
                polynomialsList.append(currentPolynomial)
461 105 storres
            # End for iPower.
462 105 storres
        else: # pPower > 0: (p^1..p^alpha)
463 105 storres
            # This where we introduce the p^pPower * N^(alpha-pPower)
464 105 storres
            # polynomial. This is also where the t^pPower monomials shows up for
465 105 storres
            # the first time.
466 105 storres
            if columnsWidth != 0:
467 105 storres
                polExpStr = spo_expression_as_string(0, 0, pPower, alpha-pPower)
468 105 storres
                print "->", polExpStr
469 105 storres
            currentPolynomial = polynomialAtPower * nAtPower
470 105 storres
            polynomialsList.append(currentPolynomial)
471 106 storres
            # Exit when pPower == alpha
472 106 storres
            if pPower == alpha:
473 106 storres
                return((knownMonomials, polynomialsList))
474 105 storres
            # This is where the "i-shifts" take place. Mixed terms, i^k * t^l
475 105 storres
            # (that were introduced at a previous
476 105 storres
            # stage or are introduced now) are only shifted to already existing
477 105 storres
            # ones with the notable exception of i^iPower * t^pPower, which
478 105 storres
            # must be manually introduced.
479 105 storres
            # p^pPower is "shifted" to higher degrees in i as far as
480 105 storres
            # possible, up to of the degree in i of p^(pPower+1).
481 105 storres
            # These "pure" i^k monomials can only show up with i multiplications.
482 105 storres
            for iPower in xrange(1, pIdegree + 1):
483 105 storres
                # The i^iPower * t^pPower monomial. Notice the alpha exponent
484 105 storres
                # for N.
485 105 storres
                internalIpower = iPower
486 105 storres
                for tPower in xrange(pPower,0,-1):
487 105 storres
                    if columnsWidth != 0:
488 105 storres
                        polExpStr = spo_expression_as_string(internalIpower, \
489 105 storres
                                                             tPower,  \
490 105 storres
                                                             0, \
491 105 storres
                                                             alpha)
492 105 storres
                        print "->", polExpStr
493 105 storres
                    currentExpression = i^internalIpower * t^tPower * nAtAlpha
494 105 storres
                    currentPolynomial = pRing(currentExpression)
495 105 storres
                    polynomialsList.append(currentPolynomial)
496 105 storres
                    internalIpower += pIdegree
497 105 storres
                # End for tPower
498 105 storres
                # The i^iPower * p^pPower * N^(alpha-pPower) i-shift.
499 105 storres
                if columnsWidth != 0:
500 105 storres
                    polExpStr = spo_expression_as_string(iPower, \
501 105 storres
                                                         0,      \
502 105 storres
                                                         pPower, \
503 105 storres
                                                         alpha-pPower)
504 105 storres
                    print "->", polExpStr
505 105 storres
                currentExpression = i^iPower * nAtPower
506 105 storres
                currentPolynomial = pRing(currentExpression) * polynomialAtPower
507 105 storres
                polynomialsList.append(currentPolynomial)
508 105 storres
            # End for iPower
509 105 storres
        polynomialAtPower *= p
510 105 storres
        nAtPower /= N
511 105 storres
    # End for pPower loop
512 109 storres
    return polynomialsList
513 105 storres
# End spo_polynomial_to_proto_matrix_2
514 105 storres
515 109 storres
def spo_polynomial_to_polynomials_list_3(p, alpha, N, iBound, tBound, \
516 109 storres
                                         columnsWidth=0):
517 108 storres
    """
518 108 storres
    From p, alpha, N build a list of polynomials...
519 108 storres
    TODO: more in depth rationale...
520 108 storres
521 108 storres
    Our goal is to introduce each monomial with the smallest coefficient.
522 108 storres
523 108 storres
524 108 storres
525 108 storres
    Parameters
526 108 storres
    ----------
527 108 storres
    p: the (bivariate) polynomial;
528 108 storres
    pRing: the ring over which p is defined;
529 108 storres
    alpha:
530 108 storres
    N:
531 108 storres
    columsWidth: if == 0, no information is displayed, otherwise data is
532 108 storres
                 printed in colums of columnsWitdth width.
533 108 storres
    """
534 108 storres
    pRing = p.parent()
535 108 storres
    knownMonomials = []
536 108 storres
    polynomialsList = []
537 108 storres
    pVariables = p.variables()
538 108 storres
    iVariable = pVariables[0]
539 108 storres
    tVariable = pVariables[1]
540 108 storres
    polynomialAtPower = pRing(1)
541 108 storres
    currentPolynomial = pRing(1)
542 108 storres
    pIdegree = p.degree(iVariable)
543 108 storres
    pTdegree = p.degree(tVariable)
544 108 storres
    currentIdegree = currentPolynomial.degree(iVariable)
545 108 storres
    nAtAlpha = N^alpha
546 108 storres
    nAtPower = nAtAlpha
547 108 storres
    polExpStr = ""
548 108 storres
    # We work from p^0 * N^alpha to p^alpha * N^0
549 108 storres
    for pPower in xrange(0, alpha + 1):
550 108 storres
        # pPower == 0 is a special case. We introduce all the monomials in i
551 108 storres
        # up to i^pIdegree.
552 108 storres
        if pPower == 0:
553 108 storres
            # Notice who iPower runs up to i^pIdegree.
554 108 storres
            for iPower in xrange(0, pIdegree + 1):
555 108 storres
                # No t power is taken into account as we limit our selves to
556 108 storres
                # degree 1 in t and make no "t-shifts".
557 108 storres
                if columnsWidth != 0:
558 108 storres
                    polExpStr = spo_expression_as_string(iPower,
559 108 storres
                                                         0,
560 108 storres
                                                         0,
561 108 storres
                                                         alpha)
562 108 storres
                    print "->", polExpStr
563 108 storres
                currentExpression = iVariable^iPower * nAtAlpha
564 108 storres
                # polynomialAtPower == 1 here. Next line should be commented
565 108 storres
                # out but it does not work! Some conversion problem?
566 108 storres
                currentPolynomial = pRing(currentExpression)
567 108 storres
                polynomialsList.append(currentPolynomial)
568 108 storres
            # End for iPower.
569 108 storres
        else: # pPower > 0: (p^1..p^alpha)
570 108 storres
            # This where we introduce the p^pPower * N^(alpha-pPower)
571 108 storres
            # polynomial. This is also where the t^pPower monomials shows up for
572 108 storres
            # the first time. It app
573 108 storres
            if columnsWidth != 0:
574 108 storres
                polExpStr = spo_expression_as_string(0, 0, pPower, alpha-pPower)
575 108 storres
                print "->", polExpStr
576 108 storres
            currentPolynomial = polynomialAtPower * nAtPower
577 108 storres
            polynomialsList.append(currentPolynomial)
578 108 storres
            # Exit when pPower == alpha
579 108 storres
            if pPower == alpha:
580 108 storres
                return((knownMonomials, polynomialsList))
581 108 storres
            # This is where the "i-shifts" take place. Mixed terms, i^k * t^l
582 108 storres
            # (that were introduced at a previous
583 108 storres
            # stage or are introduced now) are only shifted to already existing
584 108 storres
            # ones with the notable exception of i^iPower * t^pPower, which
585 108 storres
            # must be manually introduced.
586 108 storres
            # p^pPower is "shifted" to higher degrees in i as far as
587 108 storres
            # possible, up to of the degree in i of p^(pPower+1).
588 108 storres
            # These "pure" i^k monomials can only show up with i multiplications.
589 108 storres
            for iPower in xrange(1, pIdegree + 1):
590 108 storres
                # The i^iPower * t^pPower monomial. Notice the alpha exponent
591 108 storres
                # for N.
592 108 storres
                internalIpower = iPower
593 108 storres
                for tPower in xrange(pPower,0,-1):
594 108 storres
                    if columnsWidth != 0:
595 108 storres
                        polExpStr = spo_expression_as_string(internalIpower, \
596 108 storres
                                                             tPower,  \
597 108 storres
                                                             0, \
598 108 storres
                                                             alpha)
599 108 storres
                        print "->", polExpStr
600 108 storres
                    currentExpression = i^internalIpower * t^tPower * nAtAlpha
601 108 storres
                    currentPolynomial = pRing(currentExpression)
602 108 storres
                    polynomialsList.append(currentPolynomial)
603 108 storres
                    internalIpower += pIdegree
604 108 storres
                # End for tPower
605 109 storres
                # Here we have to choose between a
606 109 storres
                # i^iPower * p^pPower * N^(alpha-pPower) i-shift and
607 109 storres
                # i^iPower * i^(d_i(p) * pPower) * N^alpha, depend on which
608 109 storres
                # coefficient is smallest.
609 109 storres
                IcurrentExponent = iPower + \
610 109 storres
                                        (pPower * polynomialAtPower.degree(i))
611 109 storres
                currentMonomial = pRing(i^(IcurrentExponent))
612 109 storres
                currentPolynomial = pRing(i^iPower * nAtPower) * \
613 109 storres
                                                            polynomialAtPower
614 109 storres
                currMonomials = currentPolynomial.monomials()
615 109 storres
                currCoefficients = currentPolynomial.coefficients()
616 109 storres
                currentCoefficient = spo_get_coefficient_for_monomial( \
617 109 storres
                                                    currMonomials,
618 109 storres
                                                    currCoefficients,
619 109 storres
                                                    currentMonomial)
620 109 storres
                if currentCoefficient > nAtAlpha:
621 109 storres
                    if columnsWidth != 0:
622 109 storres
                        polExpStr = spo_expression_as_string(IcurrentCoefficient, \
623 109 storres
                                                             0,      \
624 109 storres
                                                             0, \
625 109 storres
                                                             alpha)
626 108 storres
                    print "->", polExpStr
627 109 storres
                    polynomialsList.append(currentMonomial * nAtAlpha)
628 109 storres
                else:
629 109 storres
                    if columnsWidth != 0:
630 109 storres
                        polExpStr = spo_expression_as_string(iPower, \
631 109 storres
                                                             0,      \
632 109 storres
                                                             pPower, \
633 109 storres
                                                             alpha-pPower)
634 109 storres
                    print "->", polExpStr
635 109 storres
                    polynomialsList.append(currentPolynomial)
636 108 storres
            # End for iPower
637 108 storres
        polynomialAtPower *= p
638 108 storres
        nAtPower /= N
639 108 storres
    # End for pPower loop
640 109 storres
    return polynomialsList
641 108 storres
# End spo_polynomial_to_proto_matrix_3
642 108 storres
643 90 storres
def spo_proto_to_column_matrix(protoMatrixColumns, \
644 90 storres
                               knownMonomialsList, \
645 90 storres
                               boundVar1, \
646 90 storres
                               boundVar2):
647 83 storres
    """
648 87 storres
    Create a column (each row holds the coefficients of one monomial) matrix.
649 83 storres
650 83 storres
    Parameters
651 83 storres
    ----------
652 87 storres
    protoMatrixColumns: a list of coefficient lists.
653 83 storres
    """
654 87 storres
    numColumns = len(protoMatrixColumns)
655 87 storres
    if numColumns == 0:
656 83 storres
        return None
657 87 storres
    # The last column holds has the maximum length.
658 87 storres
    numRows = len(protoMatrixColumns[numColumns-1])
659 83 storres
    if numColumns == 0:
660 83 storres
        return None
661 83 storres
    baseMatrix = matrix(ZZ, numRows, numColumns)
662 87 storres
    for colIndex in xrange(0, numColumns):
663 87 storres
        for rowIndex in xrange(0, len(protoMatrixColumns[colIndex])):
664 90 storres
            if protoMatrixColumns[colIndex][rowIndex] != 0:
665 90 storres
                baseMatrix[rowIndex, colIndex] = \
666 90 storres
                    protoMatrixColumns[colIndex][rowIndex] * \
667 90 storres
                    knownMonomialsList[rowIndex](boundVar1, boundVar2)
668 83 storres
    return baseMatrix
669 83 storres
# End spo_proto_to_column_matrix.
670 83 storres
#
671 88 storres
def spo_proto_to_row_matrix(protoMatrixRows, \
672 88 storres
                            knownMonomialsList, \
673 88 storres
                            boundVar1, \
674 88 storres
                            boundVar2):
675 83 storres
    """
676 90 storres
    Create a row (each column holds the evaluation one monomial at boundVar1 and
677 90 storres
    boundVar2 values) matrix.
678 83 storres
679 83 storres
    Parameters
680 83 storres
    ----------
681 83 storres
    protoMatrixRows: a list of coefficient lists.
682 83 storres
    """
683 83 storres
    numRows = len(protoMatrixRows)
684 83 storres
    if numRows == 0:
685 83 storres
        return None
686 91 storres
    # The last row is the longest one.
687 83 storres
    numColumns = len(protoMatrixRows[numRows-1])
688 83 storres
    if numColumns == 0:
689 83 storres
        return None
690 83 storres
    baseMatrix = matrix(ZZ, numRows, numColumns)
691 83 storres
    for rowIndex in xrange(0, numRows):
692 83 storres
        for colIndex in xrange(0, len(protoMatrixRows[rowIndex])):
693 89 storres
            if protoMatrixRows[rowIndex][colIndex] !=  0:
694 89 storres
                baseMatrix[rowIndex, colIndex] = \
695 89 storres
                    protoMatrixRows[rowIndex][colIndex] * \
696 89 storres
                    knownMonomialsList[colIndex](boundVar1,boundVar2)
697 89 storres
            #print rowIndex, colIndex,
698 89 storres
            #print protoMatrixRows[rowIndex][colIndex],
699 89 storres
            #print knownMonomialsList[colIndex](boundVar1,boundVar2)
700 83 storres
    return baseMatrix
701 83 storres
# End spo_proto_to_row_matrix.
702 83 storres
#
703 87 storres
print "\t...sagePolynomialOperations loaded"