Statistiques
| Révision :

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
        print
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.