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

Added function to check if a group is Cyclic or not #16522

Merged
merged 10 commits into from
Apr 6, 2019

Conversation

divyanshu132
Copy link
Member

Brief description of what is fixed or changed

Added method is_cyclic for both PermutationGroup and FpGroup. Also, added a method to compute the exponent of a PermutationGroup.

Other comments

Release Notes

  • combinatorics
    • added functions is_cyclic and exponent

@sympy-bot
Copy link

sympy-bot commented Mar 31, 2019

Hi, I am the SymPy bot (v145). I'm here to help you write a release notes entry. Please read the guide on how to write release notes.

Your release notes are in good order.

Here is what the release notes will look like:

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.5.

Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it.

Click here to see the pull request description that was parsed.

<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234". See
https://github.com/blog/1506-closing-issues-via-pull-requests . Please also
write a comment on that issue linking back to this pull request once it is
open. -->


#### Brief description of what is fixed or changed

Added method `is_cyclic` for both `PermutationGroup` and FpGroup. Also, added a method to compute the exponent of a PermutationGroup.
#### Other comments


#### Release Notes

<!-- Write the release notes for this release below. See
https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more information
on how to write release notes. The bot will check your release notes
automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
*  combinatorics
   *  added functions is_cyclic and exponent
<!-- END RELEASE NOTES -->

Update

The release notes on the wiki have been updated.

@divyanshu132
Copy link
Member Author

@jksuom please review!

@codecov
Copy link

codecov bot commented Mar 31, 2019

Codecov Report

Merging #16522 into master will increase coverage by 0.079%.
The diff coverage is 65.714%.

@@              Coverage Diff              @@
##            master    #16522       +/-   ##
=============================================
+ Coverage   73.677%   73.757%   +0.079%     
=============================================
  Files          618       619        +1     
  Lines       158567    158656       +89     
  Branches     37224     37185       -39     
=============================================
+ Hits        116828    117020      +192     
+ Misses       36322     36217      -105     
- Partials      5417      5419        +2

False

"""
if len(self.generators) == 1:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about the trivial case (no generators)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll include that.

Copy link
Member Author

@divyanshu132 divyanshu132 Apr 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like that will also have length of 1 for permutation group but I have added for Fp group.

>>> g=PermutationGroup()
>>> g.generators
[Permutation()]
>>> len(g.generators)
1
>>> g=PermutationGroup([Permutation(1,2,3)])
>>> len(g.generators)
1

return True
if not self.is_abelian:
return False
for p in primefactors(self.order()):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order should probably be finite.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for the current implementation order is finite, For infinite order we probably have to implement Abelian Invariants which I have included in my GSoC proposal!

@jksuom
Copy link
Member

jksuom commented Apr 1, 2019

Would it be possible to implement is_cyclic first for permutation groups and then extend that to finitely presented groups using the methods of #13119? That way a single copy of the algorithm would suffice.

@divyanshu132
Copy link
Member Author

@jksuom I'll look into it.

pgens = []
for g in self.generators:
pgens.append(g**p)
K, T = self.subgroup(pgens, homomorphism=True)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually both the is_cyclic methods are not completely same there is a slight difference so, I doubt it if a single method would be suffice or not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that is_cyclic has different meanings for permutation groups and finitely presented groups?

Copy link
Member Author

@divyanshu132 divyanshu132 Apr 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually we are using the method .subgroup which has been defined separately for both the permutation groups and fp groups also we are keeping homomorphism=True in the subgroup method so that we can have a list of generators which can be passed to the index method below. Otherwise the generators will simply produce the free variables and we will not be able to compute the index below.

But this is not the case in permutation group where the subgroup method directly returns a group via which index can be calculated easily.

Copy link
Member Author

@divyanshu132 divyanshu132 Apr 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess is_cyclic is same for both but it actually depends on the implementation of subgroup method which works differently.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to apply PermutationGroup.is_cyclic also for an instance of FpGroup by transforming it to a permutation group using _to_perm_group? One could first check the 0-1 generator cases.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we can do this.

>>> F, x, y = free_group("x, y")
>>> f = FpGroup(F, [x*y*x**-1*y**-1, y**5, x**4])
>>> g, t = f._to_perm_group()
>>> g.is_cyclic()
True
>>> g
PermutationGroup([
    (0 1 5 2)(3 6 12 8)(4 7 13 9)(10 14 18 16)(11 15 19 17),
    (0 3 10 11 4)(1 6 14 15 7)(2 8 16 17 9)(5 12 18 19 13)])

@divyanshu132
Copy link
Member Author

@jksuom can this be merged.

False

"""
if self.order() == S.Infinity:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An infinite group could be cyclic if there is only one generator.

