2246 | | - ``l`` - a list of integers `(x_i)` such that `0 \leq x_i < d_i` and |
2247 | | `x = \prod_i g_i^{x_i}` in `(R/I)^*`, where `I` = self, `R` = ring of |
2248 | | integers of the field, and `g_i` are the generators of `(R/I)^*`, of |
2249 | | orders `d_i` respectively, as given in the ``bid`` structure of |
2250 | | the ideal self. |
2251 | | |
| 2252 | - ``l`` - a list of non-negative integers `(x_i)` such that `x = |
| 2253 | \prod_i g_i^{x_i}` in `(R/I)^*`, where `x_i` are the generators, and |
| 2254 | the list `(x_i)` is lexicographically minimal with respect to this |
| 2255 | requirement. If the `x_i` generate independent cyclic factors of |
| 2256 | order `d_i`, as is the case for the default generators calculated by |
| 2257 | :meth:`~idealstar`, this just means that `0 \le x_i < d_i`. |
| 2258 | |
| 2259 | A ``ValueError`` will be raised if the elements specified in ``gens`` |
| 2260 | do not in fact generate the unit group (even if the element `x` is in |
| 2261 | the subgroup they generate). |
| 2262 | |
2264 | | ALGORITHM: Uses Pari function ``ideallog`` |
| 2275 | Examples with custom generators:: |
| 2276 | |
| 2277 | sage: K.<a> = NumberField(x^2 - 7) |
| 2278 | sage: I = K.ideal(17) |
| 2279 | sage: I.ideallog(a + 7, [1+a, 2]) |
| 2280 | [10, 3] |
| 2281 | sage: I.ideallog(a + 7, [2, 1+a]) |
| 2282 | [0, 118] |
| 2283 | |
| 2284 | sage: L.<b> = NumberField(x^4 - x^3 - 7*x^2 + 3*x + 2) |
| 2285 | sage: J = L.ideal(-b^3 - b^2 - 2) |
| 2286 | sage: u = -14*b^3 + 21*b^2 + b - 1 |
| 2287 | sage: v = 4*b^2 + 2*b - 1 |
| 2288 | sage: J.ideallog(5+2*b, [u, v], check=True) |
| 2289 | [4, 13] |
| 2290 | |
| 2291 | A non-example:: |
| 2292 | |
| 2293 | sage: I.ideallog(a + 7, [2]) |
| 2294 | Traceback (most recent call last): |
| 2295 | ... |
| 2296 | ValueError: Given elements do not generate unit group -- they generate a subgroup of index 36 |
| 2297 | |
| 2298 | ALGORITHM: Uses Pari function ``ideallog``, and (if ``gens`` is not |
| 2299 | None) a Hermite normal form calculation to express the result in terms |
| 2300 | of the generators ``gens``. |
2273 | | return map(ZZ, k.pari_nf().ideallog(x._pari_(), self._pari_bid_(2))) |
| 2313 | L = map(ZZ, k.pari_nf().ideallog(x._pari_(), self._pari_bid_(2))) |
| 2314 | |
| 2315 | if gens is None: |
| 2316 | return L |
| 2317 | |
| 2318 | # otherwise translate answer in terms of given gens |
| 2319 | G = self.idealstar(2) |
| 2320 | invs = G.invariants() |
| 2321 | g = G.gens() |
| 2322 | n = G.ngens() |
| 2323 | |
| 2324 | from sage.matrix.all import matrix, identity_matrix, zero_matrix, diagonal_matrix, block_matrix |
| 2325 | |
| 2326 | # We use Hermite normal form twice: once to express the standard |
| 2327 | # generators in terms of the new ones (independently of x) and once to |
| 2328 | # reduce the resulting logarithm of x so it is lexicographically |
| 2329 | # minimal. |
| 2330 | |
| 2331 | mat = matrix(ZZ, map(self.ideallog, gens)).augment(identity_matrix(ZZ, len(gens))) |
| 2332 | mat = mat.stack( diagonal_matrix(ZZ, invs).augment(zero_matrix(ZZ, len(invs), len(gens)))) |
| 2333 | hmat = mat.hermite_form() |
| 2334 | A = hmat[0:len(invs), 0:len(invs)] |
| 2335 | if A != identity_matrix(len(invs)): |
| 2336 | raise ValueError, "Given elements do not generate unit group -- they generate a subgroup of index %s" % A.det() |
| 2337 | B = hmat[0:len(invs), len(invs):] |
| 2338 | C = hmat[len(invs):, len(invs):] |
| 2339 | #print "Matrix of relations:\n%s" % C |
| 2340 | M = (matrix(ZZ, L) * B) |
| 2341 | N = block_matrix([identity_matrix(1), M, zero_matrix(len(gens), 1), C], 2,2,subdivide=False) |
| 2342 | ans = N.hermite_form()[0, 1:].list() |
| 2343 | |
| 2344 | if check: |
| 2345 | from sage.rings.all import Zmod |
| 2346 | t = 1 |
| 2347 | for i in xrange(len(ans)): |
| 2348 | t = self.reduce(t * gens[i]**ans[i]) |
| 2349 | assert t == self.reduce(x * x.denominator() * (~Zmod(self.norm())(x.denominator())).lift()) |
| 2350 | |
| 2351 | return ans |