Re: [sage-combinat-devel] Re: Category Questions
On Wed, Feb 10, 2010 at 11:10:46AM -0500, Jason Bandlow wrote: I am indifferent to the choice of convention. I agree that the conflict you point out is disturbing. My choice for using the smallest support was based on the current behavior of printing in sage (for most combinatorics). sage: X = CombinatorialFreeModule(QQ, [1,2,3]); B = X.basis() sage: B[3] + B[1] B[1] + B[3] sage: SF = SymmetricFunctions(QQ); SF.inject_shorthands() sage: s(e[1]^3) s[1, 1, 1] + 2*s[2, 1] + s[3] I vote -1 on leading_term always giving the last term printed and trailing_term always giving the first term printed. I have no problem with changing the order of printing, though. Ah, interesting. As Simon, I really have a Gröbner point of view here (leading = large). I had actually never associated the leading term of something with how it reads on screen. Probably because the printing convention varies from system to system, and even within a system. For polynomials, the terms are sorted decreasingly, so it would be consistent to do the same for symmetric functions and the like (although series are probably printed the other way around). I am just a bit reluctant to fix all the doctests accordingly, but sage -fixdoctest can probably relieve us from most of the trouble. Preference anyone? In particular, who thinks consistency between leading / trailing and the way elements are printed is important? A related call for votes: what do we want to mean by upper/lower triangular morphisms? Let X be a module with basis, and b its basis. Then, a morphism f: X-X is upper triangular if, for all i, - Option 1: f( b[i] ) = c * b[i] + smaller terms - Option 2: f( b[i] ) = c * b[i] + larger terms Intuitively, I vote for Option 1. An argument is that this matches with upper triangularity of the matrix A of f when writing the images f(b[i]) as column vectors, which is the usual convention when f(x) is calculated by A * X. Well, maybe it isn't too unusual to think of x as a row-vector and compute f(x) = x * A. I know ... I am fairly agnostic as well, and probably are mostly influenced by the fact that we always teach A*X in class, or at least here in France. Hmm, one point though: morphisms in Sage compose from right to left (as the usual \circ). So it would be consistent to think left action / multiplication by their matrix on the left. After all, a list of coefficients looks like a row vector and not a column vector. As an example, currently in sage we have sage: SF = SymmetricFunctions(QQ); SF.inject_shorthands() sage: s.transition_matrix(m,3) [1 1 1] [0 1 2] [0 0 1] Do you agree that, in principle, this command should return the matrix representing the morphism from the Schur basis to the monomial basis? Definitely. If so, this is currently in agreement with option 2, and should be changed if we adopt option 1. Again, I am basically agnostic as to the convention we choose, as long as we document it and use it consistently. Ok. Transition matrix will have to be rewritten in a generic way at some point anyway, though we will have to be careful with backward compatibility. I'll note that we seem to be in agreement that the upper-left corner of the matrix should be indexed by the (smallest-smallest) pair of indices. Yes. I think this is useful, as it naturally generalizes to the commonly occurring case of a semi-infinite set with a smallest, but not largest, element (eg, NonNegativeIntegers). But I will point out that if we use leading_term=largest, then the rows and columns of this matrix will begin with the trailing term and end with the leading term, which again seems unfortunate to me. Yup. Cheers, Nicolas -- Nicolas M. Thiéry Isil nthi...@users.sf.net http://Nicolas.Thiery.name/ -- You received this message because you are subscribed to the Google Groups sage-combinat-devel group. To post to this group, send email to sage-combinat-de...@googlegroups.com. To unsubscribe from this group, send email to sage-combinat-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sage-combinat-devel?hl=en.
Re: [sage-combinat-devel] Re: Category Questions
Nicolas M. Thiery wrote: On Tue, Jan 26, 2010 at 04:02:17PM -0500, Jason Bandlow wrote: Ok, I tried this, but I'm running into pickling problems with attrcall: sage: f = attrcall(is_one) sage: f == loads(dumps(f)) False So I don't know how to implement the approach you suggested and wind up with something that can be pickled in the end. Suggestions? Oops, I had *completely* forgotten about #5524. I just posted a patch which needs review :-) Thanks! See the ticket for my comments. -Jason -- You received this message because you are subscribed to the Google Groups sage-combinat-devel group. To post to this group, send email to sage-combinat-de...@googlegroups.com. To unsubscribe from this group, send email to sage-combinat-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sage-combinat-devel?hl=en.
Re: [sage-combinat-devel] Re: Category Questions
Hi Jason! On Tue, Jan 12, 2010 at 10:47:01PM +0100, Nicolas M. Thiery wrote: I now have a patch up at http://trac.sagemath.org/sage_trac/ticket/7914 A couple details; could you: - rename the patch in the queue as on trac - Add a description to the top of the patch (for example using hg qrefresh -e), like: #7914: Implementation of triangular morphisms for modules with basis - extract two functions: def max(iterable, cmp = ...) def min(iterable, cmp = ...) possibly in sage.misc.misc_c, or maybe that should be in the new sage.misc.sage_itertools I introduced in #7921 (but then it will introduce a dependency upon it). Thanks! Cheers, Nicolas -- Nicolas M. Thiéry Isil nthi...@users.sf.net http://Nicolas.Thiery.name/ -- You received this message because you are subscribed to the Google Groups sage-combinat-devel group. To post to this group, send email to sage-combinat-de...@googlegroups.com. To unsubscribe from this group, send email to sage-combinat-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sage-combinat-devel?hl=en.
Re: [sage-combinat-devel] Re: Category Questions
On Thu, Jan 14, 2010 at 04:04:59PM -0500, Jason Bandlow wrote: Well, it seems sage-devel approves, so term = coeff * monomial it is. Adjugé, vendu! Thanks for handling this. I've spent today preparing a patch to do this, and I think I've done it. I have to run now, but tomorrow I'll put up a trac ticket for you to look at it. If you want a quick look tonight, it's on the combinat server. I had a quick look, and this looks good. The next step is to update the patches in the Sage-Combinat queue that are not yet in Sage and use term/monomial. Luckily, there are only a couple of them. For the ncsf one, you can go ahead, and do it in place. For the others, you can either ask permission to the patch author, or do a follow up patch to be folded in later. The last step will be for everyone to update his/her private code if needed. We should advertise this change! I'll also need to make a good explanation of what I've done to this list--I'll do that tomorrow too. Thanks! Cheers, Nicolas -- Nicolas M. Thiéry Isil nthi...@users.sf.net http://Nicolas.Thiery.name/ -- You received this message because you are subscribed to the Google Groups sage-combinat-devel group. To post to this group, send email to sage-combinat-de...@googlegroups.com. To unsubscribe from this group, send email to sage-combinat-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sage-combinat-devel?hl=en.
Re: [sage-combinat-devel] Re: Category Questions
Hi Jason, On Tue, Jan 12, 2010 at 06:05:06PM -0500, Jason Bandlow wrote: - self._monomial_coefficients is specific to the CombinatorialFreeModule implementation. But you can use directly x[k] to get the coefficient of k in an element x of a module with basis. Very good to know. Do you know how I can get the list of all basis elements which appear in x? Will x.support() work? Yes! The standard ModulesWithBasis methods ought to be listed and documented in the category, either as abstract_methods or as default implementations. Please see the attached document I had written with Mike when he implemented CombinatorialFreeModule (and that I should have advertised). It contains a (preliminary/to be cleaned up) list of standard ModulesWithBasis methods. See also: http://mupad-combinat.svn.sourceforge.net/viewvc/mupad-combinat/trunk/MuPAD-Combinat/lib/DOMAINS/CATEGORY/ModulesWithBasis.mu?view=markup http://mupad-combinat.svn.sourceforge.net/viewvc/mupad-combinat/trunk/MuPAD-Combinat/lib/DOMAINS/CATEGORY/DOC/ModuleWithBasis.mupdoc?view=markup http://mupad-combinat.svn.sourceforge.net/viewvc/mupad-combinat/trunk/MuPAD-Combinat/lib/DOMAINS/CATEGORY/TEST/ModuleWithBasis.tst?view=markup By the way, at some point, we should have an ModulesWithBasis(...).example(), with a very minimal implementation to catch this kind of things in tests. Agreed. I'll try to create this too. (It will be another good way for me to learn more about Categories). Cool, thanks! You can have a look in ModulesWithBasis.tst above for a (too minimal) example; it just had to implement fromList (replaced by from_dict in Sage), toList (replaced by __iter__ in Sage), coeff, and monomial. For Sage's minimal example, I'd suggest KK^n (where KK is the base_ring of the module with basis, and n defaults to, say, 4), with elements represented as lists of n elements of KK. Now, we hit the question of what a term is, and what a monomial is. We currently use MuPAD's convention that x^3 is a term, while 2*x^3 is a monomial. But other system use the reverse convention. I think Sage already has the reverse convention. If f=2*x^3*y^2 in a MultiPolynomialRing, f.lc() currently returns 2 and f.lm() currently returns x^3*y^2. The SymbolicRing seems to have methods leading_coefficient() and trailing_coefficient(), along with not-very-shortcuts leading/trailing_coeff(), which take a single variable as input and return everything which is multiplied by that variable in the first term in which that variable appears. A UnivariatePolynomialRing seems to have leading_coefficient() but nothing else. I had looked at these before, but your comment prompted me to look further. I found this in the doc of sage.rings.polynomial.toy_d_basis (written by Martin Albrecht): The notion of 'term' and 'monomial' in [BW93]_ is swapped from the notion of those words in Sage (or the other way around, however you prefer it). In Sage a term is a monomial multiplied by a coefficient, while in [BW93]_ a monomial is a term multiplied by a coefficient. Also, what is called LM (the leading monomial) in Sage is called HT (the head term) in [BW93]_. So, as I understand it, 3 * x^2 : term 3 : coefficient x^2 : monomial would be consistent with the rest of Sage. Do you know of someplace in Sage that is not consistent with that? Not on top of my head. But a systematic search is in order. It would be worthwhile to include embedded software in the search. Singular and Magma seem to use the same convention as Sage (term = c * monomial): http://www.singular.uni-kl.de/Manual/3-1-0/sing_231.htm#SEC272 http://magma.maths.usyd.edu.au/magma/htmlhelp/text313.htm#1968 It's kind of the last occasion we have to change that; it might actually be too late. Still, could you raise the issue on sage-devel? Do you still think so? Thinking twice about it, the change should not be that bad, since term is current essentially monomial with a default second argument coeff=1; so we can swap the two while maintaining backward compatibility. The other functions that should be fixed as well (sum_of_terms/sum_of_monomials, ...) are not that many, and I don't expect them to have been used much outside of our patches. If you do, and if you can answer my previous question, I am happy to do this. Great, thanks! For the record: I added in PS a discussion with the MuPAD team in ... 1998 ..., about the same issue :-) I would love to see it resolved once for all. Please make a call on sage-devel, and if there is a consensus for standardizing for term = coeff * monomial, go ahead with the change! I'd suggest a first patch/ticket doing the change, and then your triangularity patch on top of it. I am happy to review all of this promptly. It would be good to have all of this in Sage before Sage days 20 at the end of February. maybe x.leading_item, consistent with
Re: [sage-combinat-devel] Re: Category Questions
Hi Jason! On Tue, Jan 12, 2010 at 12:19:36PM -0500, Jason Bandlow wrote: While working on this, I added a ``TestSuite(phi)`` test where ``phi`` is a TriangularModuleMorphism, mimicking what was done for DiagonalModuleMorphism. Good idea! Unfortunately, pickling fails. I don't really know where to start tracking this down... can you give me a pointer? phi is constructed from f, which itself can't be pickled: sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename(X) sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); y = Y.basis() sage: f = lambda i: sum( y[j] for j in range(i,4) ) sage: loads(dumps(f)) Traceback (most recent call last): PicklingError: Can't pickle type 'function': attribute lookup __builtin__.function failed That's because functions are pickled by name; but the name of f is __main__.f. Pickles detects that there is no such function in the __main__module, and rightfully deduces that f could not be unpickled in a latter Sage session. Luckily, one can cheat-around this, faking f being picklable, by forcefully inserting it into __main__, as in: sage: import __main__; __main__.f = f Oh, and f should be defined with def, not lambda. sage: X = CombinatorialFreeModule(QQ, [1, 2, 3]); X.rename(X) sage: Y = CombinatorialFreeModule(QQ, [1, 2, 3]); y = Y.basis() sage: def f(i): sum( y[j] for j in range(i,4) ) sage: import __main__; __main__.f = f sage: loads(dumps(f)) function f at 0xbfbc9cc sage: phi = X.module_morphism(f, triangular=True, codomain = Y) sage: TestSuite(phi).run() See the first example of TriangularModuleMorphism. Altogether, whenever possible, I try to use standard sage functions (like factorial) for such building blocks in tests. Here is a handy trick, which involves a bit of magic in sum_of_terms (it's a morphism, and therefore * is function composition): sage: f = Y.sum_of_terms * range sage: f(5) B[0] + B[1] + B[2] + B[3] + B[4] sage: loads(dumps(f)) A map to X Cheers, Nicolas -- Nicolas M. Thiéry Isil nthi...@users.sf.net http://Nicolas.Thiery.name/ -- You received this message because you are subscribed to the Google Groups sage-combinat-devel group. To post to this group, send email to sage-combinat-de...@googlegroups.com. To unsubscribe from this group, send email to sage-combinat-devel+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sage-combinat-devel?hl=en.