Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cartesian products with orders #18223

Closed
dkrenn opened this issue Apr 16, 2015 · 69 comments
Closed

cartesian products with orders #18223

dkrenn opened this issue Apr 16, 2015 · 69 comments

Comments

@dkrenn
Copy link
Contributor

dkrenn commented Apr 16, 2015

Create cartesian products which have a particular order (lexicographically or component-wise) on its elements.

This also incorporates the proposed changes of #18586 (won't be fixed; see discussion there), namely passes keyword arguments on in cartesian_product and adds extra_category.

CC: @behackl @cheuberg @nthiery

Component: categories

Keywords: sd67

Author: Daniel Krenn

Branch/Commit: 8f9a619

Reviewer: Benjamin Hackl, Vincent Delecroix

Issue created by migration from https://trac.sagemath.org/ticket/18223

@dkrenn dkrenn added this to the sage-6.7 milestone Apr 16, 2015
@dkrenn
Copy link
Contributor Author

dkrenn commented Apr 16, 2015

Branch: u/dkrenn/cat/cartesian

@dkrenn
Copy link
Contributor Author

dkrenn commented Apr 16, 2015

New commits:

595b1c9parameter 'category' for cartesian products
afaeb0eparameter extra_category for cartesian products
2226fe9cartesian products for comparing lexicographically and component-wise (first working draft)
56eda04add docstrings and tests
46c7a04extend __init_extra__

@dkrenn
Copy link
Contributor Author

dkrenn commented Apr 16, 2015

Commit: 46c7a04

@fchapoton
Copy link
Contributor

Changed branch from u/dkrenn/cat/cartesian to public/ticket/18223

@fchapoton
Copy link
Contributor

comment:4

fixed a failing doctest


New commits:

702a8a6Merge branch 'u/dkrenn/cat/cartesian' into 6.7.b1
1013ccatrac #18223 typo in doctest

@fchapoton
Copy link
Contributor

Changed commit from 46c7a04 to 1013cca

@dkrenn
Copy link
Contributor Author

dkrenn commented Apr 19, 2015

comment:5

Replying to @fchapoton:

fixed a failing doctest

Thanks.

702a8a6 Merge branch 'u/dkrenn/cat/cartesian' into 6.7.b1

What was the reason for this merge?

@fchapoton
Copy link
Contributor

comment:6

This is forced to me by git, even when the merge is trivial. I work like that:

  1. I copy the develop branch into say branch18223

  2. I pull the branch from trac, sitting on branch18223

  3. git forces me to do a merge commit, often a trivial one.

@dkrenn
Copy link
Contributor Author

dkrenn commented Apr 19, 2015

comment:7

Replying to @fchapoton:

This is forced to me by git, even when the merge is trivial. I work like that:

  1. I copy the develop branch into say branch18223

  2. I pull the branch from trac, sitting on branch18223

  3. git forces me to do a merge commit, often a trivial one.

http://www.sagemath.org/doc/developer/manual_git.html#merging-and-rebasing says at the end of the section:

[...] do nothing unless necessary: it is perfectly fine for your branch to be behind master [...]

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 24, 2015

Branch pushed to git repo; I updated commit sha1. New commits:

98fcf3fMerge branch 'public/ticket/18223' into 6.7.b2
b924b94trac #18223 one :: missing

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 24, 2015

Changed commit from 1013cca to b924b94

@videlec
Copy link
Contributor

videlec commented May 3, 2015

comment:9

Hello Daniel,

  1. There are tons of product orders that you can define on a cartesian product of posets. You want to write a category for each of them? It is not at all usable for people that wants to build a custom product. The aim of categories is to factorize code not to expand the amount of work. I think that you should seriously develop another strategy for providing an order to a product of posets.

  2. Moreover, this looks very unnatural to me:

sage: P = Poset((srange(10), lambda left, right: left <= right))
sage: Q = cartesian_product((P, P, P),
....: extra_category=Posets().CompareLexCartesianProduct())

IMHO, something like the following would be better

sage: posets.cartesian_product((P,P,P), order = my_order)

where order could also be a custom function or a string like 'lex', 'product', ... this second remark is just from the user point of view.

  1. If there is one product, it should be the cartesian product (or the coordinate wise product) which is the categorical one (when morphisms are the monotone functions). Though as there is a lack of definitions, I am not sure that Hom between two posets are the monotone functions. Would be interesting to settle that.

  2. Sided remark: this will not work with cython Element classes (as there is no element_class)

self.element_class.__le__ = \
lambda left, right: left.parent().le(left, right)

Vincent

@nthiery
Copy link
Contributor

