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