Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (19,58 ko)

1 74 storres
load "/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageMatrixOperations.sage"
2 74 storres
3 83 storres
def spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
4 83 storres
                                            pCoefficients,
5 83 storres
                                            knownMonomials,
6 83 storres
                                            protoMatrixRows,
7 83 storres
                                            columnsWidth=0):
8 80 storres
    """
9 80 storres
    For a given polynomial (under the form of monomials and coefficents lists),
10 80 storres
    add the coefficients of the protoMatrix (a list of proto matrix rows).
11 80 storres
    Coefficients are added to the protoMatrix row in the order imposed by the
12 80 storres
    monomials discovery list (the knownMonomials list) built as construction
13 80 storres
    goes on.
14 83 storres
    As a bonus, data can be printed out for a visual check.
15 80 storres
    pMonomials     : the list of the monomials coming form some polynomial;
16 80 storres
    pCoefficients  : the list of the corresponding coefficients to add to
17 80 storres
                     the protoMatrix in the exact same order as the monomials;
18 80 storres
    knownMonomials : the list of the already knonw monomials;
19 80 storres
    protoMatrixRows: a list of lists, each one holding the coefficients of the
20 80 storres
                     monomials
21 80 storres
    columnWith     : the width, in characters, of the displayed column ; if 0,
22 80 storres
                     do not display anything.
23 80 storres
    """
24 80 storres
    # We have started with the smaller degrees in the first variable.
25 80 storres
    pMonomials.reverse()
26 80 storres
    pCoefficients.reverse()
27 80 storres
    # New empty proto matrix row.
28 80 storres
    protoMatrixRowCoefficients = []
29 80 storres
    # We work according to the order of the already known monomials
30 80 storres
    # No known monomials yet: add the pMonomials to knownMonomials
31 80 storres
    # and add the coefficients to the proto matrix row.
32 80 storres
    if len(knownMonomials) == 0:
33 80 storres
        for pmIdx in xrange(0, len(pMonomials)):
34 80 storres
            knownMonomials.append(pMonomials[pmIdx])
35 80 storres
            protoMatrixRowCoefficients.append(pCoefficients[pmIdx])
36 80 storres
            if columnsWidth != 0:
37 80 storres
                monomialAsString = str(pCoefficients[pmIdx]) + " " + \
38 80 storres
                                   str(pMonomials[pmIdx])
39 80 storres
                print monomialAsString, " " * \
40 80 storres
                      (columnsWidth - len(monomialAsString)),
41 80 storres
    # There are some known monomials. We search for them in pMonomials and
42 80 storres
    # add their coefficients to the proto matrix row.
43 80 storres
    else:
44 80 storres
        for knownMonomialIndex in xrange(0,len(knownMonomials)):
45 80 storres
            # We lazily use an exception here since pMonomials.index() function
46 80 storres
            # may fail throwing the ValueError exception.
47 80 storres
            try:
48 80 storres
                indexInPmonomials = \
49 80 storres
                    pMonomials.index(knownMonomials[knownMonomialIndex])
50 80 storres
                if columnsWidth != 0:
51 80 storres
                    monomialAsString = str(pCoefficients[indexInPmonomials]) + \
52 80 storres
                        " " + str(knownMonomials[knownMonomialIndex])
53 80 storres
                    print monomialAsString, " " * \
54 80 storres
                        (columnsWidth - len(monomialAsString)),
55 80 storres
                # Add the coefficient to the proto matrix row and delete the \
56 80 storres
                # known monomial from the current pMonomial list
57 80 storres
                #(and the corresponding coefficient as well).
58 80 storres
                protoMatrixRowCoefficients.append(pCoefficients[indexInPmonomials])
59 80 storres
                del pMonomials[indexInPmonomials]
60 80 storres
                del pCoefficients[indexInPmonomials]
61 80 storres
            # The knownMonomials element is not in pMonomials
62 80 storres
            except ValueError:
63 80 storres
                protoMatrixRowCoefficients.append(0)
64 80 storres
                if columnsWidth != 0:
65 80 storres
                    monomialAsString = "0" + " "+ \
66 80 storres
                        str(knownMonomials[knownMonomialIndex])
67 80 storres
                    print monomialAsString, " " * \
68 80 storres
                        (columnsWidth - len(monomialAsString)),
69 80 storres
        # End for knownMonomialKey loop.
70 80 storres
        # We now append the remaining monomials of pMonomials to knownMonomials
71 80 storres
        # and the corresponding coefficients to proto matrix row.
72 80 storres
        for pmIdx in xrange(0, len(pMonomials)):
