Statistiques
| Révision :

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

Historique | Voir | Annoter | Télécharger (17,07 ko)

1 74 storres
load "/home/storres/recherche/arithmetique/pobysoPythonSage/src/sageSLZ/sageMatrixOperations.sage"
2 74 storres
3 80 storres
def spo_add_polynomial_coeffs_to_matrix(pMonomials,
4 80 storres
                                        pCoefficients,
5 80 storres
                                        knownMonomials,
6 80 storres
                                        protoMatrixRows,
7 80 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 80 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 80 storres
# End spo_add_polynomial_coeffs_to_matrix
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 77 storres
def spo_polynomial_to_matrix(p, pRing, alpha, N, columnsWidth=0):
111 74 storres
    """
112 74 storres
    From a (bivariate) polynomial and some other parameters build a matrix
113 74 storres
    to be reduced by fpLLL.
114 80 storres
    The matrix is such as those found in Boneh-Durphee and Stehl?.
115 74 storres
116 74 storres
    p: the (bivariate) polynomial
117 74 storres
    alpha:
118 74 storres
    N:
119 74 storres
120 74 storres
    """
121 77 storres
    knownMonomials = []
122 77 storres
    protoMatrixRows = []
123 74 storres
    pVariables = p.variables()
124 74 storres
    iVariable = pVariables[0]
125 76 storres
    tVariable = pVariables[1]
126 74 storres
    polynomialAtPower = P(1)
127 74 storres
    currentPolynomial = P(1)
128 74 storres
    pIdegree = p.degree(pVariables[0])
129 74 storres
    pTdegree = p.degree(pVariables[1])
130 74 storres
    currentIdegree = currentPolynomial.degree(i)
131 74 storres
    nAtPower = N^alpha
132 74 storres
    # We work from p^0 * N^alpha to p^alpha * N^0
133 74 storres
    for pPower in xrange(0, alpha + 1):
134 76 storres
        # pPower == 0 is a special case. We introduce all the monomials but one
135 78 storres
        # in i and those in t necessary to be able to introduce
136 76 storres
        # p. We arbitrary choose to introduce the highest degree monomial in i
137 76 storres
        # with p. We also introduce all the mixed i^k * t^l monomials with
138 77 storres
        # k < p.degree(i) and l <= p.degree(t).
139 78 storres
        # Mixed terms introduction is necessary here before we start "i shifts"
140 78 storres
        # in the next iteration.
141 74 storres
        if pPower == 0:
142 78 storres
            # Notice that i^pIdegree is excluded as the bound of the xrange is
143 78 storres
            # pIdegree
144 74 storres
            for iPower in xrange(0, pIdegree):
145 74 storres
                for tPower in xrange(0, pTdegree + 1):
146 77 storres
                    if columnsWidth != 0:
147 76 storres
                        print "->", spo_expression_as_string(iPower,
148 76 storres
                                                             tPower,
149 76 storres
                                                             pPower,
150 74 storres
                                                             alpha)
151 74 storres
                    currentExpression = iVariable^iPower * \
152 74 storres
                                        tVariable^tPower * nAtPower
153 78 storres
                    # polynomialAtPower == 1 here. Next line should be commented
154 78 storres
                    # out but it does not work! Some conversion problem?
155 74 storres
                    currentPolynomial = pRing(currentExpression) * \
156 74 storres
                                        polynomialAtPower
157 74 storres
                    pMonomials = currentPolynomial.monomials()
158 74 storres
                    pCoefficients = currentPolynomial.coefficients()
159 77 storres
                    spo_add_polynomial_coeffs_to_matrix(pMonomials,
160 77 storres
                                                        pCoefficients,
161 77 storres
                                                        knownMonomials,
162 77 storres
                                                        protoMatrixRows,
163 77 storres
                                                        columnsWidth)
164 78 storres
                # End tPower.
165 78 storres
            # End for iPower.
166 77 storres
        else: # pPower > 0: (p^1..p^alpha)
167 78 storres
            # This where we introduce the p^pPower * N^(alpha-pPower)
168 77 storres
            # polynomial.
169 77 storres
            # This step could technically be fused as the first iteration
170 77 storres
            # of the next loop (with iPower starting at 0).
171 77 storres
            # We set it apart for clarity.
172 77 storres
            if columnsWidth != 0:
173 77 storres
                print "->", spo_expression_as_string(0, 0, pPower, alpha)
174 77 storres
            currentPolynomial = polynomialAtPower * nAtPower
175 77 storres
            pMonomials = currentPolynomial.monomials()
176 77 storres
            pCoefficients = currentPolynomial.coefficients()
177 77 storres
            spo_add_polynomial_coeffs_to_matrix(pMonomials,
178 77 storres
                                                pCoefficients,
179 77 storres
                                                knownMonomials,
180 77 storres
                                                protoMatrixRows,
181 77 storres
                                                columnsWidth)
182 77 storres
183 77 storres
            # The i^iPower * p^pPower polynomials: they add i^k monomials to
184 77 storres
            # p^pPower up to k < pIdegree * pPower. This only introduces i^k
185 77 storres
            # monomials since mixed terms (that were introduced at a previous
186 77 storres
            # stage) are only shifted to already existing
187 77 storres
            # ones. p^pPower is "shifted" to higher degrees in i as far as
188 77 storres
            # possible, one step short of the degree in i of p^(pPower+1) .
189 77 storres
            # These "pure" i^k monomials can only show up with i multiplications.
190 77 storres
            for iPower in xrange(1, pIdegree):
191 77 storres
                print "->", spo_expression_as_string(iPower, 0, pPower, alpha)
192 77 storres
                currentExpression = i^iPower * nAtPower
193 77 storres
                currentPolynomial = P(currentExpression) * polynomialAtPower
194 77 storres
                pMonomials = currentPolynomial.monomials()
195 77 storres
                pCoefficients = currentPolynomial.coefficients()
196 77 storres
                spo_add_polynomial_coeffs_to_matrix(pMonomials,
197 77 storres
                                                    pCoefficients,
198 77 storres
                                                    knownMonomials,
199 77 storres
                                                    protoMatrixRows,
200 77 storres
                                                    columnsWidth)
201 77 storres
            # End for iPower
202 77 storres
            # We want now to introduce a t * p^pPower polynomial. But before
203 77 storres
            # that we must introduce some mixed monomials.
204 77 storres
            # This loop is no triggered before pPower == 2.
205 78 storres
            # It introduces a first set of high i degree mixed monomials.
206 77 storres
            for iPower in xrange(1, pPower):
207 77 storres
                tPower = pPower - iPower + 1
208 77 storres
                if columnsWidth != 0:
209 77 storres
                    print "->", spo_expression_as_string(iPower * pIdegree,
210 77 storres
                                                         tPower,
211 77 storres
                                                         0,
212 77 storres
                                                         alpha)
213 77 storres
                currentExpression = i^(iPower * pIdegree) * t^tPower * nAtPower
214 77 storres
                currentPolynomial = P(currentExpression)
215 77 storres
                pMonomials = currentPolynomial.monomials()
216 77 storres
                pCoefficients = currentPolynomial.coefficients()
217 77 storres
                spo_add_polynomial_coeffs_to_matrix(pMonomials,
218 77 storres
                                                    pCoefficients,
219 77 storres
                                                    knownMonomials,
220 77 storres
                                                    protoMatrixRows,
221 77 storres
                                                    columnsWidth)
222 77 storres
            # End for iPower
223 78 storres
            #
224 78 storres
            # This is the mixed monomials main loop. It introduces:
225 77 storres
            # - the missing mixed monomials needed before the
226 78 storres
            #   t^l * p^pPower * N^(alpha-pPower) polynomial;
227 78 storres
            # - the t^l * p^pPower * N^(alpha-pPower) itself;
228 78 storres
            # - for each of i^k * t^l * p^pPower * N^(alpha-pPower) polynomials:
229 78 storres
            #   - the the missing mixed monomials needed  polynomials,
230 78 storres
            #   - the i^k * t^l * p^pPower * N^(alpha-pPower) itself.
231 78 storres
            # The t^l * p^pPower * N^(alpha-pPower) is introduced when
232 78 storres
            #
233 77 storres
            for iShift in xrange(0, pIdegree):
234 77 storres
                # When pTdegree == 1, the following loop only introduces
235 77 storres
                # a single new monomial.
236 77 storres
                #print "++++++++++"
237 77 storres
                for outerTpower in xrange(1, pTdegree + 1):
238 77 storres
                    # First one high i degree mixed monomial.
239 77 storres
                    iPower = iShift + pPower * pIdegree
240 77 storres
                    if columnsWidth != 0:
241 77 storres
                        print "->", spo_expression_as_string(iPower,
242 77 storres
                                                             outerTpower,
243 77 storres
                                                             0,
244 77 storres
                                                             alpha)
245 77 storres
                    currentExpression = i^iPower * t^outerTpower * nAtPower
246 77 storres
                    currentPolynomial = P(currentExpression)
247 77 storres
                    pMonomials = currentPolynomial.monomials()
248 77 storres
                    pCoefficients = currentPolynomial.coefficients()
249 77 storres
                    spo_add_polynomial_coeffs_to_matrix(pMonomials,
250 77 storres
                                                        pCoefficients,
251 77 storres
                                                        knownMonomials,
252 77 storres
                                                        protoMatrixRows,
253 77 storres
                                                        columnsWidth)
254 77 storres
                    #print "+++++"
255 78 storres
                    # At iShift == 0, the following innerTpower loop adds
256 78 storres
                    # duplicate monomials, since no extra i^l * t^k is needed
257 78 storres
                    # before introducing the
258 77 storres
                    # i^iShift * t^outerPpower * p^pPower * N^(alpha-pPower)
259 77 storres
                    # polynomial.
260 77 storres
                    # It introduces smaller i degree monomials than the
261 77 storres
                    # one(s) added previously (no pPower multiplication).
262 77 storres
                    # Here the exponent of t decreases as that of i increases.
263 78 storres
                    # This conditional is not entered before pPower == 1.
264 78 storres
                    # The innerTpower loop does not produce anything before
265 78 storres
                    # pPower == 2. We keep it anyway for other configuration of
266 78 storres
                    # p.
267 77 storres
                    if iShift > 0:
268 77 storres
                        iPower = pIdegree + iShift
269 77 storres
                        for innerTpower in xrange(pPower, 1, -1):
270 77 storres
                            if columnsWidth != 0:
271 77 storres
                                print "->", spo_expression_as_string(iPower,
272 77 storres
                                                                     innerTpower,
273 77 storres
                                                                     0,
274 77 storres
                                                                     alpha)
275 77 storres
                            currentExpression = \
276 77 storres
                                    i^(iPower) * t^(innerTpower) * nAtPower
277 77 storres
                            currentPolynomial = P(currentExpression)
278 77 storres
                            pMonomials = currentPolynomial.monomials()
279 77 storres
                            pCoefficients = currentPolynomial.coefficients()
280 77 storres
                            spo_add_polynomial_coeffs_to_matrix(pMonomials,
281 77 storres
                                                                pCoefficients,
282 77 storres
                                                                knownMonomials,
283 77 storres
                                                                protoMatrixRows,
284 77 storres
                                                                columnsWidth)
285 77 storres
                            iPower += pIdegree
286 77 storres
                        # End for innerTpower
287 77 storres
                    # End of if iShift > 0
288 78 storres
                    # When iShift == 0, just after each of the
289 78 storres
                    # p^pPower * N^(alpha-pPower) polynomials has
290 78 storres
                    # been introduced (followed by a string of
291 78 storres
                    # i^k * p^pPower * N^(alpha-pPower) polynomials) a
292 78 storres
                    # t^l *  p^pPower * N^(alpha-pPower) is introduced here.
293 78 storres
                    #
294 77 storres
                    # Eventually, the following section introduces the
295 77 storres
                    # i^iShift * t^outerTpower * p^iPower * N^(alpha-iPower)
296 77 storres
                    # polynomials.
297 77 storres
                    if columnsWidth != 0:
298 77 storres
                        print "->", spo_expression_as_string(iShift,
299 77 storres
                                                             outerTpower,
300 77 storres
                                                             pPower,
301 77 storres
                                                             alpha)
302 77 storres
                    currentExpression = i^iShift * t^outerTpower * nAtPower
303 77 storres
                    currentPolynomial = P(currentExpression) * polynomialAtPower
304 77 storres
                    pMonomials = currentPolynomial.monomials()
305 77 storres
                    pCoefficients = currentPolynomial.coefficients()
306 77 storres
                    spo_add_polynomial_coeffs_to_matrix(pMonomials,
307 77 storres
                                                        pCoefficients,
308 77 storres
                                                        knownMonomials,
309 77 storres
                                                        protoMatrixRows,
310 77 storres
                                                        columnsWidth)
311 77 storres
                # End for outerTpower
312 77 storres
                #print "++++++++++"
313 77 storres
            # End for iShift
314 77 storres
        polynomialAtPower *= p
315 77 storres
        nAtPower /= N
316 77 storres
    # End for pPower loop
317 77 storres
    return protoMatrixRows
318 74 storres
# End spo_polynomial_to_matrix