nthiery commented May 3, 2015

comment:10

Salut Vincent!

We had discussed this design with Daniel, and take my share of the blame. I am not quite happy with this solution. I am not quite happy with other solutions either. So that's a good occasion for a discussion!

I guess the main question is whether there will be other categories in
the long run where there will be several variants for the cartesian
product, and we want everything to interplay.

If not, then having a specific cartesian product for posets is
probably ok.

If yes, we would want to have some syntax where we can specify options
for the various structures.

    sage: cartesian_product([A,B,C], poset options, xxx options, ...)

This is more or less what the proposed syntax aims for. But it has the
drawbacks you mention. Possibly this would not be so bad if the
category was parametrized by a "term order":

    sage: cartesian_product([A,B,C], Posets().CartesianProducts(term_order="lex")

It would need to be checked whether we can indeed achieve this syntax
(or a similar one) without tweaking too much the functorial
construction infrastructure.

Another related question is whether a single function is sufficient to
specify the order, or not: maybe we would want to provide
implementations of other methods that apply for specific term orders.

Cheers,
Nicolas

@videlec
Copy link
Contributor

videlec commented May 3, 2015

comment:11

Salut Nicolas,

Replying to @nthiery:

We had discussed this design with Daniel, and take my share of the blame. I am not quite happy with this solution. I am not quite happy with other solutions either. So that's a good occasion for a discussion!

On the other hand the feature is clearly missing. So we need to find a solution.

I guess the main question is whether there will be other categories in
the long run where there will be several variants for the cartesian
product, and we want everything to interplay.

If not, then having a specific cartesian product for posets is
probably ok.

If yes, we would want to have some syntax where we can specify options
for the various structures.

    sage: cartesian_product([A,B,C], poset options, xxx options, ...)

This worries me a lot since cartesian product is intended for any kind of structures... not only poset. If you start adding specific options into this machinery it will be horrible as well.

This is more or less what the proposed syntax aims for. But it has the
drawbacks you mention. Possibly this would not be so bad if the
category was parametrized by a "term order":

    sage: cartesian_product([A,B,C], Posets().CartesianProducts(term_order="lex")

This is already nicer. Though, there is a problem with morphisms then (see my remark 3 in comment:9). The order in a cartesian product can not be parametrized if the morphisms are monotone functions. So doing the above will prevent defining morphisms in that way. I do not know whether it is what we want to do here.

Note that the following almost works

B = cartesian_product([A0, A1, A2])
my_cmp = lambda x,y: x[0] <= y[0] and x[1] <= y[1] and x[2] <= y[2]
P = Poset((B, my_cmp))

I say almost, because building a Poset is infinitely slow as always and works only for finite posets.

Vincent

@dkrenn
Copy link
Contributor Author

dkrenn commented May 5, 2015

comment:12

Replying to @videlec:

Note that the following almost works

B = cartesian_product([A0, A1, A2])
my_cmp = lambda x,y: x[0] <= y[0] and x[1] <= y[1] and x[2] <= y[2]
P = Poset((B, my_cmp))

I say almost, because building a Poset is infinitely slow as always and works only for finite posets.

Just a short comment: This will not work for what I have in mind, since my A0, A1, A2 will be groups or monoids or rings, and I want B to be a group or monoid or ring, resp., as well. This is also one motivation for using the category framework to add the desired comparison behavior to existing structures.

@dkrenn
Copy link
Contributor Author

dkrenn commented Jun 2, 2015

Changed branch from public/ticket/18223 to u/dkrenn/cat/cartesian-product-posets

@dkrenn

This comment has been minimized.

@dkrenn
Copy link
Contributor Author

dkrenn commented Jun 2, 2015

Dependencies: #18586

@dkrenn
Copy link
Contributor Author

dkrenn commented Jun 2, 2015

comment:13

I've now derived a class from sets.cartesian_product.CartesianProduct for posets. One can specify by a parameter which order one wants to take. User defined orderes can be used as well.

        sage: P = Poset((srange(3), lambda left, right: left <= right))
        sage: P.CartesianProduct = sage.sets.cartesian_product.CartesianProductPosets
        sage: Cl = cartesian_product((P, P), order='lex')
        sage: Cl((1, 1)) <= Cl((2, 0))
        True
        sage: Cc = cartesian_product((P, P), order='components')
        sage: Cc((1, 1)) <= Cc((2, 0))
        False
        sage: def le_sum(left, right):
        ....:     return (sum(left) < sum(right) or
        ....:             sum(left) == sum(right) and left[0] <= right[0])
        sage: Cs = cartesian_product((P, P), order=le_sum)
        sage: Cs((1, 1)) <= Cs((2, 0))
        True

Last 10 new commits:

7b098f7parameter extra_category for cartesian products
c6a01f8allow kwargs in CartesianProduct (to be used in inherited classes)
85f44f3pass on keyword arguments in cartesian product of the sets category
ba5dab9update docstring and complete doctests
55a7020create class for cartesian products of posets
6ed9246method "le"
4c9f72cmethods for comparing lexicographically and component-wise
e589e9bcreate Element: implement <=, <, >=, >
69335ccwrite a class description
9352031change one word in docstring

@dkrenn
Copy link
Contributor Author

dkrenn commented Jun 2, 2015

Changed commit from b924b94 to 9352031

@dkrenn
Copy link
Contributor Author

dkrenn commented Jun 2, 2015

Author: Daniel Krenn

@dkrenn dkrenn changed the title new categories for cartesian products with orders cartesian products with orders Jun 2, 2015
@dkrenn
Copy link
Contributor Author

dkrenn commented Sep 23, 2015

comment:38

Replying to @videlec:

Replying to @dkrenn:

  1. What is the point of adding *kwargs in the __init__ method of CartesianProduct? If this argument is not supported then it should simply not exists.

This boils down to our discussion from #18586: They are passed on to CartesianProduct where there is at least a flatten keyword. Thus there is a keyword, so arguments are simply passed.

I still do not understand at all. I am talking about sage.sets.cartesian_product.CartesianProduct. Its constructor does not pass its arguments to anybody. What is the subtle difference in behaviour between f and g below?

def f(**kwds):
   if kwds:
       raise TypeError
   ...

def g():
    ...

The only thing I see is that it needs much more to write f.

I think I see your point now and I have to admit I thought we were taking about CartesianProductPosets (and not about CartesianProduct). I agree that this is obsolete now. I've deleted it.


New commits:

4ac4014remove kwargs in CartesianProduct since not needed

Last 10 new commits:

e87db1arewrite (simplify) join of category
6714aaaadd comment pointing to #19269 in doctests using QQ as poset
298773eexplain keyword order better
08469c7add module to reference/combinat docs
98c252fallow tuples as category
eb711e9add TestSuite
ca4a844minor rephrase of docstring
693b0bdadd a native order option
f3b1387use Posets.ChainPosets in a doctest
4ac4014remove kwargs in CartesianProduct since not needed

@fchapoton
Copy link
Contributor

comment:39

two failing doctests

@behackl
Copy link
Member

behackl commented Sep 28, 2015

@behackl
Copy link
Member

behackl commented Sep 28, 2015

Changed commit from 4ac4014 to 6ca3e5f

@behackl
Copy link
Member

behackl commented Sep 28, 2015

comment:40

I fixed the two failing doctests (in 6.9.beta7 the category of the cartesian product of ZZ with itself changed) and merged 6.9.rc0 into this branch.

Vincent, as you have done quite some work here would you like to add your name to the reviewers?

Finally, as this ticket seems to have reached a stable state, this could be set to positive_review. Any objections?

Benjamin


Last 10 new commits:

298773eexplain keyword order better
08469c7add module to reference/combinat docs
98c252fallow tuples as category
eb711e9add TestSuite
ca4a844minor rephrase of docstring
693b0bdadd a native order option
f3b1387use Posets.ChainPosets in a doctest
4ac4014remove kwargs in CartesianProduct since not needed
4af1dd4Merge tag '6.9.rc0' into cat/cartesian-product-posets
6ca3e5ffixed doctests

@videlec
Copy link
Contributor

videlec commented Sep 28, 2015

comment:41

Replying to @behackl:

Vincent, as you have done quite some work here would you like to add your name to the reviewers?

done

Finally, as this ticket seems to have reached a stable state, this could be set to positive_review. Any objections?

The branch is in good shape. I would like to go through the whole changes a last time. If everything is fine I will set the positive review. Is that ok?

Vincent

@videlec
Copy link
Contributor

videlec commented Sep 28, 2015

Changed reviewer from Benjamin Hackl to Benjamin Hackl, Vincent Delecroix

@behackl
Copy link
Member

behackl commented Sep 28, 2015

comment:42

Replying to @videlec:

The branch is in good shape. I would like to go through the whole changes a last time. If everything is fine I will set the positive review. Is that ok?

Sure! Thanks for going over it once again! :-)

Benjamin

@videlec
Copy link
Contributor

videlec commented Sep 30, 2015

comment:43
  1. The name CartesianProductPosets looks weird. I would rather go for CartesianProductPoset (no s) or PosetsCartesianProduct. As it is currently it looks like the set of posets that are made from cartesian products.

  2. You should remove your name from sage/sets/cartesian_product.py. I have nothing agaist authorship but as it is, it looks like spam ;-)

  3. There is no example testing that the coercion can get involved in comparisons. Either it is worth it and it needs a use case or it can be removed.

  4. This is not nice