73 80 storres
            knownMonomials.append(pMonomials[pmIdx])
74 80 storres
            protoMatrixRowCoefficients.append(pCoefficients[pmIdx])
75 80 storres
            if columnsWidth != 0:
76 80 storres
                monomialAsString = str(pCoefficients[pmIdx]) + " " \
77 80 storres
                    + str(pMonomials[pmIdx])
78 80 storres
                print monomialAsString, " " * \
79 80 storres
                    (columnsWidth - len(monomialAsString)),
80 80 storres
        # End for pmIdx loop.
81 80 storres
    # Add the new list row elements to the proto matrix.
82 80 storres
    protoMatrixRows.append(protoMatrixRowCoefficients)
83 80 storres
    if columnsWidth != 0:
84 80 storres
        print
85 83 storres
# End spo_add_polynomial_coeffs_to_matrix_row
86 80 storres
87 80 storres
def spo_expression_as_string(powI, powT, powP, alpha):
88 80 storres
    """
89 80 storres
    Computes a string version of the i^k + t^l + p^m + N^n expression for
90 80 storres
    output.
91 80 storres
    """
92 80 storres
    expressionAsString =""
93 80 storres
    if powI != 0:
94 80 storres
        expressionAsString += "i^" + str(powI)
95 80 storres
    if powT != 0:
96 80 storres
        if len(expressionAsString) != 0:
97 80 storres
            expressionAsString += " * "
98 80 storres
        expressionAsString += "t^" + str(powT)
99 80 storres
    if powP != 0:
100 80 storres
        if len(expressionAsString) != 0:
101 80 storres
            expressionAsString += " * "
102 80 storres
        expressionAsString += "p^" + str(powP)
103 80 storres
    if (alpha - powP) != 0 :
104 80 storres
        if len(expressionAsString) != 0:
105 80 storres
            expressionAsString += " * "
106 80 storres
        expressionAsString += "N^" + str(alpha - powP)
107 80 storres
    return(expressionAsString)
108 80 storres
# End spo_expression_as_string.
109 80 storres
110 81 storres
def spo_norm(poly, degree):
111 81 storres
    """
112 81 storres
    Behaves more or less (no infinity defined) as the norm for the
113 81 storres
    univariate polynomials.
114 81 storres
    Quoting the Sage documentation:
115 81 storres
    Definition: For integer p, the p-norm of a polynomial is the pth root of
116 81 storres
    the sum of the pth powers of the absolute values of the coefficients of
117 81 storres
    the polynomial.
118 81 storres
    """
119 81 storres
    # TODO: check the arguments.
120 81 storres
    norm = 0
121 81 storres
    for coefficient in poly.coefficients():
122 81 storres
        norm +=  (coefficient^degree).abs()
123 81 storres
    return pow(norm, 1/degree)
124 81 storres
# end spo_norm
125 81 storres
126 83 storres
def spo_polynomial_to_proto_matrix(p, pRing, alpha, N, columnsWidth=0):
127 74 storres
    """
128 83 storres
    From a (bivariate) polynomial and some other parameters build a proto
129 83 storres
    matrix (an array of rows) to be converted into a "true" matrix and
130 83 storres
    eventually by reduced by fpLLL.
131 80 storres
    The matrix is such as those found in Boneh-Durphee and Stehl?.
132 74 storres
133 83 storres
    Parameters
134 83 storres
    ----------
135 74 storres
    p: the (bivariate) polynomial
136 83 storres
    pRing:
137 74 storres
    alpha:
138 74 storres
    N:
139 83 storres
    columsWidth: if == 0, no information is displayed, otherwise data is
140 83 storres
                 printed in colums of columnsWitdth width.
141 74 storres
    """
142 77 storres
    knownMonomials = []
143 77 storres
    protoMatrixRows = []
144 74 storres
    pVariables = p.variables()
145 74 storres
    iVariable = pVariables[0]
146 76 storres
    tVariable = pVariables[1]
147 74 storres
    polynomialAtPower = P(1)
148 74 storres
    currentPolynomial = P(1)
149 74 storres
    pIdegree = p.degree(pVariables[0])
150 74 storres
    pTdegree = p.degree(pVariables[1])
151 74 storres
    currentIdegree = currentPolynomial.degree(i)
152 74 storres
    nAtPower = N^alpha
153 74 storres
    # We work from p^0 * N^alpha to p^alpha * N^0
154 74 storres
    for pPower in xrange(0, alpha + 1):
155 76 storres
        # pPower == 0 is a special case. We introduce all the monomials but one
156 78 storres
        # in i and those in t necessary to be able to introduce
