On Tue, Apr 29, 2014 at 08:17:44PM +0200, Nathann Cohen wrote: > Why did you have to move the code around, though ? > What is the difference between sets.cartesian_product and > categories.cartesian_product ?
<disclaimer> My answer is most likely going to be a bit broad and include stuff you already know; I am just taking the occasion to write a blurb that could possibly end up somewhere in the documentation (typically as a complement of cartesian_product?), if someone finds it useful. </disclaimer> There can be several ways to represent an element of a cartesian product. The natural implementation is using a tuple (well, a wrapped tuple). That's what the concrete class in sets.cartesian_product.CartesianProduct does:: sage: C = cartesian_product([GF(3), GF(5)]) sage: type(C) <class 'sage.sets.cartesian_product.CartesianProduct_with_category'> sage: C.an_element() (0, 0) But if you start from vector spaces it's natural to think of the cartesian product as a direct sum, and therefore represent the cartesian product by a vector space: sage: X = CombinatorialFreeModule(QQ, ['a','b']); X.rename("X") sage: Y = CombinatorialFreeModule(QQ, ['c','d']); Y.rename("Y") sage: C = cartesian_product([X,Y]) sage: C X (+) Y sage: type(C) <class ...CombinatorialFreeModule...> This vector space has a basis indexed by the disjoint unions of that of X and of Y:: sage: C.basis().keys() Disjoint union of Family ({'a', 'b'}, {'c', 'd'}) sage: C.an_element() 2*B[(0, 'a')] + 2*B[(0, 'b')] + 3*B[(1, 'c')] So that's a second concrete implementation of a cartesian product. There could be others (e.g. one could represent the cartesian product of two permutation groups as a permutation group). That's for the concrete classes. Then, you have generic code that works in all cases (say an_element, one). This code goes in the relevant abstract classes in the category. For example the code for `an_element` is something about parents that are cartesian products of sets; so it goes in the abstract class Sets.CartesianProducts.ParentMethods. On the other hand `one` is about monoids (in fact unital magmas), so it goes in Monoids.CartesianProducts.ParentMethods (in Magmas.Unital.CartesianProducts.ParentMethods after #10963). The last player in the game is the `cartesian_product` object, as in `cartesian_product([A,B,...])`. Its role is to look at the properties of A,B,..., and decide on an appropriate concrete implementation and a category. Technically, this object is a "covariant functorial construction" and it's implemented in sage.categories.cartesian_product. In practice, unless one wants to use it as an example to create a new construction, there is no reason to fiddle with it. > Cool. I am trying to clean the CartesianProduct stuff of additive > groups and it does not look good. The methods are not inherited from > where they should -_- > > Right now, my problem is that the __add__ method from a > CombinatorialFreeModule is taken from my CommutativeAdditiveGroup. > And I thought I could expect all those objects to have a .value > argument, but apparently I can t >_< The three points you probably are hitting here are: - It's best to implement _add_ rather than __add__ (__add__ builds on _add_ and takes care of coercion for you). Equivalently you can implement the method 'summation' in the parent (that's what done for the product). - Vector spaces are already endowed with their addition. Sounds like you accidently overrode it. - Using .value directly breaks encapsulation and is thus implementation dependent. Instead, have a look at some generic method that manipulates an element of a cartesian product and see how its pieces are recovered there. E.g.: sage: C = cartesian_product([GF(3), GF(5)]) sage: C.product?? Let me know if you would want me to have a look at the code. > Okay, so I will try to see if I can guarantee correctness when you can't..... I just meant the usual caveat "not tested=likely to be broken". > > I am hesitant on whether _element_constructor should always directly > > coerce the elements, or first check if they are already in the right > > parent and if not call coercion. > > Well, your pick. I barely understand what the dilemma is about :-P Just about the "if" line I commented out in your code. Maybe it should really be there. Or we should do a separate `if` for each set. 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 unsubscribe from this group and stop receiving emails from it, send an email to sage-combinat-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-combinat-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-combinat-devel. For more options, visit https://groups.google.com/d/optout.