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