Statistiques
| Révision :

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

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