157 76 storres
        # p. We arbitrary choose to introduce the highest degree monomial in i
158 76 storres
        # with p. We also introduce all the mixed i^k * t^l monomials with
159 77 storres
        # k < p.degree(i) and l <= p.degree(t).
160 78 storres
        # Mixed terms introduction is necessary here before we start "i shifts"
161 78 storres
        # in the next iteration.
162 74 storres
        if pPower == 0:
163 78 storres
            # Notice that i^pIdegree is excluded as the bound of the xrange is
164 78 storres
            # pIdegree
165 74 storres
            for iPower in xrange(0, pIdegree):
166 74 storres
                for tPower in xrange(0, pTdegree + 1):
167 77 storres
                    if columnsWidth != 0:
168 76 storres
                        print "->", spo_expression_as_string(iPower,
169 76 storres
                                                             tPower,
170 76 storres
                                                             pPower,
171 74 storres
                                                             alpha)
172 74 storres
                    currentExpression = iVariable^iPower * \
173 74 storres
                                        tVariable^tPower * nAtPower
174 78 storres
                    # polynomialAtPower == 1 here. Next line should be commented
175 78 storres
                    # out but it does not work! Some conversion problem?
176 74 storres
                    currentPolynomial = pRing(currentExpression) * \
177 74 storres
                                        polynomialAtPower
178 74 storres
                    pMonomials = currentPolynomial.monomials()
179 74 storres
                    pCoefficients = currentPolynomial.coefficients()
180 83 storres
                    spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
181 83 storres
                                                            pCoefficients,
182 83 storres
                                                            knownMonomials,
183 83 storres
                                                            protoMatrixRows,
184 83 storres
                                                            columnsWidth)
185 78 storres
                # End tPower.
186 78 storres
            # End for iPower.
187 77 storres
        else: # pPower > 0: (p^1..p^alpha)
188 78 storres
            # This where we introduce the p^pPower * N^(alpha-pPower)
189 77 storres
            # polynomial.
190 77 storres
            # This step could technically be fused as the first iteration
191 77 storres
            # of the next loop (with iPower starting at 0).
192 77 storres
            # We set it apart for clarity.
193 77 storres
            if columnsWidth != 0:
194 77 storres
                print "->", spo_expression_as_string(0, 0, pPower, alpha)
195 77 storres
            currentPolynomial = polynomialAtPower * nAtPower
196 77 storres
            pMonomials = currentPolynomial.monomials()
197 77 storres
            pCoefficients = currentPolynomial.coefficients()
198 83 storres
            spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
199 83 storres
                                                    pCoefficients,
200 83 storres
                                                    knownMonomials,
201 83 storres
                                                    protoMatrixRows,
202 83 storres
                                                    columnsWidth)
203 77 storres
204 77 storres
            # The i^iPower * p^pPower polynomials: they add i^k monomials to
205 77 storres
            # p^pPower up to k < pIdegree * pPower. This only introduces i^k
206 77 storres
            # monomials since mixed terms (that were introduced at a previous
207 77 storres
            # stage) are only shifted to already existing
208 77 storres
            # ones. p^pPower is "shifted" to higher degrees in i as far as
209 77 storres
            # possible, one step short of the degree in i of p^(pPower+1) .
210 77 storres
            # These "pure" i^k monomials can only show up with i multiplications.
211 77 storres
            for iPower in xrange(1, pIdegree):
212 77 storres
                print "->", spo_expression_as_string(iPower, 0, pPower, alpha)
213 77 storres
                currentExpression = i^iPower * nAtPower
214 77 storres
                currentPolynomial = P(currentExpression) * polynomialAtPower
215 77 storres
                pMonomials = currentPolynomial.monomials()
216 77 storres
                pCoefficients = currentPolynomial.coefficients()
217 83 storres
                spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
218 83 storres
                                                        pCoefficients,
219 83 storres
                                                        knownMonomials,
220 83 storres
                                                        protoMatrixRows,
221 83 storres
                                                        columnsWidth)
222 77 storres
            # End for iPower
223 77 storres
            # We want now to introduce a t * p^pPower polynomial. But before
224 77 storres
            # that we must introduce some mixed monomials.
225 77 storres
            # This loop is no triggered before pPower == 2.
226 78 storres
            # It introduces a first set of high i degree mixed monomials.
227 77 storres
            for iPower in xrange(1, pPower):
228 77 storres
                tPower = pPower - iPower + 1
229 77 storres
                if columnsWidth != 0:
230 77 storres
                    print "->", spo_expression_as_string(iPower * pIdegree,
231 77 storres
                                                         tPower,
232 77 storres
                                                         0,
233 77 storres
                                                         alpha)
234 77 storres
                currentExpression = i^(iPower * pIdegree) * t^tPower * nAtPower
235 77 storres
                currentPolynomial = P(currentExpression)
236 77 storres
                pMonomials = currentPolynomial.monomials()
237 77 storres
                pCoefficients = currentPolynomial.coefficients()
238 83 storres
                spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
239 83 storres
                                                        pCoefficients,
240 83 storres
                                                        knownMonomials,
241 83 storres
                                                        protoMatrixRows,
242 83 storres
                                                        columnsWidth)
243 77 storres
            # End for iPower
244 78 storres
            #
245 78 storres
            # This is the mixed monomials main loop. It introduces:
246 77 storres
            # - the missing mixed monomials needed before the
247 78 storres
            #   t^l * p^pPower * N^(alpha-pPower) polynomial;
248 78 storres
            # - the t^l * p^pPower * N^(alpha-pPower) itself;
249 78 storres
            # - for each of i^k * t^l * p^pPower * N^(alpha-pPower) polynomials:
250 78 storres
            #   - the the missing mixed monomials needed  polynomials,
251 78 storres
            #   - the i^k * t^l * p^pPower * N^(alpha-pPower) itself.
252 78 storres
            # The t^l * p^pPower * N^(alpha-pPower) is introduced when
253 78 storres
            #
254 77 storres
            for iShift in xrange(0, pIdegree):
255 77 storres
                # When pTdegree == 1, the following loop only introduces
256 77 storres
                # a single new monomial.
257 77 storres
                #print "++++++++++"
258 77 storres
                for outerTpower in xrange(1, pTdegree + 1):
259 77 storres
                    # First one high i degree mixed monomial.
260 77 storres
                    iPower = iShift + pPower * pIdegree
261 77 storres
                    if columnsWidth != 0:
262 77 storres
                        print "->", spo_expression_as_string(iPower,
263 77 storres
                                                             outerTpower,
264 77 storres
                                                             0,
265 77 storres
                                                             alpha)
266 77 storres
                    currentExpression = i^iPower * t^outerTpower * nAtPower
267 77 storres
                    currentPolynomial = P(currentExpression)
268 77 storres
                    pMonomials = currentPolynomial.monomials()
269 77 storres
                    pCoefficients = currentPolynomial.coefficients()
270 83 storres
                    spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
271 83 storres
                                                            pCoefficients,
272 83 storres
                                                            knownMonomials,
273 83 storres
                                                            protoMatrixRows,
274 83 storres
                                                            columnsWidth)
275 77 storres
                    #print "+++++"
276 78 storres
                    # At iShift == 0, the following innerTpower loop adds
277 78 storres
                    # duplicate monomials, since no extra i^l * t^k is needed
278 78 storres
                    # before introducing the
279 77 storres
                    # i^iShift * t^outerPpower * p^pPower * N^(alpha-pPower)
280 77 storres
                    # polynomial.
281 77 storres
                    # It introduces smaller i degree monomials than the
282 77 storres
                    # one(s) added previously (no pPower multiplication).
283 77 storres
                    # Here the exponent of t decreases as that of i increases.
284 78 storres
                    # This conditional is not entered before pPower == 1.
285 78 storres
                    # The innerTpower loop does not produce anything before
286 78 storres
                    # pPower == 2. We keep it anyway for other configuration of
287 78 storres
                    # p.
288 77 storres
                    if iShift > 0:
289 77 storres
                        iPower = pIdegree + iShift
290 77 storres
                        for innerTpower in xrange(pPower, 1, -1):
291 77 storres
                            if columnsWidth != 0:
292 77 storres
                                print "->", spo_expression_as_string(iPower,
293 77 storres
                                                                     innerTpower,
294 77 storres
                                                                     0,
295 77 storres
                                                                     alpha)
296 77 storres
                            currentExpression = \
297 77 storres
                                    i^(iPower) * t^(innerTpower) * nAtPower
298 77 storres
                            currentPolynomial = P(currentExpression)
299 77 storres
                            pMonomials = currentPolynomial.monomials()
300 77 storres
                            pCoefficients = currentPolynomial.coefficients()
301 83 storres
                            spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
302 77 storres
                                                                pCoefficients,
303 77 storres
                                                                knownMonomials,
304 77 storres
                                                                protoMatrixRows,
305 77 storres
                                                                columnsWidth)
306 77 storres
                            iPower += pIdegree
307 77 storres
                        # End for innerTpower
308 77 storres
                    # End of if iShift > 0
309 78 storres
                    # When iShift == 0, just after each of the
310 78 storres
                    # p^pPower * N^(alpha-pPower) polynomials has
311 78 storres
                    # been introduced (followed by a string of
312 78 storres
                    # i^k * p^pPower * N^(alpha-pPower) polynomials) a
313 78 storres
                    # t^l *  p^pPower * N^(alpha-pPower) is introduced here.
314 78 storres
                    #
315 77 storres
                    # Eventually, the following section introduces the
316 77 storres
                    # i^iShift * t^outerTpower * p^iPower * N^(alpha-iPower)
317 77 storres
                    # polynomials.
318 77 storres
                    if columnsWidth != 0:
319 77 storres
                        print "->", spo_expression_as_string(iShift,
320 77 storres
                                                             outerTpower,
321 77 storres
                                                             pPower,
322 77 storres
                                                             alpha)
323 77 storres
                    currentExpression = i^iShift * t^outerTpower * nAtPower
324 77 storres
                    currentPolynomial = P(currentExpression) * polynomialAtPower
325 77 storres
                    pMonomials = currentPolynomial.monomials()
326 77 storres
                    pCoefficients = currentPolynomial.coefficients()
327 83 storres
                    spo_add_polynomial_coeffs_to_matrix_row(pMonomials,
328 83 storres
                                                            pCoefficients,
329 83 storres
                                                            knownMonomials,
330 83 storres
                                                            protoMatrixRows,
331 83 storres
                                                            columnsWidth)
332 77 storres
                # End for outerTpower
333 77 storres
                #print "++++++++++"
334 77 storres
            # End for iShift
335 77 storres
        polynomialAtPower *= p
336 77 storres
        nAtPower /= N
337 77 storres
    # End for pPower loop
338 77 storres
    return protoMatrixRows
339 83 storres
# End spo_polynomial_to_proto_matrix
340 81 storres
341 83 storres
def spo_proto_to_column_matrix(protoMatrixRows):
342 83 storres
    """
343 83 storres
    Create a row (each column holds the coefficients of one polynomial) matrix.
344 83 storres
    protoMatrixRows.
345 83 storres
346 83 storres
    Parameters
347 83 storres
    ----------
348 83 storres
    protoMatrixRows: a list of coefficient lists.
349 83 storres
    """
350 83 storres
    numRows = len(protoMatrixRows)
351 83 storres
    if numRows == 0:
352 83 storres
        return None
353 83 storres
    numColumns = len(protoMatrixRows[numRows-1])
354 83 storres
    if numColumns == 0:
355 83 storres
        return None
356 83 storres
    baseMatrix = matrix(ZZ, numRows, numColumns)
357 83 storres
    for rowIndex in xrange(0, numRows):
358 83 storres
        if monomialLengthChars != 0:
359 83 storres
            print protoMatrixRows[rowIndex]
360 83 storres
        for colIndex in xrange(0, len(protoMatrixRows[rowIndex])):
361 83 storres
            baseMatrix[colIndex, rowIndex] = protoMatrixRows[rowIndex][colIndex]
362 83 storres
    return baseMatrix
363 83 storres
# End spo_proto_to_column_matrix.
364 83 storres
#
365 83 storres
def spo_proto_to_row_matrix(protoMatrixRows):
366 83 storres
    """
367 83 storres
    Create a row (each row holds the coefficients of one polynomial) matrix.
368 83 storres
    protoMatrixRows.
369 83 storres
370 83 storres
    Parameters
371 83 storres
    ----------
372 83 storres
    protoMatrixRows: a list of coefficient lists.
373 83 storres
    """
374 83 storres
    numRows = len(protoMatrixRows)
375 83 storres
    if numRows == 0:
376 83 storres
        return None
377 83 storres
    numColumns = len(protoMatrixRows[numRows-1])
378 83 storres
    if numColumns == 0:
379 83 storres
        return None
380 83 storres
    baseMatrix = matrix(ZZ, numRows, numColumns)
381 83 storres
    for rowIndex in xrange(0, numRows):
382 83 storres
        if monomialLengthChars != 0:
383 83 storres
            print protoMatrixRows[rowIndex]
384 83 storres
        for colIndex in xrange(0, len(protoMatrixRows[rowIndex])):
385 83 storres
            baseMatrix[rowIndex, colIndex] = protoMatrixRows[rowIndex][colIndex]
386 83 storres
    return baseMatrix
387 83 storres
# End spo_proto_to_row_matrix.
388 83 storres
#
389 81 storres
print "sagePolynomialOperations loaded..."