Hi Travis, first of all thank you for your answer, it looks like you are one of the person I pester the most with these issues.
TropicalSemiring is, unfortunately, not what I am looking for. The object I need is a multiplicative abelian group on generators n generators y_i and an addition \prod y_i^{a_i} \oplus \prod y_i^{b_i} = \prod y_i^{\min(a_i,b_i)}. At the moment this is beyond the scope of this e-mail; I put it in just to give some prospective. As far as gcd business goes my point is not that the current behaviour is necessarily wrong but it is inconsistent. What I mean is that sage: L = LaurentPolynomialRing(ZZ, 'x0,x1,y0,y1') sage: R = LaurentPolynomialRing(LaurentPolynomialRing(ZZ, 'y0,y1'), 'x0,x1') mathematically should be (almost) the same object but sage: L.inject_variables() Defining x0, x1, y0, y1 sage: (x0+1)/(x0+1) 1 sage: R.inject_variables() Defining x0, x1 sage: (x0+1)/(x0+1) (x0 + 1)/(x0 + 1) Their fraction fields are indeed different but elements belonging to both should have the same properties. This is not the case at the moment: sage: L = L.fraction_field() sage: R = R.fraction_field() sage: L.inject_variables() Defining x0, x1, y0, y1 sage: (x0+1).gcd(x0+1) x0 + 1 sage: R.inject_variables() Defining x0, x1 sage: (x0+1).gcd(x0+1) 1 I agree with you that a rewrite might not be a good use of anyone's time so we should start bug hunting first. I will open a ticket with the last of the issues I pointed out in my previous e-mail as soon as I can find a solution. One design question: can someone explain to me the rationale of having two implementations for Laurent polynomials (one univariate and one multivariate) and then a wrapper factory function on top? If the idea is that some methods are defined only in special cases would it not be easier to add them at __init__ time with something like self.mymethod = MethodType(mymethod, self, self.__class__) This would allow to expose directly two classes LaurentPolynomialRing and LaurentPolynomial instead of a factory function. Best S. * Travis Scrimshaw <tsc...@ucdavis.edu> [2015-11-03 14:19:52]: > Hey Salvatore, > Â Â So first I would point you towards TropicalSemiring, but I don't > think that has the functionality you want, which seems to be tropical > polynomials, correct? > > Unfortunately, if one does that, there are few issues arising from > how gcd > are computed; here is a small zoo of examples: > sage: P = LaurentPolynomialRing(ZZ, 'y', 3) > sage: P > Multivariate Laurent Polynomial Ring in y0, y1, y2 over Integer Ring > sage: L = LaurentPolynomialRing(P,'x',3) > sage: L > Multivariate Laurent Polynomial Ring in x0, x1, x2 over Multivariate > Laurent Polynomial Ring in y0, y1, y2 over Integer Ring > sage: L.inject_variables() > Defining x0, x1, x2 > sage: x0/x0 > 1 > sage: x0.gcd(x0) > ... > AttributeError: 'sage.rings.polynomial.laurent_polynomial. > LaurentPolynomial_mpair' object has no attribute 'gcd' > sage: gcd(x0,x0) > ... > TypeError: unable to find gcd > sage: R = L.fraction_field() > sage: R.inject_variables() > Defining x0, x1, x2 > sage: x0.gcd(x0) > 1 > sage: x0/x0 > x0/x0 > sage: _.denominator() > x0 > > The reason the latter works is because of the following: > sage: R = LaurentPolynomialRing(ZZ, 'y', 3) > sage: R.fraction_field() > Fraction Field of Multivariate Polynomial Ring in y0, y1, y2 over > Integer Ring > I'm not completely sure mathematically if the gcd of a multivariate > Laurent polynomial ring is well defined. I imagine it is, and it would > be a matter of doing the gcd on the corresponding polynomial and then > doing the gcd of the monomial (which is how the univariate works). > Â > > Ok, I figured this was not the way to go. The next best thing would > be to have > sage: L = LaurentPolynomialRing(ZZ, 'x0,x1,x2,y0,y1,y2') > sage: P = LaurentPolynomialRing(ZZ, 'y0,y1,y2') > but then: > sage: P.inject_variables() > Defining y0, y1, y2 > sage: y0 in P > True > sage: y0 in L > False > sage: y0.parent().fraction_field()(y0) in L > True > Note that this is an issue of the multivariate implementation since > sage: R = LaurentPolynomialRing(ZZ,'x,y') > sage: T = LaurentPolynomialRing(ZZ,'y') > sage: T.inject_variables() > Defining y > sage: y in T > True > sage: y in R > True > as expected. > > I am not sure about a solution for that. However, it definitely is a > bug, > > It looks to me that the implementation of LaurentPolynomialRing is > full of > such corner case bugs and, if I understand correctly, it is still > based on > the old architecture not the new Category/Parent/Element framework. > Is there > any plan to replace it in the near future with a more modern > implementation? > Should I decide to invest time in improving it, would anyone here be > interested to help? Do you have any suggestion/reference on how this > should > be done properly? I am relatively a newbie to all this so I might > need as > many pointers as possible. > > Â Â Yes, it is one of the last parents that is of the old style and is > something that we should switch over. However I don't think it should > get a complete rewrite from the ground up as there already are plenty > of good, working features there. Moreover, it shouldn't be too hard to > change it over; at least, one would hope. I would be willing to help > where I can. I think we should work our way up and fix the bugs we know > about first, and then after that try to replace ParentWithGens with > Parent (ideally would be in the ABC of ``Ring``) and hope that only a > little breaks. > Best, > Travis -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-devel. For more options, visit https://groups.google.com/d/optout.