@jksuom
Copy link
Member

jksuom commented Apr 2, 2019

A finite group can handled in two ways. Which method is more efficient, FpGroup.is_cyclic or PermutationGroup.is_cyclic.

@divyanshu132
Copy link
Member Author

PermutationGroup.is_cyclic is far more efficient than FpGroup.is_cyclic.

@divyanshu132
Copy link
Member Author

>>> F, x, y = free_group("x, y")
>>> f = FpGroup(F, [x*y*x**-1*y**-1, y**5, x**4])
>>> f.is_cyclic()
elapsed_time =  0.23461808000000017
True

>>> g, t = f._to_perm_group()
>>> g.is_cyclic()
elapsed_time =  0.0021614229999999957
True

@jksuom
Copy link
Member

jksuom commented Apr 2, 2019

PermutationGroup.is_cyclic is far more efficient than FpGroup.is_cyclic.

That is what I expected. Therefore I suggested that the FpGroup method would apply _to_perm_group after it has been checked that the group is finite.

@divyanshu132
Copy link
Member Author

@jksuom thanks, for pointing it out, you were right we can easily use _to_perm_group to reduce the execution time of is_cyclic for Fp groups. I've updated the PR please have a look.

Should I convert is_cyclic to property?

@jksuom
Copy link
Member

jksuom commented Apr 4, 2019

It seems that is_cyclic could be a property like the other is_... methods.

Return ``True`` if group is Cyclic.

"""
if len(self.generators) == 0 or len(self.generators) == 1:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be len(self.generators) <= 1

"""
if len(self.generators) == 0 or len(self.generators) == 1:
return True
P, T = self._to_perm_group()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_to_perm_group will raise NotImplementedError if the group is infinite. That can be raised also here but the error message should probably be changed. Maybe something like this:

try:
    P, _ = self._to_perm_group()
except NotImplementedError:
    raise NotImplementedError("suitable message")

@divyanshu132
Copy link
Member Author

@jksuom I've done the above changes please have a look.

@jksuom
Copy link
Member

jksuom commented Apr 4, 2019

The purpose of self._is_cyclic is to act as a cache. Initially, it is None but it should be set when the question is decided for the first time. Next time it would suffice to check if it has been changed.

@divyanshu132
Copy link
Member Author

@jksuom can this be merged now!

@jksuom
Copy link
Member

jksuom commented Apr 5, 2019

It looks good otherwise but I am not sure about exponent if the generators do not commute. Maybe that should be left to another PR.

@divyanshu132
Copy link
Member Author

Okay I'll remove it for this PR.

@@ -1,6 +1,8 @@
"""Finitely Presented Groups and its algorithms. """

from __future__ import print_function, division
from sympy.ntheory import primefactors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably not needed.

@@ -2,6 +2,8 @@

from random import randrange, choice
from math import log
from sympy.ntheory import primefactors
from sympy.polys import lcm
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh I forget to remove it!

@divyanshu132
Copy link
Member Author

@jksuom I think now this can be merged.

@jksuom
Copy link
Member

jksuom commented Apr 6, 2019

Thanks.

@jksuom jksuom merged commit fa19fc7 into sympy:master Apr 6, 2019
@divyanshu132 divyanshu132 deleted the is-cyclic branch April 6, 2019 08:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants