SHADOWS #1508 - Don't commit #1498

Closed
wants to merge 218 commits into from
@smichr
SymPy member

Combinatorics #531 overhauled

I'm leaving this PR open as a shadow of #1508 which is against 0.7.2. That is the one that should be committed.

@smichr
SymPy member

I think the work on Polyhedron is ready to look at.

@jrioux jrioux commented on the diff Aug 19, 2012
sympy/combinatorics/polyhedron.py
+ """
+ The constructor of the Polyhedron group object.
+
+ It takes up to three parameters: the corners, faces, and
+ allowed transformations.
+
+ The corners/vertices are entered as a list of arbitrary
+ expressions that are used to identify each vertex.
+
+ The faces are entered as a list of tuples of indices; a tuple
+ of indices identifies the vertices which define the face. They
+ should be entered in a cw or ccw order; they will be standardized
+ by reversal and rotation to be give the lowest lexical ordering.
+ If no faces are given then no edges will be computed.
+
+ >>> from sympy.combinatorics.polyhedron import Polyhedron
@jrioux
SymPy member
jrioux added a note Aug 19, 2012

No need to indent.

@smichr
SymPy member
smichr added a note Aug 20, 2012

I'm not to the proper examples, yet, and this is more parenthetical. Is it ok to leave it indented or do you still think it should dedent.

@jrioux
SymPy member
jrioux added a note Aug 20, 2012

It's fine, I guess.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jrioux jrioux commented on an outdated diff Aug 19, 2012
sympy/combinatorics/polyhedron.py
+ raise ValueError("Permutation size unequal to number of corners.")
+ if len(set([a.size for a in pgroups])) > 1:
+ raise ValueError("All permutations must be of the same size.")
+ obj._pgroups = pgroups
+ return obj
+
+ @property
+ def corners(self):
+ """
+ Get the corners of the Polyhedron.
+
+ The method ``vertices`` is an alias for ``corners``.
+
+ Examples
+ ========
+ >>> from sympy.combinatorics import Polyhedron
@jrioux
SymPy member
jrioux added a note Aug 19, 2012

There needs to be an empty line before the example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jrioux
SymPy member

Each time you have

Examples
========

it should be followed by an empty line, then the actual code example.

@travisbot

This pull request passes (merged ed988314 into 5569bb2).

@Krastanov
SymPy member

SymPy Bot Summary: ✳️ All tests have passed.

Test command: setup.py test
master hash: 5569bb2
branch hash: ed988314ded03a202c8498d7de0657f285e51cd7

Interpreter 1: ✳️ All tests have passed.

Interpreter: /usr/local/bin/python2.5 (2.5.6-final-0)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYirsjDA

Interpreter 2: ✳️ All tests have passed.

Interpreter: /usr/bin/python2.7 (2.7.3-candidate-2)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYmNojDA

Interpreter 3: ✳️ All tests have passed.

Interpreter: /usr/bin/python3.2 (3.2.3-candidate-2)
Architecture: Linux (64-bit)
Cache: yes

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sY8LYiDA

Build HTML Docs: ✳️ All tests have passed.

Docs build command: make html-errors
Sphinx version: 1.1.3

Test results html report: http://reviews.sympy.org/report/agZzeW1weTNyDAsSBFRhc2sYibsjDA

Automatic review by SymPy Bot.

@amakelov

I see that some of the stuff concerning cyclic forms in permutations.py is modified here. I'm currently working on excluding singleton cycles from the cyclic form. My approach is the following: I add a _size attribute to the Permutation class, and then, when faced with something like Permutation([[2, 3], [4, 5, 6], [8]]), find the maximum index appearing in the permutation (here it's 8) and assign the size of the permutation to that + 1. Then it remains to adjust some of the other methods in the class (after I adjusted mul so that it treats permutations of different sizes as if they leave all points outside their domain fixed, all the tests passed) so that they make sense with that new approach to cyclic forms. Is that going to be harmful to this PR?

@travisbot

This pull request fails (merged c46c2bb5 into 5569bb2).

@smichr
SymPy member