+        CartesianProductPosets = LazyImport(
+            'sage.combinat.posets.cartesian_product', 'CartesianProductPosets')
+        CartesianProduct = CartesianProductPosets

because

sage: E = Posets().example()
sage: E.Car<tab>
E.CartesianProduct        E.CartesianProductPosets

which actually point toward the exact same thing. Please change for

+        CartesianProduct = LazyImport(
+            'sage.combinat.posets.cartesian_product', 'CartesianProductPosets')

And some questions:

  1. Most methods of finite posets are actually not available in this class... this is very annoying (but I do not see what can be done at the level of this ticket).

  2. Are you aware that

sage: C = cartesian_product([ZZ, ZZ], extra_category=Posets())
sage: from sage.combinat.posets.cartesian_product import CartesianProductPosets
sage: isinstance(C, CartesianProductPosets)
False

and indeed

sage: TestSuite(C).run()
Failure in _test_not_implemented_methods:
...
AssertionError: Not implemented method: le
------------------------------------------------------------
The following tests failed: _test_not_implemented_methods

@dkrenn
Copy link
Contributor Author

dkrenn commented Sep 30, 2015

@dkrenn
Copy link
Contributor Author

dkrenn commented Sep 30, 2015

Changed commit from 6ca3e5f to 8f9a619

