GroupsMath 0.7.1__tar.gz → 0.7.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GroupsMath
3
- Version: 0.7.1
3
+ Version: 0.7.2
4
4
  Summary: The educational Python library for Group Theory
5
5
  Author-email: Mario Sultan Romero <mariosultan.uem@gmail.com>
6
6
  License: PolyForm Strict License 1.0.0.
@@ -20,13 +20,13 @@ Requires-Dist: matplotlib>=3.0.0
20
20
  Requires-Dist: numpy>=1.20.0
21
21
  Dynamic: license-file
22
22
 
23
- # GroupsMath – v0.7.1 – release candidate for v1.0.0
23
+ # GroupsMath – v0.7.2 – release candidate for v1.0.0
24
24
 
25
25
  [![PyPI Downloads](https://img.shields.io/pypi/dm/groupsmath)](https://pypistats.org/packages/groupsmath)
26
26
  [![PyPI Version](https://img.shields.io/pypi/v/groupsmath?color=2A646E)](https://pypi.org/project/groupsmath/)
27
27
  [![Python Versions](https://img.shields.io/pypi/pyversions/groupsmath?color=2A646E)](https://pypi.org/project/groupsmath/)
28
28
  ![Last Commit](https://img.shields.io/github/last-commit/MarioSultan/groupsmath?color=2A646E)
29
- ![coverage](https://img.shields.io/badge/road%20to%20v1.0.0-95%25-yellowgreen?color=2A646E)
29
+ ![coverage](https://img.shields.io/badge/road%20to%20v1.0.0-97%25-yellowgreen?color=2A646E)
30
30
  <!-- ![GitHub Stars](https://img.shields.io/github/stars/MarioSultan/groupsmath?style=social) -->
31
31
 
32
32
 
@@ -39,18 +39,18 @@ The project aims to provide a **simple** and **intuitive** interface for working
39
39
 
40
40
  ![Examples](https://raw.githubusercontent.com/MarioSultan/GroupsMath/main/imgs/examples.png)
41
41
 
42
- [![Launch Binder](https://raw.githubusercontent.com/MarioSultan/GroupsMath/main/imgs/here.png)](https://mybinder.org/v2/gh/MarioSultan/GroupsMath/main?labpath=GroupsMath_demo.ipynb)
43
-
44
42
  > Visit here the [GroupsMath official documentation](https://groupsmath.readthedocs.io/en/latest/).
45
43
 
46
- > **⚠️ Notice:** Version v1.0.0 is nearing its official release.
47
44
 
45
+ ---
46
+
47
+ [![Launch Binder](https://raw.githubusercontent.com/MarioSultan/GroupsMath/main/imgs/here.png)](https://mybinder.org/v2/gh/MarioSultan/GroupsMath/main?labpath=GroupsMath_demo.ipynb)
48
48
 
49
49
  ---
50
50
 
51
51
  ## Installation
52
52
 
53
- GroupsMath is currently distributed through [PyPI](https://pypi.org/project/GroupsMath/) and [Github](https://github.com/MarioSultan/GroupsMath). To install the latest released version from PyPI, run:
53
+ GroupsMath is currently distributed through [PyPI](https://pypi.org/project/GroupsMath/) and [Github](https://github.com/MarioSultan/GroupsMath). To install the latest released version from PyPI, run the following in your preferred terminal (VS code, Jupyter, ...).
54
54
 
55
55
  ```bash
56
56
  pip install groupsmath
@@ -129,6 +129,7 @@ GroupsMath is designed to provide tools for working with finite (and infinite) g
129
129
  * Quotient groups $Q=G/H$.
130
130
  * Conmutator and derived subgroups $G'$.
131
131
  * Abelianization $G/G'$
132
+ * Hasse diagrams. (*experimental feature*)
132
133
 
133
134
  **AUTOMORPHISMS:**
134
135
  * Class `Automorphism` and automorphism functions.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GroupsMath
3
- Version: 0.7.1
3
+ Version: 0.7.2
4
4
  Summary: The educational Python library for Group Theory
5
5
  Author-email: Mario Sultan Romero <mariosultan.uem@gmail.com>
6
6
  License: PolyForm Strict License 1.0.0.
@@ -20,13 +20,13 @@ Requires-Dist: matplotlib>=3.0.0
20
20
  Requires-Dist: numpy>=1.20.0
21
21
  Dynamic: license-file
22
22
 
23
- # GroupsMath – v0.7.1 – release candidate for v1.0.0
23
+ # GroupsMath – v0.7.2 – release candidate for v1.0.0
24
24
 
25
25
  [![PyPI Downloads](https://img.shields.io/pypi/dm/groupsmath)](https://pypistats.org/packages/groupsmath)
26
26
  [![PyPI Version](https://img.shields.io/pypi/v/groupsmath?color=2A646E)](https://pypi.org/project/groupsmath/)
27
27
  [![Python Versions](https://img.shields.io/pypi/pyversions/groupsmath?color=2A646E)](https://pypi.org/project/groupsmath/)
28
28
  ![Last Commit](https://img.shields.io/github/last-commit/MarioSultan/groupsmath?color=2A646E)
29
- ![coverage](https://img.shields.io/badge/road%20to%20v1.0.0-95%25-yellowgreen?color=2A646E)
29
+ ![coverage](https://img.shields.io/badge/road%20to%20v1.0.0-97%25-yellowgreen?color=2A646E)
30
30
  <!-- ![GitHub Stars](https://img.shields.io/github/stars/MarioSultan/groupsmath?style=social) -->
31
31
 
32
32
 
@@ -39,18 +39,18 @@ The project aims to provide a **simple** and **intuitive** interface for working
39
39
 
40
40
  ![Examples](https://raw.githubusercontent.com/MarioSultan/GroupsMath/main/imgs/examples.png)
41
41
 
42
- [![Launch Binder](https://raw.githubusercontent.com/MarioSultan/GroupsMath/main/imgs/here.png)](https://mybinder.org/v2/gh/MarioSultan/GroupsMath/main?labpath=GroupsMath_demo.ipynb)
43
-
44
42
  > Visit here the [GroupsMath official documentation](https://groupsmath.readthedocs.io/en/latest/).
45
43
 
46
- > **⚠️ Notice:** Version v1.0.0 is nearing its official release.
47
44
 
45
+ ---
46
+
47
+ [![Launch Binder](https://raw.githubusercontent.com/MarioSultan/GroupsMath/main/imgs/here.png)](https://mybinder.org/v2/gh/MarioSultan/GroupsMath/main?labpath=GroupsMath_demo.ipynb)
48
48
 
49
49
  ---
50
50
 
51
51
  ## Installation
52
52
 
53
- GroupsMath is currently distributed through [PyPI](https://pypi.org/project/GroupsMath/) and [Github](https://github.com/MarioSultan/GroupsMath). To install the latest released version from PyPI, run:
53
+ GroupsMath is currently distributed through [PyPI](https://pypi.org/project/GroupsMath/) and [Github](https://github.com/MarioSultan/GroupsMath). To install the latest released version from PyPI, run the following in your preferred terminal (VS code, Jupyter, ...).
54
54
 
55
55
  ```bash
56
56
  pip install groupsmath
@@ -129,6 +129,7 @@ GroupsMath is designed to provide tools for working with finite (and infinite) g
129
129
  * Quotient groups $Q=G/H$.
130
130
  * Conmutator and derived subgroups $G'$.
131
131
  * Abelianization $G/G'$
132
+ * Hasse diagrams. (*experimental feature*)
132
133
 
133
134
  **AUTOMORPHISMS:**
134
135
  * Class `Automorphism` and automorphism functions.
@@ -1,10 +1,10 @@
1
- # GroupsMath – v0.7.1 – release candidate for v1.0.0
1
+ # GroupsMath – v0.7.2 – release candidate for v1.0.0
2
2
 
3
3
  [![PyPI Downloads](https://img.shields.io/pypi/dm/groupsmath)](https://pypistats.org/packages/groupsmath)
4
4
  [![PyPI Version](https://img.shields.io/pypi/v/groupsmath?color=2A646E)](https://pypi.org/project/groupsmath/)
5
5
  [![Python Versions](https://img.shields.io/pypi/pyversions/groupsmath?color=2A646E)](https://pypi.org/project/groupsmath/)
6
6
  ![Last Commit](https://img.shields.io/github/last-commit/MarioSultan/groupsmath?color=2A646E)
7
- ![coverage](https://img.shields.io/badge/road%20to%20v1.0.0-95%25-yellowgreen?color=2A646E)
7
+ ![coverage](https://img.shields.io/badge/road%20to%20v1.0.0-97%25-yellowgreen?color=2A646E)
8
8
  <!-- ![GitHub Stars](https://img.shields.io/github/stars/MarioSultan/groupsmath?style=social) -->
9
9
 
10
10
 
@@ -17,18 +17,18 @@ The project aims to provide a **simple** and **intuitive** interface for working
17
17
 
18
18
  ![Examples](https://raw.githubusercontent.com/MarioSultan/GroupsMath/main/imgs/examples.png)
19
19
 
20
- [![Launch Binder](https://raw.githubusercontent.com/MarioSultan/GroupsMath/main/imgs/here.png)](https://mybinder.org/v2/gh/MarioSultan/GroupsMath/main?labpath=GroupsMath_demo.ipynb)
21
-
22
20
  > Visit here the [GroupsMath official documentation](https://groupsmath.readthedocs.io/en/latest/).
23
21
 
24
- > **⚠️ Notice:** Version v1.0.0 is nearing its official release.
25
22
 
23
+ ---
24
+
25
+ [![Launch Binder](https://raw.githubusercontent.com/MarioSultan/GroupsMath/main/imgs/here.png)](https://mybinder.org/v2/gh/MarioSultan/GroupsMath/main?labpath=GroupsMath_demo.ipynb)
26
26
 
27
27
  ---
28
28
 
29
29
  ## Installation
30
30
 
31
- GroupsMath is currently distributed through [PyPI](https://pypi.org/project/GroupsMath/) and [Github](https://github.com/MarioSultan/GroupsMath). To install the latest released version from PyPI, run:
31
+ GroupsMath is currently distributed through [PyPI](https://pypi.org/project/GroupsMath/) and [Github](https://github.com/MarioSultan/GroupsMath). To install the latest released version from PyPI, run the following in your preferred terminal (VS code, Jupyter, ...).
32
32
 
33
33
  ```bash
34
34
  pip install groupsmath
@@ -107,6 +107,7 @@ GroupsMath is designed to provide tools for working with finite (and infinite) g
107
107
  * Quotient groups $Q=G/H$.
108
108
  * Conmutator and derived subgroups $G'$.
109
109
  * Abelianization $G/G'$
110
+ * Hasse diagrams. (*experimental feature*)
110
111
 
111
112
  **AUTOMORPHISMS:**
112
113
  * Class `Automorphism` and automorphism functions.
@@ -21,7 +21,7 @@ from math import gcd
21
21
 
22
22
  #################### DEFINITIONS ####################
23
23
 
24
- __version__ = "0.7.1"
24
+ __version__ = "0.7.2"
25
25
  __errorcolor__ = "\033[31m"
26
26
 
27
27
  tgl_color = "#2A646E"
@@ -30,6 +30,8 @@ tgl = mcolors.LinearSegmentedColormap.from_list("tgl", ["white", tgl_color])
30
30
  rainbow = mcolors.LinearSegmentedColormap.from_list("rainbow", ["#FF0000","#FF9100","#F2DA00","#2CDB00","#00DAE9","#1869FF"])#,"#7648FF","#D12BFF"])
31
31
  rainbow8 = mcolors.LinearSegmentedColormap.from_list("rainbow8", ["#FF0000","#FF9100","#F2DA00","#2CDB00","#00DAE9","#1869FF","#7648FF","#FF1FF4"])
32
32
 
33
+ standard = ["#FF0000", "#1869FF", "#2CDB00", "#F2DA00", "#7648FF", "#FF9100", "#00DAE9", "#FF1FF4", "#000000", "#888888"]
34
+
33
35
  def groupsmath_info():
34
36
  print("———————————————————————————————————————————————————————————————————————————")
35
37
  print(" ")
@@ -45,7 +47,7 @@ def groupsmath_info():
45
47
  print("· GitHub \033[36mhttps://github.com/MarioSultan/GroupsMath \033[0m ")
46
48
  print(" ")
47
49
  print("The documentation of this library is in the following link: ")
48
- print("· Documentation \033[36mhttps://github.com/MarioSultan/GroupsMath/tree/main/docs \033[0m ")
50
+ print("· Documentation \033[36mhttps://groupsmath.readthedocs.io/en/latest/ \033[0m ")
49
51
  print(" ")
50
52
  print("———————————————————————————————————————————————————————————————————————————")
51
53
 
@@ -184,6 +186,9 @@ class ExplicitGroup(Group):
184
186
  def cayley_table(self, title="", colormap=rainbow, names=None, math_mode=True):
185
187
  return self.toCayleyGroup().cayley_table(title=title, colormap=colormap, names=names, math_mode=math_mode)
186
188
 
189
+ def cayley_graph(self, generators=None, title="", colormap=standard, names=None, edgenames=None, math_mode=True, node_size=1000):
190
+ return self.toCayleyGroup.cayley_graph(generators=generators, title=title, colormap=colormap, names=names, edgenames=edgenames, math_mode=math_mode, node_size=node_size)
191
+
187
192
  #–> SUBGROUPS
188
193
 
189
194
  def proper_subgroups(self):
@@ -561,6 +566,62 @@ class CayleyGroup(Group):
561
566
  def delete_names(self):
562
567
  self.elements = [i for i in range(len(self.elements))]
563
568
 
569
+ def cayley_graph(self, generators=None, title="", colormap=standard, names=None, edgenames=None, math_mode=True, node_size=1000):
570
+
571
+ import networkx as nx
572
+
573
+ if generators==None:
574
+ generators = self.generators()
575
+ else:
576
+ if not self.generates(generators):
577
+ raise ValueError(__errorcolor__+"The set provided does not generate the group.")
578
+
579
+ if names==None:
580
+ if len(self)<=20:
581
+ names=True
582
+ else:
583
+ names=False
584
+
585
+ if edgenames==None:
586
+ if len(self)<=20:
587
+ edgenames=True
588
+ else:
589
+ edgenames=False
590
+
591
+ gr = nx.DiGraph()
592
+
593
+ if math_mode:
594
+ for i in self.elements:
595
+ gr.add_node("$"+str(i)+"$")
596
+ for i in self.elements:
597
+ for j in range(len(generators)):
598
+ gr.add_edge("$"+str(i)+"$","$"+str(self.operation(i,generators[j]))+"$",label=generators[j], color=colormap[j])
599
+ else:
600
+ for i in self.elements:
601
+ gr.add_node(str(i))
602
+ for i in self.elements:
603
+ for j in range(len(generators)):
604
+ gr.add_edge(str(i),str(self.operation(i,generators[j])),label=generators[j], color=colormap[j])
605
+
606
+
607
+ colors = [gr.edges[u, v]["color"]for u, v in gr.edges]
608
+
609
+ if edgenames:
610
+ edge_labels = nx.get_edge_attributes(gr, "label")
611
+ else:
612
+ edge_labels = []
613
+
614
+ pos = nx.spring_layout(gr)
615
+
616
+ if names:
617
+ nx.draw(gr,pos,with_labels=True, node_color="white", edgecolors="black", edge_color=colors, width=3, node_size=node_size)
618
+ nx.draw_networkx_edge_labels(gr, pos, edge_labels=edge_labels)
619
+ else:
620
+ nx.draw(gr,pos,with_labels=False, node_color="black", edge_color=colors, width=3, node_size=250)
621
+
622
+ plt.title(title)
623
+ plt.show()
624
+
564
625
  #–> SUBGROUPS
565
626
 
566
627
  def proper_subgroups(self):
@@ -706,6 +767,128 @@ class CayleyGroup(Group):
706
767
  def is_solvable(self):
707
768
  return len(self.derived_series()[-1]) == 1
708
769
 
770
+ def hasse_diagram(self):
771
+
772
+ import networkx as nx
773
+ from groupsmath.structure import structure_description
774
+
775
+ S = self.subgroups()
776
+ N = [] # name
777
+ R = [] # ratio
778
+ for i in S:
779
+ N.append(structure_description(i.subgroup))
780
+ R.append(int(len(self)/len(i)))
781
+
782
+ o = []
783
+ i = 0
784
+ while i<len(R):
785
+ if R[i] not in o:
786
+ o.append(R[i])
787
+ i+=1
788
+
789
+ O = {o[i]:i for i in range(len(o))}
790
+
791
+ H = []
792
+ for i in range(len(o)):
793
+ H.append([])
794
+
795
+ for i in range(len(S)):
796
+ H[O[R[i]]].append(S[i])
797
+
798
+ #print(f"N = {N}",f"R = {R}",f"o = {o}",f"O = {O}",f"H = {H}",sep="\n")
799
+
800
+ ########## Nodos y aristas ##########
801
+
802
+ gr = nx.DiGraph()
803
+
804
+ for i in range(len(S)):
805
+ gr.add_node(i,label=structure_description(S[i].subgroup))
806
+
807
+ for i in range(len(S)):
808
+ for j in range(i,len(S)):
809
+ if S[i]._is_covered(S[j]):
810
+ gr.add_edge(i,j)
811
+
812
+ ########## Posiciones ##########
813
+
814
+ pos = {}
815
+
816
+ dx = 2
817
+ dy = 2
818
+ min_distance = dx
819
+
820
+ # 1. Posiciones iniciales, distribuidas uniformemente
821
+ for level, subgroups in enumerate(H):
822
+
823
+ n = len(subgroups)
824
+ offset = -(n - 1) * dx / 2
825
+
826
+ for k, subgroup in enumerate(subgroups):
827
+
828
+ node = S.index(subgroup)
829
+
830
+ pos[node] = (
831
+ offset + k * dx,
832
+ level * dy
833
+ )
834
+
835
+
836
+ # 2. Ajustar cada nodo según sus predecesores
837
+ for level in range(1, len(H)):
838
+
839
+ for subgroup in H[level]:
840
+
841
+ node = S.index(subgroup)
842
+
843
+ predecessors = list(gr.predecessors(node))
844
+
845
+ if not predecessors:
846
+ continue
847
+
848
+ # Posición ideal: media de los predecesores
849
+ ideal_x = np.mean([
850
+ pos[p][0]
851
+ for p in predecessors
852
+ ])
853
+
854
+ y = level * dy
855
+
856
+ # --------------------------------------------------
857
+ # Buscar una posición libre alrededor de ideal_x
858
+ # --------------------------------------------------
859
+
860
+ x = ideal_x
861
+
862
+ occupied = [
863
+ p[0]
864
+ for n, p in pos.items()
865
+ if p[1] == y
866
+ ]
867
+
868
+ # Si está demasiado cerca de otro nodo,
869
+ # desplazamos alternativamente izquierda/derecha.
870
+ k = 0
871
+
872
+ while any(abs(x - ox) < min_distance for ox in occupied):
873
+
874
+ k += 1
875
+
876
+ if k % 2 == 1:
877
+ x = ideal_x + ((k + 1) // 2) * dx
878
+ else:
879
+ x = ideal_x - (k // 2) * dx
880
+
881
+ pos[node] = (x, y)
882
+
883
+ labels = nx.get_node_attributes(gr, "label")
884
+ nx.draw(gr, pos, with_labels=True, labels=labels, node_shape="s", node_color="white", edgecolors="black", node_size=1000, arrows=False)
885
+ #nx.draw_networkx_edges(gr,pos,arrows=False)
886
+ plt.show()
887
+
888
+
889
+
890
+
891
+
709
892
  #–> AUTOMORPHISMS
710
893
 
711
894
  def is_automorphism(self, phi):
@@ -1063,6 +1246,29 @@ class CayleySubgroup(CayleyGroup, Subgroup):
1063
1246
  def __lt__(self, group):
1064
1247
  return group==self.group and self.subgroup.order()<self.group.order()
1065
1248
 
1249
+ def _isin(self, subgroup):
1250
+ if not isinstance(subgroup, CayleySubgroup):
1251
+ return False
1252
+
1253
+ return set(self._indices).issubset(set(subgroup._indices))
1254
+
1255
+ def _is_covered(self, other):
1256
+ if not self._isin(other):
1257
+ return False
1258
+
1259
+ if set(self._indices) == set(other._indices):
1260
+ return False
1261
+
1262
+ for intermediate in other.group.subgroups():
1263
+ # Comprobamos que no sea idéntico en contenido a self ni a other
1264
+ if set(intermediate._indices) == set(self._indices) or set(intermediate._indices) == set(other._indices):
1265
+ continue
1266
+
1267
+ if self._isin(intermediate) and intermediate._isin(other):
1268
+ return False
1269
+
1270
+ return True
1271
+
1066
1272
  #–> QUOTIENTS
1067
1273
 
1068
1274
  def coset(self, element, side="left", return_names=True):
@@ -1187,6 +1393,9 @@ class Element:
1187
1393
  inv = self.group.inverse(self.element)
1188
1394
  return Element(inv, self.group)
1189
1395
 
1396
+ def order(self):
1397
+ return self.group.element_orders()[self.index]
1398
+
1190
1399
  class Automorphism:
1191
1400
 
1192
1401
  def __init__(self,phi:tuple,group:CayleyGroup):
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "GroupsMath" # Nombre en PyPI
7
- version = "0.7.1"
7
+ version = "0.7.2"
8
8
  description = "The educational Python library for Group Theory"
9
9
  readme = "README.md" # Esta será la documentación visible en la portada de PyPI
10
10
  requires-python = ">=3.8"
File without changes
File without changes