I see that some of the stuff concerning cyclic forms in permutations.py is modified here. I'm currently working on excluding singleton cycles from the cyclic form. My approach is the following: I add a _size attribute to the Permutation class, and then, when faced with something like Permutation([[2, 3], [4, 5, 6], [8]]), find the maximum index appearing in the permutation (here it's 8) and assign the size of the permutation to that + 1.

I thought of this, too, but the problem is that you don't know if they left out higher singletons (e.g. should [9] be in the permutation?)

Then it remains to adjust some of the other methods in the class (after I adjusted mul so that it treats permutations of different sizes as if they leave all points outside their domain fixed, all the tests passed) so that they make sense with that new approach to cyclic forms. Is that going to be harmful to this PR?

If you want to exclude them in the returned value of cyclic_form you can use the method reduced_cyclic_form.

If you have a 1-based cyclic_form you can use the function cyclic(cycle_form, n) to fill it out with singletons. I think I will modify it so you can optionally not subtract 1 from each element.

I wouldn't have been able to even talk about this 2 days ago, but I did a lot to combinaatorics over the past few days, so if you want to discuss this more it would be helpful.

@smichr
SymPy member

OK, so now you can convert a 0-based cyclic form into a 1-based cyclic form with or without singletons by using the one_based() function.

1-based -> 0-based-full with cyclic
0-based-full -> reduced-0-based-full with reduced_cyclic_form
0-based -> 1-based (full or reduced) with one_based.

@travisbot

This pull request passes (merged 0c94e217 into 5569bb2).

@amakelov

@smichr : the problem with higher singletons can be fixed in one of two ways:

  • as in my previous comment. We'll just have to make the functions treating two possibly different permutation allow different sizes. Additionally, we can supply an optional argument to the constructor that specifies the size of the permutation, something like a = Permutation([[2, 3, 4]], 20)
  • more ambitious: make a new class, ExtendedArrayForm or something, with a field _array_form that holds the usual array form of a permutation. Then we overload the __getitem__ method so that if the index is outside the bounds of self._array_form we return the index unchanged. Of course, we'll have to overload other things, like the __len__ and __str__ to make it behave like a list. Then instead of using a list to initialize the array form of a permutation, we use the corresponding ExtendedArrayForm. This will make all permutations behave as if they are acting on a practically infinite domain, and if we do it that way, we won't have to make any changes to the methods in Permutation - everything is going to work as expected, no casework like if len(a) > len(b),... will be needed. So this sounds like a rather elegant approach. On the other hand, I'm not entirely sure if it is possible to make it completely like a list, and also it doesn't seem like a very performance-efficient decision since ExtendedArrayForm instances will be created all the time.

And by the way, are we going to switch to 1-based form only? It's going to be hard and make the code uglier than it is right now; also, is it a good idea to have two standards for representing permutations -- isn't that going to get confusing?

@jrioux
SymPy member

While building docs:
Warning, treated as error:
doc/src/modules/combinatorics/permutations.rst:11: WARNING: autodoc can't import/find method 'sympy.combinatorics.permutations.perm_af_parity', it reported error: "perm_af_parity", please check your spelling and sys.path

@smichr
SymPy member

@jrioux , I got the sphinx working here and can check my own work now. The wrapping of the first See Also in partitions looks bad, however, as it appears to be trying to fill the paragraph instead of using ragged-right filling. And I added the LatticeOps change here to see that it would work in tests but will rebase this out once your request is in.

@smichr smichr closed this Aug 22, 2012
@smichr smichr reopened this Aug 23, 2012
@smichr
SymPy member

I did a total overhaul on #531. There are some other issues that were addressed along the way (e.g. quick_sort for LatticeOps args and dealing with evalf(1)) since these were causing test failures. I have already reviewed @saptman 's work but now need someone to look over the changes that I've made.

@smichr
SymPy member

@certik , you asked @saptman about whether this could be finalized...I worked with him quite a bit in review and discussion and so felt that I could do the final touches. It ended up being a lot more than that! (And I learned a lot in the process.) Perhaps you would have a chance to look this over?

@travisbot

This pull request passes (merged f73cd8a1 into 333ca3a).

@travisbot

This pull request passes (merged b86464d8 into a184841).

@travisbot

This pull request passes (merged 4b001a71 into 333ca3a).

@smichr
SymPy member

I'll close this here in favor of getting it in with 0.7.2 (#1508)

@smichr smichr closed this Aug 24, 2012
@smichr smichr reopened this Aug 30, 2012
@travisbot

This pull request passes (merged d0ed468f into d208118).

@travisbot

This pull request passes (merged e04e85e3 into d208118).

@wdjoyner

Is it possible to easily change the default printing of the elements of a perm gp to be in disjoint cycle notation?

If not, is is possible to describe in the docstring of perm gp exactly what the notation is. As I explained on the sympy list, group-theorists using this will expect disjoint cycle notation.

Is is possible to add lots more examples (eg, with the Rubik's cube group, etc) where the disjoint cycle notation is used to define a perm gp and then do lots of computations with it? For example, something like

F = Permutation([(17,19,24,22),(18,21,23,20),( 6,25,43,16),( 7,28,42,13),( 8,30,41,11)], size=49)
B = Permutation([(33,35,40,38),(34,37,39,36),( 3, 9,46,32),( 2,12,47,29),( 1,14,48,27)], size=49)
L = Permutation([( 9,11,16,14),(10,13,15,12),( 1,17,41,40),( 4,20,44,37),( 6,22,46,35)], size=49)
R = Permutation([ (25,27,32,30),(26,29,31,28),( 3,38,43,19),( 5,36,45,21),( 8,33,48,24)], size=49)
U = Permutation([ ( 1, 3, 8, 6),( 2, 5, 7, 4),( 9,33,25,17),(10,34,26,18),(11,35,27,19)], size=49)
D = Permutation([ (41,43,48,46),(42,45,47,44),(14,22,30,38),(15,23,31,39),(16,24,32,40)], size=49)
G = PermutationGroup([F,B,L,R,U,D])
G.order()
43252003274489856000

Generally, IMHO it seems to me that the documentation is minimal.

Sorry to seem so critical. This is a great contribution to sympy by Aleksander and Chris!

@travisbot

This pull request passes (merged a4c1bef1 into d208118).

@smichr
SymPy member
@wdjoyner
@smichr
SymPy member
@travisbot

This pull request passes (merged a1ab0336 into d208118).

@travisbot

This pull request passes (merged dd2c0434 into d208118).

@wdjoyner

This is much better now and, in my opinion, ready to go in.
Thanks Chris!

@smichr
SymPy member

There is now a global flag that controls output:

>>> a = Permutation([[1,2],[5,3]])
>>> a
Cycle(1, 2)(3, 5)
>>> isinstance(_, Permutation)
True
>>> Cycle(a)
[(1, 2), (3, 5)]
>>> Permutation.print_cyclic = False
>>> a
Permutation([0, 2, 1, 5, 4, 3])

So when you see Permutation or Cycle you know you are working with a
Permutation instance printing in two different ways. This is maybe a bad
idea since copying and pasting Cycle(1, 2)(3, 5) will not give a
Permutation, it will give a Cycle.

I got rid of the __mul__ method for cycle so only the Cycle(1, 2)(2, 3)
sort of notation is allowed (not Cycle(1, 2)*(2,3)).

The problem with the global flag is that now doctests have to explicitly
set the flag or else a previous test with the flag off will affect another
test that things that the flag is on (because that's what the default is).

I've got to check that all the PermutationGroups calculate properly when
they get permutations in cycle form.

@smichr
SymPy member

Should coset_decomposition fail if the input permutation is shorter than those in the PermutationGroup?


        >>> from sympy.combinatorics import Permutation, Cycle
        >>> Permutation.print_cyclic = True
        >>> from sympy.combinatorics.perm_groups import PermutationGroup
        >>> a = Permutation([[0, 1, 3, 7, 6, 4], [2, 5]])
        >>> b = Permutation([[0, 1, 3, 2], [4, 5, 7, 6]])
        >>> G = PermutationGroup([a, b])

        >>> c = Permutation([[2, 4], [3, 5]])
        >>> c.array_form
        [0, 1, 4, 5, 2, 3, 6, 7]
        >>> G.has_element(c)
        True
        >>> G.coset_decomposition(c)
        [[0, 1, 2, 3, 4, 5, 6, 7],
         [0, 1, 2, 3, 4, 5, 6, 7],
         [0, 1, 4, 5, 2, 3, 6, 7]]
        >>> Permutation.lmul(*[Permutation(p) for p in _]) == c
        True

This succeeds because the routine now adjusts input c to have the same length as the group and the result compares == because __eq__ ignores trivial tails of permutations (i.e. Permutation([1, 0, 3, 4, 5]) == Permutation([1, 0])). Does this seem right, David?

@asmeurer
SymPy member

Yes. We could make the default printing for all permutations to be the
cyclic_form. I know we used to have a flag for how polys were printed...I
thought we got rid of that and I don't recall why. Can you comment, Aaron?

Are you talking about the order keyword, because that still exists?

@smichr
SymPy member

I think I have a sane method of representation for disjoint cycle and array forms. If you look at the docstring for Permutation i try to lay it out clearly.

@smichr
SymPy member

about the order keyword

Yes...I never use it and I know that Mateusz stripped something out at one point. Thanks for clarifying.

@travisbot

This pull request fails (merged 4b81be1f into d208118).

@travisbot

This pull request fails (merged 17d12a16 into d208118).

@wdjoyner
@travisbot

This pull request passes (merged 22607286 into d208118).

@travisbot

This pull request passes (merged a113079f into d208118).

@travisbot

This pull request fails (merged 79498c27 into d208118).

@travisbot

This pull request passes (merged 8bfba19c into d208118).

@travisbot

This pull request passes (merged 533d41ee into d208118).

@smichr
SymPy member

Does it makes sense to allow duplicate permutations in a PermutationGroup? I'm thinking not, and have made the changes accordingly.

@travisbot

This pull request fails (merged 17203029 into d208118).

@travisbot

This pull request fails (merged fdee9636 into d208118).

@wdjoyner
@pernici

_af_mul is slower than perm_af_muln previously defined; on my computer computing the order of
the Rubik cube takes 1.84s using _af_mul; using the code of perm_af_muln it takes 1.6s, and taking away
the check that Permutations have the same size, as in _af_mul in this PR (which does not seem to me to be
a good idea), it takes 1.54s; in particular _af_mul takes half the time as the one in this PR.

@pernici
    def __mul__(self, other):
        """
        Routine for multiplication of permutations following R to L order.

        Note
        ====

        a*b*c applies permutations in order c, b, a which is consistent with
        function notation abc(x) meaning a(b(c(x))).

I do not think this is correct; it is lmul which is consistent with the function notation

For instance

>>> from sympy.combinatorics import Permutation
>>> Permutation.print_cyclic = False
>>> p = Permutation([1, 2, 3, 0])
>>> q = Permutation([3, 2, 0, 1])
>>> Permutation.lmul(p, q)
Permutation([0, 3, 1, 2])
>>> [p.array_form[q.array_form[i]] for i in range(4)]              # p(q(x))
[0, 3, 1, 2]
>>> p*q
Permutation([2, 0, 1])

p*q is consistent with the exponential notation `x(p*q) = (xp)**q

@smichr
SymPy member

oops, you have to escape math or else the ** gets interpreted as bold.

Regarding L to R or R to L, we can ask "did p get applied
to q or vice versa. If p gets applied to q we take position 1 from q (which is 2)
then position 2 from q (0), etc... to obtain [2, 0, 1, 3]. This is R to L
order. If q gets applied to p then that is L to R order (which is what lmul
does. If you still think I am incorrect about this, please let me know. It took a long
time to convince myself of the order (and thinking about 3 permutations
rather than 2 helped to clarify the issue).

>>> p = Permutation([1, 2, 3, 0])
>>> q = Permutation([3, 2, 0, 1])
>>> r = Permutation([3, 1, 0, 2])
>>> p*q*r
Permutation(1, 3, 2)
>>> r*q*p
Permutation(0, 2)(1, 3)
>>> Permutation.lmul(p,q,r)
Permutation(0, 2)(1, 3)

p*q*r will apply q to r then p to that result whereas lmul(p, q, r) applies
q to *p* then r to that result: permutation are applied in the order
listed, from left to right, and so it is called lmul.

If you write [a[i] for i in b] you are applying b to a so

[p.array_form[q.array_form[i]] for i in range(4)]              # p(q(x))

is applying q to p: q's elements are selcting p's elements, so I would write q(p) (and I would write the code as

[P.array_form(qi) for qi in q.array_form]
@smichr
SymPy member

@asmeurer and all others. I think this is ready to go. I only wish I could discuss groups and cosets better. Also, there is the issue about the possible name change for coset_repr -> coset_decomposition and coset_decomposition->coset_factor. @wdjoyner or @pernici or @amakelov , do you have feedback about that name change?

@smichr
SymPy member

@pernici , I split _af_mul into _af_muln -- this should restore the performance.

@smichr
SymPy member

One further question: should we get rid of the space between elements so Permutation(1, 2, 3) shows as Permutation(1,2,3)?

@wdjoyner
@wdjoyner
@smichr
SymPy member
@smichr
SymPy member
@pernici

I split _af_mul into _af_muln -- this should restore the performance.

No, it does not; computing the Rubik cube order takes the same time as before.
_af_muln with 7 arguments makes 6 lists instead of one; using master only one list is made;
this is why it is faster.

@wdjoyner
@pernici

In the documentation of __mul__ it is written

        a*b*c applies permutations in order c, b, a which is consistent with
        function notation abc(x) meaning a(b(c(x))).

This is wrong; I quote here Bachmann in https://groups.google.com/forum/?fromgroups=#!topic/sympy/4ZzZxFbRIAo

Let us fix a set X we are considering the permutation group of, below I
will take X = {1, 2, 3, 4, 5}. A permutation of X is by definition a
bijective function f:X->X. It is specified uniquely by providing the
image of every element. We can write this in the short form
[f(1), f(2), f(3), f(4), f(5)]. In this way, every permutation is
represented by an array of constant size.
...

Now let's consider composition. There are two schools of thought. Let me
write * for "ordinary" (where I come from) composition, and . for
"weird" composition. By definition, if f, g are permutations, then the
permutation fg is the unique mapping such that (fg)(x) = f(g(x))
["apply right to left"], whereas (f.g)(x) = g(f(x)) ["apply left to
right"]. [*]

[] Note that this can be made to look more sensible (for some
definitions of sensible), by writing *arguments
on the left: applying f
to x can be written as (x)f, and then (x)(f.g) = ((x)f)g ...
<\quote>

(x)f is sometimes called exponential notation x**f.
This is the convention used in this PR.

@pernici

In the example you give

```>>> from sympy.combinatorics import Permutation

Permutation.print_cyclic = False
p = Permutation([1, 2, 3, 0])
q = Permutation([3, 2, 0, 1])
r = Permutation([3, 1, 0, 2])
pqr
Permutation([0, 3, 1, 2])
rqp
Permutation([2, 3, 0, 1])
[p.array_form[q.array_form[r.array_form[i]]] for i in range(4)]
[2, 3, 0, 1]

(x)(pqr) = (p(x))(qr) = (q(p(x)))*r = r(q(p(x)))

r(q(p(x))) is given by

>>> [r.array_form[q.array_form[p.array_form[i]]] for i in range(4)]
[0, 3, 1, 2]

You write

pqr will apply q to r then p to that result whereas lmul(p, q, r) applies
q to p then r to that result: permutation are applied in the order
listed, from left to right, and so it is called lmu

I do not think it is a good terminology to say that q is applied to r; q is applied to i in [0,1,..,n-1]
not to another permutation; at least in the sense of p*q, one can apply it to q as p**q == p.conjugate(q).

I think that the definition of p.conjugate(q) should be ~q*p*q, not as defined in the code, since

((x)p)q = (x)p*q = (x)q*~q*p*q = (x)q*p.conjugate(q)

@pernici

I do not think matrix_form is right; it is the Cauchy two-line form, so that

>>> a = Permutation([2, 0, 3, 1])
>>> a.matrix_form
[0, 1, 2, 3]
[2, 0, 3, 1]

not [1, 3, 0, 2].

@pernici

In the dostring of Permutation it is written

Any permutation can be represented as a set of transpositions

it should be as a sequence of transpositions, since the order matters.

@smichr
SymPy member
@smichr
SymPy member
@wdjoyner
@smichr
SymPy member

regarding the terminology for multiplication:

Do you have a recommendation for how to say this? Is "r selects from q and
the result selects from p" for p*q*r better?

Regarding mul and lmul. I could very well be wrong about the terminology
being used but this much is sure:

The code that uses lmul is applying permutations in the opposite order of
__mul__. So whatever order we describe for a*b*c, the opposite applies
to lmul(a, b, c).

@smichr
SymPy member

array_form is already taken for the explicit permutation so cauchy_form would be better.

@smichr
SymPy member

OK, _af_mul is almost back to master...I don't like the recursive call, though...how is the performance now?

@pernici

OK, _af_mul is almost back to master...I don't like the recursive call, though...how is the performance now?

It is fine for the Rubik cube, since there are at most products of 7 permutations; for more than 8 permutations
it is still slow without the recursion; why do you not like it?

smichr and others added some commits Sep 3, 2012
@smichr smichr combinatorics: __eq__ uses cyclic_form 041291f
@smichr smichr combinatorics: (a) implement cycle I/O for Permutation c83f573
@smichr smichr permutations: rewrite docs 0c7dd8d
@smichr smichr PERM -> Permutation 9c7d8b5
@smichr smichr coset_rank aligns size of g cbe679d
@smichr smichr permutation: better checking of input c01f1cc
@smichr smichr permutations: fix max() error 0bb3a79
@smichr smichr permutations: add matrix_form method and update docstrings af84c76
@smichr smichr combinatorics: add is_group method and docstring in polyhedron b22723b
@smichr smichr combinatorics: PermutationGroup raises error if gens are duplicated
raise error in PermutationGroup if duplicate permutations are received

remove duplicate permutations from DirectProduct before passing to
PermutationGroup

remove duplicate from names_groups before sending to PermutationGroup

util
    change orbs -> orbits

perm_groups:
    use range instead of xrange in perm_groups
    clean up test for Identity generator
    clean up loop testing whether a new base should be added
    clean up tracking of _base length

permutations:
    make sure perm is a list; if it is a tuple a different obj is
    created -- this is faster than just making it a list and also
    creates a small level of safety for the private routine

    is_Identity will short circuit now without having to generate
    the entire list to make the comparison
9ea9fa7
@smichr smichr combinatorics: simplify is_trivial calc 8a0c0dc
@smichr smichr permutation: work with ints 432ae5d
@smichr smichr permutation: split af_mul into af_muln e0e27df
@smichr smichr permutations: raise error for missing 0; filter gens for PermutationG…
…roup

group_constructs
    use dups=False
named_groups
    use dups=False
perm_groups
    allow duplicate checking to sbe skipped with dups=False keyword
permutations
    don't add 0 by default to permutations entered in array form
    (entering in cycle form automatically adds it, however)

    no: Permutation([2,3,1,4])
    yes:
    >>> Permutation(1, 2, 3, size=5).array_form
    [0, 2, 3, 1, 4]
    >>> Cycle(1,2,3)(4).as_list()
    [0, 2, 3, 1, 4]
    >>> Cycle(1,2,3).as_list(5)

tests modified in keeping with the above
2a08a49
@smichr smichr permutations: differentiate between None and 0 in as_list ebf1cd2
@smichr smichr permutations: add not to lmul docstring about L to R order 30ac89b
@smichr smichr permutations: always show the size when printing 644853b
@smichr smichr perm_groups: clean up coset_decomposition -> coset_factor 445be4a
@smichr smichr coset_factor: return [] instead of False 2cce155
@smichr smichr coset_factor: look for quick exits 873fff4
@smichr smichr perm_groups: coset_repr -> coset_decomposition 48b953a
@smichr smichr permutations: return transpositions factors as list, not set f01d0d6
@smichr smichr _af_mul special cases up to 8 factors d976353
@smichr smichr combinatorics: lmul -> mul; __xor__ -> conjugate
The computation of the product of more than 8 items in _af_mul (now
_af_rmul) was made to only create 1 intermediate list.

The discussion about R or L multiplication was dropped in favor of
just demonstrating what was meant, e.g. a(b(c(i))), and giving a
corresponding doctest.

The __xor__ method was mapped to conjugate so now a^b given a.conjugate(b)

The subgroup_search test for size 16 was xfailed as slow.
2016b3d
@smichr smichr combinatorics: Permutations not equal unless size is equal, too
Things are slowed down considerably when testing cyclic forms, and
allowing permutations of different lengths to compare equal leaves
open the possibiliity of subtle errors. Permutations now compare
equal only if their array forms are equal.

An error is also raise for coset_factor if the g to be factored is
not the same length as the permutations in the group.
c6cf17e
@smichr smichr permutations: fix sphinx error 2f1ab6e
@smichr smichr polyhedron: reorder tetrahedron permutations 0e03412
@smichr smichr cube: add inline references for the pgroup 188f178
@smichr smichr permutations: make sure largest is printed first in permutation cycli…
…c form

The output should be copyable and pastable for reevaluation, and it
won't be if it is printed like Permutation(1,2)(5) instead of
Permutation(5)(1,2).
9d2067a
@smichr smichr perm_groups: minor docstring edits 7c292d8
@smichr smichr permutations: cleanup docstring 0424fdf
@smichr smichr permutation: define _hashable_content 4595ff4
@smichr smichr permutations: remove cauchy form; edit docstrings cb18cb5
@rlamy rlamy Move int_tested to the core and refactor it.
* Move int_tested() to sympy.core.compatibility, to make it
  importable anywhere.
* Simplify it to take only a single argument, like int().
* Rename it as_int().

cps: add compatibility to core.rst
717d4e3
@smichr smichr permutations: restore recursive _af_rmul 44da66e
@smichr smichr polyhedron: edit docstrings 98f2ed9
@smichr smichr permutations: change docstring so r*q!=q*r 277274a
@smichr smichr prem_groups: coset_decomposition -> stabilizer_cosets; stabilizers_ge…
…ns -> stabilizer_gens
68a8d33
@smichr smichr permutations: add note about static arrow diagrams 0750839
@smichr smichr permutations: add as_permutation method
This is inspired by the Mathematica function FindPermutation.

dec
208c021
@smichr smichr perm_groups: expand is_group docstring and modify generate docstring d6e08ca
@smichr smichr permutations: remove __xor__ operator
This is being removed until the question of whether a.conjugate(b)
should give ~a*b*a or a*b*~a.
09aae58
@smichr smichr permutations: change commutator and conjugate docstrings
Permutations were selected for commutator so xp~x~p != ~p~xpx
2c68a68
@smichr smichr as_permutation -> from_sequence ea6cbeb
@pernici pernici permutations: used __xor__ instead pf __pow__ for conjugation
In addition,

used __rxor__ to represent the application i --> i^p

Changes by Chris Smith (smichr@gmail.com)

removed conjugate method in favor or only the __xor__ method
and introduced a test function, conjugate_of to test whether
self and other are conjugates of each other.

other docstring edits
f74a09e
@pernici
    def conjugate_of(self, other):
        """Return True if self and other are conjugates, else False.

If two permutations have the same cycle structure, they are conjugates
in S_n, but not necessarily in another permutation group.

see http://math.stackexchange.com/questions/48134/why-are-two-permutations-conjugate-iff-they-have-the-same-cycle-structure

I suggest to specify that it is a test whether they are conjugate in S_n; the alternative is to add as default
parameter group=S_n, compute h such that self = other^h and check if h belongs to the group,
but I do not think it is a good idea.

@pernici

I do not think it is a good idea to introduce the division by a permutation, since permutations do not commute.

@asmeurer
SymPy member

I haven't been following this or the other PR that it shadows very closely. Please ping me when it's ready to be merged.

smichr and others added some commits Sep 11, 2012
@smichr smichr permutations: +/- on basis of rank
Partitions and Prufer add on the basis of rank and this seems to
be a better idea than adding the elements of the inversion code
together.

rank(i) now gives ith permutation

modify which form of the commutator is returned
523f73a
@smichr smichr named_groups: add the 3 polyhedral groups 6903994
@smichr smichr permutations: Cycle gets size property and __iter__ 4487a92
@smichr smichr permutations: as_list -> list method fa90805
@smichr smichr permutations: remove conjugate_of 0a31443
@smichr smichr named_groups: remove Polyhedral groups
I'm not confident enough that I understand what someone would expect
for these groups, so I'm leaving them out. They should be easy to add
back and modify if necessary.
61a9211
@smichr smichr permutations: remove test functions 660108c
@smichr smichr permutations: cycle_structure method added e952282
@smichr smichr permutations: add note about getting h*f*~h instead of ~h*f*h 029ca86
@smichr smichr iterables: lazyDSU_sort added ae76b99
@smichr smichr permutations: make cycle_structure a property; return dict 72d63d7
@smichr smichr perm_groups: remove has; add _hashable_content 165707f
@smichr smichr fix permutation str test 569d161
@smichr smichr permutation: Permutation has list method, too 0cc5f75
@smichr smichr move quick_sort to compatibility 3928e43
@smichr smichr permutations: add to contains docstring 2fb0465
@smichr smichr fix sphinx errors in compatibility 68217a3
@smichr smichr fix Permutation and PermutationGroup args 69f14da
@smichr smichr perm_groups: minor edits of insert
There is no need to append element [0,...,cmin] to the end of the
range starting from cmin since negative indices handle this just
fine.

ig was changed to gi since it represents g[i] and ig is similar to jg
which is short for JerrumGraph.

There is no need to do double work in testing to see if g is Identity
and then search for the min change. If there is no min change then
it's the identity. The only caveat would be if one got a g like
[2,1,0,3,4,5] and alpha was 3: None would be returned and the routine
would have failed. For safety, an assertion could be made that if i
is None then g[:cmin] == range(cmin)...this has not been done and no
test has failed to it was left out.
5faabf9
@smichr smichr named_groups: fix docstring d3989e4
@smichr smichr examples: minor edits d6d8759
@smichr smichr add reshape to iterables 1692d79
@smichr smichr perm_groups: remove bisect 912ff2e
@smichr smichr fix str error for PermutationGroup dee3ba2
@pernici pernici Changed is_subgroup to admit that a group can be subgroup of a group
with larger degree
69e60a3
@smichr smichr fix str error f36b1de
@smichr smichr Merge pull request #15 from pernici/combinatorics
Changed is_subgroup to admit that a group can be subgroup of a group with larger degree
cd0ff48
@smichr smichr Merge branch 'combinatorics' of github.com:smichr/sympy into combinat…
…orics
5da3f9f
@smichr smichr fix perm_group docstring 2a86561
@smichr smichr perm: add trivial check to contains 1f6dcca
@smichr smichr permutations: removed unused imports and tuplizatation of args 1ea38fa
@smichr smichr fix trouble with hash and PermutationGroup
The redefining of __eq__ required that __hash__ also be defined
as noted now in the __eq__ docstring that was edited in Basic.
32a7c3a
@smichr smichr perm_groups: minor edits 5d82051
@smichr smichr move __eq__ to contains; __eq__ is more literal 556cc4e
@smichr smichr move the old __eq__ code from contains to is_in e1ef520
@smichr smichr merge is_in and is_subgroup with strict option 9668728
@pernici pernici fixed bug in the computation of the strong base 6a4830a
@pernici pernici Added default argument `strict` to is_transitive` 8df042c
@smichr smichr Merge pull request #16 from pernici/combinatorics
Added default argument `strict` to is_transitive`; fixed bug in `base`
eeb5b73
@smichr smichr is_transitive: False for strict=False possible 77fe489
@smichr smichr contains gets strict option e1b091b
@smichr smichr resize in contains rather than in is_subgroup ea5bf22
@pernici pernici Faster coset_factor and coset_rank 51a50f1
@smichr smichr stabilizer_cosets, coset_factor and gens come back as permutations
af=True will send them back in array form
d08c9dc
@smichr smichr fix error in simplify with use of has_variety 419d310
@smichr
SymPy member

#1508 is now in.

@smichr smichr closed this Sep 18, 2012
@coveralls

Coverage Status

Changes Unknown when pulling 419d310 on smichr:combinatorics into ** on sympy:master**.

@coveralls

Coverage Status

Changes Unknown when pulling 419d310 on smichr:combinatorics into ** on sympy:master**.

@coveralls

Coverage Status

Changes Unknown when pulling 419d310 on smichr:combinatorics into ** on sympy:master**.

@coveralls

Coverage Status

Changes Unknown when pulling 419d310 on smichr:combinatorics into ** on sympy:master**.

@coveralls

Coverage Status

Changes Unknown when pulling 419d310 on smichr:combinatorics into ** on sympy:master**.

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