@dkrenn
Copy link
Contributor Author

dkrenn commented Sep 30, 2015

comment:45

Replying to @videlec:

  1. The name CartesianProductPosets looks weird. I would rather go for CartesianProductPoset (no s) or PosetsCartesianProduct. As it is currently it looks like the set of posets that are made from cartesian products.

Ok (I don't have an opinion on this); changed to CartesianProductPoset.

  1. You should remove your name from sage/sets/cartesian_product.py. I have nothing agaist authorship but as it is, it looks like spam ;-)

Ooops...forgotten to remove it (when moving to the code to combinat.posets). Thanks; removed.

  1. There is no example testing that the coercion can get involved in comparisons. Either it is worth it and it needs a use case or it can be removed.

I've added a doctest. This test can and will be rewritten once #18182 is merged.

  1. This is not nice
+        CartesianProductPosets = LazyImport(
+            'sage.combinat.posets.cartesian_product', 'CartesianProductPosets')
+        CartesianProduct = CartesianProductPosets

because

sage: E = Posets().example()
sage: E.Car<tab>
E.CartesianProduct        E.CartesianProductPosets

which actually point toward the exact same thing.

I completly agree.

Please change for

+        CartesianProduct = LazyImport(
+            'sage.combinat.posets.cartesian_product', 'CartesianProductPosets')

I wasn't aware that this works, but it is clear that it works :) Changed.

  1. Most methods of finite posets are actually not available in this class... this is very annoying (but I do not see what can be done at the level of this ticket).

True; I think this should be fixed by using the Posets-category, but definitely not on this ticket.

  1. Are you aware that
sage: C = cartesian_product([ZZ, ZZ], extra_category=Posets())
sage: from sage.combinat.posets.cartesian_product import CartesianProductPosets
sage: isinstance(C, CartesianProductPosets)
False

and indeed

sage: TestSuite(C).run()
Failure in _test_not_implemented_methods:
...
AssertionError: Not implemented method: le
------------------------------------------------------------
The following tests failed: _test_not_implemented_methods

Yes, I am aware of. Adding an extra category only makes sense if the underlying object is a poset (thus has le). Since ZZ is not a poset (see #19269), the cartesian product is not a poset (and has no le) and therefore is not an instance of CartesianProductPoset. Thus, the failure of the test suite is correct.
FYI: The class used for the cartesian product is determined by its first factor (and not by the category).


New commits:

70aa9c4rename CartesianProductPosets to CartesianProductPoset
f21990dcode-simplify CartesianProduct assignment
8f9a619add a doctest dealing with coercion while comparing

@videlec
Copy link
Contributor

videlec commented Sep 30, 2015

Changed dependencies from #18586 to none

@videlec
Copy link
Contributor

videlec commented Sep 30, 2015

comment:46

All right. Thanks for the last changes.

Vincent

@vbraun
Copy link
Member

vbraun commented Oct 12, 2015

Changed branch from u/dkrenn/cat/cartesian-product-posets to 8f9a619

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants