| 1 | ############################################################################### |
| 2 | # Sage: Open Source Mathematical Software |
| 3 | # Copyright (C) 2009 Burcin Erocal <burcin@erocal.org> |
| 4 | # Distributed under the terms of the GNU General Public License (GPL), |
| 5 | # version 2 or any later version. The full text of the GPL is available at: |
| 6 | # http://www.gnu.org/licenses/ |
| 7 | ############################################################################### |
| 8 | |
| 9 | from sage.libs.singular.function cimport RingWrap |
| 10 | from sage.libs.singular.decl cimport ring |
| 11 | from sage.rings.polynomial.multi_polynomial_libsingular cimport \ |
| 12 | MPolynomialRing_libsingular |
| 13 | |
| 14 | from sage.rings.polynomial.multi_polynomial_ring_generic import \ |
| 15 | MPolynomialRing_generic |
| 16 | from sage.rings.polynomial.term_order import TermOrder |
| 17 | |
| 18 | include "../../ext/stdsage.pxi" |
| 19 | |
| 20 | def temporary_MPolynomialRing_from_letterplace_ring(RingWrap wrapped_ring, |
| 21 | base_ring, tuple alg_gens, int dbound): |
| 22 | """ |
| 23 | Given a letterplace ring corresponding to a free algebra over the given |
| 24 | `base_ring` with the generators `alg_gens` and degree bound `dbound` |
| 25 | returns two dictionaries, one for converting free algebra elements to |
| 26 | elements of a newly created MPolynomialRing and another to convert back. |
| 27 | |
| 28 | EXAMPLE:: |
| 29 | |
| 30 | sage: from sage.libs.singular.function import lib as singular_lib |
| 31 | sage: from sage.libs.singular.function import singular_function |
| 32 | sage: singular_lib("freegb.lib") |
| 33 | sage: F.<x,y,z> = FreeAlgebra(QQ, 3) |
| 34 | sage: R = PolynomialRing(QQ, F.variable_names()) |
| 35 | sage: make_letter_place_ring = singular_function("makeLetterplaceRing") |
| 36 | sage: ring_wrap = make_letter_place_ring(10, ring=R) |
| 37 | sage: from sage.libs.singular.letterplace_ring import temporary_MPolynomialRing_from_letterplace_ring |
| 38 | sage: to_letterplace, from_letterplace = temporary_MPolynomialRing_from_letterplace_ring(ring_wrap, F.base_ring(), F.gens(), 10) |
| 39 | sage: to_letterplace |
| 40 | {y: [y(1), y(2), y(3), y(4), y(5), y(6), y(7), y(8), y(9), y(10)], x: [x(1), x(2), x(3), x(4), x(5), x(6), x(7), x(8), x(9), x(10)], z: [z(1), z(2), z(3), z(4), z(5), z(6), z(7), z(8), z(9), z(10)]} |
| 41 | sage: to_letterplace.keys()[0] |
| 42 | y |
| 43 | sage: to_letterplace.keys()[0].parent() |
| 44 | Free Algebra on 3 generators (x, y, z) over Rational Field |
| 45 | sage: from_letterplace |
| 46 | {x(1): (1, x), z(1): (1, z), y(2): (2, y), y(7): (7, y), x(3): (3, x), z(10): (10, z), y(5): (5, y), x(10): (10, x), z(4): (4, z), y(9): (9, y), x(4): (4, x), z(6): (6, z), z(8): (8, z), x(6): (6, x), x(8): (8, x), y(1): (1, y), x(2): (2, x), z(2): (2, z), x(7): (7, x), y(3): (3, y), y(10): (10, y), z(9): (9, z), x(5): (5, x), x(9): (9, x), y(4): (4, y), z(3): (3, z), y(8): (8, y), y(6): (6, y), z(7): (7, z), z(5): (5, z)} |
| 47 | """ |
| 48 | cdef MPolynomialRing_libsingular fake_ring = \ |
| 49 | <MPolynomialRing_libsingular>PY_NEW(MPolynomialRing_libsingular) |
| 50 | fake_ring._ring = wrapped_ring._ring |
| 51 | |
| 52 | # create a fake MPolynomialRing_generic object |
| 53 | # this will be used as a parent of the polynomials representing letterplace # elements in Singular |
| 54 | cdef int nvars = len(alg_gens)*dbound |
| 55 | MPolynomialRing_generic.__init__(fake_ring, base_ring, nvars, |
| 56 | ['x'+str(i) for i in range(nvars)], TermOrder('lex', nvars)) |
| 57 | fake_ring._has_singular = True |
| 58 | |
| 59 | gens = fake_ring.gens() |
| 60 | |
| 61 | # fill a dictionary indexed by the free algebra generators, used to convert # free algebra elements to letterplace polynomials |
| 62 | res = dict([(x, [0]*dbound) for x in alg_gens]) |
| 63 | alg_names = dict([(str(x), x) for x in alg_gens]) |
| 64 | # reverse conversion dictionary |
| 65 | # maps letterplace ring generator to a tuple (n, x) where n is the index, |
| 66 | # and x is the corresponding free algebra generator |
| 67 | reverse = {} |
| 68 | for g in gens: |
| 69 | gstr = str(g) |
| 70 | for name in alg_names.iterkeys(): |
| 71 | # found which free algebra generator this polynomial ring generator |
| 72 | # corresponds to |
| 73 | if gstr.startswith(name): |
| 74 | #TODO: fix this assumption of a prefix code |
| 75 | index = int(gstr[len(name)+1:-1]) |
| 76 | alg_gen = alg_names[name] |
| 77 | res[alg_gen][index-1] = g |
| 78 | |
| 79 | reverse[g] = (index, alg_gen) |
| 80 | break |
| 81 | else: |
| 82 | raise RuntimeError, "cannot find corresponding free algebra generator for letterplace element %s"%(gstr) |
| 83 | |
| 84 | return res